Ä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:
Torsten Schulz (local)
2025-09-27 22:34:31 +02:00
parent 6c4842f710
commit 75d7ac6222
2 changed files with 125 additions and 63 deletions

View File

@@ -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,24 +2155,11 @@ 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;
@@ -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 };
},