Ä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.
144 lines
4.3 KiB
JavaScript
144 lines
4.3 KiB
JavaScript
import streetData from '../data/streetCoordinates.json';
|
|
|
|
class StreetCoordinates {
|
|
constructor() {
|
|
this.data = streetData;
|
|
}
|
|
|
|
/**
|
|
* Konvertiert relative Koordinaten (0-1) zu absoluten Koordinaten
|
|
* @param {number} relativeX - Relative X-Koordinate (0-1)
|
|
* @param {number} relativeY - Relative Y-Koordinate (0-1)
|
|
* @param {number} tileSize - Größe des Tiles in Pixeln
|
|
* @returns {Object} Absolute Koordinaten {x, y}
|
|
*/
|
|
toAbsolute(relativeX, relativeY, tileSize) {
|
|
return {
|
|
x: Math.round(relativeX * tileSize),
|
|
y: Math.round(relativeY * tileSize)
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Konvertiert absolute Koordinaten zu relativen Koordinaten (0-1)
|
|
* @param {number} absoluteX - Absolute X-Koordinate
|
|
* @param {number} absoluteY - Absolute Y-Koordinate
|
|
* @param {number} tileSize - Größe des Tiles in Pixeln
|
|
* @returns {Object} Relative Koordinaten {x, y}
|
|
*/
|
|
toRelative(absoluteX, absoluteY, tileSize) {
|
|
return {
|
|
x: absoluteX / tileSize,
|
|
y: absoluteY / tileSize
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Gibt die Straßenregionen für einen Tile-Typ zurück
|
|
* @param {string} tileType - Typ des Tiles (z.B. 'cornerBottomRight')
|
|
* @returns {Array} Array von Polygonen mit relativen Koordinaten (0-1)
|
|
*/
|
|
getDriveableRegions(tileType) {
|
|
const tile = this.data.tiles[tileType];
|
|
if (!tile) {
|
|
console.warn(`Tile type '${tileType}' not found`);
|
|
return [];
|
|
}
|
|
|
|
// Gib die relativen Koordinaten (0-1) direkt zurück
|
|
return tile.regions;
|
|
}
|
|
|
|
/**
|
|
* Prüft, ob ein Punkt innerhalb der fahrbaren Bereiche liegt
|
|
* @param {number} x - X-Koordinate des Punktes (relativ 0-1)
|
|
* @param {number} y - Y-Koordinate des Punktes (relativ 0-1)
|
|
* @param {string} tileType - Typ des Tiles
|
|
* @returns {boolean} True wenn der Punkt fahrbar ist
|
|
*/
|
|
isPointDriveable(x, y, tileType) {
|
|
const regions = this.getDriveableRegions(tileType);
|
|
|
|
for (const region of regions) {
|
|
if (this.isPointInPolygon(x, y, region)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Prüft, ob ein Punkt innerhalb eines Polygons liegt (Ray Casting Algorithm)
|
|
* @param {number} x - X-Koordinate des Punktes
|
|
* @param {number} y - Y-Koordinate des Punktes
|
|
* @param {Array} polygon - Array von {x, y} Punkten
|
|
* @returns {boolean} True wenn der Punkt im Polygon liegt
|
|
*/
|
|
isPointInPolygon(x, y, polygon) {
|
|
let inside = false;
|
|
for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
|
|
if (((polygon[i].y > y) !== (polygon[j].y > y)) &&
|
|
(x < (polygon[j].x - polygon[i].x) * (y - polygon[i].y) / (polygon[j].y - polygon[i].y) + polygon[i].x)) {
|
|
inside = !inside;
|
|
}
|
|
}
|
|
return inside;
|
|
}
|
|
|
|
/**
|
|
* Zeichnet die Straßenregionen auf einem Canvas
|
|
* @param {CanvasRenderingContext2D} ctx - Canvas 2D Context
|
|
* @param {string} tileType - Typ des Tiles
|
|
* @param {number} tileSize - Größe des Tiles in Pixeln
|
|
* @param {number} offsetX - X-Offset für das Tile
|
|
* @param {number} offsetY - Y-Offset für das Tile
|
|
*/
|
|
drawDriveableRegions(ctx, tileType, tileSize, offsetX = 0, offsetY = 0) {
|
|
const regions = this.getDriveableRegions(tileType);
|
|
|
|
ctx.fillStyle = '#f0f0f0'; // Straßenfarbe
|
|
ctx.strokeStyle = '#333';
|
|
ctx.lineWidth = 1;
|
|
|
|
for (const region of regions) {
|
|
ctx.beginPath();
|
|
// 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++) {
|
|
const x = region[i].x * tileSize + offsetX;
|
|
const y = region[i].y * tileSize + offsetY;
|
|
ctx.lineTo(x, y);
|
|
}
|
|
|
|
ctx.closePath();
|
|
ctx.fill();
|
|
ctx.stroke();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gibt alle verfügbaren Tile-Typen zurück
|
|
* @returns {Array} Array von Tile-Typen
|
|
*/
|
|
getAvailableTileTypes() {
|
|
return Object.keys(this.data.tiles);
|
|
}
|
|
|
|
/**
|
|
* Gibt die ursprüngliche Tile-Größe zurück
|
|
* @returns {number} Ursprüngliche Tile-Größe in Pixeln
|
|
*/
|
|
getOriginalTileSize() {
|
|
return this.data.tileSize;
|
|
}
|
|
}
|
|
|
|
// Singleton-Instanz
|
|
const streetCoordinates = new StreetCoordinates();
|
|
|
|
export default streetCoordinates;
|