a-game

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

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

Implement a very buggy cast of the player

FossilOrigin-Name: 058b3ae614893c43f2fbb7f7b928641ef334cc95385fdf9e82ba7ab5191aeefe
Diffstat:
Msrc/game.c | 162++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 128 insertions(+), 34 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 0 +#if 1 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); #else glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); @@ -195,6 +195,127 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga glmth_clamp(&(player->pos.x), 0, ROOM_TILE_DIM_X); glmth_clamp(&(player->pos.y), 0, ROOM_TILE_DIM_Y); +#if 0 + { + 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 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++) + { + 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}, + }; + bool cast_intersects = glmth_aabb_intersect(cast_aabb, tile_aabb); + if(cast_intersects && tile_id > 0) + { + 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; + } + } + } + } +#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)) + { + 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); + } + } + } +#endif } // render tiles @@ -221,6 +342,7 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga model = glmth_scale(model, (v3) {tile_size, tile_size, 1.0f}); v3 color; + if (tile_id > 0) { color = (v3) {0.4f, 0.4f, 0.4f}; @@ -231,46 +353,18 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga } { - struct Entity *player = &game_state->player; - f32 half_w = 0.5f * player->dimensions.width; - f32 half_h = 0.5f * player->dimensions.height; + 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}, + .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 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})); - printf("max_cast: %d\n", max_cast); - for (i32 i = 0; i < max_cast; i++) - { - 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}, - }; - bool cast_intersects = glmth_aabb_intersect(cast_aabb, tile_aabb); - if(cast_intersects) - { - color = (v3) {0.4f, 0.4f, 0.8f}; - } - if(cast_intersects && tile_id > 0) - { - color = (v3) {0.8f, 0.4f, 0.8f}; - break; - } - } - } - bool player_is_in_tile = glmth_aabb_intersect(player_aabb, tile_aabb); if (player_is_in_tile) {