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.
+
+
+
+
+
+
+
+
+
+
+
âšī¸ 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,