From 5733a241a6e35dd539231c569bb54b7f1cb1e758 Mon Sep 17 00:00:00 2001 From: "Juan J. Martinez" Date: Thu, 22 Jun 2023 22:45:05 +0100 Subject: Player damage, invulnerability, death sequence and respawn --- src/player.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 81 insertions(+), 3 deletions(-) (limited to 'src/player.c') diff --git a/src/player.c b/src/player.c index a0b840f..7b51a35 100644 --- a/src/player.c +++ b/src/player.c @@ -28,11 +28,19 @@ /* used for "coyote time" */ #define MAX_MOMENTUM 8 +/* how many frames the player is invulerable after loosing a life */ +#define INVULN_TIME 96 + #define IS_NOT_GOING_UP(x) (gravity == GRAVITY_OFF || (x)>=GRAVITY_DOWN) static uint16_t x, y; static uint8_t dir, frame, delay, gravity, jump, momentum; +static uint16_t respawn_x, respawn_y; +static uint8_t respawn_dir; + +static uint8_t invuln, dying; + const uint8_t gravity_seq[GRAVITY_SEQ_LEN] = { 6, 4, 4, 2, 2, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 4 }; @@ -71,21 +79,74 @@ static const Rect frames[2][6] = void player_init(uint16_t start_x, uint8_t start_y, uint8_t start_dir) { - dir = start_dir; + respawn_dir = dir = start_dir; frame = FRAME_STANDING; delay = 0; jump = 0; momentum = 0; + invuln = 0; + dying = 0; - x = start_x; - y = start_y; + respawn_x = x = start_x; + respawn_y = y = start_y; gravity = GRAVITY_OFF; } +static void player_dying() +{ + if (gravity != GRAVITY_OFF) + { + uint8_t steps = gravity_seq[gravity - 1]; + + if (gravity > GRAVITY_DOWN) + { + /* going down! */ + for (uint8_t i = 0; i < steps; i++) + { + /* exit screen */ + if (y > MAP_H * MAP_TILE_H) + { + /* if there are lifes left, respawn */ + if (dec_lives()) + { + player_init(respawn_x, respawn_y, respawn_dir); + invuln = INVULN_TIME; + } + + /* stop falling */ + gravity = GRAVITY_OFF; + return; + } + y++; + } + } + else + { + /* going up! */ + if (y < steps) + y = 0; + else + y -= steps; + } + + if (gravity != GRAVITY_OFF && gravity != GRAVITY_SEQ_LEN) + gravity++; + } +} + void player_update() { uint8_t moved = 0; + if (dying) + { + player_dying(); + return; + } + + if (invuln) + invuln--; + if (momentum) momentum--; @@ -170,6 +231,11 @@ void player_update() { gravity = GRAVITY_OFF; frame = FRAME_STANDING; + + /* is a deadly block? */ + if (map_is_deadly(x + 11, y + 16) + || map_is_deadly(x + 4, y + 16)) + player_hit(); break; } y++; @@ -222,5 +288,17 @@ void player_draw() Rect dst = { x, y + MAP_OFFS_Y, 16, 16 }; read_buffer(bg, &dst); + + if (invuln && (invuln & 4)) + return; + blitrc(binary_sprites_start, &frames[dir][frame], &dst); } + +void player_hit() +{ + /* TODO: pickaxe */ + dying = 1; + frame = FRAME_DYING; + gravity = GRAVITY_UP; +} -- cgit v1.2.3