// main.go package main import ( "fmt" "image" _ "image/png" "math" "os" "time" "github.com/faiface/pixel" "github.com/faiface/pixel/pixelgl" "golang.org/x/image/colornames" ) type Player struct { sprite *pixel.Sprite x, y, drag, maxSpeed, xV, yV, angularVelocity, acceleration float64 vec pixel.Vec } func loadSprite(path string) (pixel.Picture, error) { file, err := os.Open(path) if err != nil { return nil, err } defer file.Close() img, _, err := image.Decode(file) if err != nil { return nil, err } return pixel.PictureDataFromImage(img), nil } func createSpriteSheet(SpriteSheetImg pixel.Picture, spriteSizeX, spriteSizeY float64) []pixel.Rect { var frames []pixel.Rect for x := SpriteSheetImg.Bounds().Min.X; x < SpriteSheetImg.Bounds().Max.X; x += spriteSizeX { for y := SpriteSheetImg.Bounds().Min.Y; y < SpriteSheetImg.Bounds().Max.Y; y += spriteSizeY { frames = append(frames, pixel.R(x, y, x+256, y+256)) } } return frames } func run() { cfgMain := pixelgl.WindowConfig{ Title: "AsterCal", Bounds: pixel.R(0, 0, 1024, 768), VSync: true, } win, err := pixelgl.NewWindow(cfgMain) if err != nil { panic(err) } spritesheet, err := loadSprite("assets/ship_sprite_sheet.png") if err != nil { panic(err) } shipFrames := createSpriteSheet(spritesheet, 256, 256) var player Player player.x = win.Bounds().Max.X / 2 player.y = win.Bounds().Max.Y / 8 player.sprite = pixel.NewSprite(spritesheet, shipFrames[0]) player.maxSpeed = 350 player.acceleration = 600 //0.15 * player.maxSpeed player.drag = 1 player.xV = 0 player.yV = 0 player.vec.X = player.x player.vec.Y = player.y var angle float64 = 0.0 var angleInDegrees float64 = 0 var ( frames = 0 second = time.Tick(time.Second) ) last := time.Now() for !win.Closed() { dt := time.Since(last).Seconds() last = time.Now() win.Clear(colornames.Whitesmoke) player.vec = pixel.Vec{player.x, player.y} mat := pixel.IM mat = mat.Rotated(pixel.ZV, angle) mat = mat.Scaled(pixel.ZV, 0.25) mat = mat.Moved(player.vec) player.sprite.Draw(win, mat) if win.Pressed(pixelgl.KeyLeft) { angle += 3 * dt } if win.Pressed(pixelgl.KeyRight) { angle -= 3 * dt } if win.Pressed(pixelgl.KeyEscape) { win.SetClosed(true) } if win.Pressed(pixelgl.KeyUp) { player.xV += math.Cos(angle-(270*math.Pi)/180) * player.acceleration * dt player.yV += math.Sin(angle-(270*math.Pi)/180) * player.acceleration * dt if player.xV > player.maxSpeed { player.xV = player.maxSpeed } if player.xV < player.maxSpeed*-1 { player.xV = player.maxSpeed * -1 } if player.yV > player.maxSpeed { player.yV = player.maxSpeed } if player.yV < player.maxSpeed*-1 { player.yV = player.maxSpeed * -1 } } if win.Pressed(pixelgl.KeyDown) { } if angle == 0 { angleInDegrees = 0 } else { angleInDegrees = (angle) * 180 / math.Pi } if angleInDegrees == 360 || angleInDegrees == -360 { angle = 0 } if angleInDegrees > 360 { angle = angle - (360*math.Pi)/180 } if angleInDegrees < -360 { angle = angle + (360*math.Pi)/180 } if player.x >= win.Bounds().Max.X-10 { player.xV = -25 } if player.x <= win.Bounds().Min.X+10 { player.xV = 25 } if player.y >= win.Bounds().Max.Y-10 { player.yV = -25 } if player.y <= win.Bounds().Min.Y+10 { player.yV = 25 } player.x += player.xV * dt player.y += player.yV * dt if player.yV > 0 { player.yV -= player.drag if player.yV < 0 { player.yV = 0 } } if player.yV < 0 { player.yV += player.drag if player.yV > 0 { player.yV = 0 } } if player.xV > 0 { player.xV -= player.drag if player.xV < 0 { player.xV = 0 } } if player.xV < 0 { player.xV += player.drag if player.xV > 0 { player.xV = 0 } } win.Update() frames++ select { case <-second: win.SetTitle(fmt.Sprintf("%s | FPS: %d | playerYSpeed: %f", cfgMain.Title, frames, player.yV)) frames = 0 default: } } } func main() { pixelgl.Run(run) }