From d4c1575ca908519e2892428931c22417f7fff66d Mon Sep 17 00:00:00 2001 From: KikooDX Date: Fri, 1 Jan 2021 02:22:48 +0100 Subject: [PATCH 1/3] The player can now vary their jump height + cleaning --- include/player.h | 3 +++ src/level.c | 8 ++++---- src/main.c | 3 ++- src/player.c | 14 +++++++++++++- 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/include/player.h b/include/player.h index 589b340..03012c3 100644 --- a/include/player.h +++ b/include/player.h @@ -1,6 +1,8 @@ #ifndef _DEF_PLAYER #define _DEF_PLAYER +#include + #include "vec.h" typedef struct Player { @@ -10,6 +12,7 @@ typedef struct Player { Vec vbox; /* the bottom left corner of the player's visual box */ Vec origin; /* the origin of the sprite (offset) */ uint grace; /* coyot jump */ + bool jump_held; /* used to control jump height */ } Player; #include "level.h" diff --git a/src/level.c b/src/level.c index 9b90b76..5efe032 100644 --- a/src/level.c +++ b/src/level.c @@ -24,10 +24,10 @@ void layer_draw(const Level *level, Camera *camera, uint layer_id) { vec_add(&display_br, VEC_PRECISE_HALF_DISP); vec_div(&display_tl, TILE_SIZE); vec_div(&display_br, TILE_SIZE); - int start_x = (display_tl.x > 0) ? display_tl.x : 0; - int start_y = (display_tl.y > 0) ? display_tl.y : 0; - int end_x = (display_br.x < level->width) ? display_br.x + 1 : level->width; - int end_y = (display_br.y < level->height) ? display_br.y + 1 : level->height; + int start_x = (display_tl.x > 0) ? (display_tl.x) : (0); + int start_y = (display_tl.y > 0) ? (display_tl.y) : (0); + int end_x = (display_br.x < level->width) ? (display_br.x + 1) : (level->width); + int end_y = (display_br.y < level->height) ? (display_br.y + 1) : (level->height); for (int y = start_y; y < end_y; ++y) { for (int x = start_x; x < end_x; ++x) { const uint8_t cell = layer[x + y * level->width]; diff --git a/src/main.c b/src/main.c index 81f0728..2413e7d 100644 --- a/src/main.c +++ b/src/main.c @@ -34,7 +34,8 @@ int play_level(uint level_id) { .hbox = {TILE_SIZE - 1, TILE_SIZE - 1}, .vbox = {7, 7}, .origin = {0 * VEC_PRECISION, 0 * VEC_PRECISION}, - .grace = 0 + .grace = 0, + .jump_held = false }; vec_cpy(&player.pos, (Vec){0, 0}); /* place the player at "0/0"*/ diff --git a/src/player.c b/src/player.c index cf67e95..8c8222f 100644 --- a/src/player.c +++ b/src/player.c @@ -13,6 +13,7 @@ #define FRICTION 0.99 #define ACCELERATION (int)(MAX_SPD * (1 - FRICTION)) #define GRAVITY PXS +#define FAST_FALL_FACTOR 3 #define JUMP_SPD (-128 * PXS) #define GRACE_UNITS (int)(UPS / 5) #define EARLY_UNITS (int)(UPS / 5) @@ -68,7 +69,12 @@ void player_step(Player *player, Input *input, const Level *level, uint step) { int xacc = move.x * ACCELERATION; /* calculate horizontal acceleration */ player->spd.x *= FRICTION; /* apply horizontal friction */ player->spd.x += xacc; /* apply horizontal acceleration */ - player->spd.y += GRAVITY; /* apply gravity */ + /* apply gravity */ + if (player->spd.y < 0 && !player->jump_held) { + player->spd.y += GRAVITY * FAST_FALL_FACTOR; + } else { + player->spd.y += GRAVITY; + } /* Grace frames allow the player to jump a short * time after leaving a platform. */ if (player->grace) { @@ -79,8 +85,14 @@ void player_step(Player *player, Input *input, const Level *level, uint step) { * corresponding y speed. */ player->grace = 0; player->spd.y = JUMP_SPD; + player->jump_held = true; } } + /* See if the player is still holding their jump button, this is + * usefull for jump height and gravity manipulation. */ + if (player->jump_held && !k_jump) { + player->jump_held = false; + } player_move(player, level); /* move the player according to their speed */ } From 4818b21ec8f39c15ce160055c2dd9a754c79f2bc Mon Sep 17 00:00:00 2001 From: KikooDX Date: Sat, 2 Jan 2021 17:52:22 +0100 Subject: [PATCH 2/3] Clipping doesn't work. --- src/player.c | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/src/player.c b/src/player.c index 8c8222f..2a3740c 100644 --- a/src/player.c +++ b/src/player.c @@ -17,7 +17,10 @@ #define JUMP_SPD (-128 * PXS) #define GRACE_UNITS (int)(UPS / 5) #define EARLY_UNITS (int)(UPS / 5) -#define SGN(x) ((x > 0) ? (1) : ((x < 0) ? (-1) : (0))) +#define H_CLIP_MARGIN (TILE_SIZE / 2) +#define V_CLIP_MARGIN (TILE_SIZE / 3) +#define SGN(x) (((x) > 0) ? (1) : (((x) < 0) ? (-1) : (0))) +#define ABS(x) (((x) > 0) ? (x) : (-(x))) #define PLAYER_COLLIDE(pos) player_collide(player, pos, level, level->solid_layer) void player_move(Player *player, const Level *level) { @@ -29,15 +32,28 @@ void player_move(Player *player, const Level *level) { /* snap the player to the grid if they hit a wall */ destination.x += player->spd.x; if (PLAYER_COLLIDE(destination)) { - destination.x = player->pos.x - player->pos.x % TILE_SIZE; - /* Move the player tile per tile until it enters an - * occuped tile. */ - while (!PLAYER_COLLIDE(destination)) { - destination.x += TILE_SIZE * sgn_spd_x; + /* Used for clipping and positionning. */ + int offset = destination.y % TILE_SIZE; + if (offset > TILE_SIZE / 2) { + offset -= TILE_SIZE; + } + if (ABS(offset) > H_CLIP_MARGIN) { + offset = 0; + } + destination.y -= offset; + if (PLAYER_COLLIDE(destination)) + { + destination.y += offset; + destination.x = player->pos.x - player->pos.x % TILE_SIZE; + /* Move the player tile per tile until it enters an + * occupied tile. */ + while (!PLAYER_COLLIDE(destination)) { + destination.x += TILE_SIZE * sgn_spd_x; + } + /* then, move it back one tile */ + destination.x -= TILE_SIZE * sgn_spd_x; + player->spd.x = 0; } - /* then, move it back one tile */ - destination.x -= TILE_SIZE * sgn_spd_x; - player->spd.x = 0; } /* do the same for y */ destination.y += player->spd.y; @@ -71,6 +87,8 @@ void player_step(Player *player, Input *input, const Level *level, uint step) { player->spd.x += xacc; /* apply horizontal acceleration */ /* apply gravity */ if (player->spd.y < 0 && !player->jump_held) { + /* The player is rising and let go the jump key, + * accelerate gravity until they reach 0. */ player->spd.y += GRAVITY * FAST_FALL_FACTOR; } else { player->spd.y += GRAVITY; From 330d66f3f07fd38d91e0bafc46585a5723e15cf4 Mon Sep 17 00:00:00 2001 From: KikooDX Date: Sat, 2 Jan 2021 18:11:09 +0100 Subject: [PATCH 3/3] =?UTF-8?q?Horizontal=20solid=20clipping=20works=20?= =?UTF-8?q?=C2=AF\=5F(=E3=83=84)=5F/=C2=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/player.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/player.c b/src/player.c index 2a3740c..58ee7d0 100644 --- a/src/player.c +++ b/src/player.c @@ -17,10 +17,9 @@ #define JUMP_SPD (-128 * PXS) #define GRACE_UNITS (int)(UPS / 5) #define EARLY_UNITS (int)(UPS / 5) -#define H_CLIP_MARGIN (TILE_SIZE / 2) +#define H_CLIP_MARGIN (TILE_SIZE / 4) #define V_CLIP_MARGIN (TILE_SIZE / 3) #define SGN(x) (((x) > 0) ? (1) : (((x) < 0) ? (-1) : (0))) -#define ABS(x) (((x) > 0) ? (x) : (-(x))) #define PLAYER_COLLIDE(pos) player_collide(player, pos, level, level->solid_layer) void player_move(Player *player, const Level *level) { @@ -34,10 +33,7 @@ void player_move(Player *player, const Level *level) { if (PLAYER_COLLIDE(destination)) { /* Used for clipping and positionning. */ int offset = destination.y % TILE_SIZE; - if (offset > TILE_SIZE / 2) { - offset -= TILE_SIZE; - } - if (ABS(offset) > H_CLIP_MARGIN) { + if (offset > H_CLIP_MARGIN) { offset = 0; } destination.y -= offset;