cenotaph/src/player.h
2026-02-16 17:00:35 -05:00

150 lines
No EOL
3.6 KiB
C

#define PLAYER_SPEED FIX32(4)
#define PLAYER_SPEED_FOCUS FIX32(2.5)
#define PLAYER_ACCEL PLAYER_SPEED >> 3
#define PLAYER_ACCEL_FOCUS PLAYER_SPEED_FOCUS >> 3
#define PLAYER_OFF 24
#define PLAYER_BOUND_Y FIX32(PLAYER_OFF)
#define PLAYER_BOUND_H FIX32(224 - PLAYER_OFF)
#define CAMERA_X FIX32(96)
#define CAMERA_W FIX32(224)
#define SHOT_INTERVAL 15
s16 shotClock;
fix32 screenX;
fix32 playerSpeed;
fix32 playerVelX;
static void movePlayer(){
player.vel.y = 0;
fix32 targetVelX = 0;
if(ctrl.left || ctrl.right || ctrl.up || ctrl.down){
if(ctrl.b){
playerSpeed = PLAYER_SPEED_FOCUS;
} else {
playerSpeed = PLAYER_SPEED;
}
if(ctrl.left || ctrl.right){
if(!ctrl.a) player.shotAngle = ctrl.left ? 512 : 0;
targetVelX = ctrl.left ? -playerSpeed : playerSpeed;
}
if(ctrl.up) player.vel.y = -playerSpeed;
else if(ctrl.down) player.vel.y = playerSpeed;
}
if(playerVelX < targetVelX){
playerVelX += ctrl.b ? PLAYER_ACCEL_FOCUS : PLAYER_ACCEL;
if(playerVelX > targetVelX) playerVelX = targetVelX;
} else if(playerVelX > targetVelX){
playerVelX -= ctrl.b ? PLAYER_ACCEL_FOCUS : PLAYER_ACCEL;
if(playerVelX < targetVelX) playerVelX = targetVelX;
}
player.vel.x = playerVelX;
if(player.vel.x != 0 && player.vel.y != 0){
player.vel.x = fix32Mul(player.vel.x, FIX32(0.707));
player.vel.y = fix32Mul(player.vel.y, FIX32(0.707));
}
player.pos.x += player.vel.x;
player.pos.y += player.vel.y;
if(ctrl.a){
SPR_setHFlip(player.image, player.shotAngle != 0);
} else {
if(player.vel.x < 0){
SPR_setHFlip(player.image, TRUE);
} else if(player.vel.x > 0){
SPR_setHFlip(player.image, FALSE);
}
}
}
static void boundsPlayer(){
if(player.pos.y < PLAYER_BOUND_Y)
player.pos.y = PLAYER_BOUND_Y;
else if(player.pos.y > PLAYER_BOUND_H)
player.pos.y = PLAYER_BOUND_H;
if(player.pos.x >= GAME_WRAP){
player.pos.x -= GAME_WRAP;
player.camera -= GAME_WRAP;
}
if(player.pos.x <= 0){
player.pos.x += GAME_WRAP;
player.camera += GAME_WRAP;
}
player.yCamera = (fix32ToInt(player.pos.y) - FIX16(112)) >> 2;
}
static void cameraPlayer(){
screenX = player.pos.x - player.camera;
if(screenX < CAMERA_X && player.vel.x < 0)
player.camera += player.vel.x;
else if(screenX > CAMERA_W && player.vel.x > 0)
player.camera += player.vel.x;
}
static void shootPlayer(){
if(ctrl.a && shotClock == 0){
struct bulletSpawner spawner = {
.x = player.pos.x,
.y = player.pos.y,
.anim = 0,
.speed = FIX32(24),
.angle = player.shotAngle,
.player = TRUE
};
void updater(s16 i){
if(bullets[i].clock == 5) killBullet(i, TRUE);
}
spawnBullet(spawner, updater);
sfxPlayerShot();
shotClock = SHOT_INTERVAL;
} else if(shotClock > 0) shotClock--;
}
void loadPlayer(){
player.shotAngle = 0;
player.camera = 0;
player.pos.x = FIX32(128);
player.pos.y = FIX32(112);
playerVelX = 0;
player.lives = 3;
player.image = SPR_addSprite(&sakuyaSprite,
fix32ToInt(player.pos.x) - PLAYER_OFF,
fix32ToInt(player.pos.y) - PLAYER_OFF,
TILE_ATTR(PAL0, 0, 0, 0));
player.yCamera = (fix32ToInt(player.pos.y) - FIX16(112)) >> 2;
}
void updatePlayer(){
if(!gameOver){
if(player.recoveringClock > 0){
if(player.recoveringClock % 10 == 1)
SPR_setVisibility(player.image, player.recoveringClock % 20 == 1 ? VISIBLE : HIDDEN);
player.recoveringClock--;
if(player.recoveringClock == 0)
SPR_setVisibility(player.image, VISIBLE);
}
movePlayer();
boundsPlayer();
cameraPlayer();
shootPlayer();
s16 sx = getScreenX(player.pos.x, player.camera);
s16 sy = fix32ToInt(player.pos.y);
SPR_setPosition(player.image, sx - PLAYER_OFF, sy - PLAYER_OFF);
intToStr(fix32ToInt(player.pos.x), debugStr, 1);
}
}