space-game/src/shipAudio.ts
Michael Mainguy 72573054dd
All checks were successful
Build / build (push) Successful in 1m21s
Refactor Ship class into modular components
Major Refactoring:
- Extracted input handling, physics, audio, and weapons into separate modules
- Reduced Ship class from 542 lines to 305 lines (44% reduction)
- Ship now acts as coordinator between modular systems

New Modules Created:
- src/shipPhysics.ts - Pure force calculation and application logic
  - No external dependencies, fully testable in isolation
  - Handles linear/angular forces with velocity caps
  - Returns force magnitudes for audio feedback

- src/keyboardInput.ts - Keyboard and mouse input handling
  - Combines both input methods in unified interface
  - Exposes observables for shoot and camera change events
  - Clean getInputState() API

- src/controllerInput.ts - VR controller input handling
  - Maps WebXR controllers to input state
  - Handles thumbstick and button events
  - Observables for shooting and camera adjustments

- src/shipAudio.ts - Audio management system
  - Manages thrust sounds (primary and secondary)
  - Weapon fire sounds
  - Dynamic volume based on force magnitudes

- src/weaponSystem.ts - Projectile creation and lifecycle
  - Creates and manages ammo instances
  - Physics setup for projectiles
  - Auto-disposal timer

Ship Class Changes:
- Removed all input handling code (keyboard, mouse, VR)
- Removed force calculation logic
- Removed audio management code
- Removed weapon creation code
- Now wires up modular systems via observables
- Maintains same external API (backward compatible)

Material Improvements:
- Updated planet materials to use emissive texture
- Enhanced sun material with better color settings
- Set planets to unlit mode for better performance

Benefits:
- Each system independently testable
- Clear separation of concerns
- Easier to maintain and extend
- Better code organization

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-07 12:48:17 -06:00

110 lines
3.2 KiB
TypeScript

import type { AudioEngineV2, StaticSound } from "@babylonjs/core";
/**
* Manages ship audio (thrust sounds and weapon fire)
*/
export class ShipAudio {
private _audioEngine: AudioEngineV2;
private _primaryThrustSound: StaticSound;
private _secondaryThrustSound: StaticSound;
private _weaponSound: StaticSound;
private _primaryThrustPlaying: boolean = false;
private _secondaryThrustPlaying: boolean = false;
constructor(audioEngine?: AudioEngineV2) {
this._audioEngine = audioEngine;
}
/**
* Initialize sound assets
*/
public async initialize(): Promise<void> {
if (!this._audioEngine) return;
this._primaryThrustSound = await this._audioEngine.createSoundAsync(
"thrust",
"/thrust5.mp3",
{
loop: true,
volume: 0.2,
}
);
this._secondaryThrustSound = await this._audioEngine.createSoundAsync(
"thrust2",
"/thrust5.mp3",
{
loop: true,
volume: 0.5,
}
);
this._weaponSound = await this._audioEngine.createSoundAsync(
"shot",
"/shot.mp3",
{
loop: false,
volume: 0.5,
}
);
}
/**
* Update thrust audio based on current force magnitudes
* @param linearMagnitude - Forward/backward thrust magnitude (0-1)
* @param angularMagnitude - Rotation thrust magnitude (0-3)
*/
public updateThrustAudio(
linearMagnitude: number,
angularMagnitude: number
): void {
// Handle primary thrust sound (forward/backward movement)
if (linearMagnitude > 0) {
if (this._primaryThrustSound && !this._primaryThrustPlaying) {
this._primaryThrustSound.play();
this._primaryThrustPlaying = true;
}
if (this._primaryThrustSound) {
this._primaryThrustSound.volume = linearMagnitude;
}
} else {
if (this._primaryThrustSound && this._primaryThrustPlaying) {
this._primaryThrustSound.stop();
this._primaryThrustPlaying = false;
}
}
// Handle secondary thrust sound (rotation)
if (angularMagnitude > 0.1) {
if (this._secondaryThrustSound && !this._secondaryThrustPlaying) {
this._secondaryThrustSound.play();
this._secondaryThrustPlaying = true;
}
if (this._secondaryThrustSound) {
this._secondaryThrustSound.volume = angularMagnitude * 0.4;
}
} else {
if (this._secondaryThrustSound && this._secondaryThrustPlaying) {
this._secondaryThrustSound.stop();
this._secondaryThrustPlaying = false;
}
}
}
/**
* Play weapon fire sound
*/
public playWeaponSound(): void {
this._weaponSound?.play();
}
/**
* Cleanup audio resources
*/
public dispose(): void {
this._primaryThrustSound?.dispose();
this._secondaryThrustSound?.dispose();
this._weaponSound?.dispose();
}
}