Files
tower-defense-prototype/game/enemy.odin
T

78 lines
1.5 KiB
Odin

package game
Enemy :: struct {
position: Vec2,
health: int,
max_health: int,
active: bool,
path_index: int,
speed: f32,
}
acquire_enemy :: proc(world: ^World) -> ^Enemy {
// create an object pool with fixed slots to reuse instead of allocate/free every spawn
for i in 0 ..< MAX_ENEMIES {
if !world.enemies[i].active {
return &world.enemies[i]
}
}
return nil
}
spawn_enemy :: proc(world: ^World, health: int, speed: f32) {
if len(world.path) == 0 do return // don't spawn enemies if no paths exist
e := acquire_enemy(world) // grab a free slot
if e == nil do return // if there are no slots, skil spawning
e^ = Enemy {
position = world.path[0],
health = health,
max_health = health,
speed = speed,
path_index = 1,
active = true,
}
}
spawn_group :: proc(world: ^World, count: int) {
for _ in 0 ..< count {
spawn_enemy(world, 20, 60)
}
}
update_enemies :: proc(world: ^World, dt: f32) {
for i in 0 ..< MAX_ENEMIES {
e := &world.enemies[i]
if !e.active do continue
if len(world.path) == 2 do return
if e.path_index >= len(world.path) {
world.base_health -= 1
e.active = false
continue
}
target := world.path[e.path_index]
move_toward(&e.position, target, e.speed, dt)
dx := target.x - e.position.x
dy := target.y - e.position.y
if dx * dx + dy * dy < 16.0 {
e.path_index += 1
}
}
}
active_enemy_count :: proc(world: ^World) -> int {
count := 0
for i in 0 ..< MAX_ENEMIES {
if world.enemies[i].active do count += 1
}
return count
}