Ä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:
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user