Änderung: Verbesserung der Rotlichtüberprüfung und Debugging im Taxi-Spiel
Änderungen: - Einführung eines Flags `skipRedLightOneFrame`, um die Rotlichtprüfung beim ersten Tile-Wechsel auszusetzen und falsche Positives zu vermeiden. - Anpassung der Logik zur Überprüfung von Rotlichtverstößen, um die Bedingungen für die Verletzung präziser zu gestalten. - Erweiterung der Debugging-Ausgaben zur besseren Nachverfolgbarkeit von Rotlichtverstößen und Taxi-Bewegungen. Diese Anpassungen erhöhen die Genauigkeit der Rotlichtüberprüfung und verbessern die Debugging-Möglichkeiten im Spiel.
This commit is contained in:
@@ -309,6 +309,7 @@ export default {
|
||||
,houseNumbers: {}
|
||||
,prevTaxiX: 250
|
||||
,prevTaxiY: 250
|
||||
,skipRedLightOneFrame: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -489,6 +490,10 @@ export default {
|
||||
this.taxi.y = 250 - this.taxi.height/2; // Zentriert in der Mitte
|
||||
this.taxi.angle = 0; // Fahrtrichtung nach oben
|
||||
this.taxi.speed = 0; // Geschwindigkeit zurücksetzen
|
||||
// Vorherige Position und Skip-Flag setzen, damit erste Prüfung nicht triggert
|
||||
this.prevTaxiX = this.taxi.x;
|
||||
this.prevTaxiY = this.taxi.y;
|
||||
this.skipRedLightOneFrame = true;
|
||||
|
||||
// Aktuelle Tile-Position setzen
|
||||
this.currentTile.row = 0;
|
||||
@@ -551,6 +556,11 @@ export default {
|
||||
if (moved) {
|
||||
this.currentTile.row = newRow;
|
||||
this.currentTile.col = newCol;
|
||||
// Nach Tile-Wechsel: eine Frame lang Rotlicht-Prüfung aussetzen
|
||||
// und prev-Position auf aktuelle setzen, um false positives zu vermeiden
|
||||
this.prevTaxiX = this.taxi.x;
|
||||
this.prevTaxiY = this.taxi.y;
|
||||
this.skipRedLightOneFrame = true;
|
||||
// Radar mit 12% Wahrscheinlichkeit aktivieren beim Betreten des neuen Tiles
|
||||
this.activeRadar = Math.random() < 0.12;
|
||||
// Achse und Position festlegen: Messung findet bei 150px vom Rand statt
|
||||
@@ -1585,7 +1595,11 @@ export default {
|
||||
}
|
||||
// Rotlichtverstöße prüfen
|
||||
if (!this.isPaused) {
|
||||
this.checkRedLightViolation();
|
||||
if (!this.skipRedLightOneFrame) {
|
||||
this.checkRedLightViolation();
|
||||
}
|
||||
// Einmal-Flag nach der Prüfung zurücksetzen
|
||||
if (this.skipRedLightOneFrame) this.skipRedLightOneFrame = false;
|
||||
}
|
||||
|
||||
// Prüfe Hindernisse nur wenn das Spiel nicht pausiert ist
|
||||
@@ -1608,6 +1622,8 @@ export default {
|
||||
|
||||
const phase = this.getTrafficLightPhase(this.currentTile.col + (this.currentMap.offsetX||0), this.currentTile.row + (this.currentMap.offsetY||0));
|
||||
const rects = this.getVirtualStopLineRects(tileSize, approaches);
|
||||
// Kleine Toleranz für Segmenttreffer (dick=5px, daher +-4px ausreichend)
|
||||
const tol = 4;
|
||||
|
||||
// Einseitige Prüfung je Richtung und Phasen-Logik
|
||||
// Zu prüfende Ecken laut Vorgabe:
|
||||
@@ -1627,19 +1643,41 @@ export default {
|
||||
const vx = currCX - prevCX;
|
||||
const vy = currCY - prevCY;
|
||||
|
||||
// WICHTIG: Nur prüfen wenn das Taxi tatsächlich bewegt wurde (mindestens 1 Pixel)
|
||||
const movementThreshold = 1;
|
||||
if (Math.abs(vx) < movementThreshold && Math.abs(vy) < movementThreshold) {
|
||||
return; // Keine Bewegung, keine Verletzung möglich
|
||||
}
|
||||
// DEBUG: Umfassendes Logging
|
||||
console.log('=== ROTLICHT DEBUG ===');
|
||||
console.log('Tile:', this.currentTile.col, this.currentTile.row);
|
||||
console.log('TileType:', tileType);
|
||||
console.log('Approaches:', approaches);
|
||||
console.log('Phase:', phase, 'isHorRed:', isHorRed, 'isVerRed:', isVerRed);
|
||||
console.log('Taxi Position: prev(' + prevCX.toFixed(1) + ',' + prevCY.toFixed(1) + ') curr(' + currCX.toFixed(1) + ',' + currCY.toFixed(1) + ')');
|
||||
console.log('Movement: vx=' + vx.toFixed(1) + ', vy=' + vy.toFixed(1));
|
||||
console.log('StopLine Rects:', rects);
|
||||
|
||||
// Hinweis: Keine globale Bewegungsschwelle mehr.
|
||||
// Die Richtungsbedingungen (vy/vx > 0 bzw. < 0) in den jeweiligen Fällen
|
||||
// stellen bereits sicher, dass nur bei tatsächlicher Bewegung geprüft wird.
|
||||
|
||||
|
||||
// Top-Band: von oben nach unten (prev oben, curr unten), Eintritt über obere Bandkante y0
|
||||
if (rects.top && approaches.top) {
|
||||
const x0 = rects.top.x, x1 = rects.top.x + rects.top.width;
|
||||
const y0 = rects.top.y, y1 = rects.top.y + rects.top.height;
|
||||
const inX = (prevCX >= x0 && prevCX <= x1) || (currCX >= x0 && currCX <= x1);
|
||||
// Nur verletzen wenn das Taxi tatsächlich die Linie überquert (von außerhalb zu innerhalb)
|
||||
if (vy > 0 && inX && prevCY < y0 && currCY >= y0 && isVerRed) {
|
||||
// Für horizontale Haltelinien: Y-Position muss in der Nähe der Haltelinie sein
|
||||
const isNearStopLine = currCY >= (y0 - 50) && currCY <= (y1 + 50);
|
||||
// Zusätzlich: innerhalb des horizontalen Liniensegments (X-Span) sein
|
||||
const withinXSpan = (
|
||||
(prevCX >= x0 - tol && prevCX <= x1 + tol) ||
|
||||
(currCX >= x0 - tol && currCX <= x1 + tol) ||
|
||||
// oder Strecke zwischen prevCX und currCX schneidet [x0, x1]
|
||||
(Math.min(prevCX, currCX) <= x1 + tol && Math.max(prevCX, currCX) >= x0 - tol)
|
||||
);
|
||||
|
||||
console.log('TOP-Band: x0=' + x0 + ', x1=' + x1 + ', y0=' + y0 + ', y1=' + y1);
|
||||
console.log('TOP: vy=' + vy + ', prevCY=' + prevCY.toFixed(1) + ', currCY=' + currCY.toFixed(1) + ', isVerRed=' + isVerRed + ', isNearStopLine=' + isNearStopLine + ', withinXSpan=' + withinXSpan);
|
||||
console.log('TOP: prevCY < y0 =', prevCY < y0, ', currCY >= y0 =', currCY >= y0);
|
||||
|
||||
if (vy > 0 && prevCY < y0 && currCY >= y0 && isVerRed && isNearStopLine && withinXSpan) {
|
||||
console.log('🚨 TOP-Band VIOLATION!');
|
||||
violated = true;
|
||||
}
|
||||
}
|
||||
@@ -1647,9 +1685,21 @@ export default {
|
||||
if (rects.bottom && approaches.bottom) {
|
||||
const x0 = rects.bottom.x, x1 = rects.bottom.x + rects.bottom.width;
|
||||
const y0 = rects.bottom.y, y1 = rects.bottom.y + rects.bottom.height;
|
||||
const inX = (prevCX >= x0 && prevCX <= x1) || (currCX >= x0 && currCX <= x1);
|
||||
// Nur verletzen wenn das Taxi tatsächlich die Linie überquert (von außerhalb zu innerhalb)
|
||||
if (vy < 0 && inX && prevCY > y1 && currCY <= y1 && isVerRed) {
|
||||
// Für horizontale Haltelinien: Y-Position muss in der Nähe der Haltelinie sein
|
||||
const isNearStopLine = currCY >= (y0 - 50) && currCY <= (y1 + 50);
|
||||
// Zusätzlich: innerhalb des horizontalen Liniensegments (X-Span) sein
|
||||
const withinXSpan = (
|
||||
(prevCX >= x0 - tol && prevCX <= x1 + tol) ||
|
||||
(currCX >= x0 - tol && currCX <= x1 + tol) ||
|
||||
(Math.min(prevCX, currCX) <= x1 + tol && Math.max(prevCX, currCX) >= x0 - tol)
|
||||
);
|
||||
|
||||
console.log('BOTTOM-Band: x0=' + x0 + ', x1=' + x1 + ', y0=' + y0 + ', y1=' + y1);
|
||||
console.log('BOTTOM: vy=' + vy + ', prevCY=' + prevCY.toFixed(1) + ', currCY=' + currCY.toFixed(1) + ', isVerRed=' + isVerRed + ', isNearStopLine=' + isNearStopLine + ', withinXSpan=' + withinXSpan);
|
||||
console.log('BOTTOM: prevCY > y1 =', prevCY > y1, ', currCY <= y1 =', currCY <= y1);
|
||||
|
||||
if (vy < 0 && prevCY > y1 && currCY <= y1 && isVerRed && isNearStopLine && withinXSpan) {
|
||||
console.log('🚨 BOTTOM-Band VIOLATION!');
|
||||
violated = true;
|
||||
}
|
||||
}
|
||||
@@ -1657,9 +1707,21 @@ export default {
|
||||
if (rects.left && approaches.left) {
|
||||
const x0 = rects.left.x, x1 = rects.left.x + rects.left.width;
|
||||
const y0 = rects.left.y, y1 = rects.left.y + rects.left.height;
|
||||
const inY = (prevCY >= y0 && prevCY <= y1) || (currCY >= y0 && currCY <= y1);
|
||||
// Nur verletzen wenn das Taxi tatsächlich die Linie überquert (von außerhalb zu innerhalb)
|
||||
if (vx > 0 && inY && prevCX < x0 && currCX >= x0 && isHorRed) {
|
||||
// Für vertikale Haltelinien: X-Position muss in der Nähe der Haltelinie sein
|
||||
const isNearStopLine = currCX >= (x0 - 50) && currCX <= (x1 + 50);
|
||||
// Zusätzlich: innerhalb des vertikalen Liniensegments (Y-Span) sein
|
||||
const withinYSpan = (
|
||||
(prevCY >= y0 - tol && prevCY <= y1 + tol) ||
|
||||
(currCY >= y0 - tol && currCY <= y1 + tol) ||
|
||||
(Math.min(prevCY, currCY) <= y1 + tol && Math.max(prevCY, currCY) >= y0 - tol)
|
||||
);
|
||||
|
||||
console.log('LEFT-Band: x0=' + x0 + ', x1=' + x1 + ', y0=' + y0 + ', y1=' + y1);
|
||||
console.log('LEFT: vx=' + vx + ', prevCX=' + prevCX.toFixed(1) + ', currCX=' + currCX.toFixed(1) + ', isHorRed=' + isHorRed + ', isNearStopLine=' + isNearStopLine + ', withinYSpan=' + withinYSpan);
|
||||
console.log('LEFT: prevCX < x0 =', prevCX < x0, ', currCX >= x0 =', currCX >= x0);
|
||||
|
||||
if (vx > 0 && prevCX < x0 && currCX >= x0 && isHorRed && isNearStopLine && withinYSpan) {
|
||||
console.log('🚨 LEFT-Band VIOLATION!');
|
||||
violated = true;
|
||||
}
|
||||
}
|
||||
@@ -1667,19 +1729,37 @@ export default {
|
||||
if (rects.right && approaches.right) {
|
||||
const x0 = rects.right.x, x1 = rects.right.x + rects.right.width;
|
||||
const y0 = rects.right.y, y1 = rects.right.y + rects.right.height;
|
||||
const inY = (prevCY >= y0 && prevCY <= y1) || (currCY >= y0 && currCY <= y1);
|
||||
// Nur verletzen wenn das Taxi tatsächlich die Linie überquert (von außerhalb zu innerhalb)
|
||||
if (vx < 0 && inY && prevCX > x1 && currCX <= x1 && isHorRed) {
|
||||
// Für vertikale Haltelinien: X-Position muss in der Nähe der Haltelinie sein
|
||||
const isNearStopLine = currCX >= (x0 - 50) && currCX <= (x1 + 50);
|
||||
// Zusätzlich: innerhalb des vertikalen Liniensegments (Y-Span) sein
|
||||
const withinYSpan = (
|
||||
(prevCY >= y0 - tol && prevCY <= y1 + tol) ||
|
||||
(currCY >= y0 - tol && currCY <= y1 + tol) ||
|
||||
(Math.min(prevCY, currCY) <= y1 + tol && Math.max(prevCY, currCY) >= y0 - tol)
|
||||
);
|
||||
|
||||
console.log('RIGHT-Band: x0=' + x0 + ', x1=' + x1 + ', y0=' + y0 + ', y1=' + y1);
|
||||
console.log('RIGHT: vx=' + vx + ', prevCX=' + prevCX.toFixed(1) + ', currCX=' + currCX.toFixed(1) + ', isHorRed=' + isHorRed + ', isNearStopLine=' + isNearStopLine + ', withinYSpan=' + withinYSpan);
|
||||
console.log('RIGHT: prevCX < x0 =', prevCX < x0, ', currCX >= x0 =', currCX >= x0);
|
||||
|
||||
if (vx < 0 && prevCX > x1 && currCX <= x1 && isHorRed && isNearStopLine && withinYSpan) {
|
||||
console.log('🚨 RIGHT-Band VIOLATION!');
|
||||
violated = true;
|
||||
}
|
||||
}
|
||||
|
||||
console.log('=== FINAL RESULT ===');
|
||||
console.log('Violated:', violated);
|
||||
|
||||
if (violated) {
|
||||
// Entprellen: pro Tile nur einmal pro tatsächlichem Übertritt zählen
|
||||
const key = `${this.currentTile.col},${this.currentTile.row}`;
|
||||
const now = Date.now();
|
||||
const last = this.redLightLastCount[key] || 0;
|
||||
console.log('Violation detected! Key:', key, 'Last:', last, 'Now:', now, 'Diff:', now - last);
|
||||
|
||||
if (now - last > 500) { // 0.5s Sperrzeit
|
||||
console.log('✅ VIOLATION REGISTERED! Count:', this.redLightViolations + 1);
|
||||
this.redLightLastCount[key] = now;
|
||||
this.redLightViolations += 1;
|
||||
this.playRedLightSound();
|
||||
@@ -1697,8 +1777,12 @@ export default {
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
console.log('❌ VIOLATION IGNORED (too soon)');
|
||||
}
|
||||
}
|
||||
|
||||
console.log('=== END ROTLICHT DEBUG ===');
|
||||
},
|
||||
|
||||
checkRadarMeasurement() {
|
||||
@@ -1892,6 +1976,10 @@ export default {
|
||||
this.taxi.y = 250 - this.taxi.height/2; // Mitte des Canvas (500px / 2)
|
||||
this.taxi.speed = 0;
|
||||
this.taxi.angle = 0;
|
||||
// Prev-Position synchronisieren und erste Prüfung aussetzen
|
||||
this.prevTaxiX = this.taxi.x;
|
||||
this.prevTaxiY = this.taxi.y;
|
||||
this.skipRedLightOneFrame = true;
|
||||
},
|
||||
|
||||
isTaxiOnRoad() {
|
||||
@@ -2360,41 +2448,45 @@ export default {
|
||||
);
|
||||
},
|
||||
|
||||
// Haltelinien: 120px vom Rand, 5px dick, 40px breit, an allen vier Zufahrten
|
||||
// Haltelinien: Basierend auf den korrigierten Koordinaten
|
||||
drawStopLinesOnMainCanvas(ctx, size, approaches = { top:true, right:true, bottom:true, left:true }) {
|
||||
const margin = 120; // Basis-Abstand vom Rand
|
||||
const extra = 30; // 10px zurück (von +40 auf +30)
|
||||
const m = margin + extra;
|
||||
const thickness = 5;
|
||||
const width = 60; // +20px breiter (vorher 40)
|
||||
ctx.save();
|
||||
ctx.fillStyle = '#ffffff';
|
||||
// Oben (horizontale Linie, zentriert)
|
||||
if (approaches.top) ctx.fillRect((size - width) / 2 - 30, m - thickness, width, thickness);
|
||||
// Unten
|
||||
if (approaches.bottom) ctx.fillRect((size - width) / 2 + 30, size - m, width, thickness);
|
||||
// Links (vertikale Linie, zentriert)
|
||||
if (approaches.left) ctx.fillRect(m - thickness, (size - width) / 2 + 30, thickness, width);
|
||||
// Rechts
|
||||
if (approaches.right) ctx.fillRect(size - m, (size - width) / 2 - 30, thickness, width);
|
||||
|
||||
// Basierend auf den korrigierten Koordinaten:
|
||||
// Links: sichtbar: 145/294 - 150/313
|
||||
if (approaches.left) ctx.fillRect(145, 294, thickness, 19);
|
||||
|
||||
// Rechts: sichtbar: 150/186 - 355/293
|
||||
if (approaches.right) ctx.fillRect(350, 186, thickness, 107);
|
||||
|
||||
// Unten: sichtbar: 250/360 - 312/365
|
||||
if (approaches.bottom) ctx.fillRect(250, 360, 62, thickness);
|
||||
|
||||
// Oben: berechnet aus den anderen Angaben (symmetrisch zu unten)
|
||||
if (approaches.top) ctx.fillRect(250, 5, 62, thickness);
|
||||
|
||||
ctx.restore();
|
||||
},
|
||||
// Liefert die virtuellen (breit verdoppelten) Haltelinienrechtecke pro Seite, ohne zu zeichnen
|
||||
getVirtualStopLineRects(size, approaches = { top:true, right:true, bottom:true, left:true }) {
|
||||
const margin = 120;
|
||||
const extra = 30;
|
||||
const m = margin + extra;
|
||||
const thickness = 5 * 2; // doppelte Breite für Erkennung
|
||||
const width = 60; // Länge der Linie unverändert
|
||||
const rects = {};
|
||||
// Oben
|
||||
if (approaches.top) rects.top = { x: (size - width) / 2 - 30, y: m - thickness, width: width, height: thickness };
|
||||
// Unten
|
||||
if (approaches.bottom) rects.bottom = { x: (size - width) / 2 + 30, y: size - m, width: width, height: thickness };
|
||||
// Links
|
||||
if (approaches.left) rects.left = { x: m - thickness, y: (size - width) / 2 + 30, width: thickness, height: width };
|
||||
// Rechts
|
||||
if (approaches.right) rects.right = { x: size - m, y: (size - width) / 2 - 30, width: thickness, height: width };
|
||||
|
||||
// Basierend auf den korrigierten Koordinaten:
|
||||
// Links: virtuell: 145/186 - 150/313; sichtbar: 145/294 - 150/313
|
||||
if (approaches.left) rects.left = { x: 145, y: 186, width: thickness, height: 127 };
|
||||
|
||||
// Rechts: virtuell: 350/186 - 355/313; sichtbar: 150/186 - 355/293
|
||||
if (approaches.right) rects.right = { x: 350, y: 186, width: thickness, height: 127 };
|
||||
|
||||
// Unten: virtuell: 187/360- 312/365; sichtbar: 250/360 - 312/365
|
||||
if (approaches.bottom) rects.bottom = { x: 187, y: 360, width: 125, height: thickness };
|
||||
|
||||
// Oben: berechnet aus den anderen Angaben (symmetrisch zu unten)
|
||||
if (approaches.top) rects.top = { x: 187, y: 5, width: 125, height: thickness };
|
||||
|
||||
return rects;
|
||||
},
|
||||
// Liefert, von welchen Seiten eine Straße an dieses Tile anbindet
|
||||
|
||||
Reference in New Issue
Block a user