aboutsummaryrefslogtreecommitdiff
path: root/src/player.c
diff options
context:
space:
mode:
authorJuan J. Martinez <jjm@usebox.net>2023-06-22 22:45:05 +0100
committerJuan J. Martinez <jjm@usebox.net>2023-06-22 22:45:05 +0100
commit5733a241a6e35dd539231c569bb54b7f1cb1e758 (patch)
treefc7680c8f0e4dd3a90d3fd30109e515872fbcec9 /src/player.c
parent4a8127146eafd4fef5b478c1bf9f5a152c8c4cd5 (diff)
downloadgold-mine-run-5733a241a6e35dd539231c569bb54b7f1cb1e758.tar.gz
gold-mine-run-5733a241a6e35dd539231c569bb54b7f1cb1e758.zip
Player damage, invulnerability, death sequence and respawn
Diffstat (limited to 'src/player.c')
-rw-r--r--src/player.c84
1 files changed, 81 insertions, 3 deletions
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;
+}