diff --git a/include/friction.h b/include/friction.h index 0bfdcb9..a68b546 100644 --- a/include/friction.h +++ b/include/friction.h @@ -1,3 +1,10 @@ -float apply_friction(int x, int y, char level[]); -void mod_ice(int x, int y, char level[], float *friction); -void mod_solid(int x, int y, char level[], float *friction); \ No newline at end of file +#pragma once + +#define MAX_HSPD 2.0 +#define HFRICTION 0.2 +#define HACCELERATION (MAX_HSPD * HFRICTION) + +void mod_accel_and_fric(float *acceleration, float *friction, int x, int y, + char level[]); +int mod_ice(float *acceleration, float *friction, int x, int y, char level[]); +int mod_solid(float *acceleration, float *friction, int x, int y, char level[]); diff --git a/src/friction.c b/src/friction.c index 55377dc..183c97f 100644 --- a/src/friction.c +++ b/src/friction.c @@ -1,23 +1,31 @@ #include "friction.h" #include "collide.h" -float apply_friction(int x, int y, char level[]) { - float friction = 0.2; - mod_solid(x, y, level, &friction); - mod_ice(x, y, level, &friction); - return friction; +void mod_accel_and_fric(float *acceleration, float *friction, int x, int y, + char level[]) +{ + *acceleration = HACCELERATION; + *friction = HFRICTION; + if (!mod_ice(acceleration, friction, x, y, level)) + mod_solid(acceleration, friction, x, y, level); } -void mod_ice(int x, int y, char level[], float *friction) { - if (collide(x, y - 1, level, 'i') || - collide(x, y + 1, level, 'i')) { - *friction = 0.15; - } -} - -void mod_solid(int x, int y, char level[], float *friction) { - if(collide_solid(x, y - 1, level) || - collide_solid(x, y + 1, level)) { - *friction = 0.2; +int mod_ice(float *acceleration, float *friction, int x, int y, char level[]) +{ + if (collide(x, y - 1, level, 'i') || collide(x, y + 1, level, 'i')) { + *friction /= 4.0; + *acceleration /= 2.0; + return 1; } -} \ No newline at end of file + return 0; +} + +int mod_solid(float *acceleration, float *friction, int x, int y, char level[]) +{ + if (collide_solid(x, y - 1, level) || collide_solid(x, y + 1, level)) { + *friction *= 2.0; + *acceleration *= 2.0; + return 1; + } + return 0; +} diff --git a/src/main.c b/src/main.c index ed51012..647a68e 100644 --- a/src/main.c +++ b/src/main.c @@ -19,9 +19,7 @@ #include #define VACCELERATION 0.2 -#define HACCELERATION 0.4 #define MAX_VSPD 9.0 -#define MAX_HSPD 2.0 static void startmenu_launcher(); static int callback(volatile int *frame_elapsed); @@ -105,6 +103,9 @@ static void game(int *id_level, char mode, char *type) char check_nbswitch = 0; float vspd = 1.0; float hspd = 0.0; + float hrem = 0.0; + float friction; + float acceleration; if (*id_level == 10 && *type != 3) *type = 2; @@ -166,25 +167,34 @@ static void game(int *id_level, char mode, char *type) death_count--; } - // right and left collision - if (keydown_any(KEY_RIGHT, KEY_LEFT, 0)) { - char signe = (keydown(KEY_RIGHT) - keydown(KEY_LEFT)); - float friction = apply_friction(player_x, player_y, level); - hspd *= 1 - friction; - hspd += signe * HACCELERATION; - - if (!collide_solid(player_x + round(hspd) + signe * 1, - player_y, level)) - player_x += round(hspd); - else if (!collide_solid(player_x + signe * 1, player_y, - level)) - player_x += signe; - if (player_x >= 388) - player_x = -4; - if (player_x < -9) - player_x = 384; - } else - hspd = 0; + // right and left movement + collision + const int signe = (keydown(KEY_RIGHT) - keydown(KEY_LEFT)); + mod_accel_and_fric(&acceleration, &friction, player_x, player_y, level); + hspd *= 1 - friction; + hspd += signe * acceleration; + + /* speed reminder */ + /* TODO + * Please note than `hrem` should be reset after horizontal collision + * with a wall, death or level change. This is necessary to avoid + * cross-level jank/garbage data to be carreid that would ultimatly + * introduce inconsistancies. I didn't do it myself 'cause I couldn't + * find were to do this. + * -- KikooDX */ + const float spd_n_rem_x = hspd + hrem; + const int spd_x = (int)spd_n_rem_x; + hrem = spd_n_rem_x - (float)spd_x; + + if (!collide_solid(player_x + round(hspd) + signe * 1, + player_y, level)) + player_x += round(hspd); + else if (!collide_solid(player_x + signe * 1, player_y, + level)) + player_x += signe; + if (player_x >= 388) + player_x = -4; + if (player_x < -9) + player_x = 384; // Action key if (keydown(KEY_SHIFT) && !check && nbswitch > 0 && @@ -447,4 +457,4 @@ static void game(int *id_level, char mode, char *type) draw_end((int)frame, LEVEL_MAX, 2); sleep_ms(7000); } -} \ No newline at end of file +}