command an entity to move
This commit is contained in:
+84
-9
@@ -1,15 +1,24 @@
|
||||
package main
|
||||
|
||||
import "core:math"
|
||||
import rl "vendor:raylib"
|
||||
|
||||
Entity :: distinct u32
|
||||
|
||||
Entity_World :: struct {
|
||||
count: int,
|
||||
active: [MAX_ENTITIES]bool,
|
||||
position: [MAX_ENTITIES]Tile_Coord,
|
||||
color: [MAX_ENTITIES]rl.Color,
|
||||
is_colonist: [MAX_ENTITIES]bool,
|
||||
count: int,
|
||||
active: [MAX_ENTITIES]bool,
|
||||
position: [MAX_ENTITIES]Tile_Coord,
|
||||
color: [MAX_ENTITIES]rl.Color,
|
||||
is_colonist: [MAX_ENTITIES]bool,
|
||||
move_state: [MAX_ENTITIES]Move_State,
|
||||
move_target: [MAX_ENTITIES]Tile_Coord,
|
||||
visual_position: [MAX_ENTITIES]rl.Vector2,
|
||||
}
|
||||
|
||||
Move_State :: enum {
|
||||
Idle,
|
||||
Moving,
|
||||
}
|
||||
|
||||
entity_world_init :: proc() -> Entity_World {
|
||||
@@ -24,6 +33,8 @@ entity_spawn_colonist :: proc(ew: ^Entity_World, pos: Tile_Coord) -> Entity {
|
||||
ew.color[i] = {80, 140, 220, 225}
|
||||
ew.is_colonist[i] = true
|
||||
ew.count += 1
|
||||
ew.visual_position[i] = tile_center_world(pos)
|
||||
ew.move_state[i] = .Idle
|
||||
return Entity(u32(i + 1))
|
||||
}
|
||||
}
|
||||
@@ -41,10 +52,8 @@ entity_draw :: proc(ew: ^Entity_World, camera: ^Camera2D) {
|
||||
continue
|
||||
}
|
||||
|
||||
pos := ew.position[i]
|
||||
wx := f32(pos.x * TILE_SIZE) + f32(TILE_SIZE) * 0.5
|
||||
wy := f32(pos.y * TILE_SIZE) + f32(TILE_SIZE) * 0.5
|
||||
sx, sy := world_to_screen(camera, wx, wy)
|
||||
vp := ew.visual_position[i]
|
||||
sx, sy := world_to_screen(camera, vp.x, vp.y)
|
||||
radius := f32(TILE_SIZE) * 0.3 * camera.zoom
|
||||
|
||||
rl.DrawCircle(i32(sx), i32(sy), radius, ew.color[i])
|
||||
@@ -52,3 +61,69 @@ entity_draw :: proc(ew: ^Entity_World, camera: ^Camera2D) {
|
||||
}
|
||||
}
|
||||
|
||||
tile_center_world :: proc(t: Tile_Coord) -> rl.Vector2 {
|
||||
return rl.Vector2 {
|
||||
f32(t.x * TILE_SIZE) + f32(TILE_SIZE) * 0.5,
|
||||
f32(t.y * TILE_SIZE) + f32(TILE_SIZE) * 0.5,
|
||||
}
|
||||
}
|
||||
|
||||
entity_set_move_target :: proc(ew: ^Entity_World, e: Entity, target: Tile_Coord) -> bool {
|
||||
i := entity_index(e)
|
||||
if i < 0 || !ew.active[i] {return false}
|
||||
|
||||
if ew.position[i] == target {
|
||||
ew.move_state[i] = .Idle
|
||||
return true
|
||||
}
|
||||
|
||||
ew.move_target[i] = target
|
||||
ew.move_state[i] = .Moving
|
||||
return true
|
||||
}
|
||||
|
||||
entity_update_movement :: proc(ew: ^Entity_World, dt: f32) {
|
||||
speed := f32(TILE_SIZE) * MOVE_SPEED
|
||||
|
||||
for i in 0 ..< MAX_ENTITIES {
|
||||
if !ew.active[i] || ew.move_state[i] != .Moving {
|
||||
continue
|
||||
}
|
||||
|
||||
pos := ew.position[i]
|
||||
target := ew.move_target[i]
|
||||
if pos == target {
|
||||
ew.move_state[i] = .Idle
|
||||
continue
|
||||
}
|
||||
|
||||
next := pos
|
||||
if pos.x != target.x {
|
||||
next.x += pos.x < target.x ? 1 : -1
|
||||
} else if pos.y != target.y {
|
||||
next.y += pos.y < target.y ? 1 : -1
|
||||
}
|
||||
|
||||
goal := tile_center_world(next)
|
||||
vp := ew.visual_position[i]
|
||||
|
||||
dx := goal.x - vp.x
|
||||
dy := goal.y - vp.y
|
||||
dist := math.sqrt(dx * dx + dy * dy)
|
||||
|
||||
if dist < 1.0 {
|
||||
ew.position[i] = next
|
||||
ew.visual_position[i] = goal
|
||||
} else {
|
||||
step := speed * dt
|
||||
if step >= dist {
|
||||
ew.visual_position[i] = goal
|
||||
ew.position[i] = next
|
||||
} else {
|
||||
ew.visual_position[i].x += dx / dist * step
|
||||
ew.visual_position[i].y += dy / dist * step
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user