use package glfw3
Entity_Handles :: struct {
- update : (entity: ^Entity, dt: f32) -> void = null_proc;
- draw : (entity: ^Entity) -> void = null_proc;
+ update : (entity: ^Entity, dt: f32) -> void = null_proc;
+ draw : (entity: ^Entity) -> void = null_proc;
+ get_rect : (entity: ^Entity) -> Rect = null_proc;
}
Entity :: struct {
next_entity_id: u32;
- register :: entity_manager_register;
- add :: entity_manager_add;
- update :: entity_manager_update;
- draw :: entity_manager_draw;
+ register :: entity_manager_register;
+ add :: entity_manager_add;
+ update :: entity_manager_update;
+ draw :: entity_manager_draw;
+ query_entities :: entity_manager_query_entities;
}
entity_manager_make :: () -> Entity_Manager {
for entities {
vtable := ^entity_types[it.type];
if vtable == null do continue;
+ if vtable.update == null_proc do continue;
vtable.update(it, dt);
}
for entities {
vtable := ^entity_types[it.type];
if vtable == null do continue;
+ if vtable.draw == null_proc do continue;
vtable.draw(it);
}
}
+entity_manager_query_entities :: (use this: ^Entity_Manager, area: Rect, type: type_expr = void) -> [] ^Entity {
+ ents: [..] ^Entity;
+ for entities {
+ if type != void && it.type != type do continue;
+
+ vtable := ^entity_types[it.type];
+ if vtable == null do continue;
+ if vtable.get_rect == null_proc do continue;
+
+ if Rect.intersects(vtable.get_rect(it), area) {
+ ents << it;
+ }
+ }
+ return ents;
+}
\ No newline at end of file
use package glfw3
Player :: struct {
- handles :: Entity_Handles.{ update, draw }
+ handles :: Entity_Handles.{ update, draw, get_rect }
use entity: Entity;
return player;
}
+ get_rect :: (use this: ^Player) => Rect.{ pos.x, pos.y, 64, 64 };
+
update :: (use this: ^Player, dt: f32) {
- if is_key_down(GLFW_KEY_W) do pos.y -= 200 * dt;
- if is_key_down(GLFW_KEY_S) do pos.y += 200 * dt;
- if is_key_down(GLFW_KEY_A) do pos.x -= 200 * dt;
- if is_key_down(GLFW_KEY_D) do pos.x += 200 * dt;
+ delta: Vector2;
+ if is_key_down(GLFW_KEY_W) do delta.y -= 200 * dt;
+ if is_key_down(GLFW_KEY_S) do delta.y += 200 * dt;
+ if is_key_down(GLFW_KEY_A) do delta.x -= 200 * dt;
+ if is_key_down(GLFW_KEY_D) do delta.x += 200 * dt;
+
+ walls := entity_manager->query_entities(.{pos.x - 100, pos.y - 100, 200, 200}, Wall);
+ defer memory.free_slice(^walls);
+
+ try_move(this, .{delta.x, 0}, walls);
+ try_move(this, .{0, delta.y}, walls);
+ }
+
+ try_move :: (use this: ^Player, delta: Vector2, obsticles: [] ^Entity) {
+ pos += delta;
+ ent_rect := get_rect(this);
+
+ for obsticles {
+ if Rect.intersects(ent_rect, Wall.get_rect(~~ it)) {
+ pos -= delta;
+ break;
+ }
+ }
}
draw :: (use this: ^Player) {
}
}
-
player_texture: Texture;
+
+
+
+Wall :: struct {
+ handles :: Entity_Handles.{ get_rect = get_rect, draw = draw }
+
+ use entity: Entity;
+ size: Vector2;
+
+ make :: (pos, size: Vector2) -> ^Wall {
+ wall := new(Wall);
+ wall.pos = pos;
+ wall.size = size;
+ return wall;
+ }
+
+ get_rect :: (use this: ^Wall) => Rect.{ pos.x, pos.y, size.x, size.y };
+
+ draw :: (use this: ^Wall) {
+ immediate_set_color(.{1,1,1});
+ immediate_rectangle(pos.x, pos.y, size.x, size.y);
+ }
+}
\ No newline at end of file
entity_manager = entity_manager_make();
player := Player.make();
entity_manager->add(player);
+
+ entity_manager->add(Wall.make(.{100, 100}, .{200, 100}));
}
update :: (dt: f32) {
conv.format(output, "({}, {}, {})", v.x, v.y, v.z);
}
}
+
+
+
+Rect :: struct {
+ x, y, w, h: f32;
+
+ intersects :: (r1, r2: Rect) -> bool {
+ return r1.x <= r2.x + r2.w
+ && r1.x + r1.w >= r2.x
+ && r1.y <= r2.y + r2.h
+ && r1.y + r1.h >= r2.y;
+ }
+}
\ No newline at end of file