package tins2020 import ( "github.com/veandco/go-sdl2/sdl" ) type GameControls struct { Container game *Game dialogs *Dialogs menu ButtonBar top ButtonBar flowers ButtonBar otherTools ButtonBar pause *IconButton run *IconButton runFast *IconButton shovel *IconButton research *IconButton } func NewGameControls(game *Game, dialogs *Dialogs) *GameControls { return &GameControls{game: game, dialogs: dialogs} } func (c *GameControls) createBuyFlowerButton(id string) *BuyFlowerButton { flower, _ := c.game.Herbarium.Find(id) return NewBuyFlowerButton( flower.IconTemplate.Variant(1), flower.IconTemplate.Disabled(), id, flower, EmptyEvent(func() { c.game.SelectPlantFlowerTool(id) }), ) } func (c *GameControls) speedChanged(state interface{}) { speed := state.(GameSpeed) disable := func(b *IconButton, expected GameSpeed) { b.IsDisabled = speed == expected } disable(c.pause, GameSpeedPaused) disable(c.run, GameSpeedNormal) disable(c.runFast, GameSpeedFast) } func (c *GameControls) toolChanged(state interface{}) { tool, _ := state.(Tool) var flowerID string if tool, ok := tool.(*PlantFlowerTool); ok { flowerID = tool.FlowerID } for _, control := range c.flowers.Buttons { button := control.(*BuyFlowerButton) button.IsActive = button.FlowerID == flowerID button.IsDisabled = !c.game.Herbarium.IsUnlocked(button.FlowerID) } _, shovel := tool.(*ShovelTool) c.shovel.IsActive = shovel } func (c *GameControls) updateFlowerControls(ctx *Context) { for _, b := range c.flowers.Buttons { button := b.(*BuyFlowerButton) flower, ok := c.game.Herbarium.Find(button.FlowerID) if ok { button.Update(ctx, flower) } } } func (c *GameControls) Arrange(ctx *Context, bounds Rectangle) { c.Bounds = bounds c.menu.Arrange(ctx, Rect(bounds.X, bounds.Y, buttonBarWidth, bounds.H)) c.top.Arrange(ctx, RectAbs(bounds.X+bounds.W/2+8, bounds.Y, bounds.Right(), bounds.Y+64)) c.flowers.Arrange(ctx, Rect(bounds.Right()-buttonBarWidth, bounds.Y, buttonBarWidth, bounds.H)) c.otherTools.Arrange(ctx, Rect(bounds.Right()-buttonBarWidth, bounds.Bottom()-2*buttonBarWidth, buttonBarWidth, 2*buttonBarWidth)) } func (c *GameControls) Init(ctx *Context) error { c.game.SpeedChanged().RegisterItf(c.speedChanged) c.game.ToolChanged().RegisterItf(c.toolChanged) c.dialogs.DialogOpened().Register(func() { c.game.Pause() }) c.dialogs.DialogClosed().Register(func() { c.updateFlowerControls(ctx) c.game.Resume() }) c.flowers.Background = MustHexColor("#356dad") c.flowers.ButtonLength = 64 for _, id := range c.game.Herbarium.Flowers() { c.flowers.Buttons = append(c.flowers.Buttons, c.createBuyFlowerButton(id)) } c.top.Orientation = OrientationHorizontal c.pause = NewIconButtonConfig("control-pause", EmptyEvent(func() { c.game.Pause() }), func(b *IconButton) { b.IconDisabled = "control-pause-disabled" }) c.run = NewIconButtonConfig("control-run", EmptyEvent(func() { c.game.Run() }), func(b *IconButton) { b.IconDisabled = "control-run-disabled" }) c.runFast = NewIconButtonConfig("control-run-fast", EmptyEvent(func() { c.game.RunFast() }), func(b *IconButton) { b.IconDisabled = "control-run-fast-disabled" }) c.speedChanged(c.game.Speed) c.top.Buttons = []Control{c.pause, c.run, c.runFast} c.menu.Background = MustHexColor("#356dad") c.menu.Buttons = []Control{ NewIconButtonConfig("control-settings", c.dialogs.ShowSettings, func(b *IconButton) { b.IsDisabled = true b.IconDisabled = "#afafaf" }), NewIconButton("control-save", func(*Context) { c.game.Save() }), NewIconButton("control-load", func(ctx *Context) { c.game.Load() c.updateFlowerControls(ctx) }), NewIconButton("control-new", func(ctx *Context) { c.game.New() c.updateFlowerControls(ctx) }), NewIconButton("control-information", c.dialogs.ShowIntro), } c.shovel = NewIconButtonConfig("control-shovel", func(*Context) { c.game.SelectShovel() }, func(b *IconButton) { b.IconHeight = 32 }) c.research = NewIconButtonConfig("control-research", c.dialogs.ShowResearch, func(b *IconButton) { b.IconHeight = 32 }) c.otherTools.Buttons = []Control{c.shovel, c.research} c.Container.AddChild(&c.menu) c.Container.AddChild(&c.top) c.Container.AddChild(&c.flowers) c.Container.AddChild(&c.otherTools) return c.Container.Init(ctx) } func (c *GameControls) Handle(ctx *Context, event sdl.Event) bool { if c.Container.Handle(ctx, event) { return true } switch e := event.(type) { case *sdl.KeyboardEvent: if e.Type == sdl.KEYDOWN { switch e.Keysym.Sym { case sdl.K_SPACE: c.game.TogglePause() case sdl.K_1: c.game.Run() case sdl.K_2: c.game.RunFast() case sdl.K_h: c.game.SelectShovel() case sdl.K_r: c.dialogs.ShowResearch(ctx) case sdl.K_ESCAPE: if c.game.Tool() == nil { c.dialogs.ShowIntro(ctx) } else { c.game.CancelTool() } return true case sdl.K_F3: c.game.Debug = !c.game.Debug } } } return false } func (c *GameControls) Render(ctx *Context) { topBar := MustHexColor("#0000007f") SetDrawColor(ctx.Renderer, topBar) ctx.Renderer.FillRect(RectAbs(c.menu.Bounds.Right(), 0, c.flowers.Bounds.X, 64).SDLPtr()) ctx.Fonts.Font("balance").RenderCopyAlign(ctx.Renderer, FmtMoney(c.game.Balance), Pt(c.top.Bounds.X-8, 58), MustHexColor("#4AC69A"), TextAlignmentRight) c.Container.Render(ctx) }