add collision to placeables
buildbot/windows Build done.
buildbot/linux Build done.

This commit is contained in:
Sven Balzer
2026-08-07 19:11:14 +02:00
parent ecd6571785
commit 3f9f154939
+41 -7
View File
@@ -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;