Files
mac-container-dev 76bad46d09 Initial commit: Retro 90s flight simulator MVP
Loading screen, main menu, 3D flight sim with CRT post-processing,
procedural terrain, airport with buildings, low-poly aircraft,
flight physics, HUD instruments, and sound.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-05 10:43:22 +00:00

78 lines
2.3 KiB
JavaScript

export class Sound {
constructor() {
this.ctx = null;
this.engineOsc = null;
this.engineGain = null;
this.initialized = false;
}
init() {
if (this.initialized) return;
try {
this.ctx = new (window.AudioContext || window.webkitAudioContext)();
this.engineOsc = this.ctx.createOscillator();
this.engineOsc.type = 'sawtooth';
this.engineGain = this.ctx.createGain();
this.engineGain.gain.value = 0;
// Low-pass filter for muffled engine sound
this.engineFilter = this.ctx.createBiquadFilter();
this.engineFilter.type = 'lowpass';
this.engineFilter.frequency.value = 300;
this.engineOsc.connect(this.engineFilter);
this.engineFilter.connect(this.engineGain);
this.engineGain.connect(this.ctx.destination);
this.engineOsc.start();
this.initialized = true;
} catch {
// Audio not available, silently fail
}
}
update(throttle) {
if (!this.initialized || !this.engineOsc) return;
const baseFreq = 60;
const maxFreq = 180;
this.engineOsc.frequency.value = baseFreq + throttle * (maxFreq - baseFreq);
this.engineGain.gain.value = Math.min(throttle * 0.08, 0.08);
this.engineFilter.frequency.value = 200 + throttle * 200;
}
beep(frequency = 800, duration = 80) {
if (!this.initialized) return;
try {
const osc = this.ctx.createOscillator();
const gain = this.ctx.createGain();
osc.type = 'square';
osc.frequency.value = frequency;
gain.gain.value = 0.05;
osc.connect(gain);
gain.connect(this.ctx.destination);
osc.start();
osc.stop(this.ctx.currentTime + duration / 1000);
} catch {
// Ignore audio errors
}
}
takeoffSound() {
if (!this.initialized) return;
try {
const osc = this.ctx.createOscillator();
const gain = this.ctx.createGain();
osc.type = 'triangle';
osc.frequency.value = 400;
osc.frequency.linearRampToValueAtTime(800, this.ctx.currentTime + 0.3);
gain.gain.value = 0.08;
gain.gain.linearRampToValueAtTime(0, this.ctx.currentTime + 0.5);
osc.connect(gain);
gain.connect(this.ctx.destination);
osc.start();
osc.stop(this.ctx.currentTime + 0.5);
} catch {
// Ignore
}
}
}