mirror of
https://github.com/luksamuk/engine-psx.git
synced 2025-04-28 13:28:02 +03:00
Add physics constants separation and underwater physics
This commit is contained in:
parent
765334738f
commit
1524f371d4
5 changed files with 207 additions and 72 deletions
|
@ -6,32 +6,31 @@
|
|||
#include "level.h"
|
||||
#include "collision.h"
|
||||
#include "input.h"
|
||||
#include "player_constants.h"
|
||||
|
||||
// Constants for running the game at a fixed 60 FPS.
|
||||
// These constants are also in a 12-scale format for fixed point math.
|
||||
#define X_ACCEL 0x000c0
|
||||
#define X_AIR_ACCEL 0x00180
|
||||
#define X_FRICTION 0x000c0
|
||||
#define X_DECEL 0x00800
|
||||
#define X_TOP_SPD 0x06000
|
||||
#define Y_GRAVITY 0x00380
|
||||
#define Y_HURT_GRAVITY 0x00300
|
||||
#define Y_MIN_JUMP 0x04000
|
||||
#define Y_JUMP_STRENGTH 0x06800
|
||||
#define X_MIN_ROLL_SPD 0x01000
|
||||
#define X_MIN_UNCURL_SPD 0x00800
|
||||
#define X_ROLL_FRICTION 0x00060
|
||||
#define X_ROLL_DECEL 0x00200
|
||||
#define X_SLOPE_MIN_SPD 0x000d0
|
||||
#define X_SLOPE_NORMAL 0x00200
|
||||
#define X_SLOPE_ROLLUP 0x00140
|
||||
#define X_SLOPE_ROLLDOWN 0x00500
|
||||
#define X_MAX_SPD 0x10000
|
||||
#define X_MAX_SLIP_SPD 0x02800
|
||||
#define X_DRPSPD 0x08000
|
||||
#define X_DRPMAX 0x0c000
|
||||
#define Y_HURT_FORCE 0x04000
|
||||
#define X_HURT_FORCE 0x02000
|
||||
/* #define X_ACCEL 0x000c0 */
|
||||
/* #define X_AIR_ACCEL 0x00180 */
|
||||
/* #define X_FRICTION 0x000c0 */
|
||||
/* #define X_DECEL 0x00800 */
|
||||
/* #define X_TOP_SPD 0x06000 */
|
||||
/* #define Y_GRAVITY 0x00380 */
|
||||
/* #define Y_HURT_GRAVITY 0x00300 */
|
||||
/* #define Y_MIN_JUMP 0x04000 */
|
||||
/* #define Y_JUMP_STRENGTH 0x06800 */
|
||||
/* #define X_MIN_ROLL_SPD 0x01000 */
|
||||
/* #define X_MIN_UNCURL_SPD 0x00800 */
|
||||
/* #define X_ROLL_FRICTION 0x00060 */
|
||||
/* #define X_ROLL_DECEL 0x00200 */
|
||||
/* #define X_SLOPE_MIN_SPD 0x000d0 */
|
||||
/* #define X_SLOPE_NORMAL 0x00200 */
|
||||
/* #define X_SLOPE_ROLLUP 0x00140 */
|
||||
/* #define X_SLOPE_ROLLDOWN 0x00500 */
|
||||
/* #define X_MAX_SPD 0x10000 */
|
||||
/* #define X_MAX_SLIP_SPD 0x02800 */
|
||||
/* #define X_DRPSPD 0x08000 */
|
||||
/* #define X_DRPMAX 0x0c000 */
|
||||
/* #define Y_HURT_FORCE 0x04000 */
|
||||
/* #define X_HURT_FORCE 0x02000 */
|
||||
|
||||
// Constants for adjusting hitbox and sensors
|
||||
#define WIDTH_RADIUS_NORMAL 9
|
||||
|
@ -59,9 +58,9 @@ typedef enum {
|
|||
typedef LinecastDirection CollMode;
|
||||
|
||||
typedef struct {
|
||||
InputState input;
|
||||
|
||||
Chara chara;
|
||||
InputState input;
|
||||
PlayerConstants *cnst;
|
||||
Chara chara;
|
||||
|
||||
CharaAnim *cur_anim;
|
||||
VECTOR pos;
|
||||
|
|
37
include/player_constants.h
Normal file
37
include/player_constants.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
#ifndef PLAYER_CONSTANTS_H
|
||||
#define PLAYER_CONSTANTS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// Constants for running the game at a fixed 60 FPS.
|
||||
// These constants are also in a 12-scale format for fixed point math.
|
||||
typedef struct {
|
||||
int32_t
|
||||
x_accel,
|
||||
x_air_accel,
|
||||
x_friction,
|
||||
x_decel,
|
||||
x_top_spd,
|
||||
y_gravity,
|
||||
y_hurt_gravity,
|
||||
y_min_jump,
|
||||
y_jump_strength,
|
||||
x_min_roll_spd,
|
||||
x_min_uncurl_spd,
|
||||
x_roll_friction,
|
||||
x_roll_decel,
|
||||
x_slope_min_spd,
|
||||
x_slope_normal,
|
||||
x_slope_rollup,
|
||||
x_slope_rolldown,
|
||||
x_max_spd,
|
||||
x_map_slip_spd,
|
||||
x_drpspd,
|
||||
x_drpmax,
|
||||
y_hurt_force,
|
||||
x_hurt_force;
|
||||
} PlayerConstants;
|
||||
|
||||
// SEE PLAYER_CONSTANTS.C FOR CONSTANTS DEFINITIONS!!!!
|
||||
|
||||
#endif
|
|
@ -801,7 +801,7 @@ _bubble_update(ObjectState *state, ObjectTableEntry *, VECTOR *pos)
|
|||
player.action = ACTION_NONE;
|
||||
player_set_animation_direct(&player, ANIM_WALKING); // TODO!!!
|
||||
player.grnd = 0;
|
||||
player.vel.vy = 0;
|
||||
player.vel.vx = player.vel.vy = player.vel.vz = 0;
|
||||
sound_play_vag(sfx_bubble, 0);
|
||||
return;
|
||||
}
|
||||
|
|
128
src/player.c
128
src/player.c
|
@ -11,6 +11,9 @@
|
|||
#include "collision.h"
|
||||
#include "basic_font.h"
|
||||
|
||||
extern PlayerConstants CNST_DEFAULT;
|
||||
extern PlayerConstants CNST_UNDERWATER;
|
||||
|
||||
#define TMP_ANIM_SPD 7
|
||||
#define ANIM_IDLE_TIMER_MAX 180
|
||||
|
||||
|
@ -66,6 +69,7 @@ load_player(Player *player,
|
|||
player->input = (InputState){ 0 };
|
||||
load_chara(&player->chara, chara_filename, sprites);
|
||||
player->cur_anim = NULL;
|
||||
player->cnst = &CNST_DEFAULT;
|
||||
player->pos = (VECTOR){ 0 };
|
||||
player->vel = (VECTOR){ 0 };
|
||||
player->angle = 0;
|
||||
|
@ -541,18 +545,27 @@ _player_update_collision_tb(Player *player)
|
|||
|| (player->vel.vx < 0 && player->anim_dir == 1);
|
||||
if(!moving_backwards) {
|
||||
// gsp = (gsp / 4) + (drpspd * dir)
|
||||
player->vel.vz = (player->vel.vz >> 2) + (X_DRPSPD * player->anim_dir);
|
||||
player->vel.vz = (player->vel.vz >> 2)
|
||||
+ (player->cnst->x_drpspd * player->anim_dir);
|
||||
if(player->vel.vz > 0)
|
||||
player->vel.vz = (player->vel.vz > X_DRPMAX) ? X_DRPMAX : player->vel.vz;
|
||||
else player->vel.vz = (player->vel.vz < X_DRPMAX) ? -X_DRPMAX : player->vel.vz;
|
||||
player->vel.vz = (player->vel.vz > player->cnst->x_drpmax)
|
||||
? player->cnst->x_drpmax
|
||||
: player->vel.vz;
|
||||
else player->vel.vz = (player->vel.vz < player->cnst->x_drpmax)
|
||||
? -player->cnst->x_drpmax : player->vel.vz;
|
||||
} else {
|
||||
if(player->angle == 0) player->vel.vz = X_DRPSPD * player->anim_dir;
|
||||
if(player->angle == 0)
|
||||
player->vel.vz = player->cnst->x_drpspd * player->anim_dir;
|
||||
else {
|
||||
// gsp = (gsp / 2) + (drpspd * dir)
|
||||
player->vel.vz = (player->vel.vz >> 1) + (X_DRPSPD * player->anim_dir);
|
||||
player->vel.vz = (player->vel.vz >> 1)
|
||||
+ (player->cnst->x_drpspd * player->anim_dir);
|
||||
if(player->vel.vz > 0)
|
||||
player->vel.vz = (player->vel.vz > X_DRPMAX) ? X_DRPMAX : player->vel.vz;
|
||||
else player->vel.vz = (player->vel.vz < X_DRPMAX) ? -X_DRPMAX : player->vel.vz;
|
||||
player->vel.vz = (player->vel.vz > player->cnst->x_drpmax)
|
||||
? player->cnst->x_drpmax
|
||||
: player->vel.vz;
|
||||
else player->vel.vz = (player->vel.vz < player->cnst->x_drpmax)
|
||||
? -player->cnst->x_drpmax
|
||||
: player->vel.vz;
|
||||
}
|
||||
}
|
||||
sound_play_vag(sfx_relea, 0);
|
||||
|
@ -713,22 +726,27 @@ player_update(Player *player)
|
|||
int32_t angle_sin = rsin(player->angle);
|
||||
player->vel.vz -= (
|
||||
(SIGNUM(player->vel.vz) == SIGNUM(angle_sin)
|
||||
? X_SLOPE_ROLLUP
|
||||
: X_SLOPE_ROLLDOWN)
|
||||
? player->cnst->x_slope_rollup
|
||||
: player->cnst->x_slope_rolldown)
|
||||
* angle_sin) >> 12;
|
||||
|
||||
// Deceleration on input
|
||||
if(player->vel.vz > 0 && input_pressing(&player->input, PAD_LEFT))
|
||||
player->vel.vz -= X_ROLL_DECEL + X_ROLL_FRICTION;
|
||||
player->vel.vz -=
|
||||
player->cnst->x_roll_decel + player->cnst->x_roll_friction;
|
||||
else if(player->vel.vz < 0 && input_pressing(&player->input, PAD_RIGHT))
|
||||
player->vel.vz += X_ROLL_DECEL + X_ROLL_FRICTION;
|
||||
player->vel.vz +=
|
||||
player->cnst->x_roll_decel + player->cnst->x_roll_friction;
|
||||
else {
|
||||
// Apply roll friction
|
||||
player->vel.vz -= (player->vel.vz > 0 ? X_ROLL_FRICTION : -X_ROLL_FRICTION);
|
||||
player->vel.vz -=
|
||||
(player->vel.vz > 0
|
||||
? player->cnst->x_roll_friction
|
||||
: -player->cnst->x_roll_friction);
|
||||
}
|
||||
|
||||
// Uncurl if too slow
|
||||
if(abs(player->vel.vz) < X_MIN_UNCURL_SPD)
|
||||
if(abs(player->vel.vz) < player->cnst->x_min_uncurl_spd)
|
||||
player->action = ACTION_NONE;
|
||||
} else if(player->action == ACTION_SPINDASH) {
|
||||
// Release
|
||||
|
@ -756,31 +774,35 @@ player_update(Player *player)
|
|||
&& (player->ctrllock == 0)) {
|
||||
if(player->vel.vz < 0) {
|
||||
player->action = ACTION_SKIDDING;
|
||||
player->vel.vz += X_DECEL;
|
||||
player->vel.vz += player->cnst->x_decel;
|
||||
} else {
|
||||
if(player->vel.vz < X_TOP_SPD)
|
||||
player->vel.vz += X_ACCEL;
|
||||
if(player->vel.vz < player->cnst->x_top_spd)
|
||||
player->vel.vz += player->cnst->x_accel;
|
||||
player->anim_dir = 1;
|
||||
}
|
||||
} else if(input_pressing(&player->input, PAD_LEFT)
|
||||
&& (player->ctrllock == 0)) {
|
||||
if(player->vel.vz > 0) {
|
||||
player->action = ACTION_SKIDDING;
|
||||
player->vel.vz -= X_DECEL;
|
||||
player->vel.vz -= player->cnst->x_decel;
|
||||
} else {
|
||||
if(player->vel.vz > -X_TOP_SPD)
|
||||
player->vel.vz -= X_ACCEL;
|
||||
if(player->vel.vz > -player->cnst->x_top_spd)
|
||||
player->vel.vz -= player->cnst->x_accel;
|
||||
player->anim_dir = -1;
|
||||
}
|
||||
} else {
|
||||
// Apply friction
|
||||
player->vel.vz -= (player->vel.vz > 0 ? X_FRICTION : -X_FRICTION);
|
||||
if(abs(player->vel.vz) <= X_FRICTION) player->vel.vz = 0;
|
||||
player->vel.vz -=
|
||||
(player->vel.vz > 0
|
||||
? player->cnst->x_friction
|
||||
: -player->cnst->x_friction);
|
||||
if(abs(player->vel.vz) <= player->cnst->x_friction)
|
||||
player->vel.vz = 0;
|
||||
}
|
||||
|
||||
// Slope factor application. Should only not work when in ceiling
|
||||
if(abs(player->vel.vz) >= X_SLOPE_MIN_SPD)
|
||||
player->vel.vz -= (X_SLOPE_NORMAL * rsin(player->angle)) >> 12;
|
||||
// Slope factor application. TODO: Should only not work when in ceiling
|
||||
if(abs(player->vel.vz) >= player->cnst->x_slope_min_spd)
|
||||
player->vel.vz -= (player->cnst->x_slope_normal * rsin(player->angle)) >> 12;
|
||||
|
||||
// Slip down slopes if they are too steep
|
||||
// TODO: FIX THIS!
|
||||
|
@ -797,7 +819,7 @@ player_update(Player *player)
|
|||
|
||||
/* Action changers */
|
||||
if(input_pressing(&player->input, PAD_DOWN)) {
|
||||
if(abs(player->vel.vz) >= X_MIN_ROLL_SPD) { // Rolling
|
||||
if(abs(player->vel.vz) >= player->cnst->x_min_roll_spd) { // Rolling
|
||||
player->action = ACTION_ROLLING;
|
||||
player_set_animation_direct(player, ANIM_ROLLING);
|
||||
sound_play_vag(sfx_roll, 0);
|
||||
|
@ -813,8 +835,10 @@ player_update(Player *player)
|
|||
}
|
||||
|
||||
// Ground speed cap
|
||||
if(player->vel.vz > X_MAX_SPD) player->vel.vz = X_MAX_SPD;
|
||||
else if(player->vel.vz < -X_MAX_SPD) player->vel.vz = -X_MAX_SPD;
|
||||
if(player->vel.vz > player->cnst->x_max_spd)
|
||||
player->vel.vz = player->cnst->x_max_spd;
|
||||
else if(player->vel.vz < -player->cnst->x_max_spd)
|
||||
player->vel.vz = -player->cnst->x_max_spd;
|
||||
|
||||
// Distribute ground speed onto X and Y components
|
||||
player->vel.vx = (player->vel.vz * rcos(player->angle)) >> 12;
|
||||
|
@ -823,20 +847,20 @@ player_update(Player *player)
|
|||
// Air X movement
|
||||
if(input_pressing(&player->input, PAD_RIGHT)
|
||||
&& (player->ctrllock == 0)) {
|
||||
if(player->vel.vx < X_TOP_SPD)
|
||||
player->vel.vx += X_AIR_ACCEL;
|
||||
if(player->vel.vx < player->cnst->x_top_spd)
|
||||
player->vel.vx += player->cnst->x_air_accel;
|
||||
if(!player->airdirlock)
|
||||
player->anim_dir = 1;
|
||||
} else if(input_pressing(&player->input, PAD_LEFT)
|
||||
&& (player->ctrllock == 0)) {
|
||||
if(player->vel.vx > -X_TOP_SPD)
|
||||
player->vel.vx -= X_AIR_ACCEL;
|
||||
if(player->vel.vx > -player->cnst->x_top_spd)
|
||||
player->vel.vx -= player->cnst->x_air_accel;
|
||||
if(!player->airdirlock)
|
||||
player->anim_dir = -1;
|
||||
}
|
||||
|
||||
// Air drag. Calculated before applying gravity.
|
||||
if((player->vel.vy < 0 && player->vel.vy > -Y_MIN_JUMP)
|
||||
if((player->vel.vy < 0 && player->vel.vy > -player->cnst->y_min_jump)
|
||||
&& (player->action != ACTION_HURT)) {
|
||||
// xsp -= (xsp div 0.125) / 256
|
||||
int32_t air_drag = (div12(abs(player->vel.vx), 0x200) << 12) / 0x100000;
|
||||
|
@ -847,8 +871,10 @@ player_update(Player *player)
|
|||
}
|
||||
|
||||
// Air speed cap
|
||||
if(player->vel.vx > X_MAX_SPD) player->vel.vx = X_MAX_SPD;
|
||||
else if(player->vel.vx < -X_MAX_SPD) player->vel.vx = -X_MAX_SPD;
|
||||
if(player->vel.vx > player->cnst->x_max_spd)
|
||||
player->vel.vx = player->cnst->x_max_spd;
|
||||
else if(player->vel.vx < -player->cnst->x_max_spd)
|
||||
player->vel.vx = -player->cnst->x_max_spd;
|
||||
}
|
||||
|
||||
// Y movement
|
||||
|
@ -856,8 +882,8 @@ player_update(Player *player)
|
|||
if(player->action == ACTION_JUMPING) {
|
||||
if(!input_pressing(&player->input, PAD_CROSS)) {
|
||||
// Short jump
|
||||
if(player->vel.vy < -Y_MIN_JUMP)
|
||||
player->vel.vy = -Y_MIN_JUMP;
|
||||
if(player->vel.vy < -player->cnst->y_min_jump)
|
||||
player->vel.vy = -player->cnst->y_min_jump;
|
||||
player->holding_jump = 0;
|
||||
} else {
|
||||
// Drop dash charge wait
|
||||
|
@ -872,13 +898,13 @@ player_update(Player *player)
|
|||
}
|
||||
}
|
||||
player->vel.vy += (player->action == ACTION_HURT)
|
||||
? Y_HURT_GRAVITY
|
||||
: Y_GRAVITY;
|
||||
? player->cnst->y_hurt_gravity
|
||||
: player->cnst->y_gravity;
|
||||
} else {
|
||||
if(input_pressed(&player->input, PAD_CROSS) && player->action != ACTION_SPINDASH) {
|
||||
// TODO: Review jump according to angle
|
||||
player->vel.vx -= (Y_JUMP_STRENGTH * rsin(player->angle)) >> 12;
|
||||
player->vel.vy -= (Y_JUMP_STRENGTH * rcos(player->angle)) >> 12;
|
||||
player->vel.vx -= (player->cnst->y_jump_strength * rsin(player->angle)) >> 12;
|
||||
player->vel.vy -= (player->cnst->y_jump_strength * rcos(player->angle)) >> 12;
|
||||
player->grnd = 0;
|
||||
player_set_animation_direct(player, ANIM_ROLLING);
|
||||
sound_play_vag(sfx_jump, 0);
|
||||
|
@ -1000,6 +1026,22 @@ player_update(Player *player)
|
|||
if(((player->pos.vy > level_water_y) && !player->underwater)
|
||||
|| ((player->pos.vy < level_water_y) && player->underwater)) {
|
||||
player->underwater = !player->underwater;
|
||||
|
||||
// Change constants accordingly!
|
||||
if(player->underwater) { // Entered underwater state
|
||||
player->cnst = &CNST_UNDERWATER;
|
||||
// Halve player's X speed
|
||||
if(player->grnd) player->vel.vz = player->vel.vz >> 1;
|
||||
else player->vel.vx = player->vel.vx >> 1;
|
||||
// Quarter player's Y speed
|
||||
player->vel.vy = player->vel.vy >> 2;
|
||||
} else {
|
||||
// TODO: Check for speed shoes
|
||||
player->cnst = &CNST_DEFAULT;
|
||||
// Double Y speed, limiting it to -16.0 (0x00010000)
|
||||
player->vel.vy = MAX(player->vel.vy << 1, -0x10000);
|
||||
}
|
||||
|
||||
PoolObject *explosion = object_pool_create(OBJ_EXPLOSION);
|
||||
explosion->freepos.vx = player->pos.vx;
|
||||
explosion->freepos.vy = level_water_y;
|
||||
|
@ -1131,9 +1173,9 @@ _player_set_hurt(Player *player, int32_t hazard_x)
|
|||
{
|
||||
player->action = ACTION_HURT;
|
||||
player->grnd = 0;
|
||||
player->vel.vy = -Y_HURT_FORCE;
|
||||
player->vel.vy = -player->cnst->y_hurt_force;
|
||||
int32_t a = SIGNUM(player->pos.vx - hazard_x);
|
||||
player->vel.vx = X_HURT_FORCE * ((a == 0) ? 1 : a);
|
||||
player->vel.vx = player->cnst->x_hurt_force * ((a == 0) ? 1 : a);
|
||||
player->ctrllock = 2;
|
||||
}
|
||||
|
||||
|
|
57
src/player_constants.c
Normal file
57
src/player_constants.c
Normal file
|
@ -0,0 +1,57 @@
|
|||
#include "player_constants.h"
|
||||
|
||||
// Default player values
|
||||
PlayerConstants CNST_DEFAULT = {
|
||||
.x_accel = 0x000c0,
|
||||
.x_air_accel = 0x00180,
|
||||
.x_friction = 0x000c0,
|
||||
.x_decel = 0x00800,
|
||||
.x_top_spd = 0x06000,
|
||||
.y_gravity = 0x00380,
|
||||
.y_hurt_gravity = 0x00300,
|
||||
.y_min_jump = 0x04000,
|
||||
.y_jump_strength = 0x06800,
|
||||
.x_min_roll_spd = 0x01000,
|
||||
.x_min_uncurl_spd = 0x00800,
|
||||
.x_roll_friction = 0x00060,
|
||||
.x_roll_decel = 0x00200,
|
||||
.x_slope_min_spd = 0x000d0,
|
||||
.x_slope_normal = 0x00200,
|
||||
.x_slope_rollup = 0x00140,
|
||||
.x_slope_rolldown = 0x00500,
|
||||
.x_max_spd = 0x10000,
|
||||
.x_map_slip_spd = 0x02800,
|
||||
.x_drpspd = 0x08000,
|
||||
.x_drpmax = 0x0c000,
|
||||
.y_hurt_force = 0x04000,
|
||||
.x_hurt_force = 0x02000
|
||||
};
|
||||
|
||||
// Underwater player values.
|
||||
// Most values are simply halved from base defaults
|
||||
PlayerConstants CNST_UNDERWATER = {
|
||||
.x_accel = 0x00060, // Changed
|
||||
.x_air_accel = 0x000c0, // Changed
|
||||
.x_friction = 0x00060, // Changed
|
||||
.x_decel = 0x00400, // Changed
|
||||
.x_top_spd = 0x03000, // Changed
|
||||
.y_gravity = 0x00100, // Changed
|
||||
.y_hurt_gravity = 0x000c0, // Changed, not documented, y_gravity - half diff on default
|
||||
.y_min_jump = 0x02000, // Changed
|
||||
.y_jump_strength = 0x03800, // Changed
|
||||
.x_min_roll_spd = 0x01000,
|
||||
.x_min_uncurl_spd = 0x00800,
|
||||
.x_roll_friction = 0x00030, // Changed
|
||||
.x_roll_decel = 0x00200,
|
||||
.x_slope_min_spd = 0x000d0,
|
||||
.x_slope_normal = 0x00200,
|
||||
.x_slope_rollup = 0x00140,
|
||||
.x_slope_rolldown = 0x00500,
|
||||
.x_max_spd = 0x10000,
|
||||
.x_map_slip_spd = 0x02800,
|
||||
.x_drpspd = 0x08000,
|
||||
.x_drpmax = 0x0c000,
|
||||
.y_hurt_force = 0x02000, // Changed
|
||||
.x_hurt_force = 0x01000 // Changed
|
||||
};
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue