Ä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() {
|
updateCurrentTile() {
|
||||||
// Berechne aktuelle Tile-Position basierend auf Taxi-Position
|
// Wechsel auf benachbarte Tiles, sobald der Rand erreicht wird
|
||||||
if (this.currentMap && this.currentMap.mapData) {
|
if (!this.currentMap || !this.currentMap.mapData) return;
|
||||||
const mapData = this.currentMap.mapData;
|
const mapData = this.currentMap.mapData;
|
||||||
const rows = mapData.length;
|
const rows = mapData.length;
|
||||||
const cols = mapData[0] ? mapData[0].length : 0;
|
const cols = mapData[0] ? mapData[0].length : 0;
|
||||||
|
const tileSize = this.tiles.size; // 500px
|
||||||
|
|
||||||
// Da das Taxi nur in einem 400x400px Canvas ist, verwende das erste Tile der Map
|
let newRow = this.currentTile.row;
|
||||||
// Das sollte das korrekte Tile sein, das in der Map definiert ist
|
let newCol = this.currentTile.col;
|
||||||
this.currentTile.row = 0;
|
let moved = false;
|
||||||
this.currentTile.col = 0;
|
|
||||||
|
|
||||||
|
// Nach rechts: sobald rechte Kante den Rand erreicht (>=)
|
||||||
// Stelle sicher, dass Taxi innerhalb des Canvas bleibt
|
if (this.taxi.x + this.taxi.width >= tileSize && newCol < cols - 1) {
|
||||||
this.taxi.x = Math.max(0, Math.min(this.canvas.width - this.taxi.width, this.taxi.x));
|
this.taxi.x = 0; // direkt an linken Rand des neuen Tiles
|
||||||
this.taxi.y = Math.max(0, Math.min(this.canvas.height - this.taxi.height, this.taxi.y));
|
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() {
|
setupEventListeners() {
|
||||||
@@ -1007,10 +1037,10 @@ export default {
|
|||||||
async handleCanvasClick(event) {
|
async handleCanvasClick(event) {
|
||||||
// AudioContext bei erster Benutzerinteraktion initialisieren
|
// AudioContext bei erster Benutzerinteraktion initialisieren
|
||||||
if (import.meta.env?.DEV) console.log('[Audio] CanvasClick: start, hasCtx=', !!this.audioContext);
|
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 (this.audioContext && this.audioContext.state === 'suspended') {
|
||||||
if (import.meta.env?.DEV) console.log('[Audio] CanvasClick: resume()');
|
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);
|
if (import.meta.env?.DEV) console.log('[Audio] CanvasClick: state=', this.audioContext.state);
|
||||||
}
|
}
|
||||||
// Motor ggf. direkt starten (Klick ist User-Geste)
|
// Motor ggf. direkt starten (Klick ist User-Geste)
|
||||||
@@ -1025,10 +1055,10 @@ export default {
|
|||||||
|
|
||||||
// AudioContext bei erster Benutzerinteraktion initialisieren
|
// AudioContext bei erster Benutzerinteraktion initialisieren
|
||||||
if (import.meta.env?.DEV) console.log('[Audio] KeyDown: key=', event.key, 'hasCtx=', !!this.audioContext);
|
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 (this.audioContext && this.audioContext.state === 'suspended') {
|
||||||
if (import.meta.env?.DEV) console.log('[Audio] KeyDown: resume()');
|
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)
|
// Bei Beschleunigungs-Key Motor starten (User-Geste garantiert)
|
||||||
if ((event.key === 'ArrowUp' || event.key === 'w' || event.key === 'W') && this.motorSound && !this.motorSound.isPlaying) {
|
if ((event.key === 'ArrowUp' || event.key === 'w' || event.key === 'W') && this.motorSound && !this.motorSound.isPlaying) {
|
||||||
@@ -1046,6 +1076,26 @@ export default {
|
|||||||
event.preventDefault();
|
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) {
|
handleKeyUp(event) {
|
||||||
this.keys[event.key] = false;
|
this.keys[event.key] = false;
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user