Änderung: Anpassung der Straßenkoordinaten und Optimierung der Kollisionserkennung im Taxi-Spiel

Änderungen:
- Entfernung der `tileSize` aus der JSON-Datei, um die Handhabung der Koordinaten zu vereinheitlichen.
- Anpassung der Methode `getDriveableRegions`, um relative Koordinaten (0-1) direkt zurückzugeben.
- Aktualisierung der Kollisionserkennung im Taxi-Spiel zur Verwendung von absoluten Pixel-Koordinaten anstelle von relativen.
- Verbesserung der Lesbarkeit und Wartbarkeit des Codes durch Bereinigung überflüssiger Konvertierungen.

Diese Anpassungen erhöhen die Effizienz der Kollisionserkennung und verbessern die Handhabung der Straßenkoordinaten im Spiel.
This commit is contained in:
Torsten Schulz (local)
2025-09-27 21:40:45 +02:00
parent 8ead029f45
commit ef8c9b51f3
3 changed files with 51 additions and 55 deletions

View File

@@ -1,5 +1,4 @@
{ {
"tileSize": 640,
"tiles": { "tiles": {
"cornerBottomRight": { "cornerBottomRight": {
"regions": [ "regions": [

View File

@@ -36,31 +36,28 @@ class StreetCoordinates {
/** /**
* Gibt die Straßenregionen für einen Tile-Typ zurück * Gibt die Straßenregionen für einen Tile-Typ zurück
* @param {string} tileType - Typ des Tiles (z.B. 'cornerBottomRight') * @param {string} tileType - Typ des Tiles (z.B. 'cornerBottomRight')
* @param {number} tileSize - Größe des Tiles in Pixeln * @returns {Array} Array von Polygonen mit relativen Koordinaten (0-1)
* @returns {Array} Array von Polygonen mit absoluten Koordinaten
*/ */
getDriveableRegions(tileType, tileSize) { getDriveableRegions(tileType) {
const tile = this.data.tiles[tileType]; const tile = this.data.tiles[tileType];
if (!tile) { if (!tile) {
console.warn(`Tile type '${tileType}' not found`); console.warn(`Tile type '${tileType}' not found`);
return []; return [];
} }
return tile.regions.map(region => // Gib die relativen Koordinaten (0-1) direkt zurück
region.map(point => this.toAbsolute(point.x, point.y, tileSize)) return tile.regions;
);
} }
/** /**
* Prüft, ob ein Punkt innerhalb der fahrbaren Bereiche liegt * Prüft, ob ein Punkt innerhalb der fahrbaren Bereiche liegt
* @param {number} x - X-Koordinate des Punktes * @param {number} x - X-Koordinate des Punktes (relativ 0-1)
* @param {number} y - Y-Koordinate des Punktes * @param {number} y - Y-Koordinate des Punktes (relativ 0-1)
* @param {string} tileType - Typ des Tiles * @param {string} tileType - Typ des Tiles
* @param {number} tileSize - Größe des Tiles in Pixeln
* @returns {boolean} True wenn der Punkt fahrbar ist * @returns {boolean} True wenn der Punkt fahrbar ist
*/ */
isPointDriveable(x, y, tileType, tileSize) { isPointDriveable(x, y, tileType) {
const regions = this.getDriveableRegions(tileType, tileSize); const regions = this.getDriveableRegions(tileType);
for (const region of regions) { for (const region of regions) {
if (this.isPointInPolygon(x, y, region)) { if (this.isPointInPolygon(x, y, region)) {
@@ -98,7 +95,7 @@ class StreetCoordinates {
* @param {number} offsetY - Y-Offset für das Tile * @param {number} offsetY - Y-Offset für das Tile
*/ */
drawDriveableRegions(ctx, tileType, tileSize, offsetX = 0, offsetY = 0) { drawDriveableRegions(ctx, tileType, tileSize, offsetX = 0, offsetY = 0) {
const regions = this.getDriveableRegions(tileType, tileSize); const regions = this.getDriveableRegions(tileType);
ctx.fillStyle = '#f0f0f0'; // Straßenfarbe ctx.fillStyle = '#f0f0f0'; // Straßenfarbe
ctx.strokeStyle = '#333'; ctx.strokeStyle = '#333';
@@ -106,10 +103,15 @@ class StreetCoordinates {
for (const region of regions) { for (const region of regions) {
ctx.beginPath(); ctx.beginPath();
ctx.moveTo(region[0].x + offsetX, region[0].y + offsetY); // Konvertiere relative Koordinaten zu absoluten für das Zeichnen
const startX = region[0].x * tileSize + offsetX;
const startY = region[0].y * tileSize + offsetY;
ctx.moveTo(startX, startY);
for (let i = 1; i < region.length; i++) { for (let i = 1; i < region.length; i++) {
ctx.lineTo(region[i].x + offsetX, region[i].y + offsetY); const x = region[i].x * tileSize + offsetX;
const y = region[i].y * tileSize + offsetY;
ctx.lineTo(x, y);
} }
ctx.closePath(); ctx.closePath();

View File

@@ -1959,7 +1959,7 @@ export default {
const originalTileSize = streetCoordinates.getOriginalTileSize(); // 640px const originalTileSize = streetCoordinates.getOriginalTileSize(); // 640px
const currentTileSize = 500; // Aktuelle Render-Größe const currentTileSize = 500; // Aktuelle Render-Größe
// Hole die relativen Koordinaten direkt aus der JSON (0-1) // Hole die relativen Koordinaten aus der JSON (0-1) und konvertiere zu absoluten Pixeln
const tileData = streetCoordinates.data.tiles[streetTileType]; const tileData = streetCoordinates.data.tiles[streetTileType];
const regions = tileData ? tileData.regions : []; const regions = tileData ? tileData.regions : [];
@@ -1968,17 +1968,17 @@ export default {
return true; return true;
} }
// Erstelle Taxi-Rechteck in relativen Koordinaten (0-1) // Erstelle Taxi-Rechteck in absoluten Pixel-Koordinaten (500x500px)
const taxiRect = { const taxiRect = {
x: this.taxi.x / currentTileSize, x: this.taxi.x,
y: this.taxi.y / currentTileSize, y: this.taxi.y,
width: this.taxi.width / currentTileSize, width: this.taxi.width,
height: this.taxi.height / currentTileSize height: this.taxi.height
}; };
// Alle Tiles verwenden die gleiche Logik: Prüfe ob Taxi eine der Hindernis-Polylinien schneidet // Alle Tiles verwenden die gleiche Logik: Prüfe ob Taxi eine der Hindernis-Polylinien schneidet
// Erstelle rotiertes Rechteck // Erstelle rotiertes Rechteck in absoluten Pixel-Koordinaten (500x500px)
const rotatedRect = { const rotatedRect = {
cx: taxiRect.x + taxiRect.width / 2, // Mittelpunkt X cx: taxiRect.x + taxiRect.width / 2, // Mittelpunkt X
cy: taxiRect.y + taxiRect.height / 2, // Mittelpunkt Y cy: taxiRect.y + taxiRect.height / 2, // Mittelpunkt Y
@@ -1992,11 +1992,10 @@ export default {
const region = regions[i]; const region = regions[i];
// Jede Region ist eine Polylinie mit mehreren Punkten // Jede Region ist eine Polylinie mit mehreren Punkten
if (region.length >= 2) { if (region.length >= 2) {
// Verwende die relativen Koordinaten direkt aus der JSON (0-1) // Konvertiere relative Koordinaten (0-1) zu absoluten Pixeln (500x500px)
// ohne die doppelte Konvertierung über getDriveableRegions
const regionPoints = region.map(point => ({ const regionPoints = region.map(point => ({
x: point.x, // Bereits relativ (0-1) aus der JSON x: point.x * currentTileSize, // Konvertiere von 0-1 zu 0-500px
y: point.y // Bereits relativ (0-1) aus der JSON y: point.y * currentTileSize // Konvertiere von 0-1 zu 0-500px
})); }));
// Verwende die robuste Kollisionserkennung für diese Region // Verwende die robuste Kollisionserkennung für diese Region
@@ -2038,47 +2037,43 @@ export default {
// Prüft ob eine Linie ein rotiertes Rechteck schneidet // Prüft ob eine Linie ein rotiertes Rechteck schneidet
isLineCrossingRect(rect, line) { isLineCrossingRect(rect, line) {
// Konvertiere Linien-Koordinaten von absoluten Pixeln zu relativen (0-1) // Verwende absolute Pixel-Koordinaten (500x500px)
const originalTileSize = 640; // Aus der JSON-Datei const currentTileSize = 500; // Aktuelle Render-Größe
const relativeLine = {
x1: line.x1 / originalTileSize, // Verwende Rechteck direkt in absoluten Koordinaten
y1: line.y1 / originalTileSize, const absoluteRect = {
x2: line.x2 / originalTileSize, x: rect.x,
y2: line.y2 / originalTileSize y: rect.y,
width: rect.width,
height: rect.height
}; };
// Debug-Ausgabe bei jeder Kollisionsprüfung // Konvertiere Linien-Koordinaten von 640px zu absoluten Pixeln (500x500px)
console.log('🔍 KOLLISIONS-DEBUG:'); const absoluteLine = {
console.log('Taxi Rect (relativ):', rect); x1: (line.x1 / 640) * currentTileSize,
console.log('Taxi Position (absolut):', { x: this.taxi.x, y: this.taxi.y, width: this.taxi.width, height: this.taxi.height }); y1: (line.y1 / 640) * currentTileSize,
console.log('Line (absolut aus JSON):', line); x2: (line.x2 / 640) * currentTileSize,
console.log('Line (relativ konvertiert):', relativeLine); y2: (line.y2 / 640) * currentTileSize
console.log('Original Tile Size (JSON):', originalTileSize); };
console.log('Current Tile Size:', this.tiles.size);
console.log('Taxi Angle:', this.taxi.angle);
console.log('Taxi ImageAngle:', this.taxi.imageAngle);
// Erstelle Polyline aus der Linie // Erstelle Polyline aus der absoluten Linie
const polyline = [ const polyline = [
{ x: relativeLine.x1, y: relativeLine.y1 }, { x: absoluteLine.x1, y: absoluteLine.y1 },
{ x: relativeLine.x2, y: relativeLine.y2 } { x: absoluteLine.x2, y: absoluteLine.y2 }
]; ];
// Erstelle rotiertes Rechteck // Erstelle rotiertes Rechteck in absoluten Koordinaten (500x500px)
const rotatedRect = { const rotatedRect = {
cx: rect.x + rect.width / 2, // Mittelpunkt X cx: absoluteRect.x + absoluteRect.width / 2, // Mittelpunkt X
cy: rect.y + rect.height / 2, // Mittelpunkt Y cy: absoluteRect.y + absoluteRect.height / 2, // Mittelpunkt Y
theta: this.taxi.imageAngle + this.taxi.angle, // Rotation theta: this.taxi.imageAngle + this.taxi.angle, // Rotation
hx: rect.width / 2, // halbe Breite hx: absoluteRect.width / 2, // halbe Breite
hy: rect.height / 2 // halbe Höhe hy: absoluteRect.height / 2 // halbe Höhe
}; };
// Verwende die robuste Kollisionserkennung // Verwende die robuste Kollisionserkennung
const result = this.polylineIntersectsRotatedRect(polyline, rotatedRect); const result = this.polylineIntersectsRotatedRect(polyline, rotatedRect);
// Debug-Ausgabe für Kollisionsergebnis (nur bei Fuel Horizontal Tiles)
// Diese Funktion wird nicht direkt für Fuel Tiles verwendet, daher keine Debug-Ausgabe hier
return result.hit; return result.hit;
}, },
@@ -3138,7 +3133,7 @@ export default {
if (!wantH && !wantV) return; if (!wantH && !wantV) return;
const streetTileType = this.mapTileTypeToStreetCoordinates(tileType); const streetTileType = this.mapTileTypeToStreetCoordinates(tileType);
const regions = streetCoordinates.getDriveableRegions(streetTileType, size); const regions = streetCoordinates.getDriveableRegions(streetTileType);
if (!regions || regions.length === 0) return; if (!regions || regions.length === 0) return;
// Banddicke exakt 12px (bei Referenz 50px) skaliert auf aktuelle size // Banddicke exakt 12px (bei Referenz 50px) skaliert auf aktuelle size