package game import ( "image/color" "time" "github.com/hajimehoshi/ebiten/v2" "github.com/atridad/BigFeelings/internal/hero" "github.com/atridad/BigFeelings/internal/status" "github.com/atridad/BigFeelings/internal/ui/hud" ) const ( ScreenWidth = 960 ScreenHeight = 540 TargetTPS = 60 WindowTitle = "Big Feelings" ) var ( backgroundColor = color.NRGBA{R: 0, G: 0, B: 0, A: 255} ) type controls struct { Left bool Right bool Up bool Down bool } func readControls() controls { return controls{ Left: ebiten.IsKeyPressed(ebiten.KeyArrowLeft) || ebiten.IsKeyPressed(ebiten.KeyA), Right: ebiten.IsKeyPressed(ebiten.KeyArrowRight) || ebiten.IsKeyPressed(ebiten.KeyD), Up: ebiten.IsKeyPressed(ebiten.KeyArrowUp) || ebiten.IsKeyPressed(ebiten.KeyW), Down: ebiten.IsKeyPressed(ebiten.KeyArrowDown) || ebiten.IsKeyPressed(ebiten.KeyS), } } type Game struct { state *state } func New() *Game { return &Game{state: newState()} } func (g *Game) Update() error { g.state.update(readControls()) return nil } func (g *Game) Draw(screen *ebiten.Image) { g.state.draw(screen) } func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) { return ScreenWidth, ScreenHeight } type state struct { hero *hero.Hero status *status.Manager hud hud.Overlay bounds hero.Bounds lastTick time.Time } func newState() *state { now := time.Now() return &state{ hero: hero.New(hero.Config{ StartX: ScreenWidth / 2, StartY: ScreenHeight / 2, Radius: 28, Speed: 180, Color: color.NRGBA{R: 210, G: 220, B: 255, A: 255}, }), status: status.NewManager([]status.Config{ {Label: "Core", Base: 60, Color: color.NRGBA{R: 255, G: 208, B: 0, A: 255}}, {Label: "Drive", Base: 45, Color: color.NRGBA{R: 0, G: 190, B: 255, A: 255}}, {Label: "Flux", Base: 30, Color: color.NRGBA{R: 255, G: 92, B: 120, A: 255}}, }), hud: hud.Overlay{ X: ScreenWidth - 220, Y: 20, Color: color.White, }, bounds: hero.Bounds{ Width: ScreenWidth, Height: ScreenHeight, }, lastTick: now, } } func (s *state) update(input controls) { now := time.Now() dt := now.Sub(s.lastTick).Seconds() s.lastTick = now s.hero.Update(hero.Input{ Left: input.Left, Right: input.Right, Up: input.Up, Down: input.Down, }, dt, s.bounds) s.status.Update() } func (s *state) draw(screen *ebiten.Image) { screen.Fill(backgroundColor) s.hero.Draw(screen) s.hud.Draw(screen, s.status.Meters()) }