a-game

2D platformer written from scratch.
git clone git://git.amin.space/a-game.git
Log | Files | Refs | README | LICENSE

commit c75172ff8195c05adc80689819b54f2f73f635db
parent 7e4dcea3ca6776cbaca7a54236e9bbc82ce20ad5
Author: amin <dev@aminmesbah.com>
Date:   Tue, 23 Apr 2019 21:37:59 +0000

Fix tunneling bug

Wow! So satisfying! We were failing to take into account the new player
delta during the consecutive iterations of the collision solver, so
residual velocity was being allowed to push the player through walls.

FossilOrigin-Name: 6e5e06e152d1250a70862f678fb80e9ffce13c40c0a7cffd8ea078f2572a8301
Diffstat:
Msrc/game.c | 62++++++++++++++------------------------------------------------
1 file changed, 14 insertions(+), 48 deletions(-)

diff --git a/src/game.c b/src/game.c @@ -373,33 +373,7 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga #define RENDER_COLLISION_DEBUG_QUAD(r, c) render_debug_quad(game_state, (r), (c), &view, &projection); v2 old_p = player->pos; v2 new_p = glmth_v2_a(old_p, glmth_v2f_m(player->velocity, dt)); - player->pos = new_p; - glmth_clamp(&player->pos.x, 0.0f, ROOM_TILE_DIM_X); - glmth_clamp(&player->pos.y, 0.0f, ROOM_TILE_DIM_Y); - v2 collision_ghost_origin = { - 11.0f + (0.5f * player->dimensions.width), - 4.0f + (0.5f * player->dimensions.height) - }; - old_p = collision_ghost_origin; - { // render collision ghost origin - shader_use(&game_state->player.shader); - glBindVertexArray(game_state->tiles.vao); - - m4 model = glmth_m4_init_id(); - model = glmth_translate(model, (v3) {collision_ghost_origin.x, collision_ghost_origin.y, 0.0f}); - model = glmth_scale(model, (v3) {player->dimensions.x, player->dimensions.y, 1.0f}); - - v3 color = (v3) { 1.0f, 1.0f, 0.0f }; - - shader_setv3(&game_state->tiles.shader, "color", &color); - shader_setm4(&game_state->tiles.shader, "model", &model); - shader_setm4(&game_state->tiles.shader, "view", &view); - shader_setm4(&game_state->tiles.shader, "projection", &projection); - - glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); - glBindVertexArray(0); - } rect player_traversal_bb = { .min = {glmth_min(old_p.x, new_p.x), glmth_min(old_p.y, new_p.y)}, .max = {glmth_max(old_p.x, new_p.x), glmth_max(old_p.y, new_p.y)}, @@ -421,11 +395,13 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga }; RENDER_COLLISION_DEBUG_QUAD(tile_search_range, ((v3) {0.8f, 0.8f, 0.8f})); - struct Entity collision_ghost = {0}; v2 player_delta = glmth_v2_s(new_p, old_p); f32 remaining_time_factor = 1.0f; for (u32 i = 0; i < 4 && remaining_time_factor > 0.0f; i++) { + old_p = player->pos; + new_p = glmth_v2_a(old_p, glmth_v2f_m(player->velocity, dt)); + player_delta = glmth_v2_s(new_p, old_p); v2 wall_normal = {0}; f32 smallest_distance_scale_factor = 1.0f; for (i32 tile_y = tile_search_range.min.y; tile_y < tile_search_range.max.y; tile_y++) @@ -522,32 +498,22 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga } } v2 nearest_collision_p = glmth_v2_a(old_p, glmth_v2f_m(player_delta, smallest_distance_scale_factor)); - collision_ghost.pos = nearest_collision_p; + player->pos = nearest_collision_p; + player->velocity = glmth_v2_s( + player->velocity, + glmth_v2f_m(wall_normal, glmth_v2_dot(player->velocity, wall_normal)) + ); + player_delta = glmth_v2_s( + player_delta, + glmth_v2f_m(player_delta, glmth_v2_dot(player->velocity, wall_normal)) + ); remaining_time_factor -= smallest_distance_scale_factor * remaining_time_factor; } - - // render collision_ghost - { - shader_use(&game_state->player.shader); - glBindVertexArray(game_state->tiles.vao); - - m4 model = glmth_m4_init_id(); - model = glmth_translate(model, (v3) {collision_ghost.pos.x, collision_ghost.pos.y, 0.0f}); - model = glmth_scale(model, (v3) {player->dimensions.x, player->dimensions.y, 1.0f}); - - v3 color = (v3) { 0.0f, 1.0f, 1.0f }; - - shader_setv3(&game_state->tiles.shader, "color", &color); - shader_setm4(&game_state->tiles.shader, "model", &model); - shader_setm4(&game_state->tiles.shader, "view", &view); - shader_setm4(&game_state->tiles.shader, "projection", &projection); - - glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); - glBindVertexArray(0); - } } #undef RENDER_COLLISION_DEBUG_QUAD #endif + glmth_clamp(&player->pos.x, 0.0f, ROOM_TILE_DIM_X); + glmth_clamp(&player->pos.y, 0.0f, ROOM_TILE_DIM_Y); }