a-game

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

commit 0cef6f18a8140f33375b8c6a1b1e248c552db435
parent ce05fe56055d4841aa66d46b86684049d266f315
Author: amin <dev@aminmesbah.com>
Date:   Thu, 25 Apr 2019 21:46:06 +0000

Add a room struct

FossilOrigin-Name: bf89b975a783219f105119f70a4952a857608b07496fba4343fe64fab89a042d
Diffstat:
Msrc/game.c | 156+++++++++++++++++++++++++++++++++-----------------------------------------------
Msrc/game.h | 6++++++
2 files changed, 70 insertions(+), 92 deletions(-)

diff --git a/src/game.c b/src/game.c @@ -137,33 +137,44 @@ internal struct WallCollision get_wall_collision(v2 entity_p_initial, v2 entity_ return result; } -internal bool tile_is_solid(u32 tiles[][ROOM_TILE_DIM_X], v2 tile_pos) +internal u32 get_tile_value(u32 *tiles, v2 tile_pos) { assert(tiles); - bool is_solid = false; - - v2u tile_index = { + v2u tile_i_2d = { tile_pos.x, ROOM_TILE_DIM_Y - 1.0f - tile_pos.y, }; assert(glmth_v2_lt( - (v2) {tile_index.x, tile_index.y}, + (v2) {tile_i_2d.x, tile_i_2d.y}, (v2) {ROOM_TILE_DIM_X, ROOM_TILE_DIM_Y})); assert(glmth_v2_ge( - (v2) {tile_index.x, tile_index.y}, + (v2) {tile_i_2d.x, tile_i_2d.y}, (v2) {0})); - u32 tile_value = tiles[tile_index.y][tile_index.x]; - is_solid = tile_value > 0; + u32 tile_i_linearized = (ROOM_TILE_DIM_X * tile_i_2d.y) + tile_i_2d.x; + assert(tile_i_linearized < ROOM_TILE_DIM_X * ROOM_TILE_DIM_Y); + + u32 tile_value = tiles[tile_i_linearized]; + return tile_value; +} +internal bool tile_is_solid(u32 *tiles, v2 tile_pos) +{ + assert(tiles); + + bool is_solid = false; + u32 tile_value = get_tile_value(tiles, tile_pos); + is_solid = tile_value > 0; return is_solid; } -internal bool wall_is_screen_edge(u32 tiles[][ROOM_TILE_DIM_X], segment wall) +internal bool wall_is_screen_edge(u32 *tiles, segment wall) { + assert(tiles); + bool is_screen_edge = false; bool wall_is_horizontal = wall.min.y == wall.max.y; bool wall_is_vertical = wall.min.x == wall.max.x; @@ -184,8 +195,10 @@ internal bool wall_is_screen_edge(u32 tiles[][ROOM_TILE_DIM_X], segment wall) return is_screen_edge; } -internal bool wall_is_internal(u32 tiles[][ROOM_TILE_DIM_X], segment wall) +internal bool wall_is_internal(u32 *tiles, segment wall) { + assert(tiles); + bool is_internal = false; bool wall_is_horizontal = wall.min.y == wall.max.y; bool wall_is_vertical = wall.min.x == wall.max.x; @@ -265,36 +278,42 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga // Screen origin is in the upper left m4 projection = glmth_projection_ortho(0.0f, framebuffer.width, framebuffer.height, 0.0f, -1.0f, 0.0f); - // the little hanging fly village from knytt - u32 tiles[ROOM_TILE_DIM_Y][ROOM_TILE_DIM_X] = { - { 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1 }, - { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1 }, - { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1 }, - { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0 }, - - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, - { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + struct Room knytt_hanging_fly_village = { + .index = {0, 0}, + .tiles = { + 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + }, }; - // collision and physics testing map - //u32 tiles[ROOM_TILE_DIM_Y][ROOM_TILE_DIM_X] = { - // { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - // { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 }, - // { 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0 }, - // { 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0 }, - // { 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0 }, - - // { 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0 }, - // { 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0 }, - // { 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0 }, - // { 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0 }, - // { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - //}; + struct Room collision_test_zone = { + .index = {0, 1}, + .tiles = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, + 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, + 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, + 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, + + 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, + 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, + 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, + 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }, + }; + u32 *tiles = knytt_hanging_fly_village.tiles; + tiles = collision_test_zone.tiles; // render tiles { @@ -309,7 +328,6 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga x, ROOM_TILE_DIM_Y - 1.0f - y, }; - u32 tile_id = tiles[y][x]; m4 model = glmth_m4_init_id(); // our square verts are anchored around the center point of the @@ -321,7 +339,8 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga v3 color; - if (tile_id > 0) + bool solid = tile_is_solid(tiles, tile_pos); + if (solid) { color = (v3) {0.4f, 0.4f, 0.4f}; } @@ -348,7 +367,7 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga { color = (v3) {0.4f, 0.8f, 0.4f}; } - if (player_is_in_tile && tile_id > 0) + if (player_is_in_tile && solid) { color = (v3) {0.8f, 0.4f, 0.4f}; assert(false); @@ -416,54 +435,6 @@ 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); -#if 0 - { - f32 half_w = 0.5f * player->dimensions.width; - f32 half_h = 0.5f * player->dimensions.height; - 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; - rect search_range = { - .min = {player_tile.x - 1, player_tile.y - 1}, - .max = {player_tile.x + 2, player_tile.y + 2}, - }; - render_debug_quad(game_state, search_range, (v3) {0.8f, 0.8f, 0.8f}, &view, &projection); - for (i32 y = search_range.min.y; y <= search_range.max.y; y++) - { - if (y < 0 || y >= ROOM_TILE_DIM_Y) - { - continue; - } - for (i32 x = search_range.min.x; x <= search_range.max.x + 1; x++) - { - if (x < 0 || x >= ROOM_TILE_DIM_X) - { - continue; - } - - rect tile_aabb = { - .min = {x, y}, - .max = {x + TILE_SIZE, y + TILE_SIZE}, - }; - 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_intersect_aabb_aabb(player_aabb, tile_aabb) && tile_id == 1) - { - next_pos_is_valid = false; - } - } - } - if (next_pos_is_valid) - { - player->pos = next_player_pos; - } - } -#else { #define RENDER_COLLISION_DEBUG_QUAD(r, c) render_debug_quad(game_state, (r), (c), &view, &projection); v2 player_delta = glmth_v2f_m(player->velocity, dt); @@ -502,10 +473,12 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga { assert(tile_x < ROOM_TILE_DIM_X); assert(tile_y < ROOM_TILE_DIM_Y); - v2u tile_index = {tile_x, ROOM_TILE_DIM_Y - tile_y - 1}; - u32 tile_id = tiles[tile_index.y][tile_index.x]; + v2 tile_pos = { + tile_x, + tile_y, + }; - if (tile_id == 1) + if (tile_is_solid(tiles, tile_pos)) { rect tile_aabb = { .min = {tile_x, tile_y}, @@ -633,7 +606,6 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga } } #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); } diff --git a/src/game.h b/src/game.h @@ -33,6 +33,12 @@ struct Entity struct Shader shader; }; +struct Room +{ + v2i index; + u32 tiles[ROOM_TILE_DIM_Y * ROOM_TILE_DIM_X]; +}; + struct GameState { struct Tiles tiles;