Änderung: Überarbeitung der TaxiGame.vue zur Verbesserung der Spielmechanik und Benutzeroberfläche

Änderungen:
- Entfernung der alten Pause-Anzeige und Integration eines neuen Tacho-Displays zur Geschwindigkeitsanzeige.
- Anpassung der Spielparameter, einschließlich der Taxi-Position und der Canvas-Größe auf 500x500px.
- Implementierung einer neuen Geschwindigkeitsregelung mit 5er-Schritten und Anpassung der Lenkgeschwindigkeit basierend auf der aktuellen Geschwindigkeit.
- Verbesserung der Benutzeroberfläche durch zentrierte Layouts und optimierte CSS-Klassen.

Diese Anpassungen verbessern die Benutzererfahrung und die Spielmechanik im Taxi-Minispiel erheblich.
This commit is contained in:
Torsten Schulz (local)
2025-09-15 23:29:31 +02:00
parent 3f33da06e5
commit 4a126c552d

View File

@@ -12,16 +12,6 @@
<div class="game-layout">
<!-- Spielbrett (links) -->
<div class="game-board-section">
<!-- Pause-Anzeige -->
<div v-if="showPauseOverlay" class="pause-overlay">
<div class="pause-message">
<h2>{{ $t('minigames.taxi.paused') }}</h2>
<button @click="togglePause" class="resume-button">
{{ $t('minigames.taxi.resume') }}
</button>
</div>
</div>
<!-- Spielbereich mit Canvas und Legende -->
<div class="game-area">
<!-- Legende (links) -->
@@ -70,17 +60,39 @@
</div>
</div>
<!-- Spiel-Canvas -->
<div class="game-canvas-container">
<canvas
ref="gameCanvas"
width="400"
height="400"
class="game-canvas"
@click="handleCanvasClick"
@keydown="handleKeyDown"
tabindex="0"
></canvas>
<!-- Spiel-Canvas mit Tacho -->
<div class="game-canvas-section">
<!-- Tacho-Display -->
<div class="tacho-display">
<div class="tacho-speed">
<span class="tacho-icon"></span>
<span class="speed-value">{{ taxi.speed * 5 }}</span>
<span class="speed-unit">km/h</span>
</div>
</div>
<!-- Pause-Anzeige -->
<div v-if="showPauseOverlay" class="pause-overlay">
<div class="pause-message">
<h2>{{ $t('minigames.taxi.paused') }}</h2>
<button @click="togglePause" class="resume-button">
{{ $t('minigames.taxi.resume') }}
</button>
</div>
</div>
<!-- Canvas -->
<div class="game-canvas-container">
<canvas
ref="gameCanvas"
width="500"
height="500"
class="game-canvas"
@click="handleCanvasClick"
@keydown="handleKeyDown"
tabindex="0"
></canvas>
</div>
</div>
</div>
@@ -193,20 +205,22 @@ export default {
gameRunning: false,
crashes: 0,
gameLoop: null,
lastSpeedChange: 0,
speedChangeInterval: 100, // 200ms = 0.2 Sekunden
canvas: null,
ctx: null,
minimapCanvas: null,
minimapCtx: null,
isStatsExpanded: true,
taxi: {
x: 200, // Mitte des 400x400px Tiles
y: 200, // Mitte des 400x400px Tiles
x: 250, // Mitte des 400x400px Tiles
y: 250, // Mitte des 400x400px Tiles
width: 30, // Skalierte Breite (50px Höhe * 297/506)
height: 50, // 50px Höhe
angle: 0, // Fahrtrichtung
imageAngle: Math.PI / 2, // Bildrotation (90° nach rechts)
speed: 0,
maxSpeed: 3,
maxSpeed: 24, // 24 = 120 km/h (5er-Schritte: 0, 5, 10, ..., 120)
image: null // Taxi-Bild
},
currentTile: {
@@ -214,7 +228,7 @@ export default {
col: 0
},
tiles: {
size: 400, // 400x400px pro Tile
size: 500, // 400x400px pro Tile
images: {}
},
maps: [], // Geladene Maps aus der Datenbank
@@ -260,8 +274,8 @@ export default {
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.x = 250 - this.taxi.width/2; // Zentriert in der Mitte
this.taxi.y = 250 - this.taxi.height/2; // Zentriert in der Mitte
this.taxi.angle = 0; // Fahrtrichtung nach oben
this.taxi.speed = 0; // Geschwindigkeit zurücksetzen
@@ -275,8 +289,8 @@ export default {
updateCanvasSize() {
// Canvas ist immer 400x400px für ein einzelnes Tile
this.canvas.width = 400;
this.canvas.height = 400;
this.canvas.width = 500;
this.canvas.height = 500;
},
updateCurrentTile() {
@@ -379,7 +393,7 @@ export default {
}
// Fallback: Mitte des Spielfelds
return { x: 200, y: 200 };
return { x: 250, y: 250 };
},
getRandomOffRoadPosition() {
@@ -434,34 +448,50 @@ export default {
},
updateTaxi() {
// Beschleunigung bei gedrücktem Pfeil nach oben
if (this.keys['ArrowUp'] || this.keys['w'] || this.keys['W']) {
this.taxi.speed = Math.min(this.taxi.speed + 0.015625, this.taxi.maxSpeed);
// Prüfe ob das Spiel pausiert ist
if (this.isPaused) {
return;
}
// 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
const currentTime = Date.now();
// Prüfe ob genug Zeit vergangen ist für Geschwindigkeitsänderung
if (currentTime - this.lastSpeedChange >= this.speedChangeInterval) {
// Beschleunigung bei gedrücktem Pfeil nach oben (5er-Schritte)
if (this.keys['ArrowUp'] || this.keys['w'] || this.keys['W']) {
this.taxi.speed = Math.min(this.taxi.speed + 1, this.taxi.maxSpeed);
this.lastSpeedChange = currentTime;
}
// Abbremsen bei gedrücktem Pfeil nach unten (5er-Schritte)
if (this.keys['ArrowDown'] || this.keys['x'] || this.keys['X']) {
this.taxi.speed = Math.max(this.taxi.speed - 1, 0); // Bremsen bis 0, nicht rückwärts
this.lastSpeedChange = currentTime;
}
}
// Lenkung
// Lenkung - abhängig von der Geschwindigkeit
const baseSteeringSpeed = 0.07; // Basis-Lenkgeschwindigkeit für 20 km/h (Stufe 4)
const currentSpeedLevel = this.taxi.speed; // 0-24 (entspricht 0-120 km/h)
const steeringSpeed = baseSteeringSpeed * (currentSpeedLevel / 4); // Skaliert auf Stufe 4
if (this.keys['ArrowLeft'] || this.keys['a'] || this.keys['A']) {
this.taxi.angle -= 0.025;
this.taxi.angle -= steeringSpeed;
}
if (this.keys['ArrowRight'] || this.keys['d'] || this.keys['D']) {
this.taxi.angle += 0.025;
this.taxi.angle += steeringSpeed;
}
// Aktualisiere Position
this.taxi.x += Math.cos(this.taxi.angle) * this.taxi.speed;
this.taxi.y += Math.sin(this.taxi.angle) * this.taxi.speed;
// Aktualisiere Position (1/4 der ursprünglichen Bewegung)
this.taxi.x += Math.cos(this.taxi.angle) * this.taxi.speed * 0.25;
this.taxi.y += Math.sin(this.taxi.angle) * this.taxi.speed * 0.25;
// Aktualisiere aktuelle Tile-Position
this.updateCurrentTile();
// Verbrauche Treibstoff
if (Math.abs(this.taxi.speed) > 0.1) {
this.fuel = Math.max(0, this.fuel - 0.1);
this.fuel = Math.max(0, this.fuel - 0.01);
}
},
@@ -557,6 +587,12 @@ export default {
const crashMessage = `Du hattest einen Unfall! Crashes: ${this.crashes}`;
const crashTitle = 'Unfall!';
this.$root?.$refs?.messageDialog?.open?.(crashMessage, crashTitle, {}, this.handleCrashDialogClose);
// Test: Direkter Aufruf nach 3 Sekunden (falls Dialog-Callback nicht funktioniert)
setTimeout(() => {
console.log('Test: Automatischer Reset nach 3 Sekunden');
this.handleCrashDialogClose();
}, 3000);
console.log('Crash-Dialog wird angezeigt:', {
crashes: this.crashes,
isPaused: this.isPaused,
@@ -577,18 +613,24 @@ export default {
this.isPaused = false;
this.showPauseOverlay = false;
console.log('Nach Dialog-Close - isPaused:', this.isPaused, 'showPauseOverlay:', this.showPauseOverlay);
// Taxi-Position zurücksetzen
this.resetTaxiPosition();
// Fokus zurück auf Canvas setzen
this.$nextTick(() => {
if (this.canvas) {
this.canvas.focus();
}
console.log('Nach nextTick - isPaused:', this.isPaused);
});
},
resetTaxiPosition() {
// Taxi in der Mitte des Screens platzieren
this.taxi.x = 200 - this.taxi.width/2;
this.taxi.y = 200 - this.taxi.height/2;
this.taxi.x = 250 - this.taxi.width/2;
this.taxi.y = 250 - this.taxi.height/2;
this.taxi.speed = 0;
this.taxi.angle = 0;
@@ -612,7 +654,7 @@ export default {
const tileType = this.getCurrentTileType();
const streetTileType = this.mapTileTypeToStreetCoordinates(tileType);
const originalTileSize = streetCoordinates.getOriginalTileSize(); // 640px
const currentTileSize = 400; // Aktuelle Render-Größe
const currentTileSize = 500; // Aktuelle Render-Größe
// Hole die Polygon-Koordinaten für dieses Tile
const regions = streetCoordinates.getDriveableRegions(streetTileType, originalTileSize);
@@ -915,8 +957,8 @@ export default {
this.money = 0;
this.passengersDelivered = 0;
this.fuel = 100;
this.taxi.x = 400;
this.taxi.y = 300;
this.taxi.x = 250;
this.taxi.y = 250;
this.taxi.angle = 0;
this.taxi.speed = 0;
this.generateLevel();
@@ -1010,8 +1052,8 @@ export default {
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.x = 250 - this.taxi.width/2; // Zentriert in der Mitte
this.taxi.y = 250 - this.taxi.height/2; // Zentriert in der Mitte
this.taxi.angle = 0; // Fahrtrichtung nach oben
this.taxi.speed = 0; // Geschwindigkeit zurücksetzen
@@ -1106,16 +1148,16 @@ export default {
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;
scaleX = tileSize / 500; // 400 ist die neue Tile-Größe
scaleY = tileSize / 500;
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;
scaleX = tileSize / 500;
scaleY = tileSize / 500;
offsetX = (canvas.width - 8 * tileSize) / 2;
offsetY = (canvas.height - 8 * tileSize) / 2;
}
@@ -1144,8 +1186,8 @@ export default {
// Taxi (blau) - Position basierend auf aktueller Tile-Position
ctx.fillStyle = '#2196F3';
ctx.beginPath();
const taxiGlobalX = this.currentTile.col * 400 + this.taxi.x;
const taxiGlobalY = this.currentTile.row * 400 + this.taxi.y;
const taxiGlobalX = this.currentTile.col * 500 + this.taxi.x;
const taxiGlobalY = this.currentTile.row * 500 + this.taxi.y;
ctx.arc(offsetX + taxiGlobalX * scaleX, offsetY + taxiGlobalY * scaleY, 3, 0, 2 * Math.PI);
ctx.fill();
@@ -1205,6 +1247,51 @@ export default {
align-items: flex-start;
}
/* Game Canvas Section */
.game-canvas-section {
display: flex;
flex-direction: column;
align-items: center;
width: 500px;
margin: 0 auto; /* Zentriert den gesamten Container */
}
/* Tacho-Display */
.tacho-display {
width: 500px; /* Gleiche Breite wie das zentrale Tile */
background: #f8f9fa;
border: 1px solid #ddd;
border-radius: 4px;
padding: 8px 12px;
margin: 0; /* Kein Margin */
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
box-sizing: border-box; /* Padding wird in die Breite eingerechnet */
}
.tacho-speed {
display: flex;
justify-content: flex-end;
align-items: center;
gap: 6px;
font-size: 10pt;
color: #333;
font-weight: 500;
}
.tacho-icon {
font-size: 10pt;
}
.speed-value {
font-weight: bold;
color: #2196F3;
}
.speed-unit {
color: #666;
font-size: 9pt;
}
.game-board-section {
flex: 1;
display: flex;
@@ -1220,6 +1307,7 @@ export default {
align-items: flex-start;
width: 100%;
max-width: 1200px;
justify-content: center; /* Zentriert den Inhalt */
}
.sidebar-section {
@@ -1435,9 +1523,10 @@ export default {
/* Game Canvas */
.game-canvas-container {
margin: 20px 0;
margin: 0; /* Kein Margin */
text-align: center;
flex: 1;
width: 500px; /* Feste Breite wie das Tacho-Display */
box-sizing: border-box; /* Border wird in die Breite eingerechnet */
}
.game-canvas {