Änderung: Verbesserung der Audio-Integration und Steuerung im Taxi-Spiel

Änderungen:
- Hinzufügung einer motorStopTimeout-Logik zur verzögerten Stopp-Funktion des Motorgeräuschs, um eine realistischere Audio-Steuerung zu ermöglichen.
- Übernahme eines globalen AudioContext und MotorSound, um die Wiederverwendbarkeit zu verbessern und die Initialisierung zu optimieren.
- Anpassung der Logik zur Audio-Initialisierung und -Steuerung, um die Benutzererfahrung zu verbessern.

Diese Anpassungen optimieren die Audio-Performance und die Interaktion im Taxi-Minispiel erheblich.
This commit is contained in:
Torsten Schulz (local)
2025-09-18 14:33:53 +02:00
parent 7207274ab5
commit f56e26a9b4

View File

@@ -247,6 +247,7 @@ export default {
audioContext: null,
audioUnlockHandler: null,
selectedStreetName: null
,motorStopTimeout: null
,houseNumbers: {}
}
},
@@ -488,7 +489,13 @@ export default {
if (this.audioContext) return; // Bereits initialisiert
try {
this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
// Übernehme ggf. global vorhandenen Context
if (window.__TaxiAudioContext) {
this.audioContext = window.__TaxiAudioContext;
} else {
this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
window.__TaxiAudioContext = this.audioContext;
}
if (import.meta.env?.DEV) console.log('[Audio] init: Context erstellt. state=', this.audioContext.state, 'rate=', this.audioContext.sampleRate);
// Autoplay-Policy: Context sofort im User-Gesture fortsetzen
if (this.audioContext.state === 'suspended') {
@@ -496,9 +503,17 @@ export default {
await this.audioContext.resume();
if (import.meta.env?.DEV) console.log('[Audio] init: state nach resume=', this.audioContext.state);
}
const generator = new NoiseGenerator();
this.motorSound = new MotorSound(this.audioContext, generator);
await this.motorSound.init();
if (!this.motorSound) {
// Ggf. globalen Motor übernehmen
if (window.__TaxiMotorSound) {
this.motorSound = window.__TaxiMotorSound;
} else {
const generator = new NoiseGenerator();
this.motorSound = new MotorSound(this.audioContext, generator);
await this.motorSound.init();
window.__TaxiMotorSound = this.motorSound;
}
}
if (import.meta.env?.DEV) console.log('[Audio] init: MotorSound initialisiert');
// Falls bereits Bewegung anliegt, Sound direkt starten
const speedKmh = this.taxi.speed * 5;
@@ -524,10 +539,25 @@ export default {
const isMoving = speedKmh > 0;
if (import.meta.env?.DEV) console.log('[Audio] update:', { speedKmh, isMoving, ctx: this.audioContext?.state, playing: this.motorSound.isPlaying });
// Start NICHT hier (kein User-Gesture). Nur Stop, wenn still.
if (!isMoving && this.motorSound.isPlaying) {
if (import.meta.env?.DEV) console.log('[Audio] update: motorSound.stop()');
this.motorSound.stop();
// Start NICHT hier (kein User-Gesture). Stop mit 1s Verzögerung, wenn still
if (!isMoving) {
if (this.motorStopTimeout == null && this.motorSound.isPlaying) {
this.motorStopTimeout = setTimeout(() => {
// Nur stoppen, wenn weiterhin keine Bewegung
const still = (this.taxi.speed * 5) <= 0;
if (still && this.motorSound && this.motorSound.isPlaying) {
if (import.meta.env?.DEV) console.log('[Audio] update: delayed motorSound.stop()');
this.motorSound.stop();
}
this.motorStopTimeout = null;
}, 500);
}
} else {
// Bewegung: ggf. geplanten Stopp abbrechen
if (this.motorStopTimeout) {
clearTimeout(this.motorStopTimeout);
this.motorStopTimeout = null;
}
}
if (isMoving) {
@@ -546,12 +576,12 @@ export default {
if (this.gameLoop) {
cancelAnimationFrame(this.gameLoop);
}
if (this.motorSound) {
this.motorSound.stop();
}
if (this.audioContext) {
this.audioContext.close();
if (this.motorSound) { this.motorSound.stop(); }
if (this.motorStopTimeout) {
clearTimeout(this.motorStopTimeout);
this.motorStopTimeout = null;
}
// AudioContext bleibt global erhalten, nicht schließen
document.removeEventListener('keydown', this.handleKeyDown);
document.removeEventListener('keyup', this.handleKeyUp);
if (this.audioUnlockHandler) {
@@ -1298,7 +1328,8 @@ export default {
ensureAudioUnlockedInEvent() {
// Muss synchron im Event-Handler laufen (ohne await), damit Policies greifen
if (!this.audioContext) {
this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
this.audioContext = window.__TaxiAudioContext || new (window.AudioContext || window.webkitAudioContext)();
window.__TaxiAudioContext = this.audioContext;
}
try {
if (this.audioContext.state === 'suspended') {
@@ -1308,10 +1339,14 @@ export default {
// ignore
}
if (!this.motorSound) {
const generator = new NoiseGenerator();
this.motorSound = new MotorSound(this.audioContext, generator);
// nicht awaiten, bleibt im gleichen Event-Frame
this.motorSound.init();
this.motorSound = window.__TaxiMotorSound;
if (!this.motorSound) {
const generator = new NoiseGenerator();
this.motorSound = new MotorSound(this.audioContext, generator);
// nicht awaiten, bleibt im gleichen Event-Frame
this.motorSound.init();
window.__TaxiMotorSound = this.motorSound;
}
}
},