Änderung: Erweiterung der TaxiGame.vue und Aktualisierung des Taxi-SVG
Änderungen: - Hinzufügung eines Kartenwählers zur Auswahl von Maps im Taxi-Spiel. - Anpassung der Taxi-Parameter für eine verbesserte Darstellung und Positionierung. - Implementierung von Methoden zum Laden von Taxi-Bildern und Maps aus der Datenbank. - Aktualisierung des SVG-Bildes des Taxis mit neuen Pfaden und Farben. Diese Anpassungen verbessern die Benutzeroberfläche und die Funktionalität des Taxi-Minispiels, indem sie eine dynamische Kartenwahl ermöglichen und die grafische Darstellung optimieren.
This commit is contained in:
182
frontend/public/images/taxi/car1.svg
Normal file
182
frontend/public/images/taxi/car1.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 97 KiB |
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 179 KiB |
@@ -137,6 +137,17 @@
|
|||||||
<div class="minimap-card">
|
<div class="minimap-card">
|
||||||
<div class="minimap-header">
|
<div class="minimap-header">
|
||||||
<h3 class="minimap-title">Minimap</h3>
|
<h3 class="minimap-title">Minimap</h3>
|
||||||
|
<div class="map-selector">
|
||||||
|
<select v-model="selectedMapId" @change="onMapChange" class="map-select">
|
||||||
|
<option
|
||||||
|
v-for="map in maps"
|
||||||
|
:key="map.id"
|
||||||
|
:value="map.id"
|
||||||
|
>
|
||||||
|
{{ map.name }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="minimap-container">
|
<div class="minimap-container">
|
||||||
<canvas
|
<canvas
|
||||||
@@ -176,21 +187,29 @@ export default {
|
|||||||
minimapCtx: null,
|
minimapCtx: null,
|
||||||
isStatsExpanded: true,
|
isStatsExpanded: true,
|
||||||
taxi: {
|
taxi: {
|
||||||
x: 200,
|
x: 200, // Mitte des 400x400px Tiles
|
||||||
y: 200,
|
y: 200, // Mitte des 400x400px Tiles
|
||||||
width: 20,
|
width: 30, // Skalierte Breite (50px Höhe * 297/506)
|
||||||
height: 15,
|
height: 50, // 50px Höhe
|
||||||
angle: 0,
|
angle: 0, // Fahrtrichtung
|
||||||
|
imageAngle: Math.PI / 2, // Bildrotation (90° nach rechts)
|
||||||
speed: 0,
|
speed: 0,
|
||||||
maxSpeed: 3
|
maxSpeed: 3,
|
||||||
|
image: null // Taxi-Bild
|
||||||
|
},
|
||||||
|
currentTile: {
|
||||||
|
row: 0,
|
||||||
|
col: 0
|
||||||
},
|
},
|
||||||
tiles: {
|
tiles: {
|
||||||
size: 50, // 400px / 8 tiles = 50px per tile
|
size: 400, // 400x400px pro Tile
|
||||||
images: {}
|
images: {}
|
||||||
},
|
},
|
||||||
|
maps: [], // Geladene Maps aus der Datenbank
|
||||||
|
currentMap: null, // Aktuell verwendete Map
|
||||||
|
selectedMapId: null, // ID der ausgewählten Map
|
||||||
passengers: [],
|
passengers: [],
|
||||||
destinations: [],
|
destinations: [],
|
||||||
gasStations: [],
|
|
||||||
obstacles: [],
|
obstacles: [],
|
||||||
keys: {}
|
keys: {}
|
||||||
}
|
}
|
||||||
@@ -199,6 +218,8 @@ export default {
|
|||||||
this.initializeGame();
|
this.initializeGame();
|
||||||
this.initializeMinimap();
|
this.initializeMinimap();
|
||||||
this.loadTiles();
|
this.loadTiles();
|
||||||
|
this.loadTaxiImage();
|
||||||
|
this.loadMaps();
|
||||||
this.setupEventListeners();
|
this.setupEventListeners();
|
||||||
},
|
},
|
||||||
beforeUnmount() {
|
beforeUnmount() {
|
||||||
@@ -209,10 +230,48 @@ export default {
|
|||||||
this.canvas = this.$refs.gameCanvas;
|
this.canvas = this.$refs.gameCanvas;
|
||||||
this.ctx = this.canvas.getContext('2d');
|
this.ctx = this.canvas.getContext('2d');
|
||||||
this.canvas.focus();
|
this.canvas.focus();
|
||||||
|
|
||||||
|
// Taxi in die Mitte des 400x400px Tiles positionieren
|
||||||
|
this.taxi.x = 200 - this.taxi.width/2; // Zentriert in der Mitte
|
||||||
|
this.taxi.y = 200 - this.taxi.height/2; // Zentriert in der Mitte
|
||||||
|
this.taxi.angle = 0; // Fahrtrichtung nach oben
|
||||||
|
this.taxi.speed = 0; // Geschwindigkeit zurücksetzen
|
||||||
|
|
||||||
|
// Aktuelle Tile-Position setzen
|
||||||
|
this.currentTile.row = 0;
|
||||||
|
this.currentTile.col = 0;
|
||||||
|
|
||||||
this.generateLevel();
|
this.generateLevel();
|
||||||
this.startGame();
|
this.startGame();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
updateCanvasSize() {
|
||||||
|
// Canvas ist immer 400x400px für ein einzelnes Tile
|
||||||
|
this.canvas.width = 400;
|
||||||
|
this.canvas.height = 400;
|
||||||
|
},
|
||||||
|
|
||||||
|
updateCurrentTile() {
|
||||||
|
// Berechne aktuelle Tile-Position basierend auf Taxi-Position
|
||||||
|
if (this.currentMap && this.currentMap.mapData) {
|
||||||
|
const mapData = this.currentMap.mapData;
|
||||||
|
const rows = mapData.length;
|
||||||
|
const cols = mapData[0] ? mapData[0].length : 0;
|
||||||
|
|
||||||
|
// Berechne Tile-Koordinaten basierend auf Taxi-Position
|
||||||
|
const tileRow = Math.floor(this.taxi.y / this.tiles.size);
|
||||||
|
const tileCol = Math.floor(this.taxi.x / this.tiles.size);
|
||||||
|
|
||||||
|
// Begrenze auf Map-Grenzen
|
||||||
|
this.currentTile.row = Math.max(0, Math.min(rows - 1, tileRow));
|
||||||
|
this.currentTile.col = Math.max(0, Math.min(cols - 1, tileCol));
|
||||||
|
|
||||||
|
// Stelle sicher, dass Taxi innerhalb des Canvas bleibt
|
||||||
|
this.taxi.x = Math.max(0, Math.min(this.canvas.width - this.taxi.width, this.taxi.x));
|
||||||
|
this.taxi.y = Math.max(0, Math.min(this.canvas.height - this.taxi.height, this.taxi.y));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
setupEventListeners() {
|
setupEventListeners() {
|
||||||
document.addEventListener('keydown', this.handleKeyDown);
|
document.addEventListener('keydown', this.handleKeyDown);
|
||||||
document.addEventListener('keyup', this.handleKeyUp);
|
document.addEventListener('keyup', this.handleKeyUp);
|
||||||
@@ -229,7 +288,6 @@ export default {
|
|||||||
generateLevel() {
|
generateLevel() {
|
||||||
this.passengers = [];
|
this.passengers = [];
|
||||||
this.destinations = [];
|
this.destinations = [];
|
||||||
this.gasStations = [];
|
|
||||||
this.obstacles = [];
|
this.obstacles = [];
|
||||||
|
|
||||||
// Generiere Passagiere (auf Straßen)
|
// Generiere Passagiere (auf Straßen)
|
||||||
@@ -256,14 +314,6 @@ export default {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generiere Tankstellen (auf Straßen)
|
|
||||||
const fuelPosition = this.getRandomRoadPosition();
|
|
||||||
this.gasStations.push({
|
|
||||||
x: fuelPosition.x,
|
|
||||||
y: fuelPosition.y,
|
|
||||||
width: 20,
|
|
||||||
height: 20
|
|
||||||
});
|
|
||||||
|
|
||||||
// Generiere Hindernisse (außerhalb der Straßen)
|
// Generiere Hindernisse (außerhalb der Straßen)
|
||||||
for (let i = 0; i < 3; i++) {
|
for (let i = 0; i < 3; i++) {
|
||||||
@@ -346,7 +396,7 @@ export default {
|
|||||||
|
|
||||||
this.updateTaxi();
|
this.updateTaxi();
|
||||||
this.handlePassengerActions();
|
this.handlePassengerActions();
|
||||||
this.checkCollisions();
|
// this.checkCollisions(); // Temporär deaktiviert für freie Fahrt
|
||||||
this.render();
|
this.render();
|
||||||
|
|
||||||
// Minimap zeichnen
|
// Minimap zeichnen
|
||||||
@@ -356,29 +406,30 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
updateTaxi() {
|
updateTaxi() {
|
||||||
// Bewegung basierend auf gedrückten Tasten
|
// Beschleunigung bei gedrücktem Pfeil nach oben
|
||||||
if (this.keys['ArrowUp'] || this.keys['w'] || this.keys['W']) {
|
if (this.keys['ArrowUp'] || this.keys['w'] || this.keys['W']) {
|
||||||
this.taxi.speed = Math.min(this.taxi.speed + 0.2, this.taxi.maxSpeed);
|
this.taxi.speed = Math.min(this.taxi.speed + 0.015625, this.taxi.maxSpeed);
|
||||||
} else if (this.keys['ArrowDown'] || this.keys['x'] || this.keys['X']) {
|
|
||||||
this.taxi.speed = Math.max(this.taxi.speed - 0.2, -this.taxi.maxSpeed);
|
|
||||||
} else {
|
|
||||||
this.taxi.speed *= 0.9; // Reibung
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Abbremsen bei gedrücktem Pfeil nach unten
|
||||||
|
if (this.keys['ArrowDown'] || this.keys['x'] || this.keys['X']) {
|
||||||
|
this.taxi.speed = Math.max(this.taxi.speed - 0.0625, 0); // Bremsen bis 0, nicht rückwärts
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lenkung
|
||||||
if (this.keys['ArrowLeft'] || this.keys['a'] || this.keys['A']) {
|
if (this.keys['ArrowLeft'] || this.keys['a'] || this.keys['A']) {
|
||||||
this.taxi.angle -= 0.1;
|
this.taxi.angle -= 0.025;
|
||||||
}
|
}
|
||||||
if (this.keys['ArrowRight'] || this.keys['d'] || this.keys['D']) {
|
if (this.keys['ArrowRight'] || this.keys['d'] || this.keys['D']) {
|
||||||
this.taxi.angle += 0.1;
|
this.taxi.angle += 0.025;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Aktualisiere Position
|
// Aktualisiere Position
|
||||||
this.taxi.x += Math.cos(this.taxi.angle) * this.taxi.speed;
|
this.taxi.x += Math.cos(this.taxi.angle) * this.taxi.speed;
|
||||||
this.taxi.y += Math.sin(this.taxi.angle) * this.taxi.speed;
|
this.taxi.y += Math.sin(this.taxi.angle) * this.taxi.speed;
|
||||||
|
|
||||||
// Begrenze auf Canvas
|
// Aktualisiere aktuelle Tile-Position
|
||||||
this.taxi.x = Math.max(0, Math.min(this.canvas.width - this.taxi.width, this.taxi.x));
|
this.updateCurrentTile();
|
||||||
this.taxi.y = Math.max(0, Math.min(this.canvas.height - this.taxi.height, this.taxi.y));
|
|
||||||
|
|
||||||
// Verbrauche Treibstoff
|
// Verbrauche Treibstoff
|
||||||
if (Math.abs(this.taxi.speed) > 0.1) {
|
if (Math.abs(this.taxi.speed) > 0.1) {
|
||||||
@@ -518,43 +569,67 @@ export default {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Zeichne Tankstellen
|
|
||||||
this.gasStations.forEach(station => {
|
|
||||||
this.ctx.fillStyle = '#FFC107';
|
|
||||||
this.ctx.fillRect(station.x, station.y, station.width, station.height);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Zeichne Taxi
|
// Zeichne Taxi
|
||||||
this.ctx.save();
|
this.ctx.save();
|
||||||
this.ctx.translate(this.taxi.x + this.taxi.width/2, this.taxi.y + this.taxi.height/2);
|
this.ctx.translate(this.taxi.x + this.taxi.width/2, this.taxi.y + this.taxi.height/2);
|
||||||
this.ctx.rotate(this.taxi.angle);
|
this.ctx.rotate(this.taxi.imageAngle + this.taxi.angle);
|
||||||
this.ctx.fillStyle = '#2196F3';
|
|
||||||
this.ctx.fillRect(-this.taxi.width/2, -this.taxi.height/2, this.taxi.width, this.taxi.height);
|
if (this.taxi.image) {
|
||||||
|
// Zeichne Taxi-Bild
|
||||||
|
console.log('Zeichne Taxi-Bild:', this.taxi.image, 'Position:', this.taxi.x, this.taxi.y);
|
||||||
|
this.ctx.drawImage(
|
||||||
|
this.taxi.image,
|
||||||
|
-this.taxi.width/2,
|
||||||
|
-this.taxi.height/2,
|
||||||
|
this.taxi.width,
|
||||||
|
this.taxi.height
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// Fallback: Zeichne blaues Rechteck wenn Bild nicht geladen
|
||||||
|
console.log('Taxi-Bild nicht geladen, zeichne Fallback-Rechteck');
|
||||||
|
this.ctx.fillStyle = '#2196F3';
|
||||||
|
this.ctx.fillRect(-this.taxi.width/2, -this.taxi.height/2, this.taxi.width, this.taxi.height);
|
||||||
|
}
|
||||||
|
|
||||||
this.ctx.restore();
|
this.ctx.restore();
|
||||||
},
|
},
|
||||||
|
|
||||||
drawRoads() {
|
drawRoads() {
|
||||||
const tileSize = this.tiles.size;
|
const tileSize = this.tiles.size; // 400x400px
|
||||||
const cols = 8; // 400px / 50px = 8 tiles
|
|
||||||
const rows = 8;
|
|
||||||
|
|
||||||
// Erstelle ein 8x8 Raster mit Straßen
|
// Zeichne nur das aktuelle Tile
|
||||||
for (let row = 0; row < rows; row++) {
|
if (this.currentMap && this.currentMap.mapData) {
|
||||||
for (let col = 0; col < cols; col++) {
|
const mapData = this.currentMap.mapData;
|
||||||
const x = col * tileSize;
|
const rows = mapData.length;
|
||||||
const y = row * tileSize;
|
const cols = mapData[0] ? mapData[0].length : 0;
|
||||||
|
|
||||||
|
// Prüfe ob aktuelle Tile-Position gültig ist
|
||||||
|
if (this.currentTile.row >= 0 && this.currentTile.row < rows &&
|
||||||
|
this.currentTile.col >= 0 && this.currentTile.col < cols) {
|
||||||
|
|
||||||
// Bestimme Tile-Typ basierend auf Position
|
const tileType = mapData[this.currentTile.row][this.currentTile.col];
|
||||||
let tileType = this.getTileType(row, col, rows, cols);
|
if (tileType) {
|
||||||
|
// Zeichne Straßenregionen für das aktuelle Tile
|
||||||
// Zeichne Straßenregionen basierend auf Koordinaten
|
streetCoordinates.drawDriveableRegions(this.ctx, tileType, tileSize, 0, 0);
|
||||||
streetCoordinates.drawDriveableRegions(this.ctx, tileType, tileSize, x, y);
|
|
||||||
|
// Zeichne Tile-Overlay falls verfügbar
|
||||||
// Zeichne Tile-Overlay falls verfügbar
|
if (this.tiles.images[tileType]) {
|
||||||
if (this.tiles.images[tileType]) {
|
this.ctx.drawImage(this.tiles.images[tileType], 0, 0, tileSize, tileSize);
|
||||||
this.ctx.drawImage(this.tiles.images[tileType], x, y, tileSize, tileSize);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// Fallback: Zeichne Standard-Tile wenn keine Map geladen ist
|
||||||
|
const tileType = 'cornertopleft'; // Standard-Tile
|
||||||
|
|
||||||
|
// Zeichne Straßenregionen
|
||||||
|
streetCoordinates.drawDriveableRegions(this.ctx, tileType, tileSize, 0, 0);
|
||||||
|
|
||||||
|
// Zeichne Tile-Overlay falls verfügbar
|
||||||
|
if (this.tiles.images[tileType]) {
|
||||||
|
this.ctx.drawImage(this.tiles.images[tileType], 0, 0, tileSize, tileSize);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -648,6 +723,71 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
loadTaxiImage() {
|
||||||
|
const img = new Image();
|
||||||
|
img.onload = () => {
|
||||||
|
console.log('Taxi-Bild erfolgreich geladen:', img);
|
||||||
|
this.taxi.image = img;
|
||||||
|
};
|
||||||
|
img.onerror = (error) => {
|
||||||
|
console.error('Fehler beim Laden des Taxi-Bildes:', error);
|
||||||
|
console.log('Versuche Pfad:', '/images/taxi/taxi.svg');
|
||||||
|
};
|
||||||
|
img.src = '/images/taxi/taxi.svg';
|
||||||
|
console.log('Lade Taxi-Bild von:', '/images/taxi/taxi.svg');
|
||||||
|
},
|
||||||
|
|
||||||
|
async loadMaps() {
|
||||||
|
try {
|
||||||
|
const response = await apiClient.get('/api/taxi-maps/maps');
|
||||||
|
this.maps = response.data.data || [];
|
||||||
|
|
||||||
|
// Verwende die erste verfügbare Map als Standard
|
||||||
|
if (this.maps.length > 0) {
|
||||||
|
this.currentMap = this.maps[0];
|
||||||
|
this.selectedMapId = this.maps[0].id;
|
||||||
|
console.log('Geladene Map:', this.currentMap);
|
||||||
|
|
||||||
|
// Canvas-Größe an geladene Map anpassen
|
||||||
|
this.updateCanvasSize();
|
||||||
|
|
||||||
|
// Minimap neu zeichnen nach dem Laden der Map
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.drawMinimap();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Fehler beim Laden der Maps:', error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onMapChange() {
|
||||||
|
// Wechsle zur ausgewählten Map
|
||||||
|
const selectedMap = this.maps.find(map => map.id === this.selectedMapId);
|
||||||
|
if (selectedMap) {
|
||||||
|
this.currentMap = selectedMap;
|
||||||
|
console.log('Gewechselt zu Map:', selectedMap);
|
||||||
|
|
||||||
|
// Canvas-Größe an neue Map anpassen
|
||||||
|
this.updateCanvasSize();
|
||||||
|
|
||||||
|
// Taxi in die Mitte des 400x400px Tiles positionieren
|
||||||
|
this.taxi.x = 200 - this.taxi.width/2; // Zentriert in der Mitte
|
||||||
|
this.taxi.y = 200 - this.taxi.height/2; // Zentriert in der Mitte
|
||||||
|
this.taxi.angle = 0; // Fahrtrichtung nach oben
|
||||||
|
this.taxi.speed = 0; // Geschwindigkeit zurücksetzen
|
||||||
|
|
||||||
|
// Aktuelle Tile-Position zurücksetzen
|
||||||
|
this.currentTile.row = 0;
|
||||||
|
this.currentTile.col = 0;
|
||||||
|
|
||||||
|
// Minimap neu zeichnen
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.drawMinimap();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
drawMinimap() {
|
drawMinimap() {
|
||||||
if (!this.minimapCtx) return;
|
if (!this.minimapCtx) return;
|
||||||
|
|
||||||
@@ -661,38 +801,93 @@ export default {
|
|||||||
ctx.fillStyle = '#f0f0f0';
|
ctx.fillStyle = '#f0f0f0';
|
||||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||||
|
|
||||||
// Skalierungsfaktor (Hauptspiel zu Minimap)
|
// Zeichne Map-Tiles aus der geladenen Map
|
||||||
const scaleX = canvas.width / 400;
|
if (this.currentMap && this.currentMap.mapData) {
|
||||||
const scaleY = canvas.height / 400;
|
const mapData = this.currentMap.mapData;
|
||||||
|
const rows = mapData.length;
|
||||||
// Zeichne Map-Tiles
|
const cols = mapData[0] ? mapData[0].length : 0;
|
||||||
const tileSize = this.tiles.size;
|
|
||||||
const cols = 8;
|
// Berechne optimale Tile-Größe für quadratische Tiles
|
||||||
const rows = 8;
|
const maxTiles = Math.max(rows, cols);
|
||||||
|
const tileSize = Math.min(canvas.width / maxTiles, canvas.height / maxTiles);
|
||||||
for (let row = 0; row < rows; row++) {
|
|
||||||
for (let col = 0; col < cols; col++) {
|
// Zentriere die Map im Canvas
|
||||||
const x = col * tileSize * scaleX;
|
const offsetX = (canvas.width - cols * tileSize) / 2;
|
||||||
const y = row * tileSize * scaleY;
|
const offsetY = (canvas.height - rows * tileSize) / 2;
|
||||||
const width = tileSize * scaleX;
|
|
||||||
const height = tileSize * scaleY;
|
for (let row = 0; row < rows; row++) {
|
||||||
|
for (let col = 0; col < cols; col++) {
|
||||||
let tileType = this.getTileType(row, col, rows, cols);
|
const x = offsetX + col * tileSize;
|
||||||
let mapTileType = 'map-' + tileType;
|
const y = offsetY + row * tileSize;
|
||||||
|
|
||||||
// Zeichne Map-Tile falls verfügbar
|
const tileType = mapData[row][col];
|
||||||
if (this.tiles.images[mapTileType]) {
|
if (tileType) {
|
||||||
ctx.drawImage(this.tiles.images[mapTileType], x, y, width, height);
|
const mapTileType = 'map-' + tileType;
|
||||||
|
|
||||||
|
// Zeichne Map-Tile falls verfügbar
|
||||||
|
if (this.tiles.images[mapTileType]) {
|
||||||
|
ctx.drawImage(this.tiles.images[mapTileType], x, y, tileSize, tileSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Fallback: Zeichne statische Map wenn keine Map geladen ist
|
||||||
|
const cols = 8;
|
||||||
|
const rows = 8;
|
||||||
|
|
||||||
|
// Berechne optimale Tile-Größe für quadratische Tiles
|
||||||
|
const maxTiles = Math.max(rows, cols);
|
||||||
|
const tileSize = Math.min(canvas.width / maxTiles, canvas.height / maxTiles);
|
||||||
|
|
||||||
|
// Zentriere die Map im Canvas
|
||||||
|
const offsetX = (canvas.width - cols * tileSize) / 2;
|
||||||
|
const offsetY = (canvas.height - rows * tileSize) / 2;
|
||||||
|
|
||||||
|
for (let row = 0; row < rows; row++) {
|
||||||
|
for (let col = 0; col < cols; col++) {
|
||||||
|
const x = offsetX + col * tileSize;
|
||||||
|
const y = offsetY + row * tileSize;
|
||||||
|
|
||||||
|
let tileType = this.getTileType(row, col, rows, cols);
|
||||||
|
let mapTileType = 'map-' + tileType;
|
||||||
|
|
||||||
|
// Zeichne Map-Tile falls verfügbar
|
||||||
|
if (this.tiles.images[mapTileType]) {
|
||||||
|
ctx.drawImage(this.tiles.images[mapTileType], x, y, tileSize, tileSize);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Berechne Skalierung für Passagiere, Ziele und Tankstellen
|
||||||
|
let scaleX, scaleY, offsetX, offsetY;
|
||||||
|
if (this.currentMap && this.currentMap.mapData) {
|
||||||
|
const mapData = this.currentMap.mapData;
|
||||||
|
const rows = mapData.length;
|
||||||
|
const cols = mapData[0] ? mapData[0].length : 0;
|
||||||
|
const maxTiles = Math.max(rows, cols);
|
||||||
|
const tileSize = Math.min(canvas.width / maxTiles, canvas.height / maxTiles);
|
||||||
|
scaleX = tileSize / 400; // 400 ist die neue Tile-Größe
|
||||||
|
scaleY = tileSize / 400;
|
||||||
|
offsetX = (canvas.width - cols * tileSize) / 2;
|
||||||
|
offsetY = (canvas.height - rows * tileSize) / 2;
|
||||||
|
} else {
|
||||||
|
// Fallback für statische Map
|
||||||
|
const maxTiles = 8;
|
||||||
|
const tileSize = Math.min(canvas.width / maxTiles, canvas.height / maxTiles);
|
||||||
|
scaleX = tileSize / 400;
|
||||||
|
scaleY = tileSize / 400;
|
||||||
|
offsetX = (canvas.width - 8 * tileSize) / 2;
|
||||||
|
offsetY = (canvas.height - 8 * tileSize) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
// Passagiere (grün)
|
// Passagiere (grün)
|
||||||
ctx.fillStyle = '#4CAF50';
|
ctx.fillStyle = '#4CAF50';
|
||||||
this.passengers.forEach(passenger => {
|
this.passengers.forEach(passenger => {
|
||||||
if (!passenger.pickedUp) {
|
if (!passenger.pickedUp) {
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.arc(passenger.x * scaleX, passenger.y * scaleY, 2, 0, 2 * Math.PI);
|
ctx.arc(offsetX + passenger.x * scaleX, offsetY + passenger.y * scaleY, 2, 0, 2 * Math.PI);
|
||||||
ctx.fill();
|
ctx.fill();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -702,34 +897,31 @@ export default {
|
|||||||
this.destinations.forEach(dest => {
|
this.destinations.forEach(dest => {
|
||||||
if (!dest.completed) {
|
if (!dest.completed) {
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.arc(dest.x * scaleX, dest.y * scaleY, 2, 0, 2 * Math.PI);
|
ctx.arc(offsetX + dest.x * scaleX, offsetY + dest.y * scaleY, 2, 0, 2 * Math.PI);
|
||||||
ctx.fill();
|
ctx.fill();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Tankstellen (gelb)
|
|
||||||
ctx.fillStyle = '#FF9800';
|
|
||||||
this.gasStations.forEach(station => {
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.arc(station.x * scaleX, station.y * scaleY, 2, 0, 2 * Math.PI);
|
|
||||||
ctx.fill();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Taxi (blau)
|
// Taxi (blau) - Position basierend auf aktueller Tile-Position
|
||||||
ctx.fillStyle = '#2196F3';
|
ctx.fillStyle = '#2196F3';
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.arc(this.taxi.x * scaleX, this.taxi.y * scaleY, 3, 0, 2 * Math.PI);
|
const taxiGlobalX = this.currentTile.col * 400 + this.taxi.x;
|
||||||
ctx.fill();
|
const taxiGlobalY = this.currentTile.row * 400 + this.taxi.y;
|
||||||
|
ctx.arc(offsetX + taxiGlobalX * scaleX, offsetY + taxiGlobalY * scaleY, 3, 0, 2 * Math.PI);
|
||||||
// Taxi-Richtung anzeigen
|
ctx.fill();
|
||||||
ctx.strokeStyle = '#2196F3';
|
|
||||||
ctx.lineWidth = 1;
|
// Taxi-Richtung anzeigen
|
||||||
ctx.beginPath();
|
ctx.strokeStyle = '#2196F3';
|
||||||
const endX = this.taxi.x * scaleX + Math.cos(this.taxi.angle) * 6;
|
ctx.lineWidth = 1;
|
||||||
const endY = this.taxi.y * scaleY + Math.sin(this.taxi.angle) * 6;
|
ctx.beginPath();
|
||||||
ctx.moveTo(this.taxi.x * scaleX, this.taxi.y * scaleY);
|
const taxiX = offsetX + taxiGlobalX * scaleX;
|
||||||
ctx.lineTo(endX, endY);
|
const taxiY = offsetY + taxiGlobalY * scaleY;
|
||||||
ctx.stroke();
|
const endX = taxiX + Math.cos(this.taxi.angle) * 6;
|
||||||
|
const endY = taxiY + Math.sin(this.taxi.angle) * 6;
|
||||||
|
ctx.moveTo(taxiX, taxiY);
|
||||||
|
ctx.lineTo(endX, endY);
|
||||||
|
ctx.stroke();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -887,6 +1079,9 @@ export default {
|
|||||||
background: #f8f9fa;
|
background: #f8f9fa;
|
||||||
border-bottom: 1px solid #ddd;
|
border-bottom: 1px solid #ddd;
|
||||||
padding: 15px 20px;
|
padding: 15px 20px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.minimap-title {
|
.minimap-title {
|
||||||
@@ -896,6 +1091,24 @@ export default {
|
|||||||
color: #333;
|
color: #333;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.map-selector {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-select {
|
||||||
|
padding: 5px 10px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
background: white;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-select:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: #F9A22C;
|
||||||
|
}
|
||||||
|
|
||||||
.minimap-container {
|
.minimap-container {
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|||||||
Reference in New Issue
Block a user