From c8dfcd857e9bacf474879c1e0d1a49a6f4753c5d Mon Sep 17 00:00:00 2001 From: declan Date: Sat, 4 Oct 2025 17:36:47 +0100 Subject: [PATCH 1/3] raycast start --- code/first.c | 101 ++++++++++++++++++++-------------------- code/game/aabb.h | 7 ++- code/game/impl/aabb.c | 24 +++++++++- code/game/impl/player.c | 49 +++++++++++-------- code/game/player.h | 1 + 5 files changed, 107 insertions(+), 75 deletions(-) diff --git a/code/first.c b/code/first.c index 4a2bd06..4f186d8 100644 --- a/code/first.c +++ b/code/first.c @@ -19,9 +19,10 @@ #include "game/impl/npc.c" #include "game/testnavmesh.h" -int main(int argc, char **argv) { - (void) argc; - (void) argv; +int main(int argc, char **argv) +{ + (void)argc; + (void)argv; if (!SDL_Init(SDL_INIT_VIDEO)) { @@ -58,43 +59,43 @@ int main(int argc, char **argv) { camera->fov = 60.0f; camera->nearp = 0.01f; - camera->farp = 1000.0f; + camera->farp = 1000.0f; game->draw.camera = camera; World *world = M_ArenaPush(arena, World); - game->world = world; - world->random = Random_Seed(29237489723847); - world->npcCount = 2; - NPC *npc1 = &world->npcs[0]; - npc1->collision.pos.x = 15; - npc1->collision.pos.y = 15; - npc1->collision.size.x = 10; - npc1->collision.size.y = 10; - npc1->name = S("Matt"); - npc1->mode = NPC_ACTION_WAITING; - npc1->waitTime = 0; - npc1->maxWaitTime = 5; - npc1->currentNavNode = 87; - npc1->collision.pos.x = 15; - npc1->collision.pos.y = 15; - npc1->collision.size.x = 10; - npc1->collision.size.y = 10; + game->world = world; + world->random = Random_Seed(29237489723847); + world->npcCount = 2; + NPC *npc1 = &world->npcs[0]; + npc1->collision.pos.x = 15; + npc1->collision.pos.y = 15; + npc1->collision.size.x = 10; + npc1->collision.size.y = 10; + npc1->name = S("Matt"); + npc1->mode = NPC_ACTION_WAITING; + npc1->waitTime = 0; + npc1->maxWaitTime = 5; + npc1->currentNavNode = 87; + npc1->collision.pos.x = 15; + npc1->collision.pos.y = 15; + npc1->collision.size.x = 10; + npc1->collision.size.y = 10; - NPC *npc2 = &world->npcs[1]; - npc2->collision.pos.x = 15; - npc2->collision.pos.y = 15; - npc2->collision.size.x = 10; - npc2->collision.size.y = 10; - npc2->name = S("James"); - npc2->mode = NPC_ACTION_WAITING; - npc2->waitTime = 0; - npc2->maxWaitTime = 10; - npc2->currentNavNode = 0; + NPC *npc2 = &world->npcs[1]; + npc2->collision.pos.x = 15; + npc2->collision.pos.y = 15; + npc2->collision.size.x = 10; + npc2->collision.size.y = 10; + npc2->name = S("James"); + npc2->mode = NPC_ACTION_WAITING; + npc2->waitTime = 0; + npc2->maxWaitTime = 10; + npc2->currentNavNode = 0; - world->navMesh = &TestNavMesh; - world->npcPOI[0] = 100; - world->player.pos.x = 0; - world->player.pos.y = 0; + world->navMesh = &TestNavMesh; + world->npcPOI[0] = 100; + world->player.pos.x = 0; + world->player.pos.y = 0; } bool running = true; @@ -110,17 +111,17 @@ int main(int argc, char **argv) { { running = false; } - ProcessEvents(&e, game->world); + ProcessEvents(&e, game->world); } - UpdateWorld(1.0/60.0, game->world); + UpdateWorld(1.0 / 60.0, game->world); int w, h; SDL_GetWindowSizeInPixels(window, &w, &h); - game->draw.window_width = w; + game->draw.window_width = w; game->draw.window_height = h; - G_CalculateCamera(&game->camera, (F32) w / (F32) h); + G_CalculateCamera(&game->camera, (F32)w / (F32)h); Vk_Frame *frame = Vk_FrameBegin(window); VkCommandBuffer cmd = frame->cmd; @@ -132,27 +133,27 @@ int main(int argc, char **argv) { clear_colour.color.float32[3] = 1.0f; VkRenderingAttachmentInfo colour_attachment = {0}; - colour_attachment.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO; - colour_attachment.imageView = vk.swapchain.views[frame->image]; + colour_attachment.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO; + colour_attachment.imageView = vk.swapchain.views[frame->image]; colour_attachment.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - colour_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - colour_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - colour_attachment.clearValue = clear_colour; + colour_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + colour_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + colour_attachment.clearValue = clear_colour; VkRenderingInfo rendering_info = {0}; - rendering_info.sType = VK_STRUCTURE_TYPE_RENDERING_INFO; - rendering_info.renderArea = (VkRect2D) { 0, 0, w, h }; - rendering_info.layerCount = 1; + rendering_info.sType = VK_STRUCTURE_TYPE_RENDERING_INFO; + rendering_info.renderArea = (VkRect2D){0, 0, w, h}; + rendering_info.layerCount = 1; rendering_info.colorAttachmentCount = 1; - rendering_info.pColorAttachments = &colour_attachment; + rendering_info.pColorAttachments = &colour_attachment; vk.CmdBeginRendering(cmd, &rendering_info); D_Begin(&game->draw, frame, D_MAX_RECTS); - D_Rect(&game->draw, 0.0f, 0.0f, .texture = 1); + D_Rect(&game->draw, 0.0f, 0.0f, .texture = 1); D_Rect(&game->draw, -8.0f, 0.0f, .texture = 2, .scale = 2.0f); - D_Rect(&game->draw, 6.0f, 0.0f, .texture = 3); + D_Rect(&game->draw, 6.0f, 0.0f, .texture = 3); D_End(&game->draw, frame); diff --git a/code/game/aabb.h b/code/game/aabb.h index e61ba60..ca7f2f4 100644 --- a/code/game/aabb.h +++ b/code/game/aabb.h @@ -3,15 +3,14 @@ #include "../core/types.h" #include "../core/macros.h" - typedef struct AABB AABB; -struct AABB { +struct AABB +{ V2f pos; V2f size; }; - function bool AABB_Collide(AABB a, AABB b); function bool AABB_Point(AABB a, V2f v); -#endif // LD_GAME_AABB_H_ +#endif // LD_GAME_AABB_H_ diff --git a/code/game/impl/aabb.c b/code/game/impl/aabb.c index c1d1fba..a6a6360 100644 --- a/code/game/impl/aabb.c +++ b/code/game/impl/aabb.c @@ -1,15 +1,35 @@ #include "game/aabb.h" #include "core/types.h" -bool AABB_Collide(AABB a, AABB b) { +bool AABB_Collide(AABB a, AABB b) +{ bool collision_x = a.pos.x + a.size.x >= b.pos.x && b.pos.x + b.size.x >= a.pos.x; bool collision_y = a.pos.y + a.size.x >= b.pos.y && b.pos.y + b.size.y >= a.pos.y; return collision_x && collision_y; } -bool AABB_Point(AABB a, V2f v) { +bool AABB_Point(AABB a, V2f v) +{ bool collision_x = a.pos.x + a.size.x >= v.x && a.pos.x <= v.x; bool collision_y = a.pos.x + a.size.y >= v.y && a.pos.y <= v.y; return collision_x && collision_y; } +bool AABB_Slab(V2f origin, V2f point, AABB a) +{ + V2f start = a.pos; + V2f finish = {a.pos.x + a.size.x, a.pos.y + a.size.y}; + V2f direction = {origin.x - point.x, origin.y - point.y}; + // x + F32 tLow = (start.x - origin.x) / direction.x; + F32 tHigh = (finish.x - origin.x) / direction.x; + F32 tMin = min(tLow, tHigh); + F32 tMax = max(tLow, tHigh); + // y + tLow = (start.x - origin.x) / direction.x; + tHigh = (finish.x - origin.x) / direction.x; + + tMin = max(tMin, min(tLow, tHigh)); + tMax = min(tMax, max(tLow, tHigh)); + return tMax >= max(0.0, tMin); +} \ No newline at end of file diff --git a/code/game/impl/player.c b/code/game/impl/player.c index ae8ded7..043a729 100644 --- a/code/game/impl/player.c +++ b/code/game/impl/player.c @@ -4,23 +4,34 @@ void PlayerUpdate(SDL_Event *event, Player *player) { - SDL_KeyboardEvent key = event->key; - switch(key.key) { - case SDLK_W: { - player->pos.y += 10; - break; - } - case SDLK_A: { - player->pos.x -= 10; - break; - } - case SDLK_D: { - player->pos.x += 10; - break; - } - case SDLK_S: { - player->pos.y -= 10; - break; - } - } + SDL_KeyboardEvent key = event->key; + SDL_MouseButtonEvent mouseBtn = event->button; + switch (key.key) + { + case SDLK_W: + { + player->pos.y += 10; + break; + } + case SDLK_A: + { + player->pos.x -= 10; + break; + } + case SDLK_D: + { + player->pos.x += 10; + break; + } + case SDLK_S: + { + player->pos.y -= 10; + break; + } + } + if (mouseBtn.clicks == 1) + { + // shooting + player->bulletsLoaded -= 1; + } } diff --git a/code/game/player.h b/code/game/player.h index 8067026..fddf014 100644 --- a/code/game/player.h +++ b/code/game/player.h @@ -10,6 +10,7 @@ typedef struct Player Player; struct Player { V2f pos; + U32 bulletsLoaded; }; function void PlayerUpdate(SDL_Event *event, Player *player); From 628a6c5adea3e8e9e72145fa96d04013d3a4f0a9 Mon Sep 17 00:00:00 2001 From: declan Date: Sun, 5 Oct 2025 16:05:57 +0100 Subject: [PATCH 2/3] raycast fin --- code/game/aabb.h | 1 + code/game/impl/aabb.c | 15 +++++---- code/game/impl/nav.c | 75 ++++++++++++++++++++++++++---------------- code/game/impl/world.c | 12 ++++--- 4 files changed, 64 insertions(+), 39 deletions(-) diff --git a/code/game/aabb.h b/code/game/aabb.h index ca7f2f4..9344521 100644 --- a/code/game/aabb.h +++ b/code/game/aabb.h @@ -12,5 +12,6 @@ struct AABB function bool AABB_Collide(AABB a, AABB b); function bool AABB_Point(AABB a, V2f v); +function bool AABB_Slab(V2f origin, V2f point, AABB a); #endif // LD_GAME_AABB_H_ diff --git a/code/game/impl/aabb.c b/code/game/impl/aabb.c index a6a6360..9711a44 100644 --- a/code/game/impl/aabb.c +++ b/code/game/impl/aabb.c @@ -1,5 +1,5 @@ #include "game/aabb.h" -#include "core/types.h" +#include bool AABB_Collide(AABB a, AABB b) { @@ -19,17 +19,18 @@ bool AABB_Slab(V2f origin, V2f point, AABB a) { V2f start = a.pos; V2f finish = {a.pos.x + a.size.x, a.pos.y + a.size.y}; - V2f direction = {origin.x - point.x, origin.y - point.y}; + V2f invdirection = {1 / (origin.x - point.x), 1 / (origin.y - point.y)}; // x - F32 tLow = (start.x - origin.x) / direction.x; - F32 tHigh = (finish.x - origin.x) / direction.x; + F32 tLow = (start.x - origin.x) * invdirection.x; + F32 tHigh = (finish.x - origin.x) * invdirection.x; F32 tMin = min(tLow, tHigh); F32 tMax = max(tLow, tHigh); // y - tLow = (start.x - origin.x) / direction.x; - tHigh = (finish.x - origin.x) / direction.x; + tLow = (start.y - origin.y) * invdirection.y; + tHigh = (finish.y - origin.y) * invdirection.y; tMin = max(tMin, min(tLow, tHigh)); tMax = min(tMax, max(tLow, tHigh)); - return tMax >= max(0.0, tMin); + + return tMax >= tMin; } \ No newline at end of file diff --git a/code/game/impl/nav.c b/code/game/impl/nav.c index a6e7fe9..b420475 100644 --- a/code/game/impl/nav.c +++ b/code/game/impl/nav.c @@ -6,7 +6,8 @@ #define MAX_UNFINISHED 128 typedef struct navSearchNodeState navSearchNodeState; -struct navSearchNodeState{ +struct navSearchNodeState +{ bool visited; U64 distance; U32 shortest; @@ -14,37 +15,45 @@ struct navSearchNodeState{ }; typedef struct navSearchState navSearchState; -struct navSearchState{ +struct navSearchState +{ navSearchNodeState nodeStates[NAV_MAX_NODES]; }; -navSearchState initState(U32 start, U32 meshSize) { - navSearchState state = {}; - for(U32 i = 0; i < meshSize; i++) { - state.nodeStates[i].visited = false; +navSearchState initState(U32 start, U32 meshSize) +{ + navSearchState state; + for (U32 i = 0; i < meshSize; i++) + { + state.nodeStates[i].visited = false; state.nodeStates[i].addedToUnvisited = false; - state.nodeStates[i].distance = U64_MAX; - state.nodeStates[i].shortest = 0; + state.nodeStates[i].distance = U64_MAX; + state.nodeStates[i].shortest = 0; } state.nodeStates[start].distance = 0; return state; } -U32 getLowestState(U32 unfinishedIndexes[128], U32 unfinishedCount, navSearchState state, U32 *offset) { - U32 lowest = U32_MAX; +U32 getLowestState(U32 unfinishedIndexes[128], U32 unfinishedCount, navSearchState state, U32 *offset) +{ + U32 lowest = U32_MAX; U32 lowestI = U32_MAX; bool startFound = false; - for(U32 i = *offset; i < unfinishedCount; i++) { + for (U32 i = *offset; i < unfinishedCount; i++) + { navSearchNodeState checkNode = state.nodeStates[unfinishedIndexes[i]]; - if(checkNode.visited) { - if(!startFound) { + if (checkNode.visited) + { + if (!startFound) + { *offset = i; } continue; } startFound = true; - if (lowest > checkNode.distance) { - lowest = cast(U32) checkNode.distance; + if (lowest > checkNode.distance) + { + lowest = cast(U32) checkNode.distance; lowestI = unfinishedIndexes[i]; } } @@ -52,7 +61,8 @@ U32 getLowestState(U32 unfinishedIndexes[128], U32 unfinishedCount, navSearchSta } // Generate a path to follow between the start and end node. -NavPath Nav_Path(NavMesh *mesh, U32 start, U32 end) { +NavPath Nav_Path(NavMesh *mesh, U32 start, U32 end) +{ navSearchState state = initState(start, mesh->nodeCount); U32 unfinishedCount = 1; U32 unfinishedIndexes[NAV_MAX_NODES] = {start}; @@ -63,19 +73,26 @@ NavPath Nav_Path(NavMesh *mesh, U32 start, U32 end) { U32 unfinishedOffset = 0; U32 lowestNodeIndex = start; bool found = false; - while(!found) { - for(int connectionI = 0 ; connectionI < mesh->nodes[lowestNodeIndex].connectionCount; connectionI++) { - NavConnection *connection = &mesh->nodes[lowestNodeIndex].connections[connectionI]; - navSearchNodeState *testNode = &state.nodeStates[connection->NodeIndex]; - if(testNode->visited) {continue;} - U32 distance = cast(U32) (state.nodeStates[lowestNodeIndex].distance + connection->Cost); - distance += cast(U32) (mesh->nodes[end].pos.x - mesh->nodes[connection->NodeIndex].pos.x); - distance += cast(U32) (mesh->nodes[end].pos.y - mesh->nodes[connection->NodeIndex].pos.y); - if(testNode->distance > distance) { + while (!found) + { + for (int connectionI = 0; connectionI < mesh->nodes[lowestNodeIndex].connectionCount; connectionI++) + { + NavConnection *connection = &mesh->nodes[lowestNodeIndex].connections[connectionI]; + navSearchNodeState *testNode = &state.nodeStates[connection->NodeIndex]; + if (testNode->visited) + { + continue; + } + U32 distance = cast(U32)(state.nodeStates[lowestNodeIndex].distance + connection->Cost); + distance += cast(U32)(mesh->nodes[end].pos.x - mesh->nodes[connection->NodeIndex].pos.x); + distance += cast(U32)(mesh->nodes[end].pos.y - mesh->nodes[connection->NodeIndex].pos.y); + if (testNode->distance > distance) + { testNode->distance = distance; testNode->shortest = lowestNodeIndex; } - if(!testNode->addedToUnvisited) { + if (!testNode->addedToUnvisited) + { unfinishedIndexes[unfinishedCount] = connection->NodeIndex; unfinishedCount++; testNode->addedToUnvisited = true; @@ -83,13 +100,15 @@ NavPath Nav_Path(NavMesh *mesh, U32 start, U32 end) { } state.nodeStates[lowestNodeIndex].visited = true; lowestNodeIndex = getLowestState(unfinishedIndexes, unfinishedCount, state, &unfinishedOffset); - if(lowestNodeIndex == end) { + if (lowestNodeIndex == end) + { found = true; } } NavPath res_path = {0}; U32 index = end; - while(index!=start) { + while (index != start) + { res_path.indexes[res_path.nodeCount] = index; res_path.nodeCount++; index = state.nodeStates[index].shortest; diff --git a/code/game/impl/world.c b/code/game/impl/world.c index 405601f..900ff79 100644 --- a/code/game/impl/world.c +++ b/code/game/impl/world.c @@ -3,16 +3,20 @@ #include "../player.h" #include -void UpdateWorld(F32 delta, World *world) { +void UpdateWorld(F32 delta, World *world) +{ UpdateNPCs(delta, world); } -void UpdateNPCs(F32 delta, World *world) { - for(U32 i = 0; i < world->npcCount; i++) { +void UpdateNPCs(F32 delta, World *world) +{ + for (U32 i = 0; i < world->npcCount; i++) + { updateNPC(delta, &world->npcs[i], world); } } -void ProcessEvents(SDL_Event *event, World *world) { +void ProcessEvents(SDL_Event *event, World *world) +{ PlayerUpdate(event, &world->player); } From 9a46a802e09c8d79951a4202733ccf96f7f2c11b Mon Sep 17 00:00:00 2001 From: declan Date: Sun, 5 Oct 2025 16:07:55 +0100 Subject: [PATCH 3/3] add ignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index f25181b..c094b4f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ build/ code/compile_commands.json code/.cache +.vscode