Änderung: Verbesserung der Tile-Logik und Audio-Integration im Taxi-Spiel
Änderungen: - Implementierung einer Logik zum Wechseln zwischen benachbarten Tiles, wenn die Taxi-Position den Rand erreicht. - Einführung einer neuen Methode `ensureAudioUnlockedInEvent`, um den AudioContext synchron im Event-Handler zu aktivieren. - Anpassung der Audio-Initialisierung, um eine bessere Benutzerinteraktion zu gewährleisten. Diese Anpassungen verbessern die Spielmechanik und die Audio-Performance im Taxi-Minispiel erheblich.
This commit is contained in:
@@ -287,22 +287,52 @@ export default {
|
||||
},
|
||||
|
||||
updateCurrentTile() {
|
||||
// Berechne aktuelle Tile-Position basierend auf Taxi-Position
|
||||
if (this.currentMap && this.currentMap.mapData) {
|
||||
const mapData = this.currentMap.mapData;
|
||||
const rows = mapData.length;
|
||||
const cols = mapData[0] ? mapData[0].length : 0;
|
||||
|
||||
// Da das Taxi nur in einem 400x400px Canvas ist, verwende das erste Tile der Map
|
||||
// Das sollte das korrekte Tile sein, das in der Map definiert ist
|
||||
this.currentTile.row = 0;
|
||||
this.currentTile.col = 0;
|
||||
|
||||
|
||||
// Stelle sicher, dass Taxi innerhalb des Canvas bleibt
|
||||
this.taxi.x = Math.max(0, Math.min(this.canvas.width - this.taxi.width, this.taxi.x));
|
||||
this.taxi.y = Math.max(0, Math.min(this.canvas.height - this.taxi.height, this.taxi.y));
|
||||
// Wechsel auf benachbarte Tiles, sobald der Rand erreicht wird
|
||||
if (!this.currentMap || !this.currentMap.mapData) return;
|
||||
const mapData = this.currentMap.mapData;
|
||||
const rows = mapData.length;
|
||||
const cols = mapData[0] ? mapData[0].length : 0;
|
||||
const tileSize = this.tiles.size; // 500px
|
||||
|
||||
let newRow = this.currentTile.row;
|
||||
let newCol = this.currentTile.col;
|
||||
let moved = false;
|
||||
|
||||
// Nach rechts: sobald rechte Kante den Rand erreicht (>=)
|
||||
if (this.taxi.x + this.taxi.width >= tileSize && newCol < cols - 1) {
|
||||
this.taxi.x = 0; // direkt an linken Rand des neuen Tiles
|
||||
newCol += 1;
|
||||
moved = true;
|
||||
}
|
||||
// Nach links: sobald linke Kante den Rand erreicht (<= 0)
|
||||
if (!moved && this.taxi.x <= 0 && newCol > 0) {
|
||||
this.taxi.x = tileSize - this.taxi.width; // direkt an rechten Rand des neuen Tiles
|
||||
newCol -= 1;
|
||||
moved = true;
|
||||
}
|
||||
// Nach unten: sobald untere Kante den Rand erreicht (>=)
|
||||
if (!moved && this.taxi.y + this.taxi.height >= tileSize && newRow < rows - 1) {
|
||||
this.taxi.y = 0; // direkt an oberen Rand des neuen Tiles
|
||||
newRow += 1;
|
||||
moved = true;
|
||||
}
|
||||
// Nach oben: sobald obere Kante den Rand erreicht (<= 0)
|
||||
if (!moved && this.taxi.y <= 0 && newRow > 0) {
|
||||
this.taxi.y = tileSize - this.taxi.height; // direkt an unteren Rand des neuen Tiles
|
||||
newRow -= 1;
|
||||
moved = true;
|
||||
}
|
||||
|
||||
// Falls Wechsel möglich war, übernehme neue Tile-Position
|
||||
if (moved) {
|
||||
this.currentTile.row = newRow;
|
||||
this.currentTile.col = newCol;
|
||||
return;
|
||||
}
|
||||
|
||||
// An den äußeren Grenzen der Map: innerhalb des aktuellen Tiles halten
|
||||
this.taxi.x = Math.max(0, Math.min(tileSize - this.taxi.width, this.taxi.x));
|
||||
this.taxi.y = Math.max(0, Math.min(tileSize - this.taxi.height, this.taxi.y));
|
||||
},
|
||||
|
||||
setupEventListeners() {
|
||||
@@ -1007,10 +1037,10 @@ export default {
|
||||
async handleCanvasClick(event) {
|
||||
// AudioContext bei erster Benutzerinteraktion initialisieren
|
||||
if (import.meta.env?.DEV) console.log('[Audio] CanvasClick: start, hasCtx=', !!this.audioContext);
|
||||
await this.initAudioOnUserInteraction();
|
||||
this.ensureAudioUnlockedInEvent();
|
||||
if (this.audioContext && this.audioContext.state === 'suspended') {
|
||||
if (import.meta.env?.DEV) console.log('[Audio] CanvasClick: resume()');
|
||||
await this.audioContext.resume().catch(() => {});
|
||||
this.audioContext.resume().catch(() => {});
|
||||
if (import.meta.env?.DEV) console.log('[Audio] CanvasClick: state=', this.audioContext.state);
|
||||
}
|
||||
// Motor ggf. direkt starten (Klick ist User-Geste)
|
||||
@@ -1025,10 +1055,10 @@ export default {
|
||||
|
||||
// AudioContext bei erster Benutzerinteraktion initialisieren
|
||||
if (import.meta.env?.DEV) console.log('[Audio] KeyDown: key=', event.key, 'hasCtx=', !!this.audioContext);
|
||||
await this.initAudioOnUserInteraction();
|
||||
this.ensureAudioUnlockedInEvent();
|
||||
if (this.audioContext && this.audioContext.state === 'suspended') {
|
||||
if (import.meta.env?.DEV) console.log('[Audio] KeyDown: resume()');
|
||||
await this.audioContext.resume().catch(() => {});
|
||||
this.audioContext.resume().catch(() => {});
|
||||
}
|
||||
// Bei Beschleunigungs-Key Motor starten (User-Geste garantiert)
|
||||
if ((event.key === 'ArrowUp' || event.key === 'w' || event.key === 'W') && this.motorSound && !this.motorSound.isPlaying) {
|
||||
@@ -1045,6 +1075,26 @@ export default {
|
||||
|
||||
event.preventDefault();
|
||||
},
|
||||
|
||||
ensureAudioUnlockedInEvent() {
|
||||
// Muss synchron im Event-Handler laufen (ohne await), damit Policies greifen
|
||||
if (!this.audioContext) {
|
||||
this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
|
||||
}
|
||||
try {
|
||||
if (this.audioContext.state === 'suspended') {
|
||||
this.audioContext.resume();
|
||||
}
|
||||
} catch (e) {
|
||||
// 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();
|
||||
}
|
||||
},
|
||||
|
||||
handleKeyUp(event) {
|
||||
this.keys[event.key] = false;
|
||||
|
||||
Reference in New Issue
Block a user