Ä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:
@@ -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 {
|
||||||
|
// Übernehme ggf. global vorhandenen Context
|
||||||
|
if (window.__TaxiAudioContext) {
|
||||||
|
this.audioContext = window.__TaxiAudioContext;
|
||||||
|
} else {
|
||||||
this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
|
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);
|
||||||
}
|
}
|
||||||
|
if (!this.motorSound) {
|
||||||
|
// Ggf. globalen Motor übernehmen
|
||||||
|
if (window.__TaxiMotorSound) {
|
||||||
|
this.motorSound = window.__TaxiMotorSound;
|
||||||
|
} else {
|
||||||
const generator = new NoiseGenerator();
|
const generator = new NoiseGenerator();
|
||||||
this.motorSound = new MotorSound(this.audioContext, generator);
|
this.motorSound = new MotorSound(this.audioContext, generator);
|
||||||
await this.motorSound.init();
|
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,11 +539,26 @@ 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.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.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) {
|
||||||
// Geschwindigkeitsabhängige Tonhöhe und Lautstärke
|
// Geschwindigkeitsabhängige Tonhöhe und Lautstärke
|
||||||
@@ -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') {
|
||||||
@@ -1307,11 +1338,15 @@ export default {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
|
if (!this.motorSound) {
|
||||||
|
this.motorSound = window.__TaxiMotorSound;
|
||||||
if (!this.motorSound) {
|
if (!this.motorSound) {
|
||||||
const generator = new NoiseGenerator();
|
const generator = new NoiseGenerator();
|
||||||
this.motorSound = new MotorSound(this.audioContext, generator);
|
this.motorSound = new MotorSound(this.audioContext, generator);
|
||||||
// nicht awaiten, bleibt im gleichen Event-Frame
|
// nicht awaiten, bleibt im gleichen Event-Frame
|
||||||
this.motorSound.init();
|
this.motorSound.init();
|
||||||
|
window.__TaxiMotorSound = this.motorSound;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user