a-game

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

commit 704f18b717c404b6a6cd96ec2290534990236aa1
parent c75172ff8195c05adc80689819b54f2f73f635db
Author: amin <dev@aminmesbah.com>
Date:   Wed, 24 Apr 2019 00:00:21 +0000

Capture a failing test case for the lingering bug

The collision assert fails rather frequently just after start up with
this initial position and velocity.

FossilOrigin-Name: 5cc64ce2fef71598cfb59b2c34d50aed0148a5aa1ae1e2ffcc7376a62a51deb2
Diffstat:
Msrc/game.c | 24++++++++++++++++++++----
Msrc/glmth.h | 12++++++++++++
2 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/src/game.c b/src/game.c @@ -14,8 +14,11 @@ internal void game_init(struct GameMemory *game_memory, v2u framebuffer) struct GameState *game_state = game_memory->game_state; // init player - game_state->player.pos = (v2) {12.5f, 5.0f}; - + //game_state->player.pos = (v2) {12.5f, 5.0f}; + game_state->player.pos = (v2) {10.812491f, 3.752474f}; + game_state->player.velocity = (v2) {0.0f, 5.0f}; + game_state->player.pos = (v2) {10.736823f, 3.591690f}; + game_state->player.velocity = (v2) {5.0f, 5.0f}; // In Knytt, the player is 9 by 14 texels and a tile is 24 by 24 texels. // These dimensions are relative to a square 'meter', one tile game_state->player.dimensions = (v2) {0.375f, 0.583f}; @@ -116,7 +119,9 @@ internal struct WallCollision get_wall_collision(v2 entity_p_initial, v2 entity_ && collision_point.E[wall_axis] <= wall.max.E[wall_axis]) { result.collision_occurred = true; - result.distance_scale_factor = segment_scale_factor - 0.0001f; + result.distance_scale_factor = glmth_max( + 0.0f, + segment_scale_factor - 0.0001f); } } } @@ -266,6 +271,10 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga if (player_is_in_tile && tile_id > 0) { color = (v3) {0.8f, 0.4f, 0.4f}; + printf("!!!!!!!!!!!!!!!!\n"); + glmth_print(glmth_v2_a(player.pos, glmth_v2f_m(player.dimensions, 0.5f))); + glmth_print(player.velocity); + assert(false); } } @@ -286,7 +295,8 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga f32 dt = game_input->dt; f32 max_meters_per_second = 5.0f; f32 acceleration_rate = 50.0f; - f32 friction = 0.7f; + //f32 friction = 0.7f; + f32 friction = 1.0f; if (game_input->key_up) { @@ -371,6 +381,7 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga #else { #define RENDER_COLLISION_DEBUG_QUAD(r, c) render_debug_quad(game_state, (r), (c), &view, &projection); + printf("--------------\n"); v2 old_p = player->pos; v2 new_p = glmth_v2_a(old_p, glmth_v2f_m(player->velocity, dt)); @@ -399,6 +410,7 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga f32 remaining_time_factor = 1.0f; for (u32 i = 0; i < 4 && remaining_time_factor > 0.0f; i++) { + printf("Iteration %u:\n", 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); @@ -508,6 +520,10 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga glmth_v2f_m(player_delta, glmth_v2_dot(player->velocity, wall_normal)) ); remaining_time_factor -= smallest_distance_scale_factor * remaining_time_factor; + glmth_print(player_delta); + glmth_print(glmth_v2_a(player->pos, glmth_v2f_m(player->dimensions, 0.5f))); + glmth_print(player->velocity); + printf("time remaining: %f\n", remaining_time_factor); } } #undef RENDER_COLLISION_DEBUG_QUAD diff --git a/src/glmth.h b/src/glmth.h @@ -179,6 +179,11 @@ internal inline f32 glmth_v2_dot(v2 vec1, v2 vec2) { // dot product, a.k.a. inner product or scalar product f32 dot_product = (vec1.x * vec2.x) + (vec1.y * vec2.y); + // NOTE: this value happens to be: + // |vec1| * |vec2| * Cos(theta) + // where theta is the angle between vec1 and vec2. This is useful in all + // sorts of ways: What if theta is zero? What if vec1 or vec2 is a unit + // vector? return dot_product; } @@ -196,6 +201,13 @@ internal inline v3 glmth_v3_cross(v3 vec1, v3 vec2) internal inline f32 glmth_v3_length(v3 v) { // TODO: Use inner product of v with itself + // NOTE: glmth_v3_dot(v, v) returns: + // |v| * |v| * Cos(theta) + // We know that theta, the angle between v and itself, is always 0, so we + // know that Cos(theta) is always 1. We can then simplify the above + // expression to be: + // (|v|)^2 + // so sqrtf(glmth_v3_dot(v, v)) is the length of v return sqrtf((v.x * v.x) + (v.y * v.y) + (v.z * v.z)); }