File size: 2,432 Bytes
2d54981
 
 
 
 
0c4f8d5
2d54981
 
0c4f8d5
 
 
 
 
 
 
 
 
 
 
 
 
 
2d54981
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0c4f8d5
 
 
2d54981
 
0c4f8d5
2d54981
 
0c4f8d5
2d54981
 
 
 
 
 
 
0c4f8d5
2d54981
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
// 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;
        }
    }
}