movable player
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 25 Jan 2022 03:33:32 +0000 (21:33 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 25 Jan 2022 03:33:32 +0000 (21:33 -0600)
.vscode/tasks.json [new file with mode: 0644]
src/build.onyx
src/entity/manager.onyx [new file with mode: 0644]
src/entity/player.onyx [new file with mode: 0644]
src/gfx/imgui.onyx [deleted file]
src/gfx/immediate.onyx [new file with mode: 0644]
src/main.onyx
src/utils/input.onyx

diff --git a/.vscode/tasks.json b/.vscode/tasks.json
new file mode 100644 (file)
index 0000000..2242be8
--- /dev/null
@@ -0,0 +1,20 @@
+{
+    // See https://go.microsoft.com/fwlink/?LinkId=733558
+    // for the documentation about the tasks.json format
+    "version": "2.0.0",
+    "tasks": [
+        {
+            "label": "Run game",
+            "type": "shell",
+            "options": {
+                "cwd": "${workspaceFolder}/run_tree"
+            },
+            "problemMatcher": "$onyx",
+            "command": "onyx run -V -I ../src build",
+            "group": {
+                "kind": "build",
+                "isDefault": true
+            }
+        }
+    ]
+}
\ No newline at end of file
index 8c9a8d2e4000eea0c0a086632d7e787d84dc49f8..e5765dffcfc60b767aee10c9eedc328eb9849f0e 100644 (file)
@@ -7,8 +7,11 @@
 
 #load "main"
 
+#load "entity/manager"
+#load "entity/player"
+
 #load "gfx/font"
-#load "gfx/imgui"
+#load "gfx/immediate"
 #load "gfx/mesh"
 #load "gfx/shader"
 #load "gfx/texture"
diff --git a/src/entity/manager.onyx b/src/entity/manager.onyx
new file mode 100644 (file)
index 0000000..454dc55
--- /dev/null
@@ -0,0 +1,68 @@
+
+use package core
+use package glfw3
+
+Entity_Vtable :: struct {
+    draw   : (entity: ^Entity) -> void;
+    update : (entity: ^Entity, dt: f32) -> void;
+}
+
+Entity :: struct {
+    use vtable: ^Entity_Vtable;
+    id: u32;
+}
+
+Entity_Manager :: struct {
+    // The allocator for these entity pointers is assumed to be the
+    // context allocator.
+    entities: [..] ^Entity;
+
+    next_entity_id: u32;
+
+    update   :: entity_manager_update;
+    register :: entity_manager_register;
+    draw     :: entity_manager_draw;
+}
+
+entity_manager_make :: () -> Entity_Manager {
+    em: Entity_Manager;
+
+    array.init(^em.entities, 4);
+
+    // Entity ID 0 is reserved as a "empty / null" entity
+    em.next_entity_id = 1;
+
+    return em;
+}
+
+entity_manager_register :: (use this: ^Entity_Manager, entity: ^Entity) -> u32 {
+    id := next_entity_id;
+    next_entity_id += 1;
+
+    entity.id = id;
+    entities << entity;
+    return id;
+}
+
+entity_manager_update :: (use this: ^Entity_Manager, dt: f32) {
+    for entities {
+        if it.vtable == null do continue;
+
+        if it.update != null_proc {
+            it->update(dt);
+        }
+    }
+}
+
+entity_manager_draw :: (use this: ^Entity_Manager) {
+    // Entities should be sorted by z-order.
+    for entities {
+        if it.vtable == null do continue;
+
+        if it.draw != null_proc {
+            it->draw();
+        }
+    }
+}
+
+
diff --git a/src/entity/player.onyx b/src/entity/player.onyx
new file mode 100644 (file)
index 0000000..bb77b0c
--- /dev/null
@@ -0,0 +1,31 @@
+
+use package core
+use package glfw3
+
+Player :: struct {
+    use entity: Entity;
+
+    pos: Vector2;
+}
+
+player_make :: () -> ^Player {
+    player := new(Player);
+    player.vtable = ^player_vtable;
+
+    player.pos = .{0,0};
+    return player;
+}
+
+player_update :: (use this: ^Player, dt: f32) {
+    if is_key_down(GLFW_KEY_W) do pos.y -= 100 * dt; 
+    if is_key_down(GLFW_KEY_S) do pos.y += 100 * dt; 
+    if is_key_down(GLFW_KEY_A) do pos.x -= 100 * dt; 
+    if is_key_down(GLFW_KEY_D) do pos.x += 100 * dt; 
+}
+
+player_draw :: (use this: ^Player) {
+    immediate_set_color(.{0.4,0.4,1});
+    immediate_rectangle(pos.x, pos.y, 50, 50);
+}
+
+#local player_vtable := Entity_Vtable.{ update=player_update, draw=player_draw };
diff --git a/src/gfx/imgui.onyx b/src/gfx/imgui.onyx
deleted file mode 100644 (file)
index b96d224..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-
-use package core
-use package opengles
-use package glfw3
-
-immediate_init :: () {
-    memory.alloc_slice(^vertex_data, Maximum_Vertex_Count);
-    vertex_count = 0;
-
-    imgui_shader = shader_make(Shader_Vertex_Path, Shader_Fragment_Path);
-    shader_use(imgui_shader);
-    shader_link_window_matrix_block(imgui_shader);
-    shader_set_uniform(imgui_shader, #cstr "u_texture_enabled", 0.0f);
-    shader_set_uniform(imgui_shader, #cstr "u_texture", 0);
-
-    immediate_mesh = mesh_make(vertex_data, .[], GL_DYNAMIC_DRAW);
-    immediate_color = .{0,0,0};
-}
-
-immediate_flush :: () {
-    if vertex_count == 0 do return;
-
-    shader_use(imgui_shader);
-    immediate_mesh.vertex_count = vertex_count;
-    mesh_update_verticies(immediate_mesh, vertex_data);
-
-    mesh_draw(immediate_mesh);
-
-    shader_set_uniform(imgui_shader, #cstr "u_texture_enabled", 0.0f);
-    vertex_count = 0;
-}
-
-immediate_clear :: (color: Color) {
-    glClearColor(color.r, color.g, color.b, color.a);
-    glClear(GL_COLOR_BUFFER_BIT);
-}
-
-immediate_set_color :: (color: Color) {
-    immediate_color = color;
-}
-
-immediate_vertex :: (x, y: f32, t_x := 0.0f, t_y := 0.0f) {
-    if vertex_count >= Maximum_Vertex_Count do immediate_flush();
-
-    vertex_data[vertex_count] = .{ .{x, y}, .{t_x, t_y}, immediate_color };
-}
-
-immediate_triangle :: (x1, x2, x3: Vector2) {
-    if vertex_count + 3 > Maximum_Vertex_Count do immediate_flush();
-
-    vertex_data[vertex_count + 0] = .{ x1, .{0,0}, immediate_color };
-    vertex_data[vertex_count + 1] = .{ x2, .{0,0}, immediate_color };
-    vertex_data[vertex_count + 2] = .{ x3, .{0,0}, immediate_color };
-    vertex_count += 3;
-}
-
-immediate_rectangle :: (x, y, w, h: f32) {
-    if vertex_count + 6 > Maximum_Vertex_Count do immediate_flush();
-
-    vertex_data[vertex_count + 0] = .{ .{x,   y},   .{0,0}, immediate_color };
-    vertex_data[vertex_count + 1] = .{ .{x+w, y},   .{0,0}, immediate_color };
-    vertex_data[vertex_count + 2] = .{ .{x+w, y+h}, .{0,0}, immediate_color };
-    vertex_data[vertex_count + 3] = .{ .{x,   y},   .{0,0}, immediate_color };
-    vertex_data[vertex_count + 4] = .{ .{x+w, y+h}, .{0,0}, immediate_color };
-    vertex_data[vertex_count + 5] = .{ .{x,   y+h}, .{0,0}, immediate_color };
-    vertex_count += 6;
-}
-
-immediate_image :: (image: ^Texture, x, y, w, h: f32) {
-    if vertex_count > 0 do immediate_flush();
-
-    texture_use(image);
-    shader_use(imgui_shader);
-    shader_set_uniform(imgui_shader, #cstr "u_texture_enabled", 1.0f);
-    shader_set_uniform(imgui_shader, #cstr "u_texture", 0);
-
-    vertex_data[vertex_count + 0] = .{ .{x, y},     .{0,0}, immediate_color };
-    vertex_data[vertex_count + 1] = .{ .{x+w, y},   .{1,0}, immediate_color };
-    vertex_data[vertex_count + 2] = .{ .{x+w, y+h}, .{1,1}, immediate_color };
-    vertex_data[vertex_count + 3] = .{ .{x, y},     .{0,0}, immediate_color };
-    vertex_data[vertex_count + 4] = .{ .{x+w, y+h}, .{1,1}, immediate_color };
-    vertex_data[vertex_count + 5] = .{ .{x, y+h},   .{0,1}, immediate_color };
-    vertex_count += 6;
-
-    immediate_flush();
-}
-
-immediate_ellipse :: () {}
-
-Color :: struct {
-    r, g, b :  f32;
-    a       := 1.0f;
-}
-
-Immediate_Vertex :: struct {
-    pos:   Vector2;
-    tex:   Vector2;
-    color: Color;
-}
-
-#local {
-    Shader_Vertex_Path   :: "./assets/shaders/imgui_vertex.glsl"
-    Shader_Fragment_Path :: "./assets/shaders/imgui_fragment.glsl"
-    imgui_shader: Shader;
-
-    Maximum_Vertex_Count :: 1023;
-    vertex_count: i32;
-    vertex_data:  [] Immediate_Vertex;
-
-    immediate_color: Color;
-
-    immediate_mesh: ^Mesh(Immediate_Vertex);
-}
diff --git a/src/gfx/immediate.onyx b/src/gfx/immediate.onyx
new file mode 100644 (file)
index 0000000..b96d224
--- /dev/null
@@ -0,0 +1,113 @@
+
+use package core
+use package opengles
+use package glfw3
+
+immediate_init :: () {
+    memory.alloc_slice(^vertex_data, Maximum_Vertex_Count);
+    vertex_count = 0;
+
+    imgui_shader = shader_make(Shader_Vertex_Path, Shader_Fragment_Path);
+    shader_use(imgui_shader);
+    shader_link_window_matrix_block(imgui_shader);
+    shader_set_uniform(imgui_shader, #cstr "u_texture_enabled", 0.0f);
+    shader_set_uniform(imgui_shader, #cstr "u_texture", 0);
+
+    immediate_mesh = mesh_make(vertex_data, .[], GL_DYNAMIC_DRAW);
+    immediate_color = .{0,0,0};
+}
+
+immediate_flush :: () {
+    if vertex_count == 0 do return;
+
+    shader_use(imgui_shader);
+    immediate_mesh.vertex_count = vertex_count;
+    mesh_update_verticies(immediate_mesh, vertex_data);
+
+    mesh_draw(immediate_mesh);
+
+    shader_set_uniform(imgui_shader, #cstr "u_texture_enabled", 0.0f);
+    vertex_count = 0;
+}
+
+immediate_clear :: (color: Color) {
+    glClearColor(color.r, color.g, color.b, color.a);
+    glClear(GL_COLOR_BUFFER_BIT);
+}
+
+immediate_set_color :: (color: Color) {
+    immediate_color = color;
+}
+
+immediate_vertex :: (x, y: f32, t_x := 0.0f, t_y := 0.0f) {
+    if vertex_count >= Maximum_Vertex_Count do immediate_flush();
+
+    vertex_data[vertex_count] = .{ .{x, y}, .{t_x, t_y}, immediate_color };
+}
+
+immediate_triangle :: (x1, x2, x3: Vector2) {
+    if vertex_count + 3 > Maximum_Vertex_Count do immediate_flush();
+
+    vertex_data[vertex_count + 0] = .{ x1, .{0,0}, immediate_color };
+    vertex_data[vertex_count + 1] = .{ x2, .{0,0}, immediate_color };
+    vertex_data[vertex_count + 2] = .{ x3, .{0,0}, immediate_color };
+    vertex_count += 3;
+}
+
+immediate_rectangle :: (x, y, w, h: f32) {
+    if vertex_count + 6 > Maximum_Vertex_Count do immediate_flush();
+
+    vertex_data[vertex_count + 0] = .{ .{x,   y},   .{0,0}, immediate_color };
+    vertex_data[vertex_count + 1] = .{ .{x+w, y},   .{0,0}, immediate_color };
+    vertex_data[vertex_count + 2] = .{ .{x+w, y+h}, .{0,0}, immediate_color };
+    vertex_data[vertex_count + 3] = .{ .{x,   y},   .{0,0}, immediate_color };
+    vertex_data[vertex_count + 4] = .{ .{x+w, y+h}, .{0,0}, immediate_color };
+    vertex_data[vertex_count + 5] = .{ .{x,   y+h}, .{0,0}, immediate_color };
+    vertex_count += 6;
+}
+
+immediate_image :: (image: ^Texture, x, y, w, h: f32) {
+    if vertex_count > 0 do immediate_flush();
+
+    texture_use(image);
+    shader_use(imgui_shader);
+    shader_set_uniform(imgui_shader, #cstr "u_texture_enabled", 1.0f);
+    shader_set_uniform(imgui_shader, #cstr "u_texture", 0);
+
+    vertex_data[vertex_count + 0] = .{ .{x, y},     .{0,0}, immediate_color };
+    vertex_data[vertex_count + 1] = .{ .{x+w, y},   .{1,0}, immediate_color };
+    vertex_data[vertex_count + 2] = .{ .{x+w, y+h}, .{1,1}, immediate_color };
+    vertex_data[vertex_count + 3] = .{ .{x, y},     .{0,0}, immediate_color };
+    vertex_data[vertex_count + 4] = .{ .{x+w, y+h}, .{1,1}, immediate_color };
+    vertex_data[vertex_count + 5] = .{ .{x, y+h},   .{0,1}, immediate_color };
+    vertex_count += 6;
+
+    immediate_flush();
+}
+
+immediate_ellipse :: () {}
+
+Color :: struct {
+    r, g, b :  f32;
+    a       := 1.0f;
+}
+
+Immediate_Vertex :: struct {
+    pos:   Vector2;
+    tex:   Vector2;
+    color: Color;
+}
+
+#local {
+    Shader_Vertex_Path   :: "./assets/shaders/imgui_vertex.glsl"
+    Shader_Fragment_Path :: "./assets/shaders/imgui_fragment.glsl"
+    imgui_shader: Shader;
+
+    Maximum_Vertex_Count :: 1023;
+    vertex_count: i32;
+    vertex_data:  [] Immediate_Vertex;
+
+    immediate_color: Color;
+
+    immediate_mesh: ^Mesh(Immediate_Vertex);
+}
index 7bfe01075c046f4bdf167248fe4bc96e11dafc79..00c2b6fdc5c679e0cfc73c2fa6a6c89bcbb91e49 100644 (file)
@@ -14,6 +14,8 @@ window_height: u32
 player_texture: Texture;
 main_font: Font;
 
+entity_manager: Entity_Manager;
+
 init :: () {
     create_window();
     glInit(glfwGetLoadProcAddress());
@@ -35,11 +37,17 @@ init :: () {
 
     player_texture = texture_make(#cstr "./assets/images/player.png");
     main_font = font_make(.{"./assets/fonts/calibri.ttf", 32});
+
+    entity_manager = entity_manager_make();
+    player := player_make();
+    entity_manager->register(player);
 }
 
 update :: (dt: f32) {
     input_update();
     defer input_post_update();
+
+    entity_manager->update(dt);
 }
 
 draw :: () {
@@ -56,6 +64,12 @@ draw :: () {
         immediate_image(^player_texture, ~~(100 + 64 * i), 50, 64, 64);
     }
 
+    entity_manager->draw();
+
+    mx, my := mouse_get_position();
+    immediate_set_color(.{1,1,1});
+    immediate_rectangle(~~mx, ~~my, 10, 10);
+
     immediate_flush();
 
     font_set_color(.{1,0,0});
index a05c3f5a9324de085402837f41094ff2354c94c4..02a7dc61a77c438da247918850ef0340ac341587 100644 (file)
@@ -62,3 +62,7 @@ is_button_just_up   :: (button) => !buttons_this_frame[button] && buttons_last_f
 mouse_get_delta :: () -> (f64, f64) {
        return mouse_x - last_mouse_x, mouse_y - last_mouse_y;
 }
+
+mouse_get_position :: () -> (f64, f64) {
+       return mouse_x, mouse_y;
+}
\ No newline at end of file