tins2020/gamecontrols.go

218 lines
6.5 KiB
Go
Raw Normal View History

package tins2020
import (
2020-05-17 08:56:56 +00:00
"opslag.de/schobers/geom"
"opslag.de/schobers/zntg"
2020-05-23 07:11:08 +00:00
"opslag.de/schobers/zntg/play"
2020-05-17 08:56:56 +00:00
"opslag.de/schobers/zntg/ui"
)
2020-05-23 07:11:08 +00:00
const fpsOverlayName = "fps"
type GameControls struct {
2020-05-17 08:56:56 +00:00
ui.ContainerBase
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 {
2020-05-17 19:15:44 +00:00
return &GameControls{game: game, dialogs: dialogs}
}
2020-05-17 08:56:56 +00:00
2020-05-17 19:15:44 +00:00
func (c *GameControls) Init(ctx ui.Context) {
2020-05-23 07:11:08 +00:00
ctx.Overlays().AddOnTop(fpsOverlayName, &play.FPS{}, false)
2020-05-17 08:56:56 +00:00
c.game.SpeedChanged().AddHandler(c.speedChanged)
c.game.ToolChanged().AddHandler(c.toolChanged)
c.dialogs.DialogOpened().AddHandlerEmpty(func(ctx ui.Context) { c.game.Pause(ctx) })
c.dialogs.DialogClosed().AddHandlerEmpty(func(ctx ui.Context) {
c.updateFlowerControls()
c.game.Resume(ctx)
})
2020-05-23 07:11:08 +00:00
c.flowers.Background = zntg.MustHexColor("#356DAD")
2020-05-17 08:56:56 +00:00
c.flowers.ButtonLength = 64
for _, id := range c.game.Herbarium.Flowers() {
c.flowers.Children = append(c.flowers.Children, c.createBuyFlowerButton(id))
}
c.top.Orientation = ui.OrientationHorizontal
c.pause = NewIconButtonConfigure("control-pause", func(ctx ui.Context) {
c.game.Pause(ctx)
}, func(b *IconButton) {
2020-05-23 07:11:08 +00:00
b.DisabledColor = ctx.Style().Palette.Secondary
2020-05-17 08:56:56 +00:00
b.Tooltip = "Pause game"
})
c.run = NewIconButtonConfigure("control-run", func(ctx ui.Context) {
c.game.Run(ctx)
}, func(b *IconButton) {
2020-05-23 07:11:08 +00:00
b.DisabledColor = ctx.Style().Palette.Secondary
2020-05-17 08:56:56 +00:00
b.Tooltip = "Run game at normal speed"
})
c.runFast = NewIconButtonConfigure("control-run-fast", func(ctx ui.Context) {
c.game.RunFast(ctx)
}, func(b *IconButton) {
2020-05-23 07:11:08 +00:00
b.DisabledColor = ctx.Style().Palette.Secondary
2020-05-17 08:56:56 +00:00
b.Tooltip = "Run game at fast speed"
})
c.speedChanged(nil, c.game.Speed)
c.top.Children = []ui.Control{c.pause, c.run, c.runFast}
2020-05-23 07:11:08 +00:00
c.menu.Background = zntg.MustHexColor("#356DAD")
2020-05-17 08:56:56 +00:00
c.menu.Children = []ui.Control{
NewIconButtonConfigure("control-settings", c.dialogs.ShowSettings, func(b *IconButton) {
b.Disabled = true
2020-05-23 07:11:08 +00:00
b.DisabledColor = zntg.MustHexColor("#AFAFAF")
2020-05-17 08:56:56 +00:00
}),
NewIconButtonConfigure("control-save", func(ui.Context) { c.game.Save() }, func(b *IconButton) {
b.Tooltip = "Save game (overwrites previous save; no confirmation)"
}),
NewIconButtonConfigure("control-load", func(ctx ui.Context) {
c.game.Load(ctx)
c.updateFlowerControls()
}, func(b *IconButton) {
b.Tooltip = "Load last saved game (no confirmation)"
}),
NewIconButtonConfigure("control-new", func(ctx ui.Context) {
c.game.New(ctx)
c.updateFlowerControls()
}, func(b *IconButton) {
b.Tooltip = "Start new game (no confirmation)"
}),
NewIconButtonConfigure("control-information", c.dialogs.ShowIntro, func(b *IconButton) {
b.Tooltip = "Show information/intro"
}),
}
2020-05-23 07:11:08 +00:00
for i, child := range c.menu.Children {
c.menu.Children[i] = ui.FixedHeight(child, 96)
}
2020-05-17 08:56:56 +00:00
c.shovel = NewIconButtonConfigure("control-shovel", func(ctx ui.Context) { c.game.SelectShovel(ctx) }, func(b *IconButton) {
b.Tooltip = "Select harvest tool (key: H)"
})
c.research = NewIconButtonConfigure("control-research", c.dialogs.ShowResearch, func(b *IconButton) {
b.Tooltip = "Conduct research (key: R)"
})
c.otherTools.Children = []ui.Control{c.shovel, c.research}
2020-05-23 07:11:08 +00:00
for i, child := range c.otherTools.Children {
c.otherTools.Children[i] = ui.FixedHeight(child, 96)
}
2020-05-17 08:56:56 +00:00
c.AddChild(&c.menu)
c.AddChild(&c.top)
c.AddChild(&c.flowers)
c.AddChild(&c.otherTools)
}
func (c *GameControls) createBuyFlowerButton(id string) *BuyFlowerButton {
flower, _ := c.game.Herbarium.Find(id)
return NewBuyFlowerButton(
flower.IconTemplate.Variant(1),
flower.IconTemplate.Disabled(),
id,
flower,
2020-05-17 08:56:56 +00:00
func(ctx ui.Context) {
c.game.SelectPlantFlowerTool(ctx, id)
},
)
}
2020-05-17 08:56:56 +00:00
func (c *GameControls) speedChanged(_ ui.Context, state interface{}) {
speed := state.(GameSpeed)
disable := func(b *IconButton, expected GameSpeed) {
2020-05-17 08:56:56 +00:00
b.Disabled = speed == expected
}
disable(c.pause, GameSpeedPaused)
disable(c.run, GameSpeedNormal)
disable(c.runFast, GameSpeedFast)
}
2020-05-17 08:56:56 +00:00
func (c *GameControls) toolChanged(_ ui.Context, state interface{}) {
tool, _ := state.(Tool)
var flowerID string
if tool, ok := tool.(*PlantFlowerTool); ok {
flowerID = tool.FlowerID
}
2020-05-17 08:56:56 +00:00
for _, control := range c.flowers.Children {
button := control.(*BuyFlowerButton)
2020-05-23 07:11:08 +00:00
button.Active = button.FlowerID == flowerID
2020-05-17 08:56:56 +00:00
button.Disabled = !c.game.Herbarium.IsUnlocked(button.FlowerID)
}
_, shovel := tool.(*ShovelTool)
2020-05-23 07:11:08 +00:00
c.shovel.Active = shovel
}
2020-05-17 08:56:56 +00:00
func (c *GameControls) updateFlowerControls() {
for _, b := range c.flowers.Children {
2020-05-11 09:53:15 +00:00
button := b.(*BuyFlowerButton)
flower, ok := c.game.Herbarium.Find(button.FlowerID)
if ok {
2020-05-17 08:56:56 +00:00
button.Update(flower)
2020-05-11 09:53:15 +00:00
}
}
}
2020-05-17 08:56:56 +00:00
func (c *GameControls) Arrange(ctx ui.Context, bounds geom.RectangleF32, offset geom.PointF32, parent ui.Control) {
c.ContainerBase.Arrange(ctx, bounds, offset, parent)
2020-05-17 08:56:56 +00:00
c.menu.Arrange(ctx, geom.RectRelF32(bounds.Min.X, bounds.Min.Y, buttonBarWidth, bounds.Dy()), offset, c)
c.top.Arrange(ctx, geom.RectF32(bounds.Min.X+bounds.Dx()/2+8, bounds.Min.Y, bounds.Max.X, bounds.Min.Y+64), offset, c)
c.flowers.Arrange(ctx, geom.RectRelF32(bounds.Max.X-buttonBarWidth, bounds.Min.Y, buttonBarWidth, bounds.Dy()), offset, c)
2020-05-23 07:11:08 +00:00
otherToolsSize := c.otherTools.DesiredSize(ctx, bounds.Size())
c.otherTools.Arrange(ctx, geom.RectRelF32(bounds.Max.X-buttonBarWidth, bounds.Max.Y-otherToolsSize.Y, buttonBarWidth, 2*buttonBarWidth), offset, c)
}
2020-05-17 08:56:56 +00:00
func (c *GameControls) Handle(ctx ui.Context, event ui.Event) bool {
if c.ContainerBase.Handle(ctx, event) {
return true
}
switch e := event.(type) {
2020-05-17 08:56:56 +00:00
case *ui.KeyDownEvent:
switch e.Key {
case ui.KeySpace:
c.game.TogglePause(ctx)
case ui.Key1:
c.game.Run(ctx)
case ui.Key2:
c.game.RunFast(ctx)
case ui.KeyH:
c.game.SelectShovel(ctx)
case ui.KeyR:
c.dialogs.ShowResearch(ctx)
case ui.KeyEscape:
if c.game.Tool() == nil {
c.dialogs.ShowIntro(ctx)
} else {
c.game.CancelTool(ctx)
}
2020-05-17 08:56:56 +00:00
return true
2020-05-23 07:11:08 +00:00
case ui.KeyF4:
2020-05-17 08:56:56 +00:00
c.game.Debug = !c.game.Debug
2020-05-23 07:11:08 +00:00
ctx.Overlays().Toggle(fpsOverlayName)
}
}
return false
}
2020-05-17 08:56:56 +00:00
func (c *GameControls) Render(ctx ui.Context) {
2020-05-23 07:11:08 +00:00
topBar := zntg.MustHexColor("#0000007F")
2020-05-17 08:56:56 +00:00
ctx.Renderer().FillRectangle(geom.RectF32(c.menu.Bounds().Max.X, 0, c.flowers.Bounds().Min.X, 64), topBar)
2020-05-23 07:11:08 +00:00
ctx.Fonts().TextAlign("balance", geom.PtF32(c.top.Bounds().Min.X-8, 4), zntg.MustHexColor("#4AC69A"), FmtMoney(c.game.Balance), ui.AlignRight)
2020-05-17 08:56:56 +00:00
c.ContainerBase.Render(ctx)
}