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 --- TODO.md | 6 ----- data/stage.json | 2 +- src/game.c | 7 +++++ src/game.h | 2 ++ src/player.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- src/player.h | 2 ++ 6 files changed, 93 insertions(+), 10 deletions(-) diff --git a/TODO.md b/TODO.md index aacb433..5ce3720 100644 --- a/TODO.md +++ b/TODO.md @@ -2,12 +2,6 @@ - entity system - free/used lists -- player - - damage - - invulnerable - - respawn -- map - - entities - pick ups - extra time - bonuses diff --git a/data/stage.json b/data/stage.json index 1e348c1..2ae131e 100644 --- a/data/stage.json +++ b/data/stage.json @@ -3,7 +3,7 @@ "infinite":false, "layers":[ { - "data":[41, 42, 41, 42, 41, 42, 41, 42, 41, 42, 41, 42, 41, 42, 41, 42, 41, 42, 41, 42, 41, 42, 41, 42, 41, 42, 41, 42, 41, 42, 41, 42, 41, 42, 41, 42, 41, 42, 41, 42, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 41, 42, 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, 41, 42, 61, 62, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 5, 6, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 5, 6, 24, 61, 62, 41, 42, 3, 4, 5, 6, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 41, 42, 61, 62, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 5, 6, 24, 23, 24, 23, 24, 23, 24, 61, 62, 41, 42, 3, 4, 3, 4, 3, 4, 3, 4, 3, 5, 6, 4, 3, 4, 3, 4, 45, 45, 45, 45, 45, 45, 45, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 41, 42, 61, 62, 23, 24, 23, 24, 23, 24, 45, 45, 45, 45, 45, 45, 45, 24, 23, 24, 1, 1, 1, 1, 1, 2, 1, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 61, 62, 41, 42, 3, 4, 3, 4, 3, 4, 1, 2, 1, 1, 1, 2, 1, 4, 3, 4, 3, 4, 3, 4, 3, 22, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 41, 42, 61, 62, 23, 24, 5, 6, 23, 24, 23, 22, 23, 24, 23, 22, 23, 24, 23, 24, 23, 24, 23, 24, 23, 45, 45, 45, 45, 45, 23, 24, 45, 45, 45, 45, 45, 45, 23, 24, 61, 62, 41, 42, 3, 4, 3, 4, 3, 4, 3, 22, 3, 4, 3, 22, 3, 4, 3, 4, 3, 4, 3, 4, 3, 1, 1, 1, 1, 2, 3, 4, 2, 1, 1, 1, 1, 1, 3, 4, 41, 42, 61, 62, 23, 24, 23, 24, 23, 24, 23, 22, 23, 24, 23, 22, 23, 24, 23, 24, 23, 5, 6, 24, 23, 24, 23, 24, 23, 22, 23, 24, 22, 24, 23, 24, 23, 24, 23, 24, 61, 62, 41, 42, 3, 4, 3, 4, 3, 45, 45, 45, 45, 45, 45, 45, 45, 45, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 45, 45, 45, 45, 45, 3, 4, 5, 6, 3, 4, 41, 42, 61, 62, 23, 24, 23, 24, 23, 1, 1, 2, 1, 1, 1, 1, 1, 1, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 1, 1, 1, 2, 1, 23, 24, 23, 24, 23, 24, 61, 62, 41, 42, 3, 4, 3, 4, 3, 4, 3, 22, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 22, 4, 3, 4, 3, 4, 3, 4, 41, 42, 61, 62, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 23, 24, 23, 24, 23, 24, 23, 24, 23, 5, 6, 24, 23, 24, 23, 24, 23, 24, 45, 45, 45, 45, 45, 45, 23, 24, 61, 62, 41, 42, 7, 8, 1, 2, 1, 1, 1, 2, 1, 1, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 1, 1, 2, 1, 1, 1, 3, 4, 41, 42, 61, 62, 27, 28, 23, 22, 23, 24, 23, 22, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 22, 24, 23, 24, 23, 24, 61, 62, 41, 42, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 3, 4, 3, 5, 6, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 41, 42, 61, 62, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 5, 6, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 61, 62, 41, 42, 3, 4, 3, 22, 3, 4, 3, 22, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 5, 6, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 22, 4, 5, 6, 3, 4, 41, 42, 41, 42, 43, 44, 43, 44, 43, 44, 43, 44, 43, 44, 43, 44, 43, 43, 44, 3, 4, 3, 4, 3, 43, 44, 43, 44, 43, 44, 43, 44, 43, 44, 43, 44, 43, 44, 43, 44, 41, 42, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 41, 42, 101, 101, 101, 101, 101, 41, 42, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62], + "data":[41, 42, 41, 42, 41, 42, 41, 42, 41, 42, 41, 42, 41, 42, 41, 42, 41, 42, 41, 42, 41, 42, 41, 42, 41, 42, 41, 42, 41, 42, 41, 42, 41, 42, 41, 42, 41, 42, 41, 42, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 41, 42, 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, 41, 42, 61, 62, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 5, 6, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 5, 6, 24, 61, 62, 41, 42, 3, 4, 5, 6, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 41, 42, 61, 62, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 5, 6, 24, 23, 24, 23, 24, 23, 24, 61, 62, 41, 42, 3, 4, 3, 4, 3, 4, 3, 4, 3, 5, 6, 4, 3, 4, 3, 4, 45, 45, 45, 45, 45, 45, 45, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 41, 42, 61, 62, 23, 24, 23, 24, 23, 24, 45, 45, 45, 45, 45, 45, 45, 24, 23, 24, 1, 1, 1, 1, 1, 2, 1, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 61, 62, 41, 42, 3, 4, 3, 4, 3, 4, 1, 2, 1, 1, 1, 2, 1, 4, 3, 4, 3, 4, 3, 4, 3, 22, 3, 4, 3, 4, 3, 4, 3, 4, 3, 101, 101, 4, 3, 4, 41, 42, 61, 62, 23, 24, 5, 6, 23, 24, 23, 22, 23, 24, 23, 22, 23, 24, 23, 24, 23, 24, 23, 24, 23, 45, 45, 45, 45, 45, 23, 24, 45, 45, 45, 45, 45, 45, 23, 24, 61, 62, 41, 42, 3, 4, 3, 4, 3, 4, 3, 22, 3, 4, 3, 22, 3, 4, 3, 4, 3, 4, 3, 4, 3, 1, 1, 1, 1, 2, 3, 4, 2, 1, 1, 1, 1, 1, 3, 4, 41, 42, 61, 62, 23, 24, 23, 24, 23, 24, 23, 22, 23, 24, 23, 22, 23, 24, 23, 24, 23, 5, 6, 24, 23, 24, 23, 24, 23, 22, 23, 24, 22, 24, 23, 24, 23, 24, 23, 24, 61, 62, 41, 42, 3, 4, 3, 4, 3, 45, 45, 45, 45, 45, 45, 45, 45, 45, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 45, 45, 45, 45, 45, 3, 4, 5, 6, 3, 4, 41, 42, 61, 62, 23, 24, 23, 24, 23, 1, 1, 2, 1, 1, 1, 1, 1, 1, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 1, 1, 1, 2, 1, 23, 24, 23, 24, 23, 24, 61, 62, 41, 42, 3, 4, 3, 4, 3, 4, 3, 22, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 22, 4, 3, 4, 3, 4, 3, 4, 41, 42, 61, 62, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 23, 24, 23, 24, 23, 24, 23, 24, 23, 5, 6, 24, 23, 24, 23, 24, 23, 24, 45, 45, 45, 45, 45, 45, 23, 24, 61, 62, 41, 42, 7, 8, 1, 2, 1, 1, 1, 2, 1, 1, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 1, 1, 2, 1, 1, 1, 3, 4, 41, 42, 61, 62, 27, 28, 23, 22, 23, 24, 23, 22, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 22, 24, 23, 24, 23, 24, 61, 62, 41, 42, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 3, 4, 3, 5, 6, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 41, 42, 61, 62, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 5, 6, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 61, 62, 41, 42, 3, 4, 3, 22, 3, 4, 3, 22, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 5, 6, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 22, 4, 5, 6, 3, 4, 41, 42, 41, 42, 43, 44, 43, 44, 43, 44, 43, 44, 43, 44, 43, 44, 43, 43, 44, 3, 4, 3, 4, 3, 43, 44, 43, 44, 43, 44, 43, 44, 43, 44, 43, 44, 43, 44, 43, 44, 41, 42, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 41, 42, 101, 101, 101, 101, 101, 41, 42, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62, 61, 62], "height":23, "id":1, "name":"Map", diff --git a/src/game.c b/src/game.c index ddd9e63..76969ae 100644 --- a/src/game.c +++ b/src/game.c @@ -122,3 +122,10 @@ uint32_t get_hiscore() { return hiscore; } + +uint8_t dec_lives() +{ + lives--; + hud |= HUD_LIVES; + return lives; +} diff --git a/src/game.h b/src/game.h index 9a6c0d7..a13bdb9 100644 --- a/src/game.h +++ b/src/game.h @@ -16,4 +16,6 @@ void run_game(); void add_score(uint8_t v); uint32_t get_hiscore(); +uint8_t dec_lives(); + #endif /* _GAME_H */ 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; +} diff --git a/src/player.h b/src/player.h index a2a946c..9767fbe 100644 --- a/src/player.h +++ b/src/player.h @@ -7,4 +7,6 @@ void player_update(); void player_erase(); void player_draw(); +void player_hit(); + #endif /* _PLAYER_H */ -- cgit v1.2.3