This commit is contained in:
t. boddy 2026-02-14 19:31:58 -05:00
parent ab73e04b32
commit 0b905f2690
26 changed files with 1210 additions and 0 deletions

153
src/player.h Normal file
View file

@ -0,0 +1,153 @@
#define PLAYER_SPEED FIX32(5)
#define PLAYER_SPEED_NORM fix32Mul(PLAYER_SPEED, FIX32(0.707))
#define PLAYER_SPEED_FOCUS FIX32(3)
#define PLAYER_SPEED_FOCUS_NORM fix32Mul(PLAYER_SPEED_FOCUS, FIX32(0.707))
#define PLAYER_ACCEL PLAYER_SPEED >> 3
#define PLAYER_ACCEL_FOCUS PLAYER_SPEED_FOCUS >> 3
#define PLAYER_OFF 16
#define PLAYER_BOUND_Y FIX32(PLAYER_OFF)
#define PLAYER_BOUND_H FIX32(224 - PLAYER_OFF)
#define CAMERA_X FIX32(80)
#define CAMERA_W FIX32(240)
#define SHOT_INTERVAL 15
s16 shotClock;
fix32 screenX;
fix32 playerSpeed, playerSpeedNorm;
fix32 playerVelX; // Track actual X velocity for momentum
static void movePlayer(){
// Y-axis stays instant
player.vel.y = 0;
// Determine target X speed based on input
fix32 targetVelX = 0;
if(ctrl.left || ctrl.right || ctrl.up || ctrl.down){
if(ctrl.b){
playerSpeed = PLAYER_SPEED_FOCUS;
playerSpeedNorm = PLAYER_SPEED_FOCUS_NORM;
} else {
playerSpeed = PLAYER_SPEED;
playerSpeedNorm = PLAYER_SPEED_NORM;
}
player.last.x = player.pos.x;
if(ctrl.left || ctrl.right){
if(!ctrl.a) player.shotAngle = ctrl.left ? 512 : 0;
targetVelX = ctrl.left ? -playerSpeed : playerSpeed;
}
// Y velocity (instant)
if(ctrl.up) player.vel.y = -playerSpeed;
else if(ctrl.down) player.vel.y = playerSpeed;
}
// Apply acceleration toward target X velocity
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;
// Normalize if diagonal
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));
}
// Apply movement (always, for momentum to work during deceleration)
player.pos.x += player.vel.x;
player.pos.y += player.vel.y;
// Update facing direction when moving horizontally
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;
}
}
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(12),
.angle = player.shotAngle,
.player = TRUE
};
void updater(u8 i){
if(bullets[i].clock >= 16) killBullet(i);
}
spawnBullet(spawner, updater);
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));
}
void updatePlayer(){
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);
}