diff --git a/game/enemy.odin b/game/enemy.odin index 1e39316..7709242 100644 --- a/game/enemy.odin +++ b/game/enemy.odin @@ -4,6 +4,7 @@ Enemy :: struct { position: Vec2, health: int, active: bool, + speed: f32, } spawn_enemy :: proc(world: ^World) { @@ -11,8 +12,18 @@ spawn_enemy :: proc(world: ^World) { world.enemy = Enemy { position = world.path[0], - health = 20, + health = 40, + speed = 60, active = true, } } +update_enemy :: proc(world: ^World, dt: f32) { + e := &world.enemy + if !e.active do return + if len(world.path) == 0 do return + + target := world.path[len(world.path) - 1] + move_toward(&e.position, target, e.speed, dt) +} + diff --git a/game/math2d.odin b/game/math2d.odin index 046d5a8..7a774ed 100644 --- a/game/math2d.odin +++ b/game/math2d.odin @@ -1,6 +1,37 @@ package game +import "core:math" Vec2 :: struct { x, y: f32, } +grid_to_center :: proc(gx, gy: int) -> Vec2 { + return Vec2{f32(gx * TILE_SIZE + TILE_SIZE / 2), f32(gy * TILE_SIZE + TILE_SIZE / 2)} +} +screen_to_grid :: proc(px, py: f32) -> (int, int) { + gx := int(px) / TILE_SIZE + gy := int(py) / TILE_SIZE + return gx, gy +} + +distance :: proc(a, b: Vec2) -> f32 { + dx := b.x - a.x + dy := b.y - a.y + return math.sqrt(dx * dx + dy + dy) +} + +move_toward :: proc(pos: ^Vec2, target: Vec2, speed, dt: f32) { + dist := distance(pos^, target) + if dist < 1.0 do return + + step := speed * dt + if step >= dist { + pos^ = target + } else { + dx := target.x - pos.x + dy := target.y - pos.y + pos.x += dx / dist * step + pos.y += dy / dist * step + } +} + diff --git a/game/path.odin b/game/path.odin index 8ac4da5..0c83504 100644 --- a/game/path.odin +++ b/game/path.odin @@ -5,10 +5,7 @@ build_path :: proc(world_map: ^Map, path: ^[dynamic]Vec2) { for y in 0 ..< MAP_H { for x in 0 ..< MAP_W { if world_map.tiles[y][x] == .Path { - append( - path, - Vec2{f32(x * TILE_SIZE + TILE_SIZE / 2), f32(y * TILE_SIZE + TILE_SIZE / 2)}, - ) + append(path, grid_to_center(x, y)) } } } diff --git a/game/render.odin b/game/render.odin index fe4ae12..925c44f 100644 --- a/game/render.odin +++ b/game/render.odin @@ -18,6 +18,14 @@ render_world :: proc(world: ^World) { if world.enemy.active { e := world.enemy rl.DrawCircle(i32(e.position.x), i32(e.position.y), 11, rl.MAROON) + rl.DrawText( + fmt.ctprintf("%d", e.health), + i32(e.position.x) - 4, + i32(e.position.y) - 18, + 12, + rl.WHITE, + ) + } rl.DrawText(fmt.ctprintf("Gold: %d", world.gold), 10, 10, 20, rl.BLACK) // Gold HUD rl.DrawText(fmt.ctprintf("Base HP: %d", world.base_health), 10, 32, 20, rl.BLACK) // HP HUD diff --git a/game/world.odin b/game/world.odin index 3cbe3d1..7f07d77 100644 --- a/game/world.odin +++ b/game/world.odin @@ -22,8 +22,6 @@ init_world :: proc() -> World { // update world, never draw update_world :: proc(world: ^World, dt: f32) { - _ = dt - if rl.IsKeyPressed(.G) { world.gold += 10 } @@ -31,5 +29,7 @@ update_world :: proc(world: ^World, dt: f32) { if rl.IsKeyPressed(.SPACE) { spawn_enemy(world) } + + update_enemy(world, dt) }