about summary refs log tree commit diff stats
path: root/html/space/physics.js
diff options
context:
space:
mode:
Diffstat (limited to 'html/space/physics.js')
-rw-r--r--html/space/physics.js279
1 files changed, 206 insertions, 73 deletions
diff --git a/html/space/physics.js b/html/space/physics.js
index 6b71601..d4dfe55 100644
--- a/html/space/physics.js
+++ b/html/space/physics.js
@@ -1,5 +1,6 @@
 // Physics module for handling movement and collisions
 import { inputState } from './input.js';
+import { createProjectile } from './gameState.js';
 
 // Constants
 const MAX_THRUST = 0.5;        // Reduced from 2
@@ -8,113 +9,245 @@ const DECELERATION = 0.001;    // Reduced from 0.01
 const BASE_ROTATION_SPEED = 0.001;  // Reduced from 0.005
 const ROTATION_ACCELERATION = 0.0005; // Reduced from 0.002
 const ROTATION_DECELERATION = 0.0002; // Reduced from 0.001
+const MOUSE_SENSITIVITY = 0.03; // Increased from 0.01 for sharper turns
+const MAX_SPEED = 1.0; // Maximum speed in any direction
+
+// Weapon constants
+export const PRIMARY_COOLDOWN = 100; // ms between primary shots
+export const SECONDARY_COOLDOWN = 2000; // ms between secondary shots
+export const PRIMARY_BURST_COUNT = 3; // Number of shots in primary burst
+export const PRIMARY_BURST_DELAY = 50; // ms between burst shots
 
 // Player state
