Spaces:
Sleeping
Sleeping
| // Physics engine - handles movement, gravity, and forces | |
| import { PlayerState, Enemy, KeyState } from './types'; | |
| import { GAME_CONFIG } from '../constants'; | |
| const { GRAVITY, FRICTION, MAX_FALL_SPEED, PLAYER_SPEED, PLAYER_JUMP_FORCE, MOBILE_PLAYER_SPEED, MOBILE_JUMP_FORCE } = GAME_CONFIG; | |
| export class Physics { | |
| private isMobile: boolean = false; | |
| setMobileMode(isMobile: boolean): void { | |
| this.isMobile = isMobile; | |
| } | |
| private getPlayerSpeed(): number { | |
| return this.isMobile ? MOBILE_PLAYER_SPEED : PLAYER_SPEED; | |
| } | |
| private getJumpForce(): number { | |
| return this.isMobile ? MOBILE_JUMP_FORCE : PLAYER_JUMP_FORCE; | |
| } | |
| applyGravity(entity: { vy: number; isFalling?: boolean }): void { | |
| entity.vy += GRAVITY; | |
| if (entity.vy > MAX_FALL_SPEED) { | |
| entity.vy = MAX_FALL_SPEED; | |
| } | |
| } | |
| applyFriction(entity: { vx: number }): void { | |
| entity.vx *= FRICTION; | |
| if (Math.abs(entity.vx) < 0.1) { | |
| entity.vx = 0; | |
| } | |
| } | |
| updatePlayerMovement(player: PlayerState, keys: KeyState): void { | |
| const speed = this.getPlayerSpeed(); | |
| const jumpForce = this.getJumpForce(); | |
| // Horizontal movement | |
| if (keys.left) { | |
| player.vx = -speed; | |
| player.facingRight = false; | |
| } else if (keys.right) { | |
| player.vx = speed; | |
| player.facingRight = true; | |
| } else { | |
| this.applyFriction(player); | |
| } | |
| // Jump | |
| if (keys.jump && !player.isJumping && !player.isFalling) { | |
| player.vy = jumpForce; | |
| player.isJumping = true; | |
| } | |
| // Apply gravity | |
| this.applyGravity(player); | |
| // Update position | |
| player.x += player.vx; | |
| player.y += player.vy; | |
| // Check if falling | |
| if (player.vy > 0) { | |
| player.isFalling = true; | |
| player.isJumping = false; | |
| } | |
| } | |
| updateEnemyMovement(enemy: Enemy, levelWidth: number): void { | |
| if (!enemy.isAlive) return; | |
| // Apply gravity | |
| this.applyGravity(enemy); | |
| // Move in current direction | |
| enemy.vx = enemy.direction * 1.5; | |
| enemy.x += enemy.vx; | |
| enemy.y += enemy.vy; | |
| // Reverse direction at level boundaries | |
| if (enemy.x <= 0 || enemy.x >= levelWidth - enemy.width) { | |
| enemy.direction *= -1; | |
| } | |
| } | |
| } | |