a-game

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

commit e42269fa3745f6c6610263ee5bd8d58fcefd3ff0
parent 3418f76c8a1741b85df476212d4375f860c9c9bc
Author: amin <dev@aminmesbah.com>
Date:   Fri, 26 Apr 2019 01:01:43 +0000

Move between two rooms

FossilOrigin-Name: 0187b03d62d68adcc2c345b422673cb3f107029d259327c8404f09de952c5a18
Diffstat:
Msrc/game.c | 82+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
Msrc/game.h | 7+++++++
Msrc/glmth.h | 6++++++
3 files changed, 89 insertions(+), 6 deletions(-)

diff --git a/src/game.c b/src/game.c @@ -4,6 +4,8 @@ // One tile is one square meter #define TILE_SIZE 1.0f +// TODO: delete +#define NUM_ROOMS 2 #ifdef PLATFORM_HOTLOAD_GAME_CODE void game_load_opengl_symbols(void) @@ -16,8 +18,13 @@ internal void game_init(struct GameMemory *game_memory, v2u framebuffer) { struct GameState *game_state = game_memory->game_state; + game_state->player_pos_absolute = (struct AbsolutePos) { + .room_index = {0, 0}, + .room_offset = {12.5f, 5.0f}, + }; + // init player - game_state->player.pos = (v2) {12.5f, 5.0f}; + game_state->player.pos = game_state->player_pos_absolute.room_offset; // 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 @@ -85,6 +92,58 @@ internal void game_init(struct GameMemory *game_memory, v2u framebuffer) } } +internal struct AbsolutePos pos_recanonicalize(struct AbsolutePos p) +{ + struct AbsolutePos p_final = p; + v2i room_index_delta = {0}; + + if (p.room_offset.x < 0.0f) + { + room_index_delta.x -= 1; + p_final.room_offset.x = glmth_wrap(p.room_offset.x, 0.0f, ROOM_TILE_DIM_X); + } + else if (p.room_offset.x > ROOM_TILE_DIM_X) + { + room_index_delta.x += 1; + p_final.room_offset.x = glmth_wrap(p.room_offset.x, 0.0f, ROOM_TILE_DIM_X); + } + + if (p.room_offset.y < 0.0f) + { + room_index_delta.y -= 1; + p_final.room_offset.y = glmth_wrap(p.room_offset.y, 0.0f, ROOM_TILE_DIM_Y); + } + else if (p.room_offset.y > ROOM_TILE_DIM_Y) + { + room_index_delta.y += 1; + p_final.room_offset.y = glmth_wrap(p.room_offset.y, 0.0f, ROOM_TILE_DIM_Y); + } + + p_final.room_index = glmth_v2i_a(p.room_index, room_index_delta); + return p_final; +} + +struct RoomSearchResult +{ + bool room_found; + size_t room_array_index; +}; + +internal struct RoomSearchResult get_room_at_index(struct Room *rooms[NUM_ROOMS], u32 num_rooms, v2i room_i) +{ + struct RoomSearchResult result = {0}; + for (size_t i = 0; i < num_rooms; i++) + { + struct Room *r = rooms[i]; + if (r->index.x == room_i.x && r->index.y == room_i.y) + { + result.room_found = true; + result.room_array_index = i; + } + } + return result; +} + struct WallCollision { bool collision_occurred; @@ -320,8 +379,15 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga }, }; - u32 *tiles = knytt_hanging_fly_village.tiles; - tiles = collision_test_zone.tiles; + // TODO: This is, of course, just temporary. Delete it. + struct Room *rooms[NUM_ROOMS] = {&collision_test_zone, &knytt_hanging_fly_village}; + + v2i current_room_i = game_state->player_pos_absolute.room_index; + struct RoomSearchResult r = get_room_at_index(rooms, NUM_ROOMS, current_room_i); + assert(r.room_found); + struct Room *current_room = rooms[r.room_array_index]; + assert(current_room); + u32 *tiles = current_room->tiles; // render tiles { @@ -377,7 +443,8 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga if (player_is_in_tile && solid) { color = (v3) {0.8f, 0.4f, 0.4f}; - assert(false); + // TODO: re-enable this + //assert(false); } } @@ -610,8 +677,11 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga } } #undef RENDER_COLLISION_DEBUG_QUAD - glmth_clamp(&player->pos.x, 0.0f, ROOM_TILE_DIM_X); - glmth_clamp(&player->pos.y, 0.0f, ROOM_TILE_DIM_Y); + + game_state->player_pos_absolute.room_offset = player->pos; + struct AbsolutePos new_canonical_p = pos_recanonicalize(game_state->player_pos_absolute); + game_state->player_pos_absolute = new_canonical_p; + player->pos = game_state->player_pos_absolute.room_offset; } // render player diff --git a/src/game.h b/src/game.h @@ -39,10 +39,17 @@ struct Room u32 tiles[ROOM_TILE_DIM_Y * ROOM_TILE_DIM_X]; }; +struct AbsolutePos +{ + v2i room_index; + v2 room_offset; +}; + struct GameState { struct RendererState renderer; struct Entity player; + struct AbsolutePos player_pos_absolute; }; internal void game_init(struct GameMemory *game_memory, v2u framebuffer); diff --git a/src/glmth.h b/src/glmth.h @@ -187,6 +187,12 @@ internal inline f32 glmth_v2_dot(v2 vec1, v2 vec2) return dot_product; } +internal inline v2i glmth_v2i_a(v2i vec1, v2i vec2) +{ + v2i r = {vec1.x + vec2.x, vec1.y + vec2.y}; + return r; +} + internal inline v3 glmth_v3_cross(v3 vec1, v3 vec2) { // cross product, a.k.a. outer product or vector product