Änderung: Verbesserung der Kollisionserkennung und Debugging-Ausgaben im Taxi-Spiel

Änderungen:
- Anpassung der Kollisionserkennung zur Verwendung eines lokalen Koordinatensystems für präzisere Berechnungen.
- Erweiterung der Debugging-Ausgaben, um absolute Koordinaten und relevante Informationen für Kollisionen anzuzeigen.
- Einführung einer neuen Methode zur Transformation von Punkten in das lokale Koordinatensystem des Rechtecks.

Diese Anpassungen erhöhen die Genauigkeit der Kollisionserkennung und verbessern die Nachverfolgbarkeit von Kollisionen im Spiel.
This commit is contained in:
Torsten Schulz (local)
2025-09-27 21:59:19 +02:00
parent ef8c9b51f3
commit 6c4842f710

View File

@@ -1999,30 +1999,34 @@ export default {
}));
// Verwende die robuste Kollisionserkennung für diese Region
const result = this.polylineIntersectsRotatedRect(regionPoints, rotatedRect, tileType === 'fuelhorizontal');
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 (relativ):', taxiRect);
console.log('Region Polylinie:', regionPoints);
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('---');
}
// 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 Tile - Debug-Informationen:');
console.log('Taxi Rect (relativ):', taxiRect);
console.log('Crash Region Polylinie:', regionPoints);
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
@@ -2083,73 +2087,86 @@ export default {
// Debug-Ausgabe nur wenn explizit angefordert
if (debug) {
console.log('🔧 polylineIntersectsRotatedRect DEBUG:');
console.log('🔧 polylineIntersectsRotatedRect DEBUG (KORRIGIERT):');
console.log('Polyline:', polyline);
console.log('Rect:', rect);
console.log('AABB bounds: x=[', cx - hx, ',', cx + hx, '], y=[', cy - hy, ',', cy + hy, ']');
console.log('Rotation theta:', theta, 'rad =', (theta * 180 / Math.PI), 'deg');
}
// Vereinfachte Kollisionserkennung: Prüfe ob irgendein Polyline-Punkt im Rechteck liegt
// oder ob irgendein Rechteck-Punkt auf der Polyline liegt
// KORREKTUR: Transformiere die Polyline in das lokale Koordinatensystem des Rechtecks
const localPolyline = polyline.map(p => this.transformToLocal(p.x, p.y, cx, cy, theta));
// 1. Prüfe ob Polyline-Punkte im Rechteck liegen
for (let i = 0; i < polyline.length; i++) {
const p = polyline[i];
const inX = p.x >= cx - hx && p.x <= cx + hx;
const inY = p.y >= cy - hy && p.y <= cy + hy;
if (debug) {
console.log(` Punkt ${i}: (${p.x}, ${p.y}) - In AABB: ${inX && inY}`);
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;
const AABB_minY = -hy;
const AABB_maxY = hy;
// 1. Prüfe, ob transformierte Polyline-Punkte in der AABB liegen
for (let i = 0; i < localPolyline.length; i++) {
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 Rechteck`);
console.log(`✅ Kollision: Polyline-Punkt ${i} liegt im rotierten Rechteck`);
}
return { hit: true, hits: [{ type: 'point_in_rect', pointIndex: i, point: p }] };
return { hit: true, type: 'point_in_rect' };
}
}
// 2. Prüfe ob Rechteck-Ecken auf der Polyline liegen
const rectCorners = [
{ x: cx - hx, y: cy - hy }, // links oben
{ x: cx + hx, y: cy - hy }, // rechts oben
{ x: cx + hx, y: cy + hy }, // rechts unten
{ x: cx - hx, y: cy + hy } // links unten
];
// 2. Prüfe auf Segment-Schnitt mit der AABB im lokalen System
for (let i = 0; i < localPolyline.length - 1; i++) {
const A = localPolyline[i];
const B = localPolyline[i + 1];
for (let cornerIndex = 0; cornerIndex < rectCorners.length; cornerIndex++) {
const corner = rectCorners[cornerIndex];
for (let i = 0; i < polyline.length - 1; i++) {
const A = polyline[i];
const B = polyline[i + 1];
// Prüfe ob Ecke auf Liniensegment liegt
if (this.isPointOnLineSegment(corner.x, corner.y, A.x, A.y, B.x, B.y)) {
if (this.lineSegmentIntersectsRect(A.x, A.y, B.x, B.y, AABB_minX, AABB_minY, AABB_maxX, AABB_maxY)) {
if (debug) {
console.log(`✅ Kollision: Rechteck-Ecke ${cornerIndex} liegt auf Polyline-Segment ${i}`);
}
return { hit: true, hits: [{ type: 'corner_on_line', cornerIndex, segmentIndex: i, corner, segment: { A, B } }] };
console.log(`✅ Kollision: Polyline-Segment ${i} schneidet rotiertes Rechteck`);
}
return { hit: true, type: 'segment_intersects_rect' };
}
}
// 3. Prüfe Liniensegment-Überschneidungen (vereinfacht)
for (let i = 0; i < polyline.length - 1; i++) {
const A = polyline[i];
const B = polyline[i + 1];
// Prüfe ob Liniensegment das Rechteck schneidet
if (this.lineSegmentIntersectsRect(A.x, A.y, B.x, B.y, cx - hx, cy - hy, cx + hx, cy + hy)) {
if (debug) {
console.log(`✅ Kollision: Polyline-Segment ${i} schneidet Rechteck`);
}
return { hit: true, hits: [{ type: 'segment_intersects_rect', segmentIndex: i, segment: { A, B } }] };
}
}
// 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, hits: [] };
return { hit: false };
},
/**
* Transformiert einen Punkt in das lokale, achsparallele Koordinatensystem des Rechtecks.
* @param {number} px - X-Koordinate des Punktes
* @param {number} py - Y-Koordinate des Punktes
* @param {number} cx - X-Koordinate des Rechteckmittelpunkts
* @param {number} cy - Y-Koordinate des Rechteckmittelpunkts
* @param {number} theta - Rotationswinkel des Rechtecks (in Radiant)
* @returns {Object} Transformierter Punkt {x, y} im lokalen Koordinatensystem
*/
transformToLocal(px, py, cx, cy, theta) {
// 1. Translation: Verschieben des Rechteckmittelpunkts in den Ursprung (0,0)
const tx = px - cx;
const ty = py - cy;
// 2. Rotation: Gegen-Rotation um -theta
const cos = Math.cos(-theta);
const sin = Math.sin(-theta);
const lx = tx * cos - ty * sin;
const ly = tx * sin + ty * cos;
return { x: lx, y: ly };
},
// Prüft ob ein Punkt auf einem Liniensegment liegt