From e306da5e4140324f2d5cd85f24bfb302969c4ff8 Mon Sep 17 00:00:00 2001 From: KikooDX Date: Tue, 22 Dec 2020 16:46:00 +0100 Subject: [PATCH] Friction and acceleration (pfiou) --- levels/create_demo.lua | 2 +- src/player.c | 27 ++++++++++++++++++++------- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/levels/create_demo.lua b/levels/create_demo.lua index cd5b6ec..899203e 100755 --- a/levels/create_demo.lua +++ b/levels/create_demo.lua @@ -6,7 +6,7 @@ local function create_random_level(width, height, layers) io.write(height, "\n") for i = 1, layers, 1 do for r = 1, width * height, 1 do - io.write(math.floor(math.random() * 2)) --random 0 (2/3) or 1 (1/3) + io.write(math.floor(math.random() * 1.5)) --random 0 (2/3) or 1 (1/3) io.write("\n") end if i ~= layers then diff --git a/src/player.c b/src/player.c index e7bdd5a..167cef1 100644 --- a/src/player.c +++ b/src/player.c @@ -7,27 +7,39 @@ #include "input.h" #include "collide.h" +/* TODO: Determine FRICTION and ACCELERATION from UPS. */ +#define FRICTION 0.9 +#define ACCELERATION 64 #define SGN(x) ((x > 0) ? (1) : ((x < 0) ? (-1) : (0))) #define PLAYER_COLLIDE(pos) player_collide(player, pos, level, level->solid_layer) void player_move(Player *player, const Level *level) { - /* TODO: Take into account player.origin and allow to snap for - * more than one tile. THIS CODE WILL BREAK IF THE PLAYER SPEED - * IS SUPERIOR THAN TILE_SIZE! */ - //const int sgn_spd_x = SGN(player->spd.x); - //const int sgn_spd_y = SGN(player->spd.y); + /* TODO: Take into account player.origin. */ + const int sgn_spd_x = SGN(player->spd.x); + const int sgn_spd_y = SGN(player->spd.y); Vec destination; vec_cpy(&destination, player->pos); /* 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; + } + /* 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; if (PLAYER_COLLIDE(destination)) { destination.y = player->pos.y - player->pos.y % TILE_SIZE; + while (!PLAYER_COLLIDE(destination)) { + destination.y += TILE_SIZE * sgn_spd_y; + } + destination.y -= TILE_SIZE * sgn_spd_y; player->spd.y = 0; } /* move the player to their new position */ @@ -39,8 +51,9 @@ void player_step(Player *player, Input *input, const Level *level) { (input_is_down(input, K_RIGHT) - input_is_down(input, K_LEFT)), (input_is_down(input, K_DOWN) - input_is_down(input, K_UP)) }; - vec_mul(&move, 32 * PXS); /* calculate speed */ - vec_cpy(&player->spd, move); + vec_mulf(&player->spd, FRICTION); /* apply friction */ + vec_mul(&move, ACCELERATION); /* apply acceleration */ + vec_add(&player->spd, move); player_move(player, level); }