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:
M | src/game.c | | | 160 | ++++++++++++++++++++----------------------------------------------------------- |
M | src/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