User prompt
CHANGE THE IMAGE OF POWER UP TO "Power"
User prompt
IF WE MATCH 4 CANDIES, A FIERY POWER UP WILL COME, MAKE A POWER PLACE AND POWER UP WILL GO THERE. WHEN WE CLICK ON POWER UP, 5 CANDIES WILL EXPLODES AT RANDOM ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
CHANGE EXPLOSION EFFECT WITH "exp" ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
CHANGE EXPLOSION EFFECT ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Add explosion effect ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
IF WE DRAG THE CANDIES AND BRING THEM TO 3 JERSEYS SIDE BY SIDE, WE WILL GET POINTS, ADD POINT COUNTER
User prompt
WHY I CANNOT MATCH FIX Let's make a match by swiping
User prompt
BALLS CAME CLOSE TO THE SCREEN
User prompt
THE BALLS ARE TOO SMALL, MAKE THEM BIGGER
Code edit (1 edits merged)
Please save this source code
User prompt
Sweet Gem Crusher
Initial prompt
DO ME CAMDY CRUSH AND IT WILL BE THE SAME, NOTHING IS MISSING, LET IT BE POINTS, EVEN POINTS, EVEN A COMBO
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Candy = Container.expand(function (type) { var self = Container.call(this); self.type = type; self.gridX = 0; self.gridY = 0; self.isMatched = false; var candyAsset = self.attachAsset('candy' + type, { anchorX: 0.5, anchorY: 0.5 }); self.setGridPosition = function (gridX, gridY) { self.gridX = gridX; self.gridY = gridY; self.x = GRID_START_X + gridX * CELL_SIZE + CELL_SIZE / 2; self.y = GRID_START_Y + gridY * CELL_SIZE + CELL_SIZE / 2; }; self.animateToGridPosition = function (gridX, gridY, duration) { self.gridX = gridX; self.gridY = gridY; var targetX = GRID_START_X + gridX * CELL_SIZE + CELL_SIZE / 2; var targetY = GRID_START_Y + gridY * CELL_SIZE + CELL_SIZE / 2; tween(self, { x: targetX, y: targetY }, { duration: duration || 300, easing: tween.easeOut }); }; self.highlight = function () { tween(self, { scaleX: 1.2, scaleY: 1.2 }, { duration: 200, easing: tween.easeOut }); }; self.unhighlight = function () { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 200, easing: tween.easeOut }); }; self.markForRemoval = function () { self.isMatched = true; tween(self, { scaleX: 0, scaleY: 0, alpha: 0 }, { duration: 250, easing: tween.easeIn }); }; return self; }); var ExplosivePowerUp = Container.expand(function () { var self = Container.call(this); // Create explosive visual effect using Power asset with different tint var powerUpAsset = self.attachAsset('Power', { anchorX: 0.5, anchorY: 0.5 }); powerUpAsset.tint = 0xFF0000; // Red tint for explosive power-up // Add pulsing animation self.pulseAnimation = function () { tween(self, { scaleX: 1.4, scaleY: 1.4 }, { duration: 600, easing: tween.easeInOut, onFinish: function onFinish() { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 600, easing: tween.easeInOut, onFinish: function onFinish() { if (self.parent) self.pulseAnimation(); } }); } }); }; // Start pulsing immediately self.pulseAnimation(); // Handle click on power-up self.down = function (x, y, obj) { self.activate(); }; self.activate = function () { // Create explosion effect at power-up location var explosion = game.addChild(LK.getAsset('Exp', { anchorX: 0.5, anchorY: 0.5 })); explosion.x = self.x; explosion.y = self.y; explosion.scaleX = 0.1; explosion.scaleY = 0.1; explosion.alpha = 0.8; // Animate explosion tween(explosion, { scaleX: 6, scaleY: 6, alpha: 0, rotation: Math.PI * 3 }, { duration: 600, easing: tween.easeOut, onFinish: function onFinish() { explosion.destroy(); } }); // Explode 5x5 random area self.explode5x5Area(); // Remove power-up var index = powerUps.indexOf(self); if (index > -1) { powerUps.splice(index, 1); } // Update power-up counter display powerUpCountText.setText('Power-ups: ' + powerUps.length); self.destroy(); }; self.explode5x5Area = function () { // Find a random 5x5 area on the grid var startX = Math.floor(Math.random() * (GRID_SIZE - 4)); // Ensure 5x5 fits var startY = Math.floor(Math.random() * (GRID_SIZE - 4)); var candiesToExplode = []; // Collect all candies in the 5x5 area for (var i = 0; i < 5; i++) { for (var j = 0; j < 5; j++) { var gridX = startX + i; var gridY = startY + j; if (grid[gridX][gridY] && !grid[gridX][gridY].isMatched) { candiesToExplode.push(grid[gridX][gridY]); } } } // Explode all candies in the area with staggered timing for (var i = 0; i < candiesToExplode.length; i++) { (function (candy, delay) { LK.setTimeout(function () { // Create explosion effect var explosion = game.addChild(LK.getAsset('Exp', { anchorX: 0.5, anchorY: 0.5 })); explosion.x = candy.x; explosion.y = candy.y; explosion.scaleX = 0.1; explosion.scaleY = 0.1; explosion.alpha = 0.8; // Animate explosion tween(explosion, { scaleX: 3, scaleY: 3, alpha: 0, rotation: Math.PI * 2 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { explosion.destroy(); } }); // Remove candy from grid candy.alpha = 0; grid[candy.gridX][candy.gridY] = null; // Remove from candies array var index = candies.indexOf(candy); if (index > -1) { candies.splice(index, 1); } // Destroy candy after explosion LK.setTimeout(function () { candy.destroy(); }, 300); }, delay); })(candiesToExplode[i], i * 50); } // Process gravity and refill after all explosions LK.setTimeout(function () { // Add score for power-up activation gameScore += 500; scoreText.setText('Score: ' + gameScore); LK.setScore(gameScore); // Process the board LK.setTimeout(function () { applyGravity(); fillEmptySpaces(); LK.setTimeout(function () { processMatches(); }, 300); }, 100); }, candiesToExplode.length * 50 + 300); }; return self; }); var FirePowerUp = Container.expand(function () { var self = Container.call(this); // Create fiery visual effect using Power asset var powerUpAsset = self.attachAsset('Power', { anchorX: 0.5, anchorY: 0.5 }); // Add pulsing animation self.pulseAnimation = function () { tween(self, { scaleX: 1.3, scaleY: 1.3 }, { duration: 800, easing: tween.easeInOut, onFinish: function onFinish() { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 800, easing: tween.easeInOut, onFinish: function onFinish() { if (self.parent) self.pulseAnimation(); } }); } }); }; // Start pulsing immediately self.pulseAnimation(); // Handle click on power-up self.down = function (x, y, obj) { self.activate(); }; self.activate = function () { // Create explosion effect at power-up location var explosion = game.addChild(LK.getAsset('Exp', { anchorX: 0.5, anchorY: 0.5 })); explosion.x = self.x; explosion.y = self.y; explosion.scaleX = 0.1; explosion.scaleY = 0.1; explosion.alpha = 0.8; // Animate explosion tween(explosion, { scaleX: 4, scaleY: 4, alpha: 0, rotation: Math.PI * 2 }, { duration: 400, easing: tween.easeOut, onFinish: function onFinish() { explosion.destroy(); } }); // Explode 5 random candies self.explodeRandomCandies(); // Remove power-up var index = powerUps.indexOf(self); if (index > -1) { powerUps.splice(index, 1); } // Update power-up counter display powerUpCountText.setText('Power-ups: ' + powerUps.length); self.destroy(); }; self.explodeRandomCandies = function () { var availableCandies = []; for (var i = 0; i < candies.length; i++) { if (candies[i].parent && !candies[i].isMatched) { availableCandies.push(candies[i]); } } // Select up to 5 random candies var candiesToExplode = []; var numToExplode = Math.min(5, availableCandies.length); for (var i = 0; i < numToExplode; i++) { var randomIndex = Math.floor(Math.random() * availableCandies.length); candiesToExplode.push(availableCandies[randomIndex]); availableCandies.splice(randomIndex, 1); } // Explode selected candies with slight delay between each for (var i = 0; i < candiesToExplode.length; i++) { (function (candy, delay) { LK.setTimeout(function () { // Create explosion effect var explosion = game.addChild(LK.getAsset('Exp', { anchorX: 0.5, anchorY: 0.5 })); explosion.x = candy.x; explosion.y = candy.y; explosion.scaleX = 0.1; explosion.scaleY = 0.1; explosion.alpha = 0.8; // Animate explosion tween(explosion, { scaleX: 3, scaleY: 3, alpha: 0, rotation: Math.PI * 2 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { explosion.destroy(); } }); // Remove candy from grid candy.alpha = 0; grid[candy.gridX][candy.gridY] = null; // Remove from candies array var index = candies.indexOf(candy); if (index > -1) { candies.splice(index, 1); } // Destroy candy after explosion LK.setTimeout(function () { candy.destroy(); }, 300); }, delay); })(candiesToExplode[i], i * 100); } // Process gravity and refill after all explosions LK.setTimeout(function () { // Add score for power-up activation gameScore += 250; scoreText.setText('Score: ' + gameScore); LK.setScore(gameScore); // Process the board LK.setTimeout(function () { applyGravity(); fillEmptySpaces(); LK.setTimeout(function () { processMatches(); }, 300); }, 100); }, candiesToExplode.length * 100 + 300); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0xFFC0CB }); /**** * Game Code ****/ var GRID_SIZE = 8; var CELL_SIZE = 140; var GRID_START_X = (2048 - GRID_SIZE * CELL_SIZE) / 2; var GRID_START_Y = (2732 - GRID_SIZE * CELL_SIZE) / 2 - 200; var grid = []; var candies = []; var selectedCandy = null; var isProcessing = false; var gameScore = 0; var comboMultiplier = 1; var powerUps = []; var hasSpawned1000PowerUp = false; var POWER_UP_AREA_Y = GRID_START_Y + GRID_SIZE * CELL_SIZE + 150; var SECOND_POWER_UP_AREA_Y = POWER_UP_AREA_Y + 200; var gameStarted = false; var countdownValue = 3; var countdownText = new Text2('3', { size: 200, fill: 0xFFD700 }); // Initialize grid background var gridBackground = game.addChild(LK.getAsset('gridBg', { anchorX: 0.5, anchorY: 0.5 })); gridBackground.x = 2048 / 2; gridBackground.y = GRID_START_Y + GRID_SIZE * CELL_SIZE / 2; // Create cell backgrounds for (var i = 0; i < GRID_SIZE; i++) { for (var j = 0; j < GRID_SIZE; j++) { var cellBg = game.addChild(LK.getAsset('cellBg', { anchorX: 0.5, anchorY: 0.5 })); cellBg.x = GRID_START_X + i * CELL_SIZE + CELL_SIZE / 2; cellBg.y = GRID_START_Y + j * CELL_SIZE + CELL_SIZE / 2; } } // Initialize score display var scoreText = new Text2('Score: 0', { size: 80, fill: 0xFFFFFF }); scoreText.anchor.set(0.5, 0); scoreText.y = 50; LK.gui.top.addChild(scoreText); // Initialize combo display var comboText = new Text2('', { size: 50, fill: 0xFFD700 }); comboText.anchor.set(0.5, 0); comboText.y = 140; LK.gui.top.addChild(comboText); // Initialize power-up counter display var powerUpCountText = new Text2('Power-ups: 0', { size: 60, fill: 0xFF4500 }); powerUpCountText.anchor.set(0.5, 0); powerUpCountText.y = 200; LK.gui.top.addChild(powerUpCountText); // Setup countdown display countdownText.anchor.set(0.5, 0.5); countdownText.x = 2048 / 2; countdownText.y = 2732 / 2 - 150; game.addChild(countdownText); // Create power-up area var powerUpArea = game.addChild(LK.getAsset('powerUpBg', { anchorX: 0.5, anchorY: 0.5 })); powerUpArea.x = 2048 / 2 - 250; powerUpArea.y = POWER_UP_AREA_Y; powerUpArea.alpha = 0.8; // Create second power-up area var secondPowerUpArea = game.addChild(LK.getAsset('powerUpBg', { anchorX: 0.5, anchorY: 0.5 })); secondPowerUpArea.x = 2048 / 2 + 250; secondPowerUpArea.y = POWER_UP_AREA_Y; secondPowerUpArea.alpha = 0.8; secondPowerUpArea.tint = 0xFF4444; // Red tint to distinguish from first area // Initialize grid array function initializeGrid() { grid = []; for (var i = 0; i < GRID_SIZE; i++) { grid[i] = []; for (var j = 0; j < GRID_SIZE; j++) { grid[i][j] = null; } } } // Start countdown timer function startCountdown() { if (countdownValue > 0) { countdownText.setText(countdownValue.toString()); tween(countdownText, { scaleX: 1.5, scaleY: 1.5 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(countdownText, { scaleX: 1, scaleY: 1 }, { duration: 200, easing: tween.easeIn }); } }); countdownValue--; LK.setTimeout(startCountdown, 1000); } else { countdownText.setText('GO!'); tween(countdownText, { scaleX: 2, scaleY: 2, alpha: 0 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { countdownText.destroy(); gameStarted = true; // Play music when game starts LK.playMusic('music'); // Initialize game after countdown initializeGrid(); fillGrid(); // Remove initial matches LK.setTimeout(function () { processMatches(); }, 100); } }); } } // Generate random candy type function getRandomCandyType() { return Math.floor(Math.random() * 6) + 1; } // Create candy at grid position function createCandy(gridX, gridY) { var candyType = getRandomCandyType(); var candy = new Candy(candyType); candy.setGridPosition(gridX, gridY); game.addChild(candy); candies.push(candy); grid[gridX][gridY] = candy; return candy; } // Fill grid with initial candies function fillGrid() { for (var i = 0; i < GRID_SIZE; i++) { for (var j = 0; j < GRID_SIZE; j++) { if (!grid[i][j]) { createCandy(i, j); } } } } // Check if coordinates are valid function isValidPosition(x, y) { return x >= 0 && x < GRID_SIZE && y >= 0 && y < GRID_SIZE; } // Check if two positions are adjacent function areAdjacent(x1, y1, x2, y2) { var dx = Math.abs(x1 - x2); var dy = Math.abs(y1 - y2); return dx === 1 && dy === 0 || dx === 0 && dy === 1; } // Swap two candies function swapCandies(candy1, candy2) { if (!candy1 || !candy2) return; var tempX = candy1.gridX; var tempY = candy1.gridY; grid[candy1.gridX][candy1.gridY] = candy2; grid[candy2.gridX][candy2.gridY] = candy1; candy1.animateToGridPosition(candy2.gridX, candy2.gridY); candy2.animateToGridPosition(tempX, tempY); try { LK.getSound('swap').play(); } catch (e) { console.log('Error playing swap sound:', e); } } // Find matches in a line function findMatches(startX, startY, deltaX, deltaY) { var matches = []; var currentCandy = grid[startX][startY]; if (!currentCandy) return matches; var count = 1; matches.push(currentCandy); // Check forward var x = startX + deltaX; var y = startY + deltaY; while (isValidPosition(x, y) && grid[x][y] && grid[x][y].type === currentCandy.type) { matches.push(grid[x][y]); count++; x += deltaX; y += deltaY; } // Check backward x = startX - deltaX; y = startY - deltaY; while (isValidPosition(x, y) && grid[x][y] && grid[x][y].type === currentCandy.type) { matches.unshift(grid[x][y]); count++; x -= deltaX; y -= deltaY; } return count >= 3 ? matches : []; } // Find all matches on the board function findAllMatches() { var allMatches = []; var processed = []; for (var i = 0; i < GRID_SIZE; i++) { processed[i] = []; for (var j = 0; j < GRID_SIZE; j++) { processed[i][j] = false; } } for (var i = 0; i < GRID_SIZE; i++) { for (var j = 0; j < GRID_SIZE; j++) { if (grid[i][j] && !processed[i][j]) { // Check horizontal matches var horizontalMatches = findMatches(i, j, 1, 0); if (horizontalMatches.length >= 3) { for (var k = 0; k < horizontalMatches.length; k++) { var candy = horizontalMatches[k]; processed[candy.gridX][candy.gridY] = true; if (allMatches.indexOf(candy) === -1) { allMatches.push(candy); } } } // Check vertical matches var verticalMatches = findMatches(i, j, 0, 1); if (verticalMatches.length >= 3) { for (var k = 0; k < verticalMatches.length; k++) { var candy = verticalMatches[k]; processed[candy.gridX][candy.gridY] = true; if (allMatches.indexOf(candy) === -1) { allMatches.push(candy); } } } } } } return allMatches; } // Remove matched candies function removeMatches(matches) { for (var i = 0; i < matches.length; i++) { var candy = matches[i]; // Create explosion effect using "exp" asset var explosion = game.addChild(LK.getAsset('Exp', { anchorX: 0.5, anchorY: 0.5 })); explosion.x = candy.x; explosion.y = candy.y; explosion.scaleX = 0.1; explosion.scaleY = 0.1; explosion.alpha = 0.8; // Animate explosion growth and fade tween(explosion, { scaleX: 3, scaleY: 3, alpha: 0, rotation: Math.PI * 2 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { explosion.destroy(); } }); // Hide the candy immediately candy.alpha = 0; grid[candy.gridX][candy.gridY] = null; // Remove from candies array var index = candies.indexOf(candy); if (index > -1) { candies.splice(index, 1); } } // Check if we should create a power-up (4 or more candies matched) if (matches.length >= 4) { // Create fire power-up var firePowerUp = new FirePowerUp(); firePowerUp.x = 2048 / 2 - 250; firePowerUp.y = POWER_UP_AREA_Y; game.addChild(firePowerUp); powerUps.push(firePowerUp); // Update power-up counter display powerUpCountText.setText('Power-ups: ' + powerUps.length); // Flash screen to indicate power-up creation LK.effects.flashScreen(0xFF4500, 500); } // Check if we should create the special 1000-point explosive power-up if (gameScore >= 1000 && !hasSpawned1000PowerUp) { hasSpawned1000PowerUp = true; // Create explosive power-up var explosivePowerUp = new ExplosivePowerUp(); explosivePowerUp.x = 2048 / 2 + 250; explosivePowerUp.y = POWER_UP_AREA_Y; game.addChild(explosivePowerUp); powerUps.push(explosivePowerUp); // Update power-up counter display powerUpCountText.setText('Power-ups: ' + powerUps.length); // Flash screen with different color to indicate special power-up LK.effects.flashScreen(0xFF0000, 800); } // Calculate score var baseScore = matches.length * 10; var bonusScore = matches.length > 3 ? (matches.length - 3) * 20 : 0; var totalScore = (baseScore + bonusScore) * comboMultiplier; gameScore += totalScore; scoreText.setText('Score: ' + gameScore); LK.setScore(gameScore); // Show combo feedback if (comboMultiplier > 1) { comboText.setText('COMBO x' + comboMultiplier + ' (+' + totalScore + ')'); comboText.alpha = 1; tween(comboText, { alpha: 0 }, { duration: 1000, easing: tween.easeOut }); } else { comboText.setText(''); } // Flash screen effect for big matches if (matches.length >= 5) { LK.effects.flashScreen(0xFFD700, 300); } try { LK.getSound('match').play(); } catch (e) { console.log('Error playing match sound:', e); } // Schedule removal after explosion animation LK.setTimeout(function () { for (var i = 0; i < matches.length; i++) { matches[i].destroy(); } }, 300); } // Make candies fall down function applyGravity() { var moved = false; for (var i = 0; i < GRID_SIZE; i++) { for (var j = GRID_SIZE - 2; j >= 0; j--) { if (grid[i][j]) { var fallDistance = 0; var checkY = j + 1; while (checkY < GRID_SIZE && !grid[i][checkY]) { fallDistance++; checkY++; } if (fallDistance > 0) { var candy = grid[i][j]; grid[i][j] = null; grid[i][j + fallDistance] = candy; candy.animateToGridPosition(i, j + fallDistance); moved = true; } } } } return moved; } // Fill empty spaces with new candies function fillEmptySpaces() { var added = false; for (var i = 0; i < GRID_SIZE; i++) { for (var j = 0; j < GRID_SIZE; j++) { if (!grid[i][j]) { var candy = createCandy(i, j); // Start candy above the grid and animate down candy.y = GRID_START_Y - 100; candy.animateToGridPosition(i, j); added = true; } } } return added; } // Check if move creates matches function wouldCreateMatch(candy1, candy2) { // Store original positions var origX1 = candy1.gridX; var origY1 = candy1.gridY; var origX2 = candy2.gridX; var origY2 = candy2.gridY; // Temporarily swap in grid grid[candy1.gridX][candy1.gridY] = candy2; grid[candy2.gridX][candy2.gridY] = candy1; // Temporarily swap candy positions candy1.gridX = origX2; candy1.gridY = origY2; candy2.gridX = origX1; candy2.gridY = origY1; var matches1 = findMatches(candy1.gridX, candy1.gridY, 1, 0); var matches2 = findMatches(candy1.gridX, candy1.gridY, 0, 1); var matches3 = findMatches(candy2.gridX, candy2.gridY, 1, 0); var matches4 = findMatches(candy2.gridX, candy2.gridY, 0, 1); var hasMatch = matches1.length >= 3 || matches2.length >= 3 || matches3.length >= 3 || matches4.length >= 3; // Restore original positions candy1.gridX = origX1; candy1.gridY = origY1; candy2.gridX = origX2; candy2.gridY = origY2; grid[origX1][origY1] = candy1; grid[origX2][origY2] = candy2; return hasMatch; } // Process matches and cascades function processMatches() { if (isProcessing) return; isProcessing = true; var matches = findAllMatches(); if (matches.length > 0) { removeMatches(matches); comboMultiplier++; LK.setTimeout(function () { var gravityApplied = applyGravity(); var spacesAdded = fillEmptySpaces(); if (gravityApplied || spacesAdded) { LK.setTimeout(function () { isProcessing = false; processMatches(); // Check for new matches }, 300); } else { isProcessing = false; comboMultiplier = 1; } }, 300); } else { isProcessing = false; comboMultiplier = 1; } } // Get candy at screen position function getCandyAt(x, y) { // Calculate grid coordinates from screen position var gridX = Math.floor((x - GRID_START_X) / CELL_SIZE); var gridY = Math.floor((y - GRID_START_Y) / CELL_SIZE); // Check if coordinates are within grid bounds if (gridX >= 0 && gridX < GRID_SIZE && gridY >= 0 && gridY < GRID_SIZE) { return grid[gridX][gridY]; } return null; } var dragStartCandy = null; var dragCurrentCandy = null; // Game input handling game.down = function (x, y, obj) { if (!gameStarted || isProcessing) return; var candy = getCandyAt(x, y); if (candy) { dragStartCandy = candy; dragCurrentCandy = candy; candy.highlight(); } }; game.move = function (x, y, obj) { if (!gameStarted || isProcessing || !dragStartCandy) return; var candy = getCandyAt(x, y); if (candy && candy !== dragCurrentCandy) { if (dragCurrentCandy && dragCurrentCandy !== dragStartCandy) { dragCurrentCandy.unhighlight(); } dragCurrentCandy = candy; if (candy !== dragStartCandy) { candy.highlight(); } } }; game.up = function (x, y, obj) { if (!gameStarted || isProcessing || !dragStartCandy) return; var endCandy = getCandyAt(x, y); if (endCandy && endCandy !== dragStartCandy && areAdjacent(dragStartCandy.gridX, dragStartCandy.gridY, endCandy.gridX, endCandy.gridY)) { if (wouldCreateMatch(dragStartCandy, endCandy)) { swapCandies(dragStartCandy, endCandy); LK.setTimeout(function () { processMatches(); }, 400); } else { // Invalid move - swap back try { LK.getSound('Wro').play(); } catch (e) { console.log('Error playing wrong move sound:', e); } dragStartCandy.unhighlight(); if (endCandy) endCandy.unhighlight(); } } else { // No valid target - just unhighlight dragStartCandy.unhighlight(); if (dragCurrentCandy && dragCurrentCandy !== dragStartCandy) { dragCurrentCandy.unhighlight(); } } dragStartCandy = null; dragCurrentCandy = null; }; // Start countdown instead of immediate game initialization startCountdown(); game.update = function () { // Game runs automatically through event handling };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Candy = Container.expand(function (type) {
var self = Container.call(this);
self.type = type;
self.gridX = 0;
self.gridY = 0;
self.isMatched = false;
var candyAsset = self.attachAsset('candy' + type, {
anchorX: 0.5,
anchorY: 0.5
});
self.setGridPosition = function (gridX, gridY) {
self.gridX = gridX;
self.gridY = gridY;
self.x = GRID_START_X + gridX * CELL_SIZE + CELL_SIZE / 2;
self.y = GRID_START_Y + gridY * CELL_SIZE + CELL_SIZE / 2;
};
self.animateToGridPosition = function (gridX, gridY, duration) {
self.gridX = gridX;
self.gridY = gridY;
var targetX = GRID_START_X + gridX * CELL_SIZE + CELL_SIZE / 2;
var targetY = GRID_START_Y + gridY * CELL_SIZE + CELL_SIZE / 2;
tween(self, {
x: targetX,
y: targetY
}, {
duration: duration || 300,
easing: tween.easeOut
});
};
self.highlight = function () {
tween(self, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 200,
easing: tween.easeOut
});
};
self.unhighlight = function () {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.easeOut
});
};
self.markForRemoval = function () {
self.isMatched = true;
tween(self, {
scaleX: 0,
scaleY: 0,
alpha: 0
}, {
duration: 250,
easing: tween.easeIn
});
};
return self;
});
var ExplosivePowerUp = Container.expand(function () {
var self = Container.call(this);
// Create explosive visual effect using Power asset with different tint
var powerUpAsset = self.attachAsset('Power', {
anchorX: 0.5,
anchorY: 0.5
});
powerUpAsset.tint = 0xFF0000; // Red tint for explosive power-up
// Add pulsing animation
self.pulseAnimation = function () {
tween(self, {
scaleX: 1.4,
scaleY: 1.4
}, {
duration: 600,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 600,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (self.parent) self.pulseAnimation();
}
});
}
});
};
// Start pulsing immediately
self.pulseAnimation();
// Handle click on power-up
self.down = function (x, y, obj) {
self.activate();
};
self.activate = function () {
// Create explosion effect at power-up location
var explosion = game.addChild(LK.getAsset('Exp', {
anchorX: 0.5,
anchorY: 0.5
}));
explosion.x = self.x;
explosion.y = self.y;
explosion.scaleX = 0.1;
explosion.scaleY = 0.1;
explosion.alpha = 0.8;
// Animate explosion
tween(explosion, {
scaleX: 6,
scaleY: 6,
alpha: 0,
rotation: Math.PI * 3
}, {
duration: 600,
easing: tween.easeOut,
onFinish: function onFinish() {
explosion.destroy();
}
});
// Explode 5x5 random area
self.explode5x5Area();
// Remove power-up
var index = powerUps.indexOf(self);
if (index > -1) {
powerUps.splice(index, 1);
}
// Update power-up counter display
powerUpCountText.setText('Power-ups: ' + powerUps.length);
self.destroy();
};
self.explode5x5Area = function () {
// Find a random 5x5 area on the grid
var startX = Math.floor(Math.random() * (GRID_SIZE - 4)); // Ensure 5x5 fits
var startY = Math.floor(Math.random() * (GRID_SIZE - 4));
var candiesToExplode = [];
// Collect all candies in the 5x5 area
for (var i = 0; i < 5; i++) {
for (var j = 0; j < 5; j++) {
var gridX = startX + i;
var gridY = startY + j;
if (grid[gridX][gridY] && !grid[gridX][gridY].isMatched) {
candiesToExplode.push(grid[gridX][gridY]);
}
}
}
// Explode all candies in the area with staggered timing
for (var i = 0; i < candiesToExplode.length; i++) {
(function (candy, delay) {
LK.setTimeout(function () {
// Create explosion effect
var explosion = game.addChild(LK.getAsset('Exp', {
anchorX: 0.5,
anchorY: 0.5
}));
explosion.x = candy.x;
explosion.y = candy.y;
explosion.scaleX = 0.1;
explosion.scaleY = 0.1;
explosion.alpha = 0.8;
// Animate explosion
tween(explosion, {
scaleX: 3,
scaleY: 3,
alpha: 0,
rotation: Math.PI * 2
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
explosion.destroy();
}
});
// Remove candy from grid
candy.alpha = 0;
grid[candy.gridX][candy.gridY] = null;
// Remove from candies array
var index = candies.indexOf(candy);
if (index > -1) {
candies.splice(index, 1);
}
// Destroy candy after explosion
LK.setTimeout(function () {
candy.destroy();
}, 300);
}, delay);
})(candiesToExplode[i], i * 50);
}
// Process gravity and refill after all explosions
LK.setTimeout(function () {
// Add score for power-up activation
gameScore += 500;
scoreText.setText('Score: ' + gameScore);
LK.setScore(gameScore);
// Process the board
LK.setTimeout(function () {
applyGravity();
fillEmptySpaces();
LK.setTimeout(function () {
processMatches();
}, 300);
}, 100);
}, candiesToExplode.length * 50 + 300);
};
return self;
});
var FirePowerUp = Container.expand(function () {
var self = Container.call(this);
// Create fiery visual effect using Power asset
var powerUpAsset = self.attachAsset('Power', {
anchorX: 0.5,
anchorY: 0.5
});
// Add pulsing animation
self.pulseAnimation = function () {
tween(self, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (self.parent) self.pulseAnimation();
}
});
}
});
};
// Start pulsing immediately
self.pulseAnimation();
// Handle click on power-up
self.down = function (x, y, obj) {
self.activate();
};
self.activate = function () {
// Create explosion effect at power-up location
var explosion = game.addChild(LK.getAsset('Exp', {
anchorX: 0.5,
anchorY: 0.5
}));
explosion.x = self.x;
explosion.y = self.y;
explosion.scaleX = 0.1;
explosion.scaleY = 0.1;
explosion.alpha = 0.8;
// Animate explosion
tween(explosion, {
scaleX: 4,
scaleY: 4,
alpha: 0,
rotation: Math.PI * 2
}, {
duration: 400,
easing: tween.easeOut,
onFinish: function onFinish() {
explosion.destroy();
}
});
// Explode 5 random candies
self.explodeRandomCandies();
// Remove power-up
var index = powerUps.indexOf(self);
if (index > -1) {
powerUps.splice(index, 1);
}
// Update power-up counter display
powerUpCountText.setText('Power-ups: ' + powerUps.length);
self.destroy();
};
self.explodeRandomCandies = function () {
var availableCandies = [];
for (var i = 0; i < candies.length; i++) {
if (candies[i].parent && !candies[i].isMatched) {
availableCandies.push(candies[i]);
}
}
// Select up to 5 random candies
var candiesToExplode = [];
var numToExplode = Math.min(5, availableCandies.length);
for (var i = 0; i < numToExplode; i++) {
var randomIndex = Math.floor(Math.random() * availableCandies.length);
candiesToExplode.push(availableCandies[randomIndex]);
availableCandies.splice(randomIndex, 1);
}
// Explode selected candies with slight delay between each
for (var i = 0; i < candiesToExplode.length; i++) {
(function (candy, delay) {
LK.setTimeout(function () {
// Create explosion effect
var explosion = game.addChild(LK.getAsset('Exp', {
anchorX: 0.5,
anchorY: 0.5
}));
explosion.x = candy.x;
explosion.y = candy.y;
explosion.scaleX = 0.1;
explosion.scaleY = 0.1;
explosion.alpha = 0.8;
// Animate explosion
tween(explosion, {
scaleX: 3,
scaleY: 3,
alpha: 0,
rotation: Math.PI * 2
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
explosion.destroy();
}
});
// Remove candy from grid
candy.alpha = 0;
grid[candy.gridX][candy.gridY] = null;
// Remove from candies array
var index = candies.indexOf(candy);
if (index > -1) {
candies.splice(index, 1);
}
// Destroy candy after explosion
LK.setTimeout(function () {
candy.destroy();
}, 300);
}, delay);
})(candiesToExplode[i], i * 100);
}
// Process gravity and refill after all explosions
LK.setTimeout(function () {
// Add score for power-up activation
gameScore += 250;
scoreText.setText('Score: ' + gameScore);
LK.setScore(gameScore);
// Process the board
LK.setTimeout(function () {
applyGravity();
fillEmptySpaces();
LK.setTimeout(function () {
processMatches();
}, 300);
}, 100);
}, candiesToExplode.length * 100 + 300);
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xFFC0CB
});
/****
* Game Code
****/
var GRID_SIZE = 8;
var CELL_SIZE = 140;
var GRID_START_X = (2048 - GRID_SIZE * CELL_SIZE) / 2;
var GRID_START_Y = (2732 - GRID_SIZE * CELL_SIZE) / 2 - 200;
var grid = [];
var candies = [];
var selectedCandy = null;
var isProcessing = false;
var gameScore = 0;
var comboMultiplier = 1;
var powerUps = [];
var hasSpawned1000PowerUp = false;
var POWER_UP_AREA_Y = GRID_START_Y + GRID_SIZE * CELL_SIZE + 150;
var SECOND_POWER_UP_AREA_Y = POWER_UP_AREA_Y + 200;
var gameStarted = false;
var countdownValue = 3;
var countdownText = new Text2('3', {
size: 200,
fill: 0xFFD700
});
// Initialize grid background
var gridBackground = game.addChild(LK.getAsset('gridBg', {
anchorX: 0.5,
anchorY: 0.5
}));
gridBackground.x = 2048 / 2;
gridBackground.y = GRID_START_Y + GRID_SIZE * CELL_SIZE / 2;
// Create cell backgrounds
for (var i = 0; i < GRID_SIZE; i++) {
for (var j = 0; j < GRID_SIZE; j++) {
var cellBg = game.addChild(LK.getAsset('cellBg', {
anchorX: 0.5,
anchorY: 0.5
}));
cellBg.x = GRID_START_X + i * CELL_SIZE + CELL_SIZE / 2;
cellBg.y = GRID_START_Y + j * CELL_SIZE + CELL_SIZE / 2;
}
}
// Initialize score display
var scoreText = new Text2('Score: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
scoreText.y = 50;
LK.gui.top.addChild(scoreText);
// Initialize combo display
var comboText = new Text2('', {
size: 50,
fill: 0xFFD700
});
comboText.anchor.set(0.5, 0);
comboText.y = 140;
LK.gui.top.addChild(comboText);
// Initialize power-up counter display
var powerUpCountText = new Text2('Power-ups: 0', {
size: 60,
fill: 0xFF4500
});
powerUpCountText.anchor.set(0.5, 0);
powerUpCountText.y = 200;
LK.gui.top.addChild(powerUpCountText);
// Setup countdown display
countdownText.anchor.set(0.5, 0.5);
countdownText.x = 2048 / 2;
countdownText.y = 2732 / 2 - 150;
game.addChild(countdownText);
// Create power-up area
var powerUpArea = game.addChild(LK.getAsset('powerUpBg', {
anchorX: 0.5,
anchorY: 0.5
}));
powerUpArea.x = 2048 / 2 - 250;
powerUpArea.y = POWER_UP_AREA_Y;
powerUpArea.alpha = 0.8;
// Create second power-up area
var secondPowerUpArea = game.addChild(LK.getAsset('powerUpBg', {
anchorX: 0.5,
anchorY: 0.5
}));
secondPowerUpArea.x = 2048 / 2 + 250;
secondPowerUpArea.y = POWER_UP_AREA_Y;
secondPowerUpArea.alpha = 0.8;
secondPowerUpArea.tint = 0xFF4444; // Red tint to distinguish from first area
// Initialize grid array
function initializeGrid() {
grid = [];
for (var i = 0; i < GRID_SIZE; i++) {
grid[i] = [];
for (var j = 0; j < GRID_SIZE; j++) {
grid[i][j] = null;
}
}
}
// Start countdown timer
function startCountdown() {
if (countdownValue > 0) {
countdownText.setText(countdownValue.toString());
tween(countdownText, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(countdownText, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.easeIn
});
}
});
countdownValue--;
LK.setTimeout(startCountdown, 1000);
} else {
countdownText.setText('GO!');
tween(countdownText, {
scaleX: 2,
scaleY: 2,
alpha: 0
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
countdownText.destroy();
gameStarted = true;
// Play music when game starts
LK.playMusic('music');
// Initialize game after countdown
initializeGrid();
fillGrid();
// Remove initial matches
LK.setTimeout(function () {
processMatches();
}, 100);
}
});
}
}
// Generate random candy type
function getRandomCandyType() {
return Math.floor(Math.random() * 6) + 1;
}
// Create candy at grid position
function createCandy(gridX, gridY) {
var candyType = getRandomCandyType();
var candy = new Candy(candyType);
candy.setGridPosition(gridX, gridY);
game.addChild(candy);
candies.push(candy);
grid[gridX][gridY] = candy;
return candy;
}
// Fill grid with initial candies
function fillGrid() {
for (var i = 0; i < GRID_SIZE; i++) {
for (var j = 0; j < GRID_SIZE; j++) {
if (!grid[i][j]) {
createCandy(i, j);
}
}
}
}
// Check if coordinates are valid
function isValidPosition(x, y) {
return x >= 0 && x < GRID_SIZE && y >= 0 && y < GRID_SIZE;
}
// Check if two positions are adjacent
function areAdjacent(x1, y1, x2, y2) {
var dx = Math.abs(x1 - x2);
var dy = Math.abs(y1 - y2);
return dx === 1 && dy === 0 || dx === 0 && dy === 1;
}
// Swap two candies
function swapCandies(candy1, candy2) {
if (!candy1 || !candy2) return;
var tempX = candy1.gridX;
var tempY = candy1.gridY;
grid[candy1.gridX][candy1.gridY] = candy2;
grid[candy2.gridX][candy2.gridY] = candy1;
candy1.animateToGridPosition(candy2.gridX, candy2.gridY);
candy2.animateToGridPosition(tempX, tempY);
try {
LK.getSound('swap').play();
} catch (e) {
console.log('Error playing swap sound:', e);
}
}
// Find matches in a line
function findMatches(startX, startY, deltaX, deltaY) {
var matches = [];
var currentCandy = grid[startX][startY];
if (!currentCandy) return matches;
var count = 1;
matches.push(currentCandy);
// Check forward
var x = startX + deltaX;
var y = startY + deltaY;
while (isValidPosition(x, y) && grid[x][y] && grid[x][y].type === currentCandy.type) {
matches.push(grid[x][y]);
count++;
x += deltaX;
y += deltaY;
}
// Check backward
x = startX - deltaX;
y = startY - deltaY;
while (isValidPosition(x, y) && grid[x][y] && grid[x][y].type === currentCandy.type) {
matches.unshift(grid[x][y]);
count++;
x -= deltaX;
y -= deltaY;
}
return count >= 3 ? matches : [];
}
// Find all matches on the board
function findAllMatches() {
var allMatches = [];
var processed = [];
for (var i = 0; i < GRID_SIZE; i++) {
processed[i] = [];
for (var j = 0; j < GRID_SIZE; j++) {
processed[i][j] = false;
}
}
for (var i = 0; i < GRID_SIZE; i++) {
for (var j = 0; j < GRID_SIZE; j++) {
if (grid[i][j] && !processed[i][j]) {
// Check horizontal matches
var horizontalMatches = findMatches(i, j, 1, 0);
if (horizontalMatches.length >= 3) {
for (var k = 0; k < horizontalMatches.length; k++) {
var candy = horizontalMatches[k];
processed[candy.gridX][candy.gridY] = true;
if (allMatches.indexOf(candy) === -1) {
allMatches.push(candy);
}
}
}
// Check vertical matches
var verticalMatches = findMatches(i, j, 0, 1);
if (verticalMatches.length >= 3) {
for (var k = 0; k < verticalMatches.length; k++) {
var candy = verticalMatches[k];
processed[candy.gridX][candy.gridY] = true;
if (allMatches.indexOf(candy) === -1) {
allMatches.push(candy);
}
}
}
}
}
}
return allMatches;
}
// Remove matched candies
function removeMatches(matches) {
for (var i = 0; i < matches.length; i++) {
var candy = matches[i];
// Create explosion effect using "exp" asset
var explosion = game.addChild(LK.getAsset('Exp', {
anchorX: 0.5,
anchorY: 0.5
}));
explosion.x = candy.x;
explosion.y = candy.y;
explosion.scaleX = 0.1;
explosion.scaleY = 0.1;
explosion.alpha = 0.8;
// Animate explosion growth and fade
tween(explosion, {
scaleX: 3,
scaleY: 3,
alpha: 0,
rotation: Math.PI * 2
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
explosion.destroy();
}
});
// Hide the candy immediately
candy.alpha = 0;
grid[candy.gridX][candy.gridY] = null;
// Remove from candies array
var index = candies.indexOf(candy);
if (index > -1) {
candies.splice(index, 1);
}
}
// Check if we should create a power-up (4 or more candies matched)
if (matches.length >= 4) {
// Create fire power-up
var firePowerUp = new FirePowerUp();
firePowerUp.x = 2048 / 2 - 250;
firePowerUp.y = POWER_UP_AREA_Y;
game.addChild(firePowerUp);
powerUps.push(firePowerUp);
// Update power-up counter display
powerUpCountText.setText('Power-ups: ' + powerUps.length);
// Flash screen to indicate power-up creation
LK.effects.flashScreen(0xFF4500, 500);
}
// Check if we should create the special 1000-point explosive power-up
if (gameScore >= 1000 && !hasSpawned1000PowerUp) {
hasSpawned1000PowerUp = true;
// Create explosive power-up
var explosivePowerUp = new ExplosivePowerUp();
explosivePowerUp.x = 2048 / 2 + 250;
explosivePowerUp.y = POWER_UP_AREA_Y;
game.addChild(explosivePowerUp);
powerUps.push(explosivePowerUp);
// Update power-up counter display
powerUpCountText.setText('Power-ups: ' + powerUps.length);
// Flash screen with different color to indicate special power-up
LK.effects.flashScreen(0xFF0000, 800);
}
// Calculate score
var baseScore = matches.length * 10;
var bonusScore = matches.length > 3 ? (matches.length - 3) * 20 : 0;
var totalScore = (baseScore + bonusScore) * comboMultiplier;
gameScore += totalScore;
scoreText.setText('Score: ' + gameScore);
LK.setScore(gameScore);
// Show combo feedback
if (comboMultiplier > 1) {
comboText.setText('COMBO x' + comboMultiplier + ' (+' + totalScore + ')');
comboText.alpha = 1;
tween(comboText, {
alpha: 0
}, {
duration: 1000,
easing: tween.easeOut
});
} else {
comboText.setText('');
}
// Flash screen effect for big matches
if (matches.length >= 5) {
LK.effects.flashScreen(0xFFD700, 300);
}
try {
LK.getSound('match').play();
} catch (e) {
console.log('Error playing match sound:', e);
}
// Schedule removal after explosion animation
LK.setTimeout(function () {
for (var i = 0; i < matches.length; i++) {
matches[i].destroy();
}
}, 300);
}
// Make candies fall down
function applyGravity() {
var moved = false;
for (var i = 0; i < GRID_SIZE; i++) {
for (var j = GRID_SIZE - 2; j >= 0; j--) {
if (grid[i][j]) {
var fallDistance = 0;
var checkY = j + 1;
while (checkY < GRID_SIZE && !grid[i][checkY]) {
fallDistance++;
checkY++;
}
if (fallDistance > 0) {
var candy = grid[i][j];
grid[i][j] = null;
grid[i][j + fallDistance] = candy;
candy.animateToGridPosition(i, j + fallDistance);
moved = true;
}
}
}
}
return moved;
}
// Fill empty spaces with new candies
function fillEmptySpaces() {
var added = false;
for (var i = 0; i < GRID_SIZE; i++) {
for (var j = 0; j < GRID_SIZE; j++) {
if (!grid[i][j]) {
var candy = createCandy(i, j);
// Start candy above the grid and animate down
candy.y = GRID_START_Y - 100;
candy.animateToGridPosition(i, j);
added = true;
}
}
}
return added;
}
// Check if move creates matches
function wouldCreateMatch(candy1, candy2) {
// Store original positions
var origX1 = candy1.gridX;
var origY1 = candy1.gridY;
var origX2 = candy2.gridX;
var origY2 = candy2.gridY;
// Temporarily swap in grid
grid[candy1.gridX][candy1.gridY] = candy2;
grid[candy2.gridX][candy2.gridY] = candy1;
// Temporarily swap candy positions
candy1.gridX = origX2;
candy1.gridY = origY2;
candy2.gridX = origX1;
candy2.gridY = origY1;
var matches1 = findMatches(candy1.gridX, candy1.gridY, 1, 0);
var matches2 = findMatches(candy1.gridX, candy1.gridY, 0, 1);
var matches3 = findMatches(candy2.gridX, candy2.gridY, 1, 0);
var matches4 = findMatches(candy2.gridX, candy2.gridY, 0, 1);
var hasMatch = matches1.length >= 3 || matches2.length >= 3 || matches3.length >= 3 || matches4.length >= 3;
// Restore original positions
candy1.gridX = origX1;
candy1.gridY = origY1;
candy2.gridX = origX2;
candy2.gridY = origY2;
grid[origX1][origY1] = candy1;
grid[origX2][origY2] = candy2;
return hasMatch;
}
// Process matches and cascades
function processMatches() {
if (isProcessing) return;
isProcessing = true;
var matches = findAllMatches();
if (matches.length > 0) {
removeMatches(matches);
comboMultiplier++;
LK.setTimeout(function () {
var gravityApplied = applyGravity();
var spacesAdded = fillEmptySpaces();
if (gravityApplied || spacesAdded) {
LK.setTimeout(function () {
isProcessing = false;
processMatches(); // Check for new matches
}, 300);
} else {
isProcessing = false;
comboMultiplier = 1;
}
}, 300);
} else {
isProcessing = false;
comboMultiplier = 1;
}
}
// Get candy at screen position
function getCandyAt(x, y) {
// Calculate grid coordinates from screen position
var gridX = Math.floor((x - GRID_START_X) / CELL_SIZE);
var gridY = Math.floor((y - GRID_START_Y) / CELL_SIZE);
// Check if coordinates are within grid bounds
if (gridX >= 0 && gridX < GRID_SIZE && gridY >= 0 && gridY < GRID_SIZE) {
return grid[gridX][gridY];
}
return null;
}
var dragStartCandy = null;
var dragCurrentCandy = null;
// Game input handling
game.down = function (x, y, obj) {
if (!gameStarted || isProcessing) return;
var candy = getCandyAt(x, y);
if (candy) {
dragStartCandy = candy;
dragCurrentCandy = candy;
candy.highlight();
}
};
game.move = function (x, y, obj) {
if (!gameStarted || isProcessing || !dragStartCandy) return;
var candy = getCandyAt(x, y);
if (candy && candy !== dragCurrentCandy) {
if (dragCurrentCandy && dragCurrentCandy !== dragStartCandy) {
dragCurrentCandy.unhighlight();
}
dragCurrentCandy = candy;
if (candy !== dragStartCandy) {
candy.highlight();
}
}
};
game.up = function (x, y, obj) {
if (!gameStarted || isProcessing || !dragStartCandy) return;
var endCandy = getCandyAt(x, y);
if (endCandy && endCandy !== dragStartCandy && areAdjacent(dragStartCandy.gridX, dragStartCandy.gridY, endCandy.gridX, endCandy.gridY)) {
if (wouldCreateMatch(dragStartCandy, endCandy)) {
swapCandies(dragStartCandy, endCandy);
LK.setTimeout(function () {
processMatches();
}, 400);
} else {
// Invalid move - swap back
try {
LK.getSound('Wro').play();
} catch (e) {
console.log('Error playing wrong move sound:', e);
}
dragStartCandy.unhighlight();
if (endCandy) endCandy.unhighlight();
}
} else {
// No valid target - just unhighlight
dragStartCandy.unhighlight();
if (dragCurrentCandy && dragCurrentCandy !== dragStartCandy) {
dragCurrentCandy.unhighlight();
}
}
dragStartCandy = null;
dragCurrentCandy = null;
};
// Start countdown instead of immediate game initialization
startCountdown();
game.update = function () {
// Game runs automatically through event handling
};