-const player = {
+let playerState = {
     position: { x: 0, y: 0, z: 0 },
     velocity: { x: 0, y: 0, z: 0 },
-    rotation: { x: 0, y: 0, z: 0 },
-    rotationSpeed: { x: 0, y: 0 }  // Added for smooth rotation
+    rotation: { x: 0, y: 0 },
+    thrust: 0,
+    strafe: 0,
+    weapons: {
+        primary: {
+            lastFired: 0,
+            burstCount: 0,
+            burstTimer: 0
+        },
+        secondary: {
+            lastFired: 0
+        }
+    }
 };
 
 // Initialize physics
 export function initPhysics() {
     // Reset player state
-    player.position = { x: 0, y: 0, z: 0 };
-    player.velocity = { x: 0, y: 0, z: 0 };
-    player.rotation = { x: 0, y: 0, z: 0 };
-    player.rotationSpeed = { x: 0, y: 0 };
+    playerState.position = { x: 0, y: 0, z: 0 };
+    playerState.velocity = { x: 0, y: 0, z: 0 };
+    playerState.rotation = { x: 0, y: 0 };
+    playerState.thrust = 0;
+    playerState.strafe = 0;
 }
 
-// Helper function to apply force in a direction
-function applyForce(direction, magnitude, deltaTime) {
-    const force = {
-        x: direction.x * magnitude * deltaTime,
-        y: direction.y * magnitude * deltaTime,
-        z: direction.z * magnitude * deltaTime
-    };
-    
-    player.velocity.x += force.x;
-    player.velocity.y += force.y;
-    player.velocity.z += force.z;
+// Helper function to limit speed in a direction
+function limitSpeed(velocity, maxSpeed) {
+    const speed = Math.sqrt(velocity.x * velocity.x + velocity.y * velocity.y + velocity.z * velocity.z);
+    if (speed > maxSpeed) {
+        const scale = maxSpeed / speed;
+        velocity.x *= scale;
+        velocity.y *= scale;
+        velocity.z *= scale;
+    }
 }
 
-// Update physics
-export function updatePhysics(deltaTime) {
-    // Update rotation speed based on input
-    if (inputState.yaw !== 0) {
-        player.rotationSpeed.y += inputState.yaw * ROTATION_ACCELERATION * deltaTime;
+// Update player controls
+export function updatePlayerControls(controls) {
+    // Handle thrust (space bar)
+    if (controls.thrust) {
+        playerState.thrust = Math.min(playerState.thrust + THRUST_ACCELERATION, MAX_THRUST);
     } else {
-        // Smoothly decelerate rotation
-        player.rotationSpeed.y *= (1 - ROTATION_DECELERATION * deltaTime);
+        // Apply deceleration when no thrust input
+        if (playerState.thrust > 0) {
+            playerState.thrust = Math.max(playerState.thrust - DECELERATION, 0);
+        }
     }
 
-    if (inputState.pitch !== 0) {
-        player.rotationSpeed.x += inputState.pitch * ROTATION_ACCELERATION * deltaTime;
+    // Handle vertical strafing (W/S)
+    if (controls.up) {
+        playerState.verticalStrafe = Math.min(playerState.verticalStrafe + THRUST_ACCELERATION, MAX_THRUST);
+    } else if (controls.down) {
+        playerState.verticalStrafe = Math.max(playerState.verticalStrafe - THRUST_ACCELERATION, -MAX_THRUST);
     } else {
-        // Smoothly decelerate rotation
-        player.rotationSpeed.x *= (1 - ROTATION_DECELERATION * deltaTime);
+        // Apply deceleration when no vertical strafe input
+        if (playerState.verticalStrafe > 0) {
+            playerState.verticalStrafe = Math.max(playerState.verticalStrafe - DECELERATION, 0);
+        } else if (playerState.verticalStrafe < 0) {
+            playerState.verticalStrafe = Math.min(playerState.verticalStrafe + DECELERATION, 0);
+        }
+    }
+
+    // Handle horizontal strafing (A/D)
+    if (controls.left) {
+        playerState.horizontalStrafe = Math.min(playerState.horizontalStrafe + THRUST_ACCELERATION, MAX_THRUST);
+    } else if (controls.right) {
+        playerState.horizontalStrafe = Math.max(playerState.horizontalStrafe - THRUST_ACCELERATION, -MAX_THRUST);
+    } else {
+        // Apply deceleration when no horizontal strafe input
+        if (playerState.horizontalStrafe > 0) {
+            playerState.horizontalStrafe = Math.max(playerState.horizontalStrafe - DECELERATION, 0);
+        } else if (playerState.horizontalStrafe < 0) {
+            playerState.horizontalStrafe = Math.min(playerState.horizontalStrafe + DECELERATION, 0);
+        }
+    }
+
+    // Handle mouse-based rotation with smoothing
+    const targetRotationY = controls.mouseX * MOUSE_SENSITIVITY;
+    const targetRotationX = controls.mouseY * MOUSE_SENSITIVITY;
+    
+    // Smooth rotation using lerp with faster response
+    playerState.rotation.y += (targetRotationY - playerState.rotation.y) * 0.2;
+    playerState.rotation.x += (targetRotationX - playerState.rotation.x) * 0.2;
+
+    // Clamp pitch rotation
+    playerState.rotation.x = Math.max(-Math.PI/2, Math.min(Math.PI/2, playerState.rotation.x));
+
+    // Handle weapons with cooldowns
+    const currentTime = Date.now();
+    
+    // Primary weapon (burst fire)
+    if (controls.fire) {
+        const primary = playerState.weapons.primary;
+        if (currentTime - primary.lastFired >= PRIMARY_COOLDOWN && primary.burstCount === 0) {
+            primary.burstCount = PRIMARY_BURST_COUNT;
+            primary.burstTimer = currentTime;
+            firePrimaryWeapon();
+            primary.lastFired = currentTime;
+        }
     }
 
-    // Apply rotation based on current rotation speed
-    player.rotation.y += player.rotationSpeed.y * BASE_ROTATION_SPEED * deltaTime;
-    player.rotation.x += player.rotationSpeed.x * BASE_ROTATION_SPEED * deltaTime;
+    // Secondary weapon (single shot with cooldown)
+    if (controls.secondary && currentTime - playerState.weapons.secondary.lastFired >= SECONDARY_COOLDOWN) {
+        fireSecondaryWeapon();
+        playerState.weapons.secondary.lastFired = currentTime;
+    }
 
-    // Calculate forward and right vectors based on current rotation
-    const cosY = Math.cos(player.rotation.y);
-    const sinY = Math.sin(player.rotation.y);
-    const cosX = Math.cos(player.rotation.x);
-    const sinX = Math.sin(player.rotation.x);
+    // Handle burst fire timing
+    const primary = playerState.weapons.primary;
+    if (primary.burstCount > 0 && currentTime - primary.burstTimer >= PRIMARY_BURST_DELAY) {
+        firePrimaryWeapon();
+        primary.burstCount--;
+        primary.burstTimer = currentTime;
+    }
+}
 
-    // Forward vector (in the direction the ship is facing)
+// Update physics
+export function updatePhysics(deltaTime) {
+    // Calculate forward and right vectors based on rotation
     const forward = {
-        x: sinY * cosX,
-        y: sinX,
-        z: cosY * cosX
+        x: Math.sin(playerState.rotation.y) * Math.cos(playerState.rotation.x),
+        y: -Math.sin(playerState.rotation.x),
+        z: Math.cos(playerState.rotation.y) * Math.cos(playerState.rotation.x)
     };
 
-    // Right vector (perpendicular to forward)
     const right = {
-        x: cosY,
+        x: Math.cos(playerState.rotation.y),
         y: 0,
-        z: -sinY
+        z: -Math.sin(playerState.rotation.y)
     };
 
-    // Apply thrust in the direction the ship is facing
-    if (inputState.thrust !== 0) {
-        applyForce(forward, inputState.thrust * THRUST_ACCELERATION, deltaTime);
-    }
+    const up = { x: 0, y: 1, z: 0 };
 
-    // Apply strafing force
-    if (inputState.strafe !== 0) {
-        applyForce(right, inputState.strafe * THRUST_ACCELERATION, deltaTime);
-    }
+    // Apply thrust in forward direction
+    const thrustVelocity = {
+        x: forward.x * playerState.thrust * deltaTime,
+        y: forward.y * playerState.thrust * deltaTime,
+        z: forward.z * playerState.thrust * deltaTime
+    };
 
-    // Apply damping to simulate space friction (very slight)
-    const currentSpeed = Math.sqrt(
-        player.velocity.x * player.velocity.x +
-        player.velocity.y * player.velocity.y +
-        player.velocity.z * player.velocity.z
-    );
-
-    if (currentSpeed > 0) {
-        const speedDamping = 1 - (DECELERATION * deltaTime);
-        player.velocity.x *= speedDamping;
-        player.velocity.y *= speedDamping;
-        player.velocity.z *= speedDamping;
-    }
+    // Apply horizontal strafe
+    const horizontalStrafeVelocity = {
+        x: right.x * playerState.horizontalStrafe * deltaTime,
+        y: 0,
+        z: right.z * playerState.horizontalStrafe * deltaTime
+    };
+
+    // Apply vertical strafe
+    const verticalStrafeVelocity = {
+        x: 0,
+        y: up.y * playerState.verticalStrafe * deltaTime,
+        z: 0
+    };
+
+    // Add velocities
+    playerState.velocity.x += thrustVelocity.x + horizontalStrafeVelocity.x + verticalStrafeVelocity.x;
+    playerState.velocity.y += thrustVelocity.y + horizontalStrafeVelocity.y + verticalStrafeVelocity.y;
+    playerState.velocity.z += thrustVelocity.z + horizontalStrafeVelocity.z + verticalStrafeVelocity.z;
+
+    // Limit total speed
+    limitSpeed(playerState.velocity, MAX_SPEED);
+
+    // Apply velocity to position
+    playerState.position.x += playerState.velocity.x * deltaTime;
+    playerState.position.y += playerState.velocity.y * deltaTime;
+    playerState.position.z += playerState.velocity.z * deltaTime;
+
+    // Apply friction/drag
+    const drag = 0.99;
+    playerState.velocity.x *= drag;
+    playerState.velocity.y *= drag;
+    playerState.velocity.z *= drag;
+}
+
+// Weapon firing
+function firePrimaryWeapon() {
+    const forward = {
+        x: Math.sin(playerState.rotation.y) * Math.cos(playerState.rotation.x),
+        y: -Math.sin(playerState.rotation.x),
+        z: Math.cos(playerState.rotation.y) * Math.cos(playerState.rotation.x)
+    };
 
-    // Update position
-    player.position.x += player.velocity.x * deltaTime;
-    player.position.y += player.velocity.y * deltaTime;
-    player.position.z += player.velocity.z * deltaTime;
+    createProjectile({
+        position: { ...playerState.position },
+        velocity: {
+            x: forward.x * 10 + playerState.velocity.x,
+            y: forward.y * 10 + playerState.velocity.y,
+            z: forward.z * 10 + playerState.velocity.z
+        },
+        type: 'primary'
+    });
 }
 
-// Get player state for rendering
+function fireSecondaryWeapon() {
+    const forward = {
+        x: Math.sin(playerState.rotation.y) * Math.cos(playerState.rotation.x),
+        y: -Math.sin(playerState.rotation.x),
+        z: Math.cos(playerState.rotation.y) * Math.cos(playerState.rotation.x)
+    };
+
+    createProjectile({
+        position: { ...playerState.position },
+        velocity: {
+            x: forward.x * 5 + playerState.velocity.x,
+            y: forward.y * 5 + playerState.velocity.y,
+            z: forward.z * 5 + playerState.velocity.z
+        },
+        type: 'secondary'
+    });
+}
+
+// Get current player state
 export function getPlayerState() {
+    return playerState;
+}
+
+// Get weapon cooldown states
+export function getWeaponStates() {
+    const currentTime = Date.now();
     return {
-        position: { ...player.position },
-        rotation: { ...player.rotation },
-        velocity: { ...player.velocity }
+        primary: {
+            cooldown: Math.max(0, PRIMARY_COOLDOWN - (currentTime - playerState.weapons.primary.lastFired)),
+            burstCount: playerState.weapons.primary.burstCount
+        },
+        secondary: {
+            cooldown: Math.max(0, SECONDARY_COOLDOWN - (currentTime - playerState.weapons.secondary.lastFired))
+        }
     };
 } 
\ No newline at end of file