Keys.
This commit is contained in:
parent
6eb71bc83f
commit
84848ff3fd
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
7
kble.py
7
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("};")
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
44
src/player.c
44
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;
|
||||
|
|
Loading…
Reference in New Issue