Änderung: Hinzufügung des Taxi-Minispiels und zugehöriger Funktionen
Änderungen: - Integration des Taxi-Minispiels mit neuen Routen und Komponenten im Backend und Frontend. - Erstellung von Modellen und Datenbank-Schemas für das Taxi-Spiel, einschließlich TaxiGameState, TaxiLevelStats und TaxiMap. - Erweiterung der Navigationsstruktur und der Benutzeroberfläche, um das Taxi-Spiel und die zugehörigen Tools zu unterstützen. - Aktualisierung der Übersetzungen für das Taxi-Minispiel in Deutsch und Englisch. Diese Anpassungen erweitern die Funktionalität der Anwendung um ein neues Minispiel und verbessern die Benutzererfahrung durch neue Features und Inhalte.
This commit is contained in:
141
frontend/src/utils/streetCoordinates.js
Normal file
141
frontend/src/utils/streetCoordinates.js
Normal file
@@ -0,0 +1,141 @@
|
||||
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')
|
||||
* @param {number} tileSize - Größe des Tiles in Pixeln
|
||||
* @returns {Array} Array von Polygonen mit absoluten Koordinaten
|
||||
*/
|
||||
getDriveableRegions(tileType, tileSize) {
|
||||
const tile = this.data.tiles[tileType];
|
||||
if (!tile) {
|
||||
console.warn(`Tile type '${tileType}' not found`);
|
||||
return [];
|
||||
}
|
||||
|
||||
return tile.regions.map(region =>
|
||||
region.map(point => this.toAbsolute(point.x, point.y, tileSize))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prüft, ob ein Punkt innerhalb der fahrbaren Bereiche liegt
|
||||
* @param {number} x - X-Koordinate des Punktes
|
||||
* @param {number} y - Y-Koordinate des Punktes
|
||||
* @param {string} tileType - Typ des Tiles
|
||||
* @param {number} tileSize - Größe des Tiles in Pixeln
|
||||
* @returns {boolean} True wenn der Punkt fahrbar ist
|
||||
*/
|
||||
isPointDriveable(x, y, tileType, tileSize) {
|
||||
const regions = this.getDriveableRegions(tileType, tileSize);
|
||||
|
||||
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, tileSize);
|
||||
|
||||
ctx.fillStyle = '#f0f0f0'; // Straßenfarbe
|
||||
ctx.strokeStyle = '#333';
|
||||
ctx.lineWidth = 1;
|
||||
|
||||
for (const region of regions) {
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(region[0].x + offsetX, region[0].y + offsetY);
|
||||
|
||||
for (let i = 1; i < region.length; i++) {
|
||||
ctx.lineTo(region[i].x + offsetX, region[i].y + offsetY);
|
||||
}
|
||||
|
||||
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;
|
||||
Reference in New Issue
Block a user