a-game

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

commit 0f0da7db2b8740a860888e4ed9d0ad9771b62f35
parent 5d13338cbd90ed9c843a5bcea6f188f348e59662
Author: amin <dev@aminmesbah.com>
Date:   Sun, 21 Apr 2019 19:34:44 +0000

Do the most basic collision prevention possible

This doesn't work well, but it sort of works, might be a better starting
point.

FossilOrigin-Name: ca4e1dc1efe98c5ddb0f8810d90bacf1d35e8bb542a259b1c3b86355ad8a6941
Diffstat:
Msrc/game.c | 160++++++++++++++++++++-----------------------------------------------------------
Msrc/types.h | 13+++++++++++++
2 files changed, 54 insertions(+), 119 deletions(-)

diff --git a/src/game.c b/src/game.c @@ -112,7 +112,7 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga glClearColor(0.1f, 0.1f, 0.1f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); -#if 1 +#if 0 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); #else glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); @@ -151,12 +151,8 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga struct Entity *player = &game_state->player; f32 dt = game_input->dt; f32 max_meters_per_second = 5.0f; - // TODO: restore acceleration rate - //f32 acceleration_rate = 50.0f; - f32 acceleration_rate = 10.0f; - // TODO: restore friction - //f32 friction = 0.7f; - f32 friction = 1.0f; + f32 acceleration_rate = 50.0f; + f32 friction = 0.7f; if (game_input->key_up) { @@ -191,131 +187,57 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga glmth_clamp(&player->velocity.x, -max_meters_per_second, max_meters_per_second); glmth_clamp(&player->velocity.y, -max_meters_per_second, max_meters_per_second); - player->pos = glmth_v2_a(player->pos, glmth_v2f_m(player->velocity, dt)); - glmth_clamp(&(player->pos.x), 0, ROOM_TILE_DIM_X); - glmth_clamp(&(player->pos.y), 0, ROOM_TILE_DIM_Y); - -#if 0 + // prevent collision with tiles { - struct Entity *player = &game_state->player; f32 half_w = 0.5f * player->dimensions.width; f32 half_h = 0.5f * player->dimensions.height; - rect player_aabb = { - .min = {player->pos.x - half_w, player->pos.y - half_h}, - .max = {player->pos.x + half_w, player->pos.y + half_h}, - }; - rect tile_aabb = { - .min = tile_pos, - .max = {tile_pos.x + tile_size, tile_pos.y + tile_size}, - }; - - // cast player - if (glmth_v2_is_nonzero(player->velocity)) + v2 next_player_pos = glmth_v2_a(player->pos, glmth_v2f_m(player->velocity, dt)); + v2i player_tile = {(i32)next_player_pos.x, (i32)next_player_pos.y}; + bool next_pos_is_valid = true; + for (i32 y = player_tile.y - 1; y <= player_tile.y + 1; y++) { - v2 player_direction = glmth_v2_normalize(player->velocity); - - f32 step_size = 0.001f; - i32 max_cast = (f32)(1.0f / step_size) * glmth_round(glmth_v2_length((v2) {ROOM_TILE_DIM_X, ROOM_TILE_DIM_Y})); - for (i32 i = 0; i < max_cast; i++) + if (y < 0 || y >= ROOM_TILE_DIM_Y) + { + continue; + } + for (i32 x = player_tile.x - 1; x <= player_tile.x + 1; x++) { - v2 cast_pos = glmth_v2_a(player->pos, glmth_v2f_m(player_direction, i * step_size)); - rect cast_aabb = { - .min = {cast_pos.x - half_w, cast_pos.y - half_h}, - .max = {cast_pos.x + half_w, cast_pos.y + half_h}, + if (x < 0 || x >= ROOM_TILE_DIM_X) + { + continue; + } + + rect tile_aabb = { + .min = {x, y}, + .max = {x + tile_size, y + tile_size}, }; - bool cast_intersects = glmth_aabb_intersect(cast_aabb, tile_aabb); - if(cast_intersects && tile_id > 0) + rect player_aabb = { + .min = {next_player_pos.x - half_w, next_player_pos.y - half_h}, + .max = {next_player_pos.x + half_w, next_player_pos.y + half_h}, + }; + + v2u tile_index = {x, ROOM_TILE_DIM_Y - y - 1}; + u32 tile_id = tiles[tile_index.y][tile_index.x]; + if(glmth_aabb_intersect(player_aabb, tile_aabb) && tile_id == 1) { - color = (v3) {0.8f, 0.4f, 0.8f}; - if (player_direction.x > 0.0f) - { - glmth_clamp(&player->pos.x, 0.0f, tile_aabb.min.x); - } - else - { - glmth_clamp(&player->pos.x, tile_aabb.max.x, ROOM_TILE_DIM_X); - } - - if (player_direction.y > 0.0f) - { - glmth_clamp(&player->pos.y, 0.0f, tile_aabb.min.y); - } - else - { - glmth_clamp(&player->pos.y, tile_aabb.max.y, ROOM_TILE_DIM_Y); - } - break; + next_pos_is_valid = false; } } } - } -#else - { - f32 half_w = 0.5f * player->dimensions.width; - f32 half_h = 0.5f * player->dimensions.height; - rect player_aabb = { - .min = {player->pos.x - half_w, player->pos.y - half_h}, - .max = {player->pos.x + half_w, player->pos.y + half_h}, - }; - // cast player - if (glmth_v2_is_nonzero(player->velocity)) + if (next_pos_is_valid) { - v2 player_direction = glmth_v2_normalize(player->velocity); - f32 angle_to_horizontal = atan2f(player_direction.y, player_direction.x); - - i32 next_tile_grid_row = ceilf(player->pos.y); - if (player_direction.y < 0.0f) - { - next_tile_grid_row = floorf(player->pos.y); - } - assert(next_tile_grid_row >= 0.0f); - assert(next_tile_grid_row <= ROOM_TILE_DIM_Y); - - i32 next_tile_grid_column = ceilf(player->pos.x); - if (player_direction.x < 0.0f) - { - next_tile_grid_column = floorf(player->pos.x); - } - assert(next_tile_grid_column >= 0.0f); - assert(next_tile_grid_column <= ROOM_TILE_DIM_X); - - f32 distance_to_next_column = (f32)next_tile_grid_column - player->pos.x; - f32 distance_to_next_row = (f32)next_tile_grid_row - player->pos.y; - - v2 player_cast = {player->pos.x, player->pos.y}; - if (fabsf(distance_to_next_column) < fabsf(distance_to_next_row)) - { - player_cast = (v2) {distance_to_next_column, distance_to_next_column * tanf(angle_to_horizontal)}; - } - else - { - player_cast = (v2) {distance_to_next_row / tanf(angle_to_horizontal), distance_to_next_row}; - } - player_cast = glmth_v2_a(player_cast, player->pos); - glmth_v2_print(player_cast); - - // render player cast - { - shader_use(&game_state->player.shader); - glBindVertexArray(game_state->tiles.vao); - - m4 model = glmth_m4_init_id(); - model = glmth_translate(model, (v3) {player_cast.x, player_cast.y, 0.0f}); - model = glmth_scale(model, (v3) {player->dimensions.x, player->dimensions.y, 1.0f}); - - v3 color = (v3) { 0.8f, 0.4f, 0.8f }; - - 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); - } + player->pos = next_player_pos; + } + else + { + printf("Invalid: "); + glmth_v2_print(next_player_pos); + player->velocity = (v2) {0.0f, 0.0f}; } } -#endif + glmth_clamp(&player->pos.x, 0.0f, ROOM_TILE_DIM_X); + glmth_clamp(&player->pos.y, 0.0f, ROOM_TILE_DIM_Y); + } // render tiles diff --git a/src/types.h b/src/types.h @@ -45,6 +45,19 @@ typedef union { struct { + i32 x, y; + }; + struct + { + i32 width, height; + }; + i32 E[2]; +} v2i; + +typedef union +{ + struct + { f32 x, y, z; }; struct