Files
healer-man/src/game/playerMovement.ts
T
2026-08-18 16:22:19 -04:00

45 lines
1.7 KiB
TypeScript

import type { KinematicCharacterController } from "@dimforge/rapier3d-compat";
import { PLAYER_GROUND_MIN_NORMAL_Y } from "./playerJump";
export const PLAYER_GRAVITY = -18;
export const PLAYER_CHARACTER_CONTROLLER_OFFSET = 0.02;
export const PLAYER_STEP_HEIGHT = 0.55;
export const PLAYER_STEP_MIN_WIDTH = 0.15;
export const PLAYER_GROUND_SNAP_DISTANCE = PLAYER_STEP_HEIGHT;
export const PLAYER_GROUND_STICK_VELOCITY = -0.5;
export const PLAYER_MAX_FRAME_DELTA_SECONDS = 0.05;
export const PLAYER_TERMINAL_FALL_VELOCITY = -32;
/**
* Configures Rapier's kinematic controller for MMO-style traversal. Ordinary
* stairs and curb-sized seams are walkable, while taller obstacles remain
* blocking geometry and still require a real jump or another route.
*/
export function configurePlayerCharacterController(
controller: KinematicCharacterController,
): KinematicCharacterController {
controller.setUp({ x: 0, y: 1, z: 0 });
controller.setSlideEnabled(true);
controller.enableAutostep(PLAYER_STEP_HEIGHT, PLAYER_STEP_MIN_WIDTH, false);
controller.enableSnapToGround(PLAYER_GROUND_SNAP_DISTANCE);
controller.setMaxSlopeClimbAngle(Math.acos(PLAYER_GROUND_MIN_NORMAL_Y));
return controller;
}
export function playerFrameDeltaSeconds(deltaSeconds: number): number {
if (!Number.isFinite(deltaSeconds) || deltaSeconds <= 0) return 0;
return Math.min(deltaSeconds, PLAYER_MAX_FRAME_DELTA_SECONDS);
}
export function airbornePlayerVerticalVelocity(
currentVelocity: number,
deltaSeconds: number,
): number {
const velocity = Number.isFinite(currentVelocity) ? currentVelocity : 0;
const delta = playerFrameDeltaSeconds(deltaSeconds);
return Math.max(
PLAYER_TERMINAL_FALL_VELOCITY,
velocity + PLAYER_GRAVITY * delta,
);
}