diff --git a/index.html b/index.html index 55f478f..6fb0592 100644 --- a/index.html +++ b/index.html @@ -349,6 +349,46 @@ + +
+

🚀 Ship Physics

+

+ Advanced tuning parameters for ship movement and handling. Adjust these to customize how the ship responds to controls. +

+ +
+ + +
+ Maximum forward/backward speed of the ship. Higher values allow faster movement. +
+
+ +
+ + +
+ Maximum rotation speed of the ship. Higher values allow faster turning. +
+
+ +
+ + +
+ Acceleration power for forward/backward thrust. Higher values = faster acceleration. +
+
+ +
+ + +
+ Torque power for rotation. Higher values = faster rotational acceleration. +
+
+
+

â„šī¸ Quality Level Guide

diff --git a/src/gameConfig.ts b/src/gameConfig.ts index 4c0feba..5bc252a 100644 --- a/src/gameConfig.ts +++ b/src/gameConfig.ts @@ -9,6 +9,14 @@ export class GameConfig { // Physics settings public physicsEnabled: boolean = true; + // Ship physics tuning parameters + public shipPhysics = { + maxLinearVelocity: 200, + maxAngularVelocity: 1.4, + linearForceMultiplier: 800, + angularForceMultiplier: 15 + }; + /** * Private constructor for singleton pattern */ @@ -33,7 +41,8 @@ export class GameConfig { public save(): void { const config = { physicsEnabled: this.physicsEnabled, - debug: this.debug + debug: this.debug, + shipPhysics: this.shipPhysics }; localStorage.setItem('game-config', JSON.stringify(config)); } @@ -48,6 +57,16 @@ export class GameConfig { const config = JSON.parse(stored); this.physicsEnabled = config.physicsEnabled ?? true; this.debug = config.debug ?? false; + + // Load ship physics with fallback to defaults + if (config.shipPhysics) { + this.shipPhysics = { + maxLinearVelocity: config.shipPhysics.maxLinearVelocity ?? 200, + maxAngularVelocity: config.shipPhysics.maxAngularVelocity ?? 1.4, + linearForceMultiplier: config.shipPhysics.linearForceMultiplier ?? 800, + angularForceMultiplier: config.shipPhysics.angularForceMultiplier ?? 15 + }; + } } else { this.save(); } @@ -62,6 +81,12 @@ export class GameConfig { public reset(): void { this.physicsEnabled = true; this.debug = false; + this.shipPhysics = { + maxLinearVelocity: 200, + maxAngularVelocity: 1.4, + linearForceMultiplier: 800, + angularForceMultiplier: 15 + }; this.save(); } } diff --git a/src/settingsScreen.ts b/src/settingsScreen.ts index 3a88255..16b53e6 100644 --- a/src/settingsScreen.ts +++ b/src/settingsScreen.ts @@ -10,6 +10,12 @@ export function initializeSettingsScreen(): void { const physicsEnabledCheckbox = document.getElementById('physicsEnabled') as HTMLInputElement; const debugEnabledCheckbox = document.getElementById('debugEnabled') as HTMLInputElement; + // Ship physics inputs + const maxLinearVelocityInput = document.getElementById('maxLinearVelocity') as HTMLInputElement; + const maxAngularVelocityInput = document.getElementById('maxAngularVelocity') as HTMLInputElement; + const linearForceMultiplierInput = document.getElementById('linearForceMultiplier') as HTMLInputElement; + const angularForceMultiplierInput = document.getElementById('angularForceMultiplier') as HTMLInputElement; + const saveBtn = document.getElementById('saveSettingsBtn'); const resetBtn = document.getElementById('resetSettingsBtn'); const messageDiv = document.getElementById('settingsMessage'); @@ -38,6 +44,12 @@ export function initializeSettingsScreen(): void { function loadSettings(): void { if (physicsEnabledCheckbox) physicsEnabledCheckbox.checked = config.physicsEnabled; if (debugEnabledCheckbox) debugEnabledCheckbox.checked = config.debug; + + // Load ship physics settings + if (maxLinearVelocityInput) maxLinearVelocityInput.value = config.shipPhysics.maxLinearVelocity.toString(); + if (maxAngularVelocityInput) maxAngularVelocityInput.value = config.shipPhysics.maxAngularVelocity.toString(); + if (linearForceMultiplierInput) linearForceMultiplierInput.value = config.shipPhysics.linearForceMultiplier.toString(); + if (angularForceMultiplierInput) angularForceMultiplierInput.value = config.shipPhysics.angularForceMultiplier.toString(); } /** @@ -46,6 +58,13 @@ export function initializeSettingsScreen(): void { function saveSettings(): void { config.physicsEnabled = physicsEnabledCheckbox.checked; config.debug = debugEnabledCheckbox.checked; + + // Save ship physics settings + config.shipPhysics.maxLinearVelocity = parseFloat(maxLinearVelocityInput.value); + config.shipPhysics.maxAngularVelocity = parseFloat(maxAngularVelocityInput.value); + config.shipPhysics.linearForceMultiplier = parseFloat(linearForceMultiplierInput.value); + config.shipPhysics.angularForceMultiplier = parseFloat(angularForceMultiplierInput.value); + config.save(); } diff --git a/src/shipPhysics.ts b/src/shipPhysics.ts index bebf250..459d0ff 100644 --- a/src/shipPhysics.ts +++ b/src/shipPhysics.ts @@ -1,10 +1,5 @@ import { PhysicsBody, TransformNode, Vector2, Vector3 } from "@babylonjs/core"; - -// Physics constants -const MAX_LINEAR_VELOCITY = 200; -const MAX_ANGULAR_VELOCITY = 1.4; -const LINEAR_FORCE_MULTIPLIER = 800; -const ANGULAR_FORCE_MULTIPLIER = 15; +import { GameConfig } from "./gameConfig"; export interface InputState { leftStick: Vector2; @@ -18,7 +13,7 @@ export interface ForceApplicationResult { /** * Handles physics force calculations and application for the ship - * Pure calculation logic with no external dependencies + * Reads physics parameters from GameConfig for runtime tuning */ export class ShipPhysics { /** @@ -39,6 +34,9 @@ export class ShipPhysics { const { leftStick, rightStick } = inputState; + // Get physics config + const config = GameConfig.getInstance().shipPhysics; + // Get current velocities for velocity cap checks const currentLinearVelocity = physicsBody.getLinearVelocity(); const currentAngularVelocity = physicsBody.getAngularVelocity(); @@ -52,7 +50,7 @@ export class ShipPhysics { linearMagnitude = Math.abs(leftStick.y); // Only apply force if we haven't reached max velocity - if (currentSpeed < MAX_LINEAR_VELOCITY) { + if (currentSpeed < config.maxLinearVelocity) { // Get local direction (Z-axis for forward/backward thrust) const localDirection = new Vector3(0, 0, -leftStick.y); // Transform to world space @@ -60,7 +58,7 @@ export class ShipPhysics { localDirection, transformNode.getWorldMatrix() ); - const force = worldDirection.scale(LINEAR_FORCE_MULTIPLIER); + const force = worldDirection.scale(config.linearForceMultiplier); // Calculate thrust point: center of mass + offset (0, 1, 0) in world space const thrustPoint = Vector3.TransformCoordinates( @@ -83,14 +81,14 @@ export class ShipPhysics { const currentAngularSpeed = currentAngularVelocity.length(); // Only apply torque if we haven't reached max angular velocity - if (currentAngularSpeed < MAX_ANGULAR_VELOCITY) { + if (currentAngularSpeed < config.maxAngularVelocity) { const yaw = -leftStick.x; const pitch = rightStick.y; const roll = rightStick.x; // Create torque in local space, then transform to world space const localTorque = new Vector3(pitch, yaw, roll).scale( - ANGULAR_FORCE_MULTIPLIER + config.angularForceMultiplier ); const worldTorque = Vector3.TransformNormal( localTorque,