Änderung: Hinzufügen von Refuel-Logik und Verbesserung der Dialoginteraktion im Taxi-Spiel
Änderungen: - Implementierung der Logik für das Tanken, einschließlich Überprüfung der Bedingungen und Steuerung des Tankvorgangs. - Einführung von Event-Listener für die Enter-Taste zur Schließung des Dialogs. - Verbesserung der Crash-Logik bei leerem Tank und Anpassung der Kollisionserkennung. Diese Anpassungen erhöhen die Spielmechanik und Benutzerinteraktion, indem sie das Tanken und die Dialogsteuerung optimieren.
This commit is contained in:
@@ -67,14 +67,27 @@ export default {
|
||||
this.parameters = parameters;
|
||||
this.onClose = onClose;
|
||||
this.$refs.dialog.open();
|
||||
// Event Listener für Enter-Taste hinzufügen
|
||||
this.$nextTick(() => {
|
||||
document.addEventListener('keydown', this.handleKeyDown);
|
||||
});
|
||||
},
|
||||
close() {
|
||||
this.$refs.dialog.close();
|
||||
// Event Listener entfernen
|
||||
document.removeEventListener('keydown', this.handleKeyDown);
|
||||
// Rufe Callback auf, wenn vorhanden
|
||||
if (this.onClose && typeof this.onClose === 'function') {
|
||||
this.onClose();
|
||||
}
|
||||
},
|
||||
handleKeyDown(event) {
|
||||
// Schließe Dialog bei Enter-Taste
|
||||
if (event.key === 'Enter' || event.keyCode === 13) {
|
||||
event.preventDefault();
|
||||
this.close();
|
||||
}
|
||||
},
|
||||
interpolateParameters(text) {
|
||||
// Ersetze {key} Platzhalter mit den entsprechenden Werten
|
||||
let result = text;
|
||||
@@ -93,6 +106,10 @@ export default {
|
||||
console.log('Final result:', result);
|
||||
return result;
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
// Stelle sicher, dass Event Listener entfernt wird
|
||||
document.removeEventListener('keydown', this.handleKeyDown);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -246,6 +246,8 @@ export default {
|
||||
bonusMultiplier: 15, // Bonus pro Tile
|
||||
timePerTile: 8, // Sekunden pro Tile
|
||||
fuel: 100,
|
||||
isRefueling: false,
|
||||
refuelTimer: null,
|
||||
currentLevel: 1,
|
||||
gameRunning: false,
|
||||
crashes: 0,
|
||||
@@ -1054,6 +1056,82 @@ export default {
|
||||
});
|
||||
},
|
||||
|
||||
// Prüft, ob das Taxi im Tank-Bereich ist und stillsteht
|
||||
checkRefuelingConditions() {
|
||||
const tileType = this.getCurrentTileType();
|
||||
|
||||
// Nur auf Fuel-Tiles prüfen
|
||||
if (tileType !== 'fuelhorizontal' && tileType !== 'fuelvertical') {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Taxi muss stillstehen (Geschwindigkeit = 0)
|
||||
if (this.taxi.speed !== 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Prüfe Position im Tank-Bereich (absolute Koordinaten)
|
||||
if (tileType === 'fuelhorizontal') {
|
||||
// Y-Bereich zwischen 0.195 und 0.299 (relativ) = 97.5px und 149.5px (absolut)
|
||||
const minY = 0.195 * 500; // 97.5px
|
||||
const maxY = 0.299 * 500; // 149.5px
|
||||
return this.taxi.y >= minY && this.taxi.y <= maxY;
|
||||
} else if (tileType === 'fuelvertical') {
|
||||
// X-Bereich zwischen 0.701 und 0.805 (relativ) = 350.5px und 402.5px (absolut)
|
||||
const minX = 0.701 * 500; // 350.5px
|
||||
const maxX = 0.805 * 500; // 402.5px
|
||||
return this.taxi.x >= minX && this.taxi.x <= maxX;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
// Startet das Tanken
|
||||
startRefueling() {
|
||||
if (this.isRefueling || this.fuel >= 100) {
|
||||
return; // Bereits am Tanken oder Tank voll
|
||||
}
|
||||
|
||||
this.isRefueling = true;
|
||||
|
||||
// Tanken alle 0.1 Sekunden (100ms)
|
||||
this.refuelTimer = setInterval(() => {
|
||||
if (!this.checkRefuelingConditions()) {
|
||||
this.stopRefueling();
|
||||
return;
|
||||
}
|
||||
|
||||
// Tanke 0.1% pro 0.1 Sekunden
|
||||
this.fuel = Math.min(100, this.fuel + 0.1);
|
||||
|
||||
// Stoppe wenn Tank voll
|
||||
if (this.fuel >= 100) {
|
||||
this.stopRefueling();
|
||||
}
|
||||
}, 100);
|
||||
},
|
||||
|
||||
// Stoppt das Tanken
|
||||
stopRefueling() {
|
||||
if (this.refuelTimer) {
|
||||
clearInterval(this.refuelTimer);
|
||||
this.refuelTimer = null;
|
||||
}
|
||||
this.isRefueling = false;
|
||||
},
|
||||
|
||||
// Behandelt leeren Tank - Crash und Tank auffüllen
|
||||
handleEmptyTank() {
|
||||
// Stoppe das Tanken falls aktiv
|
||||
this.stopRefueling();
|
||||
|
||||
// Crash durch leeren Tank
|
||||
this.countCrash('emptytank');
|
||||
|
||||
// Zeige Crash-Dialog
|
||||
this.showCrashDialog('Leerer Tank! Der Tank wurde automatisch aufgefüllt.');
|
||||
},
|
||||
|
||||
removePassengerFromWaitingList() {
|
||||
if (this.waitingPassengersList.length > 0) {
|
||||
// Entferne den ersten Passagier aus der Liste
|
||||
@@ -1307,6 +1385,23 @@ export default {
|
||||
this.fuel = Math.max(0, this.fuel - 0.01);
|
||||
}
|
||||
|
||||
// Prüfe auf leeren Tank - Crash wenn Tank leer
|
||||
if (this.fuel <= 0) {
|
||||
this.handleEmptyTank();
|
||||
return; // Stoppe weitere Verarbeitung nach Crash
|
||||
}
|
||||
|
||||
// Prüfe Tanken-Bedingungen
|
||||
if (this.checkRefuelingConditions()) {
|
||||
if (!this.isRefueling) {
|
||||
this.startRefueling();
|
||||
}
|
||||
} else {
|
||||
if (this.isRefueling) {
|
||||
this.stopRefueling();
|
||||
}
|
||||
}
|
||||
|
||||
// Motorgeräusch aktualisieren
|
||||
this.updateMotorSound();
|
||||
},
|
||||
@@ -1733,8 +1828,7 @@ export default {
|
||||
this.redLightSincePenalty = (this.redLightSincePenalty || 0) + 1;
|
||||
if (this.redLightSincePenalty >= 3) {
|
||||
this.redLightSincePenalty = 0;
|
||||
this.crashes += 1;
|
||||
this.decrementVehicle('redlight');
|
||||
this.countCrash('redlight');
|
||||
const msg = 'Du hast wegen Rotlicht-Übertretungen ein Auto verloren.';
|
||||
const title = 'Hinweis';
|
||||
this.$root?.$refs?.messageDialog?.open?.(msg, title, {}, () => {
|
||||
@@ -1831,6 +1925,14 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
countCrash(reason = '') {
|
||||
this.crashes++;
|
||||
this.decrementVehicle(reason);
|
||||
this.taxi.speed = 0;
|
||||
this.isPaused = true; // Zuerst pausieren
|
||||
this.fuel = 100;
|
||||
},
|
||||
|
||||
handleCrash() {
|
||||
// Verhindere mehrfache Crashes in kurzer Zeit
|
||||
if (this.isPaused) {
|
||||
@@ -1839,9 +1941,7 @@ export default {
|
||||
}
|
||||
|
||||
console.log('🚨 CRASH ERKANNT!');
|
||||
this.crashes++;
|
||||
this.taxi.speed = 0;
|
||||
this.isPaused = true; // Zuerst pausieren
|
||||
this.countCrash('wall crashed');
|
||||
|
||||
// Motorgeräusch sofort stoppen
|
||||
if (this.motorSound && this.motorSound.isPlaying) {
|
||||
@@ -1862,7 +1962,6 @@ export default {
|
||||
|
||||
// Test: Direkter Aufruf nach 3 Sekunden (falls Dialog-Callback nicht funktioniert)
|
||||
this.crashDialogTimeout = setTimeout(() => {
|
||||
console.log('Test: Automatischer Reset nach 3 Sekunden');
|
||||
this.handleCrashDialogClose();
|
||||
}, 3000);
|
||||
console.log('Crash-Dialog wird angezeigt:', {
|
||||
@@ -1999,36 +2098,10 @@ export default {
|
||||
}));
|
||||
|
||||
// Verwende die robuste Kollisionserkennung für diese Region
|
||||
const result = this.polylineIntersectsRotatedRect(regionPoints, rotatedRect, tileType === 'fuelhorizontal', tileType === 'fuelhorizontal');
|
||||
|
||||
// Debug-Ausgabe nur für horizontale Fuel-Tiles
|
||||
if (tileType === 'fuelhorizontal') {
|
||||
console.log('🔍 KOLLISIONS-DEBUG (Fuel Horizontal):');
|
||||
console.log('Taxi Rect (absolut):', taxiRect);
|
||||
console.log('Region Polylinie (absolut):', regionPoints);
|
||||
console.log('Rotated Rect:', rotatedRect);
|
||||
console.log('Kollisionsergebnis:', result);
|
||||
console.log('Region (relativ aus JSON):', region);
|
||||
console.log('Taxi position:', this.taxi.x, this.taxi.y);
|
||||
console.log('Current tile size:', currentTileSize);
|
||||
console.log('Original tile size:', originalTileSize);
|
||||
console.log('---');
|
||||
}
|
||||
const result = this.polylineIntersectsRotatedRect(regionPoints, rotatedRect);
|
||||
|
||||
// Einheitliche Logik für alle Tiles: Taxi darf KEINE der Hindernis-Polylinien schneiden
|
||||
if (result.hit) {
|
||||
// Crash - zeige Debug-Informationen nur für Fuel Horizontal Tiles
|
||||
if (tileType === 'fuelhorizontal') {
|
||||
console.log('🚨 CRASH auf Fuel Horizontal Tile:');
|
||||
console.log('Taxi Rect (absolut):', taxiRect);
|
||||
console.log('Crash Region Polylinie (absolut):', regionPoints);
|
||||
console.log('Rotated Rect:', rotatedRect);
|
||||
console.log('Crash Hits:', result.hits);
|
||||
console.log('Region (relativ aus JSON):', region);
|
||||
console.log('Taxi position:', this.taxi.x, this.taxi.y);
|
||||
console.log('=== CRASH ENDE ===');
|
||||
}
|
||||
|
||||
return false; // Kollision mit Hindernis = Crash
|
||||
}
|
||||
}
|
||||
@@ -2082,25 +2155,12 @@ export default {
|
||||
},
|
||||
|
||||
// Testet, ob eine Polyline (Liste von Punkten) ein rotiertes Rechteck schneidet
|
||||
polylineIntersectsRotatedRect(polyline, rect, debug = false, eps = 1e-9) {
|
||||
polylineIntersectsRotatedRect(polyline, rect) {
|
||||
const { cx, cy, theta, hx, hy } = rect;
|
||||
|
||||
// Debug-Ausgabe nur wenn explizit angefordert
|
||||
if (debug) {
|
||||
console.log('🔧 polylineIntersectsRotatedRect DEBUG (KORRIGIERT):');
|
||||
console.log('Polyline:', polyline);
|
||||
console.log('Rect:', rect);
|
||||
console.log('Rotation theta:', theta, 'rad =', (theta * 180 / Math.PI), 'deg');
|
||||
}
|
||||
|
||||
// KORREKTUR: Transformiere die Polyline in das lokale Koordinatensystem des Rechtecks
|
||||
// Transformiere die Polyline in das lokale Koordinatensystem des Rechtecks
|
||||
const localPolyline = polyline.map(p => this.transformToLocal(p.x, p.y, cx, cy, theta));
|
||||
|
||||
if (debug) {
|
||||
console.log('Transformierte Polyline (lokal):', localPolyline);
|
||||
console.log('AABB bounds (lokal): x=[', -hx, ',', hx, '], y=[', -hy, ',', hy, ']');
|
||||
}
|
||||
|
||||
// AABB-Grenzen im lokalen Koordinatensystem
|
||||
const AABB_minX = -hx;
|
||||
const AABB_maxX = hx;
|
||||
@@ -2112,13 +2172,7 @@ export default {
|
||||
const p = localPolyline[i];
|
||||
const inX = p.x >= AABB_minX && p.x <= AABB_maxX;
|
||||
const inY = p.y >= AABB_minY && p.y <= AABB_maxY;
|
||||
if (debug) {
|
||||
console.log(` Punkt ${i}: (${p.x.toFixed(2)}, ${p.y.toFixed(2)}) - In AABB: ${inX && inY}`);
|
||||
}
|
||||
if (inX && inY) {
|
||||
if (debug) {
|
||||
console.log(`✅ Kollision: Polyline-Punkt ${i} liegt im rotierten Rechteck`);
|
||||
}
|
||||
return { hit: true, type: 'point_in_rect' };
|
||||
}
|
||||
}
|
||||
@@ -2129,19 +2183,10 @@ export default {
|
||||
const B = localPolyline[i + 1];
|
||||
|
||||
if (this.lineSegmentIntersectsRect(A.x, A.y, B.x, B.y, AABB_minX, AABB_minY, AABB_maxX, AABB_maxY)) {
|
||||
if (debug) {
|
||||
console.log(`✅ Kollision: Polyline-Segment ${i} schneidet rotiertes Rechteck`);
|
||||
}
|
||||
return { hit: true, type: 'segment_intersects_rect' };
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Prüfe ob das Rechteck vollständig innerhalb der Polyline liegt
|
||||
// (Nur für geschlossene Polygone relevant - hier überspringen wir das)
|
||||
|
||||
if (debug) {
|
||||
console.log(`❌ Keine Kollision gefunden`);
|
||||
}
|
||||
return { hit: false };
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user