From 3f9f15493974f8664567a3aa916d36736cbef997 Mon Sep 17 00:00:00 2001 From: Sven Balzer <4653051+Kyuusokuna@users.noreply.github.com> Date: Fri, 7 Aug 2026 19:11:14 +0200 Subject: [PATCH] add collision to placeables --- src/main.cpp | 48 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 7 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index c2f1a09..d885ab3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -201,6 +201,8 @@ struct Map { char name[64]; + Uint8 *static_collision_grid; + R_Texture texture; R_Buffer placeables_buffer; }; @@ -465,6 +467,16 @@ static R_Texture create_texture(const char *path) { return result; } +static void recalculate_static_collision_grid(Map *world) { + if (world->static_collision_grid) SDL_free(world->static_collision_grid); + world->static_collision_grid = (Uint8 *)SDL_calloc((world->size.x - 2) * (world->size.y - 2), sizeof(*world->static_collision_grid)); + + for (int i = 0; i < world->num_placeables; i++) { + u32vec2 pos = world->placeables[i].pos; + world->static_collision_grid[pos.y * (world->size.x - 2) + pos.x] = 1; + } +} + static bool save_worlds_list() { const char *path = ASSETS_PATH "maps/worlds.h"; @@ -680,6 +692,8 @@ static bool load_map(const char *name, Map *result) { result->placeables_buffer = renderer_buffer_create(R_BUFFER_USAGE_VERTEX, result->num_placeables * sizeof(*result->placeables), result->placeables, "placeables_buffer"); } + recalculate_static_collision_grid(result); + SDL_Log("Loaded map file."); return true; } @@ -1227,6 +1241,7 @@ static void process_event_editor(SDL_Event event) { if (current_map->placeables_buffer) renderer_buffer_destroy(current_map->placeables_buffer); current_map->placeables_buffer = renderer_buffer_create(R_BUFFER_USAGE_VERTEX, current_map->num_placeables * sizeof(*current_map->placeables), current_map->placeables, "placeables_buffer"); + recalculate_static_collision_grid(current_map); } if (show_placeable_editor && selected_placeable == -1) { @@ -1240,6 +1255,7 @@ static void process_event_editor(SDL_Event event) { if (current_map->placeables_buffer) renderer_buffer_destroy(current_map->placeables_buffer); if (current_map->num_placeables) current_map->placeables_buffer = renderer_buffer_create(R_BUFFER_USAGE_VERTEX, current_map->num_placeables * sizeof(*current_map->placeables), current_map->placeables, "placeables_buffer"); + recalculate_static_collision_grid(current_map); } if (selected_tile_kind != -1) { @@ -1731,6 +1747,30 @@ static void render_editor() { } } +static bool try_queued_move() { + queued_movement = false; + player.direction = queued_movement_direction; + + i32vec2 target_position = player.position; + switch (queued_movement_direction) { + case DIR_UP: { target_position = clamp(ivec2(0, 0), player.position + ivec2( 0, 1), current_map->size - ivec2(2, 2)); } break; + case DIR_LEFT: { target_position = clamp(ivec2(0, 0), player.position + ivec2(-1, 0), current_map->size - ivec2(2, 2)); } break; + case DIR_DOWN: { target_position = clamp(ivec2(0, 0), player.position + ivec2( 0, -1), current_map->size - ivec2(2, 2)); } break; + case DIR_RIGHT: { target_position = clamp(ivec2(0, 0), player.position + ivec2( 1, 0), current_map->size - ivec2(2, 2)); } break; + } + + if (target_position != player.position) { + if (current_map->static_collision_grid[target_position.y * (current_map->size.x - 2) + target_position.x] == 1) + return false; + + player.target_position = target_position; + player.is_moving = true; + return true; + } + + return false; +} + static void process_event_game(SDL_Event event) { ZoneScopedN("process_event"); @@ -1810,14 +1850,8 @@ static void update_state_game() { bool is_movement_key_pressed = keyboard_state[SDL_SCANCODE_W] || keyboard_state[SDL_SCANCODE_A] || keyboard_state[SDL_SCANCODE_S] || keyboard_state[SDL_SCANCODE_D] || keyboard_state[SDL_SCANCODE_UP] || keyboard_state[SDL_SCANCODE_LEFT] || keyboard_state[SDL_SCANCODE_DOWN] || keyboard_state[SDL_SCANCODE_RIGHT]; if (!player.is_moving && (queued_movement || is_movement_key_pressed)) { - switch (queued_movement_direction) { - case DIR_UP: { player.direction = queued_movement_direction; player.target_position = clamp(ivec2(0, 0), player.position + ivec2( 0, 1), current_map->size - ivec2(2, 2)); if (player.target_position != player.position) player.is_moving = true; } break; - case DIR_LEFT: { player.direction = queued_movement_direction; player.target_position = clamp(ivec2(0, 0), player.position + ivec2(-1, 0), current_map->size - ivec2(2, 2)); if (player.target_position != player.position) player.is_moving = true; } break; - case DIR_DOWN: { player.direction = queued_movement_direction; player.target_position = clamp(ivec2(0, 0), player.position + ivec2( 0, -1), current_map->size - ivec2(2, 2)); if (player.target_position != player.position) player.is_moving = true; } break; - case DIR_RIGHT: { player.direction = queued_movement_direction; player.target_position = clamp(ivec2(0, 0), player.position + ivec2( 1, 0), current_map->size - ivec2(2, 2)); if (player.target_position != player.position) player.is_moving = true; } break; - } + try_queued_move(); } - queued_movement = false; if (!player.is_moving) player.animation_time = 0;