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