command an entity to move

This commit is contained in:
2026-07-03 02:59:34 -07:00
parent c01b320032
commit 6697ba70bf
4 changed files with 107 additions and 17 deletions
+2
View File
@@ -11,3 +11,5 @@ MAP_HEIGHT :: 60
MAX_ENTITIES :: 256
INVALID_ENTITY :: Entity(0)
MOVE_SPEED :: 4.0
+84 -9
View File
@@ -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
}
}
}
}
+17 -8
View File
@@ -4,12 +4,13 @@ import "core:math"
import rl "vendor:raylib"
Game :: struct {
running: bool,
time: f32, // total time elapsed
tilemap: Tilemap,
camera: Camera2D,
selection: Selection,
world: World,
running: bool,
time: f32, // total time elapsed
tilemap: Tilemap,
camera: Camera2D,
selection: Selection,
world: World,
player_colonist: Entity,
}
Camera2D :: struct {
@@ -37,7 +38,7 @@ game_init :: proc() -> Game {
g.camera = camera_init()
g.world = world_init()
center := Tile_Coord{MAP_WIDTH / 2, MAP_HEIGHT / 2}
entity_spawn_colonist(&g.world.entities, center)
g.player_colonist = entity_spawn_colonist(&g.world.entities, center)
return g
}
@@ -102,7 +103,14 @@ game_handle_input :: proc(g: ^Game) {
}
if rl.IsMouseButtonPressed(.RIGHT) {
g.selection.active = false
mx, my := f32(rl.GetMouseX()), f32(rl.GetMouseY())
wx, wy := screen_to_world(&g.camera, mx, my)
tx, ty := world_to_tile(wx, wy)
if tile_in_bounds(&g.tilemap, tx, ty) {
entity_set_move_target(&g.world.entities, g.player_colonist, {tx, ty})
g.selection.active = true
g.selection.tile = {tx, ty}
}
}
}
game_update :: proc(g: ^Game, dt: f32) {
@@ -114,6 +122,7 @@ game_update :: proc(g: ^Game, dt: f32) {
camera_update(&g.camera, dt)
game_handle_input(g)
world_update(&g.world, dt)
}
game_draw :: proc(g: ^Game) {
+4
View File
@@ -14,3 +14,7 @@ world_draw :: proc(w: ^World, camera: ^Camera2D) {
entity_draw(&w.entities, camera)
}
world_update :: proc(world: ^World, dt: f32) {
entity_update_movement(&world.entities, dt)
}