diff --git a/src/GameScene.js b/src/GameScene.js index 89de80c..0d03bd3 100644 --- a/src/GameScene.js +++ b/src/GameScene.js @@ -15,6 +15,7 @@ export class GameScene extends Phaser.Scene { this.startRows = 5; this.level = 1; this.levelTime = 60; + this.isDropping = false; // Add selectedJewel property this.selectedJewel = null; @@ -252,7 +253,10 @@ export class GameScene extends Phaser.Scene { targets: this.swapWithJewel, x: fromX, y: fromY, - duration: 300 + duration: 300, + onComplete: () => { + this.checkMatches(); + } }); this.selectedJewel = null; this.swapWithJewel = null; @@ -268,8 +272,213 @@ export class GameScene extends Phaser.Scene { this.isSwapping = false; }); - - // Check for Matches - } + + // Function to check for matches and destroy them + checkMatches() { + const matchedJewels = new Set(); + + // Check horizontal matches + for (let row = 1; row <= this.gridConfig.rows; row++) { + let count = 1; + let currentType = this.getJewelAtPosition(1, row); + + for (let col = 2; col <= this.gridConfig.cols; col++) { + const jewelType = this.getJewelAtPosition(col, row); + + if (jewelType === currentType && jewelType !== null) { + count++; + } else { + if (count >= 3) { + // Add all jewels in this match to the matched set + for (let i = col - count; i < col; i++) { + const key = `${i},${row}`; + matchedJewels.add(key); + } + } + count = 1; + currentType = jewelType; + } + } + + // Check for match at the end of row + if (count >= 3) { + for (let i = this.gridConfig.cols - count + 1; i <= this.gridConfig.cols; i++) { + const key = `${i},${row}`; + matchedJewels.add(key); + } + } + } + + // Check vertical matches + for (let col = 1; col <= this.gridConfig.cols; col++) { + let count = 1; + let currentType = this.getJewelAtPosition(col, 0); + + for (let row = 1; row <= this.gridConfig.rows; row++) { + const jewelType = this.getJewelAtPosition(col, row); + + if (jewelType === currentType && jewelType !== null) { + count++; + } else { + if (count >= 3) { + // Add all jewels in this match to the matched set + for (let i = row - count; i < row; i++) { + const key = `${col},${i}`; + matchedJewels.add(key); + } + } + count = 1; + currentType = jewelType; + } + } + + // Check for match at the end of column + if (count >= 3) { + for (let i = this.gridConfig.rows - count + 1; i <= this.gridConfig.rows; i++) { + const key = `${col},${i}`; + matchedJewels.add(key); + } + } + } + + // If we found matches, destroy them + if (matchedJewels.size > 0) { + this.destroyMatchedJewels(matchedJewels); + return true; + } + + return false; + } + + // Function to destroy matched jewels + destroyMatchedJewels(matchedJewels) { + // Create an array of jewels to destroy + const jewelsToDestroy = []; + + this.jewels.children.iterate((jewel) => { + if (jewel) { + const col = Math.floor((jewel.x - this.gridConfig.leftPadding) / this.gridConfig.jewelWidth); + const row = Math.floor(jewel.y / this.gridConfig.jewelHeight); + const key = `${col},${row}`; + + if (matchedJewels.has(key)) { + jewelsToDestroy.push(jewel); + } + } + }); + + // Animate destruction + jewelsToDestroy.forEach((jewel) => { + this.tweens.add({ + targets: jewel, + scaleX: 0, + scaleY: 0, + alpha: 0, + duration: 200, + onComplete: () => { + jewel.destroy(); + this.time.delayedCall(100, () => { + this.dropJewels(); + }); + } + }); + }); + } + + dropJewels() { + if (this.isDropping) { + return; + } + + this.isDropping = true; + console.log('drop'); + + // Create a grid representation to track jewel positions + const grid = []; + for (let row = 1; row <= this.gridConfig.rows; row++) { + grid[row] = []; + for (let col = 1; col <= this.gridConfig.cols; col++) { + grid[row][col] = null; + } + } + + // Populate the grid with jewel positions + this.jewels.children.iterate((jewel) => { + if (jewel) { + const col = Math.floor((jewel.x - this.gridConfig.leftPadding) / this.gridConfig.jewelWidth); + const row = Math.floor(jewel.y / this.gridConfig.jewelHeight); + + // Ensure we're within grid bounds + if (col >= 1 && col <= this.gridConfig.cols && row >= 1 && row <= this.gridConfig.rows) { + grid[row][col] = jewel; + } + } + }); + + // Find jewels that need to drop and their target positions + const jewelsToDrop = []; + + for (let col = 1; col <= this.gridConfig.cols; col++) { + let emptySpaces = 0; + + // Process from bottom to top + for (let row = this.gridConfig.rows; row >= 1; row--) { + if (grid[row][col] === null) { + emptySpaces++; + } else if (emptySpaces > 0) { + // This jewel needs to drop + const jewel = grid[row][col]; + const targetRow = row + emptySpaces; + + jewelsToDrop.push({ + jewel: jewel, + fromRow: row, + toRow: targetRow + }); + + // Update grid reference + grid[row][col] = null; + grid[targetRow][col] = jewel; + } + } + } + + // If no jewels need to drop, we're done + if (jewelsToDrop.length === 0) { + this.isDropping = false; + return; + } + + // Animate the dropping + let droppedCount = 0; + + jewelsToDrop.forEach((dropInfo) => { + const { jewel, fromRow, toRow } = dropInfo; + + // Calculate target y position + const targetY = toRow * this.gridConfig.jewelHeight; + + // Animate the jewel dropping + this.tweens.add({ + targets: jewel, + y: targetY, + duration: 300, + ease: 'Linear', + onComplete: () => { + droppedCount++; + + // When all jewels have dropped, check for new matches + if (droppedCount === jewelsToDrop.length) { + this.time.delayedCall(100, () => { + this.isDropping = false; + // Check for new matches after dropping + this.checkMatches(); + }); + } + } + }); + }); + } + } \ No newline at end of file