From 84848ff3fd99d565815a9c53ca6dbf36d25795fd Mon Sep 17 00:00:00 2001 From: KikooDX Date: Thu, 4 Mar 2021 18:21:03 +0100 Subject: [PATCH] Keys. --- include/level.h | 2 ++ include/player.h | 3 +++ kble.py | 7 ++++++- src/level.c | 2 ++ src/player.c | 44 +++++++++++++++++++++++++++++++++++--------- 5 files changed, 48 insertions(+), 10 deletions(-) diff --git a/include/level.h b/include/level.h index 757943e..1be0d56 100644 --- a/include/level.h +++ b/include/level.h @@ -13,6 +13,7 @@ typedef struct Level{ tile_t content[LEVEL_WIDTH * LEVEL_HEIGHT]; Vec2 start_pos; + u8 keys; } Level; #include "player.h" @@ -20,3 +21,4 @@ typedef struct Level{ void level_load(Level *level, Player *player, u8 id); void level_draw(Level level); tile_t level_get_tile_at_px(Level level, Vec2 pos); +void level_set_tile_at_px(Level *level, Vec2 pos, tile_t tile); diff --git a/include/player.h b/include/player.h index 7f18860..905ff4f 100644 --- a/include/player.h +++ b/include/player.h @@ -46,6 +46,9 @@ void player_draw(Player player); /* Helper functions. */ bool player_collide(Level level, Vec2 pos, tile_t tile, u8 margin); bool player_move(Player *player, Level level, i8 spd_x, i8 spd_y); +u8 player_collide_key(Level *level, vec2_int_t x, vec2_int_t y); +void player_collide_keys(Player *player, Level *level); + i8 sign(i8 value); f32 signf(f32 value); i8 round(f32 value); diff --git a/kble.py b/kble.py index 6ba282d..5566eda 100644 --- a/kble.py +++ b/kble.py @@ -95,15 +95,20 @@ if __name__ == "__main__": data = kble_parse(BYTES) start_x = 0 start_y = 0 + keys = 0 for y, line in enumerate(data): for x, tile in enumerate(line): c_file.write(str(tile)) c_file.write(", ") if tile == 3: # spawn tile start_x, start_y = x, y + if tile == 5: # key tile + keys += 1 c_file.write("},\n") c_file.write("\t\t.start_pos = (Vec2){") c_file.write(f"{start_x} * TILE_SIZE + 2, {start_y} * TILE_SIZE + 4") - c_file.write("}\n\t},\n") + c_file.write("},\n") + c_file.write(f"\t\t.keys = {keys}\n") + c_file.write("\t},\n") c_file.write("};") diff --git a/src/level.c b/src/level.c index d4d0117..35ceb5f 100644 --- a/src/level.c +++ b/src/level.c @@ -38,8 +38,10 @@ void level_load(Level *level, Player *player, u8 id) { extern Level levels[LEVEL_SIZE]; memcpy(level->content, levels[id].content, LEVEL_SIZE); level->start_pos = levels[id].start_pos; + level->keys = levels[id].keys; player_init(player); player->pos = levels[id].start_pos; + player->keys_left = levels[id].keys; } tile_t level_get_tile_at_px(Level level, Vec2 pos) { diff --git a/src/player.c b/src/player.c index 60e8f28..317b225 100644 --- a/src/player.c +++ b/src/player.c @@ -98,7 +98,7 @@ void player_update(Player *player, Level *level, Input input, u8 *level_id) { if (player_collide(*level, player->pos, PAIN_TILE, 5)) { if (!player->knocked) { player->spd_y = -signf(player->spd_y) * KNOCKBACK_Y; - player->spd_x = -signf(player->facing) * KNOCKBACK_X; + player->spd_x = KNOCKBACK_X * -player->facing; player->knocked = true; } player->stun = true; @@ -117,6 +117,8 @@ void player_update(Player *player, Level *level, Input input, u8 *level_id) { player_init(player); player->pos = level->start_pos; } + /* Get keys. */ + player_collide_keys(player, level); /* Exit, victory! */ if (player->keys_left == 0 && player_collide(*level, player->pos, EXIT_TILE, 0)) { *level_id += 1; @@ -139,14 +141,14 @@ void player_draw(Player player) { /* Helper functions */ bool player_collide(Level level, Vec2 pos, tile_t tile, u8 margin) { - const vec2_int_t left = pos.x + margin; - const vec2_int_t right = pos.x + PLAYER_WIDTH - 1 - margin; - const vec2_int_t up = pos.y + margin; - const vec2_int_t down = pos.y + PLAYER_HEIGHT - 1 - margin; - return ((tile == level_get_tile_at_px(level, (Vec2){left, up})) || - (tile == level_get_tile_at_px(level, (Vec2){right, up})) || - (tile == level_get_tile_at_px(level, (Vec2){left, down})) || - (tile == level_get_tile_at_px(level, (Vec2){right, down}))); + const vec2_int_t xl = pos.x + margin; + const vec2_int_t xr = pos.x + PLAYER_WIDTH - 1 - margin; + const vec2_int_t yt = pos.y + margin; + const vec2_int_t yb = pos.y + PLAYER_HEIGHT - 1 - margin; + return ((tile == level_get_tile_at_px(level, (Vec2){xl, yt})) || + (tile == level_get_tile_at_px(level, (Vec2){xr, yt})) || + (tile == level_get_tile_at_px(level, (Vec2){xl, yb})) || + (tile == level_get_tile_at_px(level, (Vec2){xr, yb}))); } bool player_move(Player *player, Level level, i8 spd_x, i8 spd_y) { @@ -167,6 +169,30 @@ bool player_move(Player *player, Level level, i8 spd_x, i8 spd_y) { return false; } +/* Seek for a key tile at given position, if found destroy it and return 1. + * Otherwise, return 0. */ +u8 player_collide_key(Level *level, vec2_int_t x, vec2_int_t y) { + if (level_get_tile_at_px(*level, (Vec2){x, y}) == KEY_TILE) { + level_set_tile_at_px(level, (Vec2){x, y}, AIR_TILE); + return 1; + } + return 0; +} + +/* Destroy keys the player is touching and deduce them from keys left. */ +void player_collide_keys(Player *player, Level *level) { + const vec2_int_t xl = player->pos.x; + const vec2_int_t xr = xl + PLAYER_WIDTH - 1; + const vec2_int_t yt = player->pos.y; + const vec2_int_t yb = yt + PLAYER_HEIGHT - 1; + player->keys_left -= + player_collide_key(level, xl, yt) + + player_collide_key(level, xr, yt) + + player_collide_key(level, xl, yb) + + player_collide_key(level, xr, yb); +} + +/* Used by `collide_keys()`. Don't call this one directly. */ i8 sign(i8 value) { if (value > 0) return 1;