feat(match3): Erweiterung der Match-Logik und Einführung neuer Power-Ups
- Hinzufügen von Regenbogen-Power-ups zur Spielmechanik, die durch 5er-Matches aktiviert werden. - Anpassung der Logik zur Erkennung von 5er-Matches und deren Priorisierung vor L-Form-Matches. - Verbesserung der Darstellung und Animationen für Bomben und Regenbogen-Power-ups. - Erweiterung der Debug-Ausgaben zur besseren Nachverfolgbarkeit von Power-ups und Matches. - Implementierung von neuen Methoden zur Aktivierung und Handhabung von Power-ups im Spiel.
This commit is contained in:
@@ -1502,12 +1502,41 @@ export default {
|
||||
console.log(`🔧 Versuch ${attempts + 1}: ${initialMatches.length} Matches gefunden`);
|
||||
|
||||
// Wähle einen zufälligen Match
|
||||
if (initialMatches.length === 0) {
|
||||
console.log('🔧 Keine Matches mehr gefunden, Level ist bereit');
|
||||
break;
|
||||
}
|
||||
|
||||
const randomMatch = initialMatches[Math.floor(Math.random() * initialMatches.length)];
|
||||
|
||||
// Prüfe ob der Match gültig ist
|
||||
if (!Array.isArray(randomMatch) || randomMatch.length === 0) {
|
||||
console.warn('⚠️ Ungültiger Match gefunden, überspringe diesen Versuch');
|
||||
attempts++;
|
||||
continue;
|
||||
}
|
||||
|
||||
const randomTileIndex = randomMatch[Math.floor(Math.random() * randomMatch.length)];
|
||||
|
||||
// Prüfe ob der Index gültig ist und ein Tile existiert
|
||||
if (randomTileIndex === null || randomTileIndex === undefined ||
|
||||
randomTileIndex < 0 || randomTileIndex >= this.board.length ||
|
||||
!this.board[randomTileIndex]) {
|
||||
console.warn(`⚠️ Ungültiger Tile-Index: ${randomTileIndex}, überspringe diesen Versuch`);
|
||||
attempts++;
|
||||
continue;
|
||||
}
|
||||
|
||||
const currentType = this.board[randomTileIndex].type;
|
||||
|
||||
// Wähle einen anderen Tile-Typ
|
||||
const availableTypes = this.tileTypes.filter(type => type !== currentType);
|
||||
if (availableTypes.length === 0) {
|
||||
console.warn('⚠️ Keine alternativen Tile-Typen verfügbar, überspringe diesen Versuch');
|
||||
attempts++;
|
||||
continue;
|
||||
}
|
||||
|
||||
const newType = availableTypes[Math.floor(Math.random() * availableTypes.length)];
|
||||
|
||||
// Ändere den Tile-Typ
|
||||
@@ -1772,6 +1801,20 @@ export default {
|
||||
console.log('🔧 Erstelle Power-ups nach der Tile-Entfernung...');
|
||||
const powerUpsCreated = await this.createPowerUpsForMatches(matches);
|
||||
|
||||
// Wenn Raketen erstellt wurden, lass sie im nächsten Zug starten
|
||||
if (powerUpsCreated && powerUpsCreated.rockets && powerUpsCreated.rockets.length > 0) {
|
||||
console.log(`🚀 ${powerUpsCreated.rockets.length} Raketen erstellt - werden im nächsten Zug aktiviert`);
|
||||
|
||||
// Aktualisiere die Anzeige
|
||||
this.$forceUpdate();
|
||||
|
||||
// Warte kurz, damit die Rakete sichtbar wird
|
||||
await this.wait(300);
|
||||
|
||||
// KEINE automatische Aktivierung - Raketen bleiben auf dem Board
|
||||
// und werden erst durch Spieler-Aktionen aktiviert
|
||||
}
|
||||
|
||||
// Debug: Zeige alle Power-ups nach der Erstellung
|
||||
console.log('🔧 Debug: Alle Power-ups nach createPowerUpsForMatches:');
|
||||
this.debugPowerUps();
|
||||
@@ -1820,11 +1863,11 @@ export default {
|
||||
|
||||
// Prüfe ob Power-ups erstellt wurden - wenn ja, keine Cascade-Matches prüfen
|
||||
// Verwende den Rückgabewert von createPowerUpsForMatches
|
||||
if (!powerUpsCreated) {
|
||||
if (!powerUpsCreated || powerUpsCreated.count === 0) {
|
||||
// Nur Cascade-Matches prüfen, wenn keine Power-ups erstellt wurden
|
||||
await this.checkForCascadeMatches();
|
||||
} else {
|
||||
console.log(`🔧 ${powerUpsCreated} Power-ups erstellt - überspringe Cascade-Match-Prüfung`);
|
||||
console.log(`🔧 ${powerUpsCreated.count} Power-ups erstellt - überspringe Cascade-Match-Prüfung`);
|
||||
|
||||
// Debug: Zeige alle Power-ups nach der Verarbeitung
|
||||
console.log('🔧 Debug: Alle Power-ups nach Power-up-Verarbeitung:');
|
||||
@@ -2008,6 +2051,8 @@ export default {
|
||||
console.log('🔧 Prüfe auf Power-up-Erstellung...');
|
||||
|
||||
let powerUpsCreated = 0;
|
||||
const bombs = [];
|
||||
const rockets = [];
|
||||
|
||||
matches.forEach(match => {
|
||||
// Prüfe auf L-Form-Matches (Bomben)
|
||||
@@ -2020,6 +2065,7 @@ export default {
|
||||
console.log(`💣 Bombe an Position ${match.corner} erstellt`);
|
||||
console.log(`🔧 Board[${match.corner}] = ${JSON.stringify(this.board[match.corner])}`);
|
||||
powerUpsCreated++;
|
||||
bombs.push(match.corner);
|
||||
}
|
||||
// Prüfe auf normale 4er-Matches (Arrays)
|
||||
else if (Array.isArray(match) && match.length === 4) {
|
||||
@@ -2035,6 +2081,7 @@ export default {
|
||||
console.log(`🚀 Rakete ${rocketType} an Position ${rocketIndex} erstellt`);
|
||||
console.log(`🔧 Board[${rocketIndex}] = ${JSON.stringify(this.board[rocketIndex])}`);
|
||||
powerUpsCreated++;
|
||||
rockets.push(rocketIndex);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -2044,7 +2091,12 @@ export default {
|
||||
console.log(`🔧 ${powerUpsCreated} Power-ups erstellt und Board aktualisiert`);
|
||||
}
|
||||
|
||||
return powerUpsCreated;
|
||||
// Gib detaillierte Informationen über erstellte Power-ups zurück
|
||||
return {
|
||||
count: powerUpsCreated,
|
||||
bombs: bombs,
|
||||
rockets: rockets
|
||||
};
|
||||
},
|
||||
|
||||
// Bestimme den Raketen-Typ basierend auf der Match-Richtung
|
||||
@@ -2513,6 +2565,12 @@ export default {
|
||||
return await this.activateRocket(fromIndex, toIndex);
|
||||
}
|
||||
|
||||
// Prüfe ob ein Tile eine Bombe ist
|
||||
if (this.board[fromIndex].type === 'bomb' || this.board[toIndex].type === 'bomb') {
|
||||
console.log('💣 Bombe wird aktiviert!');
|
||||
return await this.activateBomb(fromIndex, toIndex);
|
||||
}
|
||||
|
||||
// Prüfe ob das Ziel ein leeres Feld ist
|
||||
if (!this.board[toIndex]) {
|
||||
console.log('⚠️ Verschieben auf leeres Feld nicht erlaubt');
|
||||
@@ -2613,6 +2671,113 @@ export default {
|
||||
return false;
|
||||
},
|
||||
|
||||
// Aktiviere eine Bombe (durch Verschieben oder Doppelklick)
|
||||
async activateBomb(bombIndex, targetIndex) {
|
||||
console.log(`💣 Aktiviere Bombe an Position ${bombIndex}`);
|
||||
|
||||
// Bestimme das Zentrum der Bomben-Explosion
|
||||
let explosionCenter;
|
||||
|
||||
if (this.board[bombIndex].type === 'bomb') {
|
||||
// Bombe wird auf ein Nachbarfeld verschoben
|
||||
explosionCenter = targetIndex;
|
||||
} else {
|
||||
// Ein Tile wird auf die Bombe verschoben
|
||||
explosionCenter = bombIndex;
|
||||
}
|
||||
|
||||
// Zeige Bomben-Effekt-Animation
|
||||
await this.showBombEffectAnimation(explosionCenter);
|
||||
|
||||
// Explodiere die Bombe mit 1 Ring (3x3 Bereich) - manuelle Aktivierung
|
||||
this.explodeBomb(explosionCenter, 1, true);
|
||||
|
||||
// Entferne die Bombe nach der Explosion
|
||||
if (this.board[bombIndex].type === 'bomb') {
|
||||
console.log(`💣 Entferne Bombe an Position ${bombIndex}`);
|
||||
this.board[bombIndex] = null;
|
||||
}
|
||||
|
||||
// Aktualisiere die Anzeige
|
||||
this.$forceUpdate();
|
||||
|
||||
// Führe Fall-Down-Logik aus
|
||||
await this.fallTilesDown();
|
||||
|
||||
// Fülle leere Positionen mit neuen Tiles auf
|
||||
await this.fillEmptyPositions();
|
||||
|
||||
// Erhöhe den Zug-Zähler
|
||||
this.moves++;
|
||||
this.movesLeft--;
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
// Aktiviere eine Rakete automatisch (für sofortige Aktivierung nach der Erstellung)
|
||||
async activateRocketAutomatically(rocketIndex) {
|
||||
console.log(`🚀 Aktiviere Rakete automatisch an Position ${rocketIndex}`);
|
||||
|
||||
// Wähle ein zufälliges Ziel für die Rakete
|
||||
const availableTargets = [];
|
||||
for (let i = 0; i < this.board.length; i++) {
|
||||
if (i !== rocketIndex && this.board[i] && !this.isRocketTile(this.board[i].type)) {
|
||||
availableTargets.push(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (availableTargets.length === 0) {
|
||||
console.warn('⚠️ Keine Ziele für Rakete verfügbar');
|
||||
return false;
|
||||
}
|
||||
|
||||
// Wähle ein zufälliges Ziel
|
||||
const randomTarget = availableTargets[Math.floor(Math.random() * availableTargets.length)];
|
||||
console.log(`🚀 Rakete startet auf zufälliges Ziel an Position ${randomTarget}`);
|
||||
|
||||
// Zeige Raketen-Explosions-Animation (einfache Version ohne Flug)
|
||||
await this.showRocketExplosionAnimationSimple(randomTarget);
|
||||
|
||||
// Entferne die Tiles um das Explosionszentrum
|
||||
const tilesToRemove = this.getRocketExplosionTiles(randomTarget);
|
||||
|
||||
if (tilesToRemove.size > 0) {
|
||||
console.log(`🚀 Entferne ${tilesToRemove.size} Tiles um Position ${randomTarget}`);
|
||||
|
||||
// Starte Schrumpf-Animation für alle zu entfernenden Tiles
|
||||
await this.animateTileRemoval(Array.from(tilesToRemove));
|
||||
|
||||
// Entferne alle Tiles nach der Animation
|
||||
tilesToRemove.forEach(index => {
|
||||
if (this.board[index]) {
|
||||
console.log(`🚀 Entferne Tile ${this.board[index].type} an Position ${index}`);
|
||||
this.board[index] = null;
|
||||
}
|
||||
});
|
||||
|
||||
// Entferne auch die Rakete selbst
|
||||
console.log(`🚀 Entferne Rakete an Position ${rocketIndex}`);
|
||||
this.board[rocketIndex] = null;
|
||||
|
||||
// Aktualisiere die Anzeige
|
||||
this.$forceUpdate();
|
||||
|
||||
// Führe Fall-Down-Logik aus
|
||||
await this.fallTilesDown();
|
||||
|
||||
// Fülle leere Positionen mit neuen Tiles auf
|
||||
await this.fillEmptyPositions();
|
||||
|
||||
// Erhöhe den Zug-Zähler
|
||||
this.moves++;
|
||||
this.movesLeft--;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
// Hole alle Tiles, die von der Raketen-Explosion betroffen sind
|
||||
getRocketExplosionTiles(centerIndex) {
|
||||
const tilesToRemove = new Set();
|
||||
@@ -2660,9 +2825,27 @@ export default {
|
||||
|
||||
// Verstecke Animation
|
||||
this.showRocketEffect = false;
|
||||
},
|
||||
|
||||
// Zeige Raketen-Explosions-Animation für automatische Aktivierung (ohne Flug)
|
||||
async showRocketExplosionAnimationSimple(centerIndex) {
|
||||
const centerPos = this.indexToCoords(centerIndex);
|
||||
const tileElement = document.querySelector(`[data-index="${centerIndex}"]`);
|
||||
|
||||
// Rakete fliegt zu einem zufälligen belegten Feld
|
||||
await this.rocketFlightToRandomTile();
|
||||
if (tileElement) {
|
||||
const rect = tileElement.getBoundingClientRect();
|
||||
this.rocketCenter = { x: rect.left + rect.width / 2, y: rect.top + rect.height / 2 };
|
||||
}
|
||||
|
||||
// Zeige Explosions-Animation
|
||||
this.showRocketEffect = true;
|
||||
this.playSound('rocket');
|
||||
|
||||
// Warte auf Animation
|
||||
await this.wait(1000);
|
||||
|
||||
// Verstecke Animation
|
||||
this.showRocketEffect = false;
|
||||
},
|
||||
|
||||
// Rakete fliegt zu einem zufälligen belegten Feld
|
||||
@@ -4213,7 +4396,7 @@ export default {
|
||||
this.removeAllTilesOfType(randomTileType);
|
||||
} else if (tile.type === 'bomb') {
|
||||
// Bomben-Tile: 9 Tiles rundherum entfernen
|
||||
this.explodeBomb(index, 1); // 1 Ring = 3x3 Bereich
|
||||
this.explodeBomb(index, 1, true); // 1 Ring = 3x3 Bereich - manuelle Aktivierung
|
||||
} else if (tile.type === 'rocket') {
|
||||
// Raketen-Tile: 4 Nachbarfelder löschen und Rakete starten
|
||||
this.handleRocketDoubleClick(index);
|
||||
@@ -4275,7 +4458,7 @@ export default {
|
||||
await this.showBombEffectAnimation(bombIndex);
|
||||
|
||||
// Aktiviere die Bombe (3x3 Bereich)
|
||||
this.explodeBomb(bombIndex, 1);
|
||||
this.explodeBomb(bombIndex, 1, true);
|
||||
|
||||
// Entferne die Bombe selbst
|
||||
console.log(`💣 Entferne Bombe an Position ${bombIndex}`);
|
||||
@@ -4351,7 +4534,7 @@ export default {
|
||||
// Zwei Bomben-Tiles getauscht: Entferne 2 Ringe (5x5 Bereich)
|
||||
const bombIndex = this.findBombIndex(originalTile1, originalTile2);
|
||||
if (bombIndex !== null) {
|
||||
this.explodeBomb(bombIndex, 2); // 2 Ringe = 5x5 Bereich
|
||||
this.explodeBomb(bombIndex, 2, true); // 2 Ringe = 5x5 Bereich - manuelle Aktivierung
|
||||
}
|
||||
return true;
|
||||
} else if (originalTile1.type === 'bomb' || originalTile2.type === 'bomb') {
|
||||
@@ -4362,7 +4545,7 @@ export default {
|
||||
// Finde die neue Position der Bombe
|
||||
const newBombIndex = this.findTileIndex(bombTile);
|
||||
if (newBombIndex !== null) {
|
||||
this.explodeBomb(newBombIndex, 1); // 1 Ring = 3x3 Bereich
|
||||
this.explodeBomb(newBombIndex, 1, true); // 1 Ring = 3x3 Bereich - manuelle Aktivierung
|
||||
}
|
||||
return true;
|
||||
} else if ((originalTile1.type === 'bomb' && originalTile2.type === 'rainbow') ||
|
||||
@@ -4460,7 +4643,7 @@ export default {
|
||||
},
|
||||
|
||||
// Neue Methode: Explodiere Bombe mit bestimmter Reichweite
|
||||
explodeBomb(centerIndex, rings) {
|
||||
explodeBomb(centerIndex, rings, isManualActivation = false) {
|
||||
const { row: centerRow, col: centerCol } = this.indexToCoords(centerIndex);
|
||||
const tilesToRemove = [];
|
||||
const powerUpsToTrigger = []; // Sammle Power-Ups für Kettenreaktionen
|
||||
@@ -4512,7 +4695,8 @@ export default {
|
||||
this.score += points;
|
||||
|
||||
// Löse Kettenreaktionen nur für Power-Ups aus, die noch existieren
|
||||
if (powerUpsToTrigger.length > 0) {
|
||||
// UND nur wenn es sich um eine manuelle Aktivierung handelt
|
||||
if (powerUpsToTrigger.length > 0 && isManualActivation) {
|
||||
setTimeout(() => {
|
||||
// Prüfe nochmal, ob die Power-Ups noch existieren, bevor sie ausgelöst werden
|
||||
const validPowerUps = powerUpsToTrigger.filter(powerUp =>
|
||||
@@ -4533,7 +4717,7 @@ export default {
|
||||
powerUps.forEach(powerUp => {
|
||||
if (powerUp.type === 'bomb') {
|
||||
// Bombe explodiert mit 1 Ring (3x3 Bereich)
|
||||
this.explodeBomb(powerUp.index, 1);
|
||||
this.explodeBomb(powerUp.index, 1, true);
|
||||
} else if (powerUp.type === 'rocket') {
|
||||
// Rakete startet auf zufälliges Feld
|
||||
this.launchRocketToRandomField(powerUp.index);
|
||||
@@ -4596,7 +4780,7 @@ export default {
|
||||
|
||||
// Löse alle Bomben aus
|
||||
bombIndices.forEach(index => {
|
||||
this.explodeBomb(index, 1);
|
||||
this.explodeBomb(index, 1, true);
|
||||
});
|
||||
|
||||
|
||||
@@ -4720,7 +4904,7 @@ export default {
|
||||
const landingIndex = availableIndices[randomIndex];
|
||||
|
||||
// Explodiere am Landungsort (9 Felder = 1 Ring)
|
||||
this.explodeBomb(landingIndex, 1);
|
||||
this.explodeBomb(landingIndex, 1, true);
|
||||
|
||||
|
||||
}
|
||||
@@ -5857,6 +6041,8 @@ export default {
|
||||
.game-tile.bomb {
|
||||
background: linear-gradient(45deg, #ff6b6b, #ff8e53) !important;
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
box-shadow: 0 0 15px rgba(255, 107, 107, 0.8);
|
||||
}
|
||||
|
||||
/* Bomben-Symbol */
|
||||
@@ -5865,6 +6051,16 @@ export default {
|
||||
color: white;
|
||||
text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
|
||||
font-weight: bold;
|
||||
animation: bombPulse 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes bombPulse {
|
||||
0%, 100% {
|
||||
transform: scale(1);
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Raketen-Explosions-Effekt */
|
||||
|
||||
Reference in New Issue
Block a user