diff --git a/main.go b/main.go index f12fbfd..fd232a1 100644 --- a/main.go +++ b/main.go @@ -4,12 +4,12 @@ import ( "fmt" _ "image/png" "log" + "time" "github.com/hajimehoshi/ebiten/v2" "github.com/hajimehoshi/ebiten/v2/ebitenutil" "github.com/hajimehoshi/ebiten/v2/inpututil" "gitlab.com/kbr4/9heroja/collision" - "gitlab.com/kbr4/9heroja/configuration" "gitlab.com/kbr4/9heroja/input" "gitlab.com/kbr4/9heroja/terrain" "gitlab.com/kbr4/9heroja/tiles" @@ -43,12 +43,6 @@ func floorMod(x, y int) int { } type Game struct { - - // The gopher's position - x16 int - y16 int - vy16 int - keys []ebiten.Key control *input.Keyboard @@ -59,12 +53,16 @@ type Game struct { bullets []*weapons.Handgun ending *tiles.Ending starting *tiles.Starting + + gameSpeed time.Duration + tickCount int + zombiesToSpawn int + zombieSpawnTicker *time.Ticker } func (g *Game) Update() error { g.keys = inpututil.AppendPressedKeys(g.keys[:0]) GameInstance.terrain.ChangeDirection(GameInstance.control.DirectionFromKeys(g.keys)) - g.world.NotifyAboutCollisions() return nil } @@ -105,28 +103,38 @@ func init() { GameInstance = &Game{} GameInstance.world = collision.NewWorld() GameInstance.control = &input.Keyboard{} - GameInstance.zombies = []*zombie.Zombie{zombie.NewZombie(), zombie.NewZombie(), zombie.NewZombie(), zombie.NewZombie(), zombie.NewZombie()} + GameInstance.zombies = []*zombie.Zombie{} GameInstance.ending = tiles.NewEnding() GameInstance.starting = tiles.NewStarting() GameInstance.world.AddEntity(GameInstance.starting) GameInstance.world.AddEntity(GameInstance.ending) - // put zombies in random places on the screen but not too close to the hero or each other - for _, z := range GameInstance.zombies { - z.X = float64(configuration.Random(50, screenWidth-50)) - z.Y = float64(configuration.Random(50, screenHeight-50)) - for z.X > float64(screenWidth/2-64) && z.X < float64(screenWidth/2+64) && z.Y > float64(screenHeight/2-64) && z.Y < float64(screenHeight/2+64) { - z.X = float64(configuration.Random(0, screenWidth)) - z.Y = float64(configuration.Random(0, screenHeight)) - } - z.WhereToGoX = GameInstance.ending.X - z.WhereToGoY = GameInstance.ending.Y - z.Walk() - GameInstance.world.AddEntity(z) - } + GameInstance.gameSpeed = 100 * time.Millisecond + GameInstance.zombieSpawnTicker = time.NewTicker(GameInstance.gameSpeed) + GameInstance.zombiesToSpawn = 20 GameInstance.terrain = terrain.NewTerrain() + + go func() { + log.Println("Starting zombie spawn ticker") + for { + select { + case <-GameInstance.zombieSpawnTicker.C: + GameInstance.tickCount++ + if GameInstance.tickCount%10 == 0 && GameInstance.zombiesToSpawn > 0 { + z := GameInstance.starting.SpawnZombie(GameInstance.ending.X, GameInstance.ending.Y) + GameInstance.zombies = append(GameInstance.zombies, z) + GameInstance.world.AddEntity(z) + GameInstance.zombiesToSpawn-- + } + } + if GameInstance.zombiesToSpawn <= 0 { + GameInstance.zombieSpawnTicker.Stop() + break + } + } + }() } func main() { diff --git a/tiles/starting.go b/tiles/starting.go index 9fda11b..24691c9 100644 --- a/tiles/starting.go +++ b/tiles/starting.go @@ -9,6 +9,7 @@ import ( "github.com/hajimehoshi/ebiten/v2" "gitlab.com/kbr4/9heroja/collision" "gitlab.com/kbr4/9heroja/resources" + "gitlab.com/kbr4/9heroja/zombie" ) var ( @@ -75,3 +76,13 @@ func (s *Starting) HandleCollisionEvent(other collision.Collidable) { fmt.Println("Starting hit by zombie") } } + +func (s *Starting) SpawnZombie(whereToGoX, whereToGoY float64) *zombie.Zombie { + z := zombie.NewZombie() + z.X = s.X + z.Y = s.Y + z.WhereToGoX = whereToGoX + z.WhereToGoY = whereToGoY + z.Walk() + return z +} diff --git a/zombie/zombie.go b/zombie/zombie.go index 7fc993d..e5f4789 100644 --- a/zombie/zombie.go +++ b/zombie/zombie.go @@ -3,34 +3,35 @@ package zombie import ( "bytes" "fmt" + "image" + "log" + "time" + "github.com/hajimehoshi/ebiten/v2" "gitlab.com/kbr4/9heroja/collision" "gitlab.com/kbr4/9heroja/configuration" "gitlab.com/kbr4/9heroja/resources" - "image" - "log" - "time" ) const WalkSpeedMs = 10 var ( - zombieImage *ebiten.Image - walkTicker *time.Ticker - animationTicker *time.Ticker + zombieImage *ebiten.Image ) type Zombie struct { - step int - direction configuration.Direction - IsWalking bool - X float64 - Y float64 - OffsetX float64 - OffsetY float64 - WhereToGoX float64 - WhereToGoY float64 - IsDead bool + step int + direction configuration.Direction + IsWalking bool + X float64 + Y float64 + OffsetX float64 + OffsetY float64 + WhereToGoX float64 + WhereToGoY float64 + IsDead bool + walkTicker *time.Ticker + animationTicker *time.Ticker } type spritePosition struct { @@ -77,8 +78,6 @@ func init() { log.Fatal(err) } zombieImage = ebiten.NewImageFromImage(img) - walkTicker = time.NewTicker(WalkSpeedMs * time.Millisecond) - animationTicker = time.NewTicker(WalkSpeedMs * 5 * time.Millisecond) // Adjust the speed of animation frames } func NewZombie() *Zombie { @@ -87,11 +86,13 @@ func NewZombie() *Zombie { IsWalking: false, IsDead: false, } + zombie.walkTicker = time.NewTicker(WalkSpeedMs * time.Millisecond) + zombie.animationTicker = time.NewTicker(WalkSpeedMs * 10 * time.Millisecond) // Adjust the speed of animation frames go func() { for { select { - case <-walkTicker.C: + case <-zombie.walkTicker.C: if zombie.IsWalking { // Move the zombie towards its target position if zombie.X < zombie.WhereToGoX { @@ -112,7 +113,7 @@ func NewZombie() *Zombie { go func() { for { select { - case <-animationTicker.C: + case <-zombie.animationTicker.C: if zombie.IsWalking { zombie.step++ if zombie.step > 3 { @@ -129,7 +130,7 @@ func NewZombie() *Zombie { func (z *Zombie) Walk() { if !z.IsWalking { - walkTicker.Reset(WalkSpeedMs * time.Millisecond) + z.walkTicker.Reset(WalkSpeedMs * time.Millisecond) z.IsWalking = true }