Add date display
parent
e052247590
commit
07a2dd7953
|
@ -46,16 +46,17 @@ func LoadSounds(ctx *audio.Context) {
|
|||
SoundSelect = LoadWAV(ctx, "sound/select/select.wav")
|
||||
SoundSelect.SetVolume(0.6)
|
||||
|
||||
const popVolume = 0.2
|
||||
SoundPop1 = LoadWAV(ctx, "sound/pop/pop1.wav")
|
||||
SoundPop2 = LoadWAV(ctx, "sound/pop/pop2.wav")
|
||||
SoundPop3 = LoadWAV(ctx, "sound/pop/pop3.wav")
|
||||
SoundPop4 = LoadWAV(ctx, "sound/pop/pop4.wav")
|
||||
SoundPop5 = LoadWAV(ctx, "sound/pop/pop5.wav")
|
||||
SoundPop1.SetVolume(0.2)
|
||||
SoundPop2.SetVolume(0.2)
|
||||
SoundPop3.SetVolume(0.2)
|
||||
SoundPop4.SetVolume(0.2)
|
||||
SoundPop5.SetVolume(0.2)
|
||||
SoundPop1.SetVolume(popVolume)
|
||||
SoundPop2.SetVolume(popVolume)
|
||||
SoundPop3.SetVolume(popVolume)
|
||||
SoundPop4.SetVolume(popVolume)
|
||||
SoundPop5.SetVolume(popVolume)
|
||||
}
|
||||
|
||||
func LoadImage(p string) *ebiten.Image {
|
||||
|
|
|
@ -11,5 +11,8 @@ import (
|
|||
func parseFlags() {
|
||||
world.World.DisableEsc = true
|
||||
|
||||
// Adjust minimum zoom level due to performance decrease when targeting WASM.
|
||||
world.CameraMinZoom = 0.6
|
||||
|
||||
ebiten.SetFullscreen(true)
|
||||
}
|
||||
|
|
|
@ -296,10 +296,17 @@ func (g *game) Draw(screen *ebiten.Image) {
|
|||
func (g *game) addSystems() {
|
||||
ecs := ECS
|
||||
|
||||
// Simulation systems.
|
||||
ecs.AddSystem(system.NewTickSystem())
|
||||
ecs.AddSystem(system.NewPowerScanSystem())
|
||||
|
||||
// Input systems.
|
||||
g.movementSystem = system.NewMovementSystem()
|
||||
ecs.AddSystem(system.NewPlayerMoveSystem(world.World.Player, g.movementSystem))
|
||||
ecs.AddSystem(system.NewplayerFireSystem())
|
||||
ecs.AddSystem(g.movementSystem)
|
||||
|
||||
// Render systems.
|
||||
ecs.AddSystem(system.NewCreepSystem())
|
||||
ecs.AddSystem(system.NewCameraSystem())
|
||||
g.renderSystem = system.NewRenderSystem()
|
||||
|
|
|
@ -109,12 +109,10 @@ func (s *playerMoveSystem) Update(ctx *gohan.Context) error {
|
|||
}
|
||||
}
|
||||
world.World.CamScaleTarget += scrollY * (world.World.CamScaleTarget / 7)
|
||||
const minZoom = .4
|
||||
const maxZoom = 1
|
||||
if world.World.CamScaleTarget < minZoom {
|
||||
world.World.CamScaleTarget = minZoom
|
||||
} else if world.World.CamScaleTarget > maxZoom {
|
||||
world.World.CamScaleTarget = maxZoom
|
||||
if world.World.CamScaleTarget < world.CameraMinZoom {
|
||||
world.World.CamScaleTarget = world.CameraMinZoom
|
||||
} else if world.World.CamScaleTarget > world.CameraMaxZoom {
|
||||
world.World.CamScaleTarget = world.CameraMaxZoom
|
||||
}
|
||||
|
||||
// Smooth zoom transition.
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
package system
|
||||
|
||||
import (
|
||||
"code.rocketnine.space/tslocum/citylimits/component"
|
||||
"code.rocketnine.space/tslocum/citylimits/world"
|
||||
"code.rocketnine.space/tslocum/gohan"
|
||||
"github.com/hajimehoshi/ebiten/v2"
|
||||
)
|
||||
|
||||
type PowerScanSystem struct {
|
||||
}
|
||||
|
||||
func NewPowerScanSystem() *PowerScanSystem {
|
||||
s := &PowerScanSystem{}
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *PowerScanSystem) Needs() []gohan.ComponentID {
|
||||
return []gohan.ComponentID{
|
||||
component.PositionComponentID,
|
||||
component.VelocityComponentID,
|
||||
component.WeaponComponentID,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *PowerScanSystem) Uses() []gohan.ComponentID {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *PowerScanSystem) Update(_ *gohan.Context) error {
|
||||
if world.World.Paused {
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO use a consistent procedure to check each building that needs power
|
||||
// as connected via road to a power plant, and power-out buildings without enough power
|
||||
// "citizens report brown-outs"
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *PowerScanSystem) Draw(ctx *gohan.Context, screen *ebiten.Image) error {
|
||||
return gohan.ErrSystemWithoutDraw
|
||||
}
|
|
@ -16,14 +16,16 @@ type RenderHudSystem struct {
|
|||
op *ebiten.DrawImageOptions
|
||||
hudImg *ebiten.Image
|
||||
tmpImg *ebiten.Image
|
||||
tmpImg2 *ebiten.Image
|
||||
sidebarColor color.RGBA
|
||||
}
|
||||
|
||||
func NewRenderHudSystem() *RenderHudSystem {
|
||||
s := &RenderHudSystem{
|
||||
op: &ebiten.DrawImageOptions{},
|
||||
hudImg: ebiten.NewImage(1, 1),
|
||||
tmpImg: ebiten.NewImage(1, 1),
|
||||
op: &ebiten.DrawImageOptions{},
|
||||
hudImg: ebiten.NewImage(1, 1),
|
||||
tmpImg: ebiten.NewImage(1, 1),
|
||||
tmpImg2: ebiten.NewImage(1, 1),
|
||||
}
|
||||
|
||||
sidebarShade := uint8(111)
|
||||
|
@ -65,9 +67,11 @@ func (s *RenderHudSystem) drawSidebar() {
|
|||
if bounds.Dx() != world.World.ScreenW || bounds.Dy() != world.World.ScreenH {
|
||||
s.hudImg = ebiten.NewImage(world.World.ScreenW, world.World.ScreenH)
|
||||
s.tmpImg = ebiten.NewImage(world.SidebarWidth, world.World.ScreenH)
|
||||
s.tmpImg2 = ebiten.NewImage(world.SidebarWidth, world.World.ScreenH)
|
||||
} else {
|
||||
s.hudImg.Clear()
|
||||
s.tmpImg.Clear()
|
||||
s.tmpImg2.Clear()
|
||||
}
|
||||
w := world.SidebarWidth
|
||||
if bounds.Dx() < w {
|
||||
|
@ -75,15 +79,15 @@ func (s *RenderHudSystem) drawSidebar() {
|
|||
}
|
||||
|
||||
// Fill background.
|
||||
s.tmpImg.Fill(s.sidebarColor)
|
||||
s.hudImg.SubImage(image.Rect(0, 0, world.SidebarWidth, world.World.ScreenH)).(*ebiten.Image).Fill(s.sidebarColor)
|
||||
|
||||
// Draw buttons.
|
||||
|
||||
paddingSize := 1
|
||||
columns := 3
|
||||
const paddingSize = 1
|
||||
const columns = 3
|
||||
|
||||
buttonWidth := world.SidebarWidth / columns
|
||||
buttonHeight := buttonWidth
|
||||
const buttonWidth = world.SidebarWidth / columns
|
||||
const buttonHeight = buttonWidth
|
||||
world.World.HUDButtonRects = make([]image.Rectangle, len(world.HUDButtons))
|
||||
var lastButtonY int
|
||||
for i, button := range world.HUDButtons {
|
||||
|
@ -107,8 +111,10 @@ func (s *RenderHudSystem) drawSidebar() {
|
|||
lastButtonY = y
|
||||
}
|
||||
|
||||
s.drawDate(lastButtonY + buttonHeight + 5)
|
||||
|
||||
// Draw RCI indicator.
|
||||
rciPadding := buttonWidth / 2
|
||||
rciPadding := buttonWidth - 14
|
||||
const rciSize = 100
|
||||
rciX := buttonWidth
|
||||
rciY := lastButtonY + buttonHeight + rciPadding
|
||||
|
@ -198,12 +204,39 @@ func (s *RenderHudSystem) drawTooltip() {
|
|||
x, y := world.SidebarWidth, 0
|
||||
w, h := (len(label)*6+10)*int(scale), 22*(int(scale))
|
||||
r := image.Rect(x, y, x+w, y+h)
|
||||
s.hudImg.SubImage(r).(*ebiten.Image).Fill(color.RGBA{0, 0, 0, 120})
|
||||
|
||||
s.tmpImg.Clear()
|
||||
ebitenutil.DebugPrint(s.tmpImg, label)
|
||||
s.hudImg.SubImage(r).(*ebiten.Image).Fill(color.RGBA{0, 0, 0, 120})
|
||||
op := &ebiten.DrawImageOptions{}
|
||||
op.GeoM.Scale(scale, scale)
|
||||
op.GeoM.Translate(world.SidebarWidth+(4*scale), 4)
|
||||
s.hudImg.DrawImage(s.tmpImg, op)
|
||||
}
|
||||
|
||||
func (s *RenderHudSystem) drawDate(y int) {
|
||||
const datePadding = 10
|
||||
month, year := world.Date()
|
||||
label := month
|
||||
|
||||
scale := 2.0
|
||||
x, y := datePadding, y
|
||||
|
||||
s.tmpImg2.Clear()
|
||||
ebitenutil.DebugPrint(s.tmpImg2, label)
|
||||
op := &ebiten.DrawImageOptions{}
|
||||
op.GeoM.Scale(scale, scale)
|
||||
op.GeoM.Translate(float64(x), float64(y))
|
||||
s.hudImg.DrawImage(s.tmpImg2, op)
|
||||
|
||||
label = year
|
||||
|
||||
x = world.SidebarWidth - 1 - datePadding - (len(label) * 6 * int(scale))
|
||||
|
||||
s.tmpImg2.Clear()
|
||||
ebitenutil.DebugPrint(s.tmpImg2, label)
|
||||
op.GeoM.Reset()
|
||||
op.GeoM.Scale(scale, scale)
|
||||
op.GeoM.Translate(float64(x), float64(y))
|
||||
s.hudImg.DrawImage(s.tmpImg2, op)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
package system
|
||||
|
||||
import (
|
||||
"code.rocketnine.space/tslocum/citylimits/component"
|
||||
"code.rocketnine.space/tslocum/citylimits/world"
|
||||
"code.rocketnine.space/tslocum/gohan"
|
||||
"github.com/hajimehoshi/ebiten/v2"
|
||||
)
|
||||
|
||||
type TickSystem struct {
|
||||
}
|
||||
|
||||
func NewTickSystem() *TickSystem {
|
||||
s := &TickSystem{}
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *TickSystem) Needs() []gohan.ComponentID {
|
||||
return []gohan.ComponentID{
|
||||
component.PositionComponentID,
|
||||
component.VelocityComponentID,
|
||||
component.WeaponComponentID,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *TickSystem) Uses() []gohan.ComponentID {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *TickSystem) Update(_ *gohan.Context) error {
|
||||
if world.World.Paused {
|
||||
return nil
|
||||
}
|
||||
|
||||
world.World.Ticks++
|
||||
// Update date display.
|
||||
if world.World.Ticks%world.MonthTicks == 0 {
|
||||
world.World.HUDUpdated = true
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *TickSystem) Draw(ctx *gohan.Context, screen *ebiten.Image) error {
|
||||
return gohan.ErrSystemWithoutDraw
|
||||
}
|
|
@ -7,6 +7,7 @@ import (
|
|||
"log"
|
||||
"math/rand"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
|
||||
"code.rocketnine.space/tslocum/citylimits/asset"
|
||||
"code.rocketnine.space/tslocum/citylimits/component"
|
||||
|
@ -16,6 +17,13 @@ import (
|
|||
"github.com/lafriks/go-tiled"
|
||||
)
|
||||
|
||||
const startingYear = 1950
|
||||
|
||||
const (
|
||||
MonthTicks = 144 * 3
|
||||
YearTicks = MonthTicks * 12
|
||||
)
|
||||
|
||||
const TileSize = 64
|
||||
|
||||
var DirtTile = uint32(9*32 + (0))
|
||||
|
@ -41,6 +49,9 @@ type HUDButton struct {
|
|||
|
||||
var HUDButtons []*HUDButton
|
||||
|
||||
var CameraMinZoom = 0.4
|
||||
var CameraMaxZoom = 1.0
|
||||
|
||||
var World = &GameWorld{
|
||||
CamScale: startingZoom,
|
||||
CamScaleTarget: startingZoom,
|
||||
|
@ -121,6 +132,10 @@ type GameWorld struct {
|
|||
HUDUpdated bool
|
||||
HUDButtonRects []image.Rectangle
|
||||
|
||||
Ticks int
|
||||
|
||||
Paused bool
|
||||
|
||||
resetTipShown bool
|
||||
}
|
||||
|
||||
|
@ -502,3 +517,23 @@ var tooltips = map[int]string{
|
|||
func Tooltip() string {
|
||||
return tooltips[World.HoverStructure]
|
||||
}
|
||||
|
||||
var monthNames = []string{
|
||||
"January",
|
||||
"February",
|
||||
"March",
|
||||
"April",
|
||||
"May",
|
||||
"June",
|
||||
"July",
|
||||
"August",
|
||||
"September",
|
||||
"October",
|
||||
"November",
|
||||
"December",
|
||||
}
|
||||
|
||||
func Date() (month string, year string) {
|
||||
y, m := World.Ticks/YearTicks, (World.Ticks%YearTicks)/MonthTicks
|
||||
return monthNames[m], strconv.Itoa(startingYear + y)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue