Änderung: Erweiterung der Spawn-Logik und Verbesserung der Kollisionserkennung im Taxi-Spiel

Änderungen:
- Implementierung einer neuen Methode zur Ermittlung erlaubter Spawn-Richtungen basierend auf dem aktuellen Tile-Typ.
- Anpassung der Spawn-Positionen für Autos, um die Logik für die Straßenseiten zu optimieren.
- Einführung einer Methode zur Überprüfung der Befahrbarkeit von Positionen, die es Fahrzeugen erlaubt, an Rändern hineinzufahren.
- Erweiterung der Debugging-Ausgaben zur besseren Nachverfolgbarkeit von Spawn-Positionen und Kollisionen.

Diese Anpassungen verbessern die Spielmechanik durch optimierte Spawn-Logik und präzisere Kollisionserkennung.
This commit is contained in:
Torsten Schulz (local)
2025-10-06 20:59:19 +02:00
parent 67701272c5
commit 9296e5e25d
2 changed files with 5221 additions and 11 deletions

View File

@@ -1393,6 +1393,41 @@ export default {
this.cars.push(car);
},
// Ermittelt erlaubte Spawn-Richtungen basierend auf dem aktuellen Tile-Typ
getAllowedSpawnDirections() {
const tileType = this.getCurrentTileType();
// Basierend auf der allowedDirections Logik aus AdminTaxiToolsView.vue
switch (tileType) {
case 'cornertopleft':
return ['left', 'up']; // Kann von links und oben spawnen
case 'cornertopright':
return ['right', 'up']; // Kann von rechts und oben spawnen
case 'cornerbottomleft':
return ['left', 'down']; // Kann von links und unten spawnen
case 'cornerbottomright':
return ['right', 'down']; // Kann von rechts und unten spawnen
case 'horizontal':
case 'fuelhorizontal':
return ['left', 'right']; // Kann von links und rechts spawnen
case 'vertical':
case 'fuelvertical':
return ['up', 'down']; // Kann von oben und unten spawnen
case 'cross':
return ['left', 'right', 'up', 'down']; // Kann von allen Seiten spawnen
case 'tup':
return ['up', 'left', 'right']; // Kann von oben, links und rechts spawnen
case 'tdown':
return ['down', 'left', 'right']; // Kann von unten, links und rechts spawnen
case 'tleft':
return ['left', 'up', 'down']; // Kann von links, oben und unten spawnen
case 'tright':
return ['right', 'up', 'down']; // Kann von rechts, oben und unten spawnen
default:
return []; // Keine erlaubten Spawn-Richtungen
}
},
// Finde eine zufällige befahrbare Spawn-Position für ein Auto
getRandomCarSpawnPosition() {
if (!this.currentMap || !this.currentMap.tiles) {
@@ -1405,24 +1440,43 @@ export default {
// Strengere Spur-Bänder: links/oben bis 0.45, rechts/unten ab 0.55
const spawnPositions = [
// Links spawnen, nach rechts fahren, auf der rechten Straßenseite (y=0.55-0.625)
{ relativeX: 0.1, relativeY: 0.55 + Math.random() * 0.075, angle: 0, direction: 'right' },
{ relativeX: 0, relativeY: 0.55 + Math.random() * 0.075, angle: 0, direction: 'right' },
// Rechts spawnen, nach links fahren, auf der linken Straßenseite (y=0.375-0.45)
{ relativeX: 0.9, relativeY: 0.375 + Math.random() * 0.075, angle: Math.PI, direction: 'left' },
{ relativeX: 1, relativeY: 0.375 + Math.random() * 0.075, angle: Math.PI, direction: 'left' },
// Oben spawnen, nach unten fahren, auf der linken Straßenseite (x=0.375-0.45)
{ relativeX: 0.375 + Math.random() * 0.075, relativeY: 0.1, angle: Math.PI / 2, direction: 'down' },
{ relativeX: 0.375 + Math.random() * 0.075, relativeY: 0, angle: Math.PI / 2, direction: 'down' },
// Unten spawnen, nach oben fahren, auf der rechten Straßenseite (x=0.55-0.625)
{ relativeX: 0.55 + Math.random() * 0.075, relativeY: 0.9, angle: -Math.PI / 2, direction: 'up' }
// Direkt im befahrbaren Bereich starten (relY ≈ 0.78)
{ relativeX: 0.55 + Math.random() * 0.075, relativeY: 1, angle: -Math.PI / 2, direction: 'up' }
];
// Wähle eine zufällige Spawn-Position
const spawnPos = spawnPositions[Math.floor(Math.random() * spawnPositions.length)];
// Debug: Aktueller Tile-Typ und Wahl
try {
const tileRaw = this.getCurrentTileType();
const streetType = this.mapTileTypeToStreetCoordinates(tileRaw);
if (spawnPos.direction === 'up') {
console.log('[Cars][debug] fromBottom on tile', { tileRaw, streetType });
}
} catch (_) {}
// Konvertiere relative Koordinaten zu absoluten Pixeln
const x = spawnPos.relativeX * tileSize;
const y = spawnPos.relativeY * tileSize;
// Intensive Debug-Ausgaben für dir==='up'
if (spawnPos.direction === 'up') {
console.log('[Cars][debug] fromBottom candidate', {
relX: Number(spawnPos.relativeX.toFixed(3)),
relY: Number(spawnPos.relativeY.toFixed(3)),
x: Math.round(x), y: Math.round(y)
});
}
// Prüfe ob Position befahrbar ist
if (this.isPositionDriveable(x, y)) {
// Prüfe ob Position befahrbar ist (für Autos: Rand entspannt)
if (this.isPositionDriveableForCars(x, y, spawnPos.direction)) {
return {
x: x,
y: y,
@@ -1436,8 +1490,15 @@ export default {
const pos = spawnPositions[i];
const testX = pos.relativeX * tileSize;
const testY = pos.relativeY * tileSize;
if (pos.direction === 'up') {
console.log('[Cars][debug] fromBottom fallback-candidate', {
relX: Number(pos.relativeX.toFixed(3)),
relY: Number(pos.relativeY.toFixed(3)),
x: Math.round(testX), y: Math.round(testY), ok: this.isPositionDriveable(testX, testY)
});
}
if (this.isPositionDriveable(testX, testY)) {
if (this.isPositionDriveableForCars(testX, testY, pos.direction)) {
return {
x: testX,
y: testY,
@@ -1446,6 +1507,9 @@ export default {
};
}
}
if (spawnPos.direction === 'up') {
console.warn('[Cars][debug] fromBottom: no driveable spawn found');
}
return null; // Keine gültige Position gefunden
},
@@ -1462,6 +1526,23 @@ export default {
return streetCoordinates.isPointDriveable(relativeX, relativeY, streetTileType, 1);
},
// Fahrzeuge (KI) dürfen in den Screen hineingleiten: Ränder als befahrbar behandeln
isPositionDriveableForCars(x, y, direction) {
// Toleranz: 1px über/unter dem Canvasrand als befahrbar werten
if (x < 0 || y < 0 || x > this.tiles.size || y > this.tiles.size) {
// Wenn wir am Rand nach innen fahren, erlauben
// up: y nimmt ab; down: y nimmt zu; right: x nimmt zu; left: x nimmt ab
if (direction === 'up' && y >= -1) return true;
if (direction === 'down' && y <= this.tiles.size + 1) return true;
if (direction === 'right' && x <= this.tiles.size + 1) return true;
if (direction === 'left' && x >= -1) return true;
// weit außerhalb: nicht befahrbar
return false;
}
// Innerhalb des Tiles: normale Prüfung
return this.isPositionDriveable(x, y);
},
// Zufällige Auto-Farbe
getRandomCarColor() {
@@ -1522,8 +1603,8 @@ export default {
const newX = car.x + Math.cos(car.angle) * car.speed;
const newY = car.y + Math.sin(car.angle) * car.speed;
// Prüfe ob neue Position befahrbar ist
if (this.isPositionDriveable(newX, newY)) {
// Prüfe ob neue Position befahrbar ist (Autos dürfen an Rändern hinein gleiten)
if (this.isPositionDriveableForCars(newX, newY, car.direction)) {
// Position ist befahrbar - bewege Auto
car.x = newX;
car.y = newY;
@@ -1535,7 +1616,7 @@ export default {
this.turnCarToTarget(car);
const tryX = car.x + Math.cos(car.angle) * car.speed;
const tryY = car.y + Math.sin(car.angle) * car.speed;
if (this.isPositionDriveable(tryX, tryY)) {
if (this.isPositionDriveableForCars(tryX, tryY, car.direction)) {
car.x = tryX;
car.y = tryY;
} else {
@@ -1712,7 +1793,7 @@ export default {
const angle = name === 'right' ? 0 : (name === 'left' ? Math.PI : (name === 'down' ? Math.PI/2 : -Math.PI/2));
const testX = car.x + Math.cos(angle) * car.speed;
const testY = car.y + Math.sin(angle) * car.speed;
if (this.isPositionDriveable(testX, testY)) {
if (this.isPositionDriveableForCars(testX, testY, name)) {
car.angle = angle;
car.direction = name;
return;