Sander Schobers
cd5ca3f04f
Separated some image related methods. Added feedback for simulation speed (colored buttons).
122 lines
2.4 KiB
Go
122 lines
2.4 KiB
Go
package tins2020
|
|
|
|
import (
|
|
"math/rand"
|
|
"time"
|
|
)
|
|
|
|
type Game struct {
|
|
Balance int
|
|
Speed GameSpeed
|
|
Terrain *Map
|
|
|
|
simulation Animation
|
|
}
|
|
|
|
type GameSpeed string
|
|
|
|
const (
|
|
GameSpeedNormal GameSpeed = "normal"
|
|
GameSpeedFast = "fast"
|
|
GameSpeedPaused = "paused"
|
|
)
|
|
|
|
type Map struct {
|
|
Temp NoiseMap
|
|
Humid NoiseMap
|
|
Variant NoiseMap
|
|
PlaceX NoiseMap // displacement map of props
|
|
PlaceY NoiseMap
|
|
|
|
Flowers map[Point]Flower
|
|
}
|
|
|
|
func (m *Map) AddFlower(pos Point, traits FlowerTraits) {
|
|
m.Flowers[pos] = m.NewFlower(pos, traits)
|
|
}
|
|
|
|
func (m *Map) NewFlower(pos Point, traits FlowerTraits) Flower {
|
|
flower := Flower{
|
|
Traits: traits,
|
|
}
|
|
temp, humid := float32(m.Temp.Value(pos.X, pos.Y)), float32(m.Humid.Value(pos.X, pos.Y))
|
|
flower.Traits.UpdateModifier(temp, humid)
|
|
return flower
|
|
}
|
|
|
|
const simulationInterval = 120 * time.Millisecond
|
|
const fastSimulationInterval = 40 * time.Millisecond
|
|
|
|
func NewGame() *Game {
|
|
terrain := &Map{
|
|
Temp: NewNoiseMap(rand.Int63()),
|
|
Humid: NewNoiseMap(rand.Int63()),
|
|
Variant: NewRandomNoiseMap(rand.Int63()),
|
|
PlaceX: NewRandomNoiseMap(rand.Int63()),
|
|
PlaceY: NewRandomNoiseMap(rand.Int63()),
|
|
Flowers: map[Point]Flower{},
|
|
}
|
|
terrain.AddFlower(Pt(0, 0), NewPoppyTraits())
|
|
return &Game{
|
|
Speed: GameSpeedNormal,
|
|
Balance: 100,
|
|
Terrain: terrain,
|
|
|
|
simulation: NewAnimation(time.Millisecond * 10),
|
|
}
|
|
}
|
|
|
|
func (g *Game) tick() {
|
|
randomNeighbor := func(pos Point) Point {
|
|
switch rand.Intn(4) {
|
|
case 0:
|
|
return Pt(pos.X-1, pos.Y)
|
|
case 1:
|
|
return Pt(pos.X, pos.Y-1)
|
|
case 2:
|
|
return Pt(pos.X+1, pos.Y)
|
|
case 3:
|
|
return Pt(pos.X, pos.Y+1)
|
|
}
|
|
return pos
|
|
}
|
|
flowers := map[Point]Flower{}
|
|
for pos, flower := range g.Terrain.Flowers {
|
|
if rand.Float32() < flower.Traits.Spread {
|
|
dst := randomNeighbor(pos)
|
|
if _, ok := g.Terrain.Flowers[dst]; !ok {
|
|
if _, ok := flowers[dst]; !ok {
|
|
flowers[dst] = g.Terrain.NewFlower(dst, flower.Traits)
|
|
}
|
|
}
|
|
}
|
|
if rand.Float32() < flower.Traits.Life*flower.Traits.LifeModifier {
|
|
flowers[pos] = flower
|
|
}
|
|
}
|
|
g.Terrain.Flowers = flowers
|
|
}
|
|
|
|
func (g *Game) Pause() {
|
|
g.Speed = GameSpeedPaused
|
|
g.simulation.Pause()
|
|
}
|
|
|
|
func (g *Game) Run() {
|
|
g.Speed = GameSpeedNormal
|
|
g.simulation.SetInterval(simulationInterval)
|
|
g.simulation.Run()
|
|
}
|
|
|
|
func (g *Game) RunFast() {
|
|
g.Speed = GameSpeedFast
|
|
g.simulation.SetInterval(fastSimulationInterval)
|
|
g.simulation.Run()
|
|
}
|
|
|
|
func (g *Game) Update() {
|
|
for g.simulation.Animate() {
|
|
g.tick()
|
|
}
|
|
}
|