diff --git a/inc/conf.h b/inc/conf.h index f11e2b7..5e57133 100644 --- a/inc/conf.h +++ b/inc/conf.h @@ -10,8 +10,11 @@ #define AIR_FRICTION (AIR_ACCELERATION / MAX_WALK_SPEED) #define GROUND_FRICTION (GROUND_ACCELERATION / MAX_WALK_SPEED) #define AIR_RESISTANCE 0.01f +#define WATER_RESISTANCE 0.15f #define GRAVITY 0.3f #define JUMP_SPEED -6.0f +#define SWIM_SPEED -1.6f +#define SWIM_OUT_SPEED -4.8f #define JUMP_BREAK 3 #define JUMP_BUFFER 12 #define JUMP_GRACE 6 diff --git a/inc/player.h b/inc/player.h index 1cd8de2..ecb4f57 100644 --- a/inc/player.h +++ b/inc/player.h @@ -7,7 +7,7 @@ struct Player { struct Vec pos, gravity; struct VecF spd, rem; enum AirState air_state; - int jump_buffer, jump_grace, burn, bouncing; + int jump_buffer, jump_grace, burn, bouncing, was_in_water; }; void player_spawn(struct Player *); diff --git a/inc/tile.h b/inc/tile.h index 82c77fa..5f52320 100644 --- a/inc/tile.h +++ b/inc/tile.h @@ -13,6 +13,7 @@ enum Tile { TILE_GRAV_U, TILE_GRAV_R, TILE_GRAV_L, + TILE_WATER, TILE_COUNT, TILE_OOB, }; diff --git a/inc/util.h b/inc/util.h index 4b9f878..436b465 100644 --- a/inc/util.h +++ b/inc/util.h @@ -2,3 +2,5 @@ int sign(int); float absf(float); +float minf(float, float); +float maxf(float, float); diff --git a/res/tileset.png b/res/tileset.png index 4e32e11..003c597 100644 Binary files a/res/tileset.png and b/res/tileset.png differ diff --git a/src/player.c b/src/player.c index ac4a817..2f90d24 100644 --- a/src/player.c +++ b/src/player.c @@ -26,6 +26,7 @@ player_spawn(struct Player *p) p->jump_buffer = 0; p->jump_grace = 0; p->burn = 0; + p->was_in_water = 0; } void @@ -33,6 +34,7 @@ player_update(struct Player *p) { const int on_ground = collide_solid(p->pos.x + p->gravity.x, p->pos.y + p->gravity.y); + const int in_water = collide(p->pos.x, p->pos.y, TILE_WATER); const int k_left = input_down(K_LEFT); const int k_right = input_down(K_RIGHT); // const int k_up = input_down(K_UP); @@ -60,7 +62,7 @@ player_update(struct Player *p) spd_x += dir_x * (on_ground ? GROUND_ACCELERATION : AIR_ACCELERATION); /* air resistance & gravity */ - spd_y *= (1 - AIR_RESISTANCE); + spd_y *= 1 - (in_water ? WATER_RESISTANCE : AIR_RESISTANCE); spd_y += (p->air_state == AS_BREAKING) ? (GRAVITY * JUMP_BREAK) : (GRAVITY); @@ -96,6 +98,13 @@ player_update(struct Player *p) p->jump_grace = 0; } + /* swim */ + if (k_jump && (p->was_in_water || in_water)) { + spd_y = + minf(spd_y, (in_water) ? (SWIM_SPEED) : (SWIM_OUT_SPEED)); + p->air_state = AS_RISING; + } + /* bounce */ if (collide(p->pos.x, p->pos.y, TILE_BOUNCER)) { if (!p->bouncing) { @@ -151,6 +160,8 @@ player_update(struct Player *p) p->gravity.x = -1; p->gravity.y = 0; } + + p->was_in_water = in_water; } void diff --git a/src/util.c b/src/util.c index 9088538..ec6b526 100644 --- a/src/util.c +++ b/src/util.c @@ -11,3 +11,15 @@ absf(float x) { return x * (-1 + 2 * (x > 0)); } + +float +minf(float x, float y) +{ + return (x < y) ? (x) : (y); +} + +float +maxf(float x, float y) +{ + return (x > y) ? (x) : (y); +}