Änderung: Hinzufügen von TaxiHighscore-Logik und Verbesserung der API-Integration
Änderungen: - Implementierung des neuen Routers für TaxiHighscore zur Verwaltung von Highscore-Daten. - Anpassung der Datenbankmodelle zur Unterstützung von TaxiHighscore-Associations. - Erweiterung der Vue-Komponenten zur Anzeige und Speicherung von Highscores im Taxi-Spiel. - Verbesserung der Statusanzeige im AppHeader zur besseren Benutzerinteraktion. Diese Anpassungen erweitern die Spielmechanik und Benutzererfahrung, indem sie die Verwaltung von Highscores integrieren und die Benutzeroberfläche optimieren.
This commit is contained in:
@@ -114,9 +114,6 @@
|
||||
<button @click="restartLevel" class="control-button">
|
||||
{{ $t('minigames.taxi.restartLevel') }}
|
||||
</button>
|
||||
<button @click="goBack" class="control-button">
|
||||
{{ $t('minigames.backToGames') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -297,6 +294,7 @@ export default {
|
||||
radarLinePos: 0,
|
||||
vehicleCount: 5,
|
||||
redLightSincePenalty: 0,
|
||||
gameStartTime: null, // Zeitstempel wann das Spiel gestartet wurde
|
||||
maps: [], // Geladene Maps aus der Datenbank
|
||||
currentMap: null, // Aktuell verwendete Map
|
||||
selectedMapId: null, // ID der ausgewählten Map
|
||||
@@ -313,6 +311,7 @@ export default {
|
||||
,prevTaxiX: 250
|
||||
,prevTaxiY: 250
|
||||
,skipRedLightOneFrame: false
|
||||
,gasStations: [] // Tankstellen im Spiel
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -761,7 +760,7 @@ export default {
|
||||
},
|
||||
|
||||
generateWaitingPassenger() {
|
||||
if (!this.currentMap || !Array.isArray(this.currentMap.tileHouses)) {
|
||||
if (!this.currentMap || !Array.isArray(this.currentMap.tileHouses) || !Array.isArray(this.currentMap.tileStreets)) {
|
||||
// Versuche es in 2 Sekunden erneut
|
||||
this.passengerGenerationTimeout = setTimeout(() => {
|
||||
this.generateWaitingPassenger();
|
||||
@@ -769,24 +768,41 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
// Erstelle Liste aller Tiles mit Häusern
|
||||
const tilesWithHouses = this.getTilesWithHouses();
|
||||
// 1. Sammle alle Straßen mit verfügbaren Häusern
|
||||
const streetsWithHouses = [];
|
||||
|
||||
if (tilesWithHouses.length === 0) {
|
||||
console.log('Keine Tiles mit Häusern gefunden');
|
||||
for (const street of this.currentMap.tileStreets) {
|
||||
// Finde alle Häuser auf diesem Straßen-Tile
|
||||
const housesOnThisTile = this.currentMap.tileHouses.filter(house =>
|
||||
house.x === street.x && house.y === street.y
|
||||
);
|
||||
|
||||
if (housesOnThisTile.length > 0) {
|
||||
// Prüfe ob diese Straße gültige Straßennamen hat
|
||||
const hasValidStreetName = (street.streetNameH && street.streetNameH.name && street.streetNameH.name.trim() !== '') ||
|
||||
(street.streetNameV && street.streetNameV.name && street.streetNameV.name.trim() !== '');
|
||||
|
||||
if (hasValidStreetName) {
|
||||
streetsWithHouses.push({
|
||||
street: street,
|
||||
houses: housesOnThisTile
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (streetsWithHouses.length === 0) {
|
||||
console.log('Keine Straßen mit verfügbaren Häusern gefunden');
|
||||
return;
|
||||
}
|
||||
|
||||
// Wähle zufälliges Tile mit Häusern
|
||||
const selectedTile = tilesWithHouses[Math.floor(Math.random() * tilesWithHouses.length)];
|
||||
// 2. Wähle zufällige Straße mit Häusern
|
||||
const selectedStreetData = streetsWithHouses[Math.floor(Math.random() * streetsWithHouses.length)];
|
||||
const selectedStreet = selectedStreetData.street;
|
||||
const availableHouses = selectedStreetData.houses;
|
||||
|
||||
// Finde alle Häuser auf diesem Tile
|
||||
const housesOnTile = this.currentMap.tileHouses.filter(house =>
|
||||
house.x === selectedTile.x && house.y === selectedTile.y
|
||||
);
|
||||
|
||||
// Wähle zufälliges Haus auf diesem Tile
|
||||
const selectedHouse = housesOnTile[Math.floor(Math.random() * housesOnTile.length)];
|
||||
// 3. Wähle zufälliges Haus auf dieser Straße
|
||||
const selectedHouse = availableHouses[Math.floor(Math.random() * availableHouses.length)];
|
||||
const houseIndex = this.currentMap.tileHouses.findIndex(h => h === selectedHouse);
|
||||
const houseId = `${selectedHouse.x}-${selectedHouse.y}-${houseIndex}`;
|
||||
|
||||
@@ -797,39 +813,37 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
// Finde die Straße für dieses spezifische Haus
|
||||
let streetName = "Unbekannte Straße";
|
||||
let houseNumber = 1;
|
||||
// 4. Bestimme Straßenname basierend auf der Haus-Ecke
|
||||
let streetName = null;
|
||||
const corner = selectedHouse.corner;
|
||||
|
||||
// Suche nach Straßennamen für das gewählte Haus-Tile
|
||||
const houseTile = this.currentMap.tileStreets?.find(ts => ts.x === selectedHouse.x && ts.y === selectedHouse.y);
|
||||
if (houseTile) {
|
||||
// Bestimme die Straße basierend auf der Haus-Ecke
|
||||
const corner = selectedHouse.corner;
|
||||
if (corner === 'lo' || corner === 'ro') {
|
||||
// Horizontale Straße
|
||||
if (houseTile.streetNameH && houseTile.streetNameH.name) {
|
||||
streetName = houseTile.streetNameH.name;
|
||||
}
|
||||
} else if (corner === 'lu' || corner === 'ru') {
|
||||
// Vertikale Straße
|
||||
if (houseTile.streetNameV && houseTile.streetNameV.name) {
|
||||
streetName = houseTile.streetNameV.name;
|
||||
}
|
||||
if (corner === 'lo' || corner === 'ro') {
|
||||
// Horizontale Straße
|
||||
if (selectedStreet.streetNameH && selectedStreet.streetNameH.name) {
|
||||
streetName = selectedStreet.streetNameH.name;
|
||||
}
|
||||
} else if (corner === 'lu' || corner === 'ru') {
|
||||
// Vertikale Straße
|
||||
if (selectedStreet.streetNameV && selectedStreet.streetNameV.name) {
|
||||
streetName = selectedStreet.streetNameV.name;
|
||||
}
|
||||
}
|
||||
if (streetName === 'Unbekannte Straße') {
|
||||
console.log(houseTile)
|
||||
|
||||
// Fallback sollte nie auftreten, da wir nur Straßen mit gültigen Namen auswählen
|
||||
if (!streetName || streetName.trim() === '') {
|
||||
console.error('Fehler: Kein gültiger Straßenname gefunden für Haus:', selectedHouse);
|
||||
this.generateWaitingPassenger(); // Versuche es erneut
|
||||
return;
|
||||
}
|
||||
|
||||
// Finde die Hausnummer für dieses spezifische Haus
|
||||
// 5. Finde die Hausnummer für dieses spezifische Haus
|
||||
const houseKey = `${selectedHouse.x},${selectedHouse.y},${selectedHouse.corner}`;
|
||||
houseNumber = this.houseNumbers[houseKey] || 1;
|
||||
const houseNumber = this.houseNumbers[houseKey] || 1;
|
||||
|
||||
// Generiere Namen und Geschlecht
|
||||
// 6. Generiere Namen und Geschlecht
|
||||
const nameData = this.generatePassengerName();
|
||||
|
||||
// Erstelle Passagier
|
||||
// 7. Erstelle Passagier
|
||||
const passenger = {
|
||||
id: Date.now() + Math.random(), // Eindeutige ID
|
||||
name: nameData.fullName,
|
||||
@@ -844,7 +858,7 @@ export default {
|
||||
createdAt: Date.now() // Zeitstempel der Erstellung
|
||||
};
|
||||
|
||||
// Füge Passagier zur Liste hinzu und markiere Haus als belegt
|
||||
// 8. Füge Passagier zur Liste hinzu und markiere Haus als belegt
|
||||
this.waitingPassengersList.push(passenger);
|
||||
this.occupiedHouses.add(houseId);
|
||||
},
|
||||
@@ -1277,6 +1291,10 @@ export default {
|
||||
|
||||
startGame() {
|
||||
this.gameRunning = true;
|
||||
// Setze Spielstart-Zeit
|
||||
if (!this.gameStartTime) {
|
||||
this.gameStartTime = Date.now();
|
||||
}
|
||||
// Stoppe bestehende Game-Loop falls vorhanden
|
||||
if (this.gameLoop) {
|
||||
cancelAnimationFrame(this.gameLoop);
|
||||
@@ -1669,6 +1687,12 @@ export default {
|
||||
},
|
||||
|
||||
refuel() {
|
||||
// Prüfe ob Tankstellen verfügbar sind
|
||||
if (!this.gasStations || this.gasStations.length === 0) {
|
||||
console.log('Keine Tankstellen verfügbar');
|
||||
return;
|
||||
}
|
||||
|
||||
// Finde nächste Tankstelle in der Nähe
|
||||
for (let i = 0; i < this.gasStations.length; i++) {
|
||||
const station = this.gasStations[i];
|
||||
@@ -1967,12 +1991,7 @@ export default {
|
||||
console.log('Crash-Dialog wird angezeigt:', {
|
||||
crashes: this.crashes,
|
||||
isPaused: this.isPaused,
|
||||
taxiSpeed: this.taxi.speed,
|
||||
messageTest: this.$t('message.test'),
|
||||
crashMessage: this.$t('minigames.taxi.crash.message'),
|
||||
allKeys: Object.keys(this.$t('minigames')),
|
||||
taxiKeys: Object.keys(this.$t('minigames.taxi')),
|
||||
crashKeys: Object.keys(this.$t('minigames.taxi.crash'))
|
||||
taxiSpeed: this.taxi.speed
|
||||
});
|
||||
|
||||
// Spiel bleibt pausiert bis Dialog geschlossen wird
|
||||
@@ -2007,15 +2026,74 @@ export default {
|
||||
this.vehicleCount = Math.max(0, this.vehicleCount - 1);
|
||||
},
|
||||
|
||||
handleOutOfVehicles() {
|
||||
const title = 'Hinweis';
|
||||
const msg = 'Keine Fahrzeuge mehr. Neustart.';
|
||||
getPlayTime() {
|
||||
if (!this.gameStartTime) return 0;
|
||||
return Math.floor((Date.now() - this.gameStartTime) / 1000);
|
||||
},
|
||||
|
||||
async saveHighscore() {
|
||||
try {
|
||||
const playTime = this.getPlayTime();
|
||||
const highscoreData = {
|
||||
passengersDelivered: this.passengersDelivered,
|
||||
playtime: playTime,
|
||||
points: this.score,
|
||||
mapId: this.currentMap ? this.currentMap.id : null
|
||||
};
|
||||
|
||||
console.log('Highscore-Daten:', highscoreData);
|
||||
console.log('Current Map:', this.currentMap);
|
||||
console.log('Passengers Delivered:', this.passengersDelivered);
|
||||
console.log('Playtime:', playTime);
|
||||
console.log('Points:', this.score);
|
||||
|
||||
const response = await apiClient.post('/api/taxi/highscore', highscoreData);
|
||||
|
||||
if (response.data.success) {
|
||||
console.log('Highscore erfolgreich gespeichert:', response.data.data);
|
||||
return response.data.data;
|
||||
} else {
|
||||
console.error('Fehler beim Speichern des Highscores:', response.data.message);
|
||||
return null;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Speichern des Highscores:', error);
|
||||
if (error.response) {
|
||||
console.error('Backend-Fehler:', error.response.data);
|
||||
console.error('Status:', error.response.status);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
async handleOutOfVehicles() {
|
||||
// Spiel stoppen
|
||||
this.isPaused = true;
|
||||
this.gameLoop = null;
|
||||
|
||||
// Highscore speichern
|
||||
const highscore = await this.saveHighscore();
|
||||
|
||||
const playTime = this.getPlayTime();
|
||||
const playTimeMinutes = Math.floor(playTime / 60);
|
||||
const playTimeSeconds = playTime % 60;
|
||||
|
||||
const title = 'Spiel beendet!';
|
||||
const msg = `Keine Fahrzeuge mehr. Spiel beendet!\n\n` +
|
||||
`Deine Leistung:\n` +
|
||||
`• Passagiere: ${this.passengersDelivered}\n` +
|
||||
`• Punkte: ${this.score}\n` +
|
||||
`• Spielzeit: ${playTimeMinutes}:${playTimeSeconds.toString().padStart(2, '0')}\n` +
|
||||
`• Map: ${this.currentMap ? this.currentMap.name : 'Unbekannt'}\n\n` +
|
||||
`Highscore wurde gespeichert!`;
|
||||
|
||||
this.$root?.$refs?.messageDialog?.open?.(msg, title, {}, () => {
|
||||
this.restartLevel();
|
||||
this.vehicleCount = 5;
|
||||
this.crashes = 0;
|
||||
this.redLightViolations = 0;
|
||||
this.redLightSincePenalty = 0;
|
||||
this.gameStartTime = null;
|
||||
});
|
||||
},
|
||||
|
||||
@@ -2854,6 +2932,9 @@ export default {
|
||||
this.taxi.angle = 0;
|
||||
this.taxi.speed = 0;
|
||||
|
||||
// Reset Spielzeit
|
||||
this.gameStartTime = null;
|
||||
|
||||
// Cleanup bestehender Timeouts
|
||||
if (this.passengerGenerationTimeout) {
|
||||
clearTimeout(this.passengerGenerationTimeout);
|
||||
@@ -2868,9 +2949,6 @@ export default {
|
||||
this.initializePassengerGeneration();
|
||||
},
|
||||
|
||||
goBack() {
|
||||
this.$router.push('/minigames');
|
||||
},
|
||||
|
||||
|
||||
initializeMinimap() {
|
||||
|
||||
Reference in New Issue
Block a user