/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var GridCell = Container.expand(function (row, col) { var self = Container.call(this); self.row = row; self.col = col; self.ballType = null; self.ball = null; self.isBomb = false; self.isWall = false; self.velocityY = 0; self.gravity = 0.5; self.isGrounded = false; var cellBg = self.attachAsset('grid_cell', { anchorX: 0.5, anchorY: 0.5 }); self.setBall = function (ballType) { if (self.ball) { self.removeChild(self.ball); } if (self.glowEffect) { self.removeChild(self.glowEffect); self.glowEffect = null; } if (ballType === 'wall') { self.ball = self.attachAsset('wall', { anchorX: 0.5, anchorY: 0.5 }); self.isWall = true; self.isBomb = false; self.ballType = ballType; } else if (ballType === 'bomb' || ballType === 'red_bomb' || ballType === 'purple_bomb' || ballType === 'yellow_bomb') { var bombAsset = ballType === 'red_bomb' ? 'red_bomb' : ballType === 'purple_bomb' ? 'purple_bomb' : ballType === 'yellow_bomb' ? 'yellow_bomb' : 'bomb'; self.ball = self.attachAsset(bombAsset, { anchorX: 0.5, anchorY: 0.5 }); self.isBomb = true; self.ballType = ballType; // Add magical pulsing effect to bomb tween(self.ball, { scaleX: 1.2, scaleY: 1.2 }, { duration: 800, easing: tween.easeInOut, onFinish: function onFinish() { tween(self.ball, { scaleX: 1.0, scaleY: 1.0 }, { duration: 800, easing: tween.easeInOut }); } }); } else if (ballType) { // Add glow effect behind the ball self.glowEffect = self.attachAsset('glow_effect', { anchorX: 0.5, anchorY: 0.5 }); self.glowEffect.alpha = 0.3; self.glowEffect.tint = self.getBallColor(ballType); // Add the main ball self.ball = self.attachAsset('ball_' + ballType, { anchorX: 0.5, anchorY: 0.5 }); self.isBomb = false; self.ballType = ballType; // Add crown if upgrade is purchased and enabled if (hasCrownUpgrade && crownEnabled) { self.crown = self.attachAsset('crown', { anchorX: 0.5, anchorY: 0.5 }); self.crown.y = -40; } // Add sparkle entrance effect with gravity self.ball.scaleX = 0; self.ball.scaleY = 0; self.ball.y = -100; // Start above the cell self.velocityY = 0; self.isGrounded = false; tween(self.ball, { scaleX: 1, scaleY: 1 }, { duration: 400, easing: tween.elasticOut }); // Add continuous gentle glow pulsing self.startGlowAnimation(); } else { self.ball = null; self.ballType = null; self.isBomb = false; self.isWall = false; } }; self.down = function (x, y, obj) { if (self.ball && !self.isWall) { if (!selectedCell) { // First selection selectedCell = self; // Add visual feedback for selection if (self.ball) { self.ball.tint = 0xaaaaaa; // Gray tint to show selection } } else if (selectedCell === self) { // Deselect if clicking same cell if (selectedCell.ball) { selectedCell.ball.tint = 0xffffff; // Remove tint } selectedCell = null; } else if (areAdjacent(selectedCell, self)) { // Valid adjacent swap secondSelectedCell = self; // Clear visual feedback if (selectedCell.ball) { selectedCell.ball.tint = 0xffffff; } // Perform the swap swapBalls(selectedCell, secondSelectedCell); // Reset selections selectedCell = null; secondSelectedCell = null; isAnimating = true; // Check for matches after swap LK.setTimeout(function () { processMatches(); }, 100); } else { // Select new cell, clear previous selection if (selectedCell.ball) { selectedCell.ball.tint = 0xffffff; } selectedCell = self; if (self.ball) { self.ball.tint = 0xaaaaaa; } } } }; self.getBallColor = function (ballType) { var colors = { 'red': 0xff4444, 'blue': 0x4444ff, 'green': 0x44ff44, 'yellow': 0xffff44, 'purple': 0xff44ff, 'orange': 0xff8844 }; return colors[ballType] || 0xffffff; }; self.startGlowAnimation = function () { if (self.glowEffect) { var _pulseGlow = function pulseGlow() { if (self.glowEffect) { tween(self.glowEffect, { alpha: 0.6 }, { duration: 1500, easing: tween.easeInOut, onFinish: function onFinish() { if (self.glowEffect) { tween(self.glowEffect, { alpha: 0.3 }, { duration: 1500, easing: tween.easeInOut, onFinish: _pulseGlow }); } } }); } }; _pulseGlow(); } }; self.createSparkles = function () { for (var i = 0; i < 5; i++) { var sparkle = self.attachAsset('sparkle', { anchorX: 0.5, anchorY: 0.5 }); sparkle.x = (Math.random() - 0.5) * 80; sparkle.y = (Math.random() - 0.5) * 80; sparkle.alpha = 0.8; sparkle.scaleX = 0.5; sparkle.scaleY = 0.5; tween(sparkle, { x: sparkle.x + (Math.random() - 0.5) * 100, y: sparkle.y + (Math.random() - 0.5) * 100, alpha: 0, scaleX: 0, scaleY: 0 }, { duration: 1000, easing: tween.easeOut, onFinish: function onFinish() { if (sparkle.parent) { sparkle.parent.removeChild(sparkle); } } }); } }; self.update = function () { if (self.ball && !self.isWall && !self.isBomb) { // Apply gravity if not grounded if (!self.isGrounded) { self.velocityY += self.gravity; self.ball.y += self.velocityY; // Check if ball has reached ground (relative to cell) if (self.ball.y >= 0) { self.ball.y = 0; self.velocityY = 0; self.isGrounded = true; } } // Add subtle bounce effect when ball lands if (self.isGrounded && Math.abs(self.velocityY) < 0.1) { // Add gentle floating animation if (!self.floatTween) { self.floatTween = true; tween(self.ball, { y: -5 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { if (self.ball) { tween(self.ball, { y: 0 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { self.floatTween = false; } }); } } }); } } } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x222222 }); /**** * Game Code ****/ var GRID_SIZE = 15; var CELL_SIZE = 160; var BALL_COLORS = ['red', 'blue', 'green', 'yellow', 'purple', 'orange']; var GRID_START_X = (2048 - GRID_SIZE * CELL_SIZE) / 2; var GRID_START_Y = 300; var grid = []; var selectedCell = null; var secondSelectedCell = null; var isAnimating = false; var bombSpawnCounter = 0; var lastWallSpawnScore = 0; var totalWallsCreated = 0; var gameStarted = false; var startScreenElements = []; var coins = storage.coins || 0; var hasCrownUpgrade = storage.hasCrownUpgrade || false; var codeUsed = storage.codeUsed || false; var marketVisible = false; var marketElements = []; var yellowBombTrail = null; var yellowBombExplosionScore = 0; var pickaxeUses = 0; var goldFrenzyTurns = storage.goldFrenzyTurns || 0; var goldMultiplier = goldFrenzyTurns > 0 ? 2 : 1; var crownToggleBtn = null; var crownEnabled = storage.crownEnabled !== undefined ? storage.crownEnabled : true; // Create score display var scoreTxt = new Text2('Score: 0', { size: 80, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Create coins display var coinsTxt = new Text2('Coins: ' + coins, { size: 60, fill: 0xFFD700 }); coinsTxt.anchor.set(1, 0); LK.gui.topRight.addChild(coinsTxt); // Create pickaxe uses display var pickaxeTxt = new Text2('Kazma: ' + pickaxeUses, { size: 50, fill: 0x8B4513 }); pickaxeTxt.anchor.set(1, 0); pickaxeTxt.y = 140; LK.gui.topRight.addChild(pickaxeTxt); // Create gold frenzy turns display var goldFrenzyTxt = new Text2('', { size: 50, fill: 0xFFD700 }); goldFrenzyTxt.anchor.set(1, 0); goldFrenzyTxt.y = 200; LK.gui.topRight.addChild(goldFrenzyTxt); // Update gold frenzy display function updateGoldFrenzyDisplay() { if (goldFrenzyTurns > 0) { goldFrenzyTxt.setText('Altın Çılgınlığı: ' + goldFrenzyTurns + ' tur'); } else { goldFrenzyTxt.setText(''); } } updateGoldFrenzyDisplay(); // Show market screen function showMarket() { marketVisible = true; // Create semi-transparent overlay var overlay = LK.getAsset('grid_cell', { anchorX: 0.5, anchorY: 0.5 }); overlay.width = 2048; overlay.height = 2732; overlay.alpha = 0.9; overlay.tint = 0x000000; overlay.x = 1024; overlay.y = 1366; game.addChild(overlay); marketElements.push(overlay); // Create market title var marketTitle = new Text2('MARKET', { size: 100, fill: 0xFFFFFF }); marketTitle.anchor.set(0.5, 0.5); marketTitle.x = 1024; marketTitle.y = 800; game.addChild(marketTitle); marketElements.push(marketTitle); // Create crown upgrade text var crownText = new Text2('Tüm Karakterlere Kral Tacı', { size: 70, fill: 0x00FF00 }); crownText.anchor.set(0.5, 0.5); crownText.x = 1024; crownText.y = 1200; game.addChild(crownText); marketElements.push(crownText); // Create price text var priceText = new Text2('100 Altın', { size: 60, fill: 0xFFD700 }); priceText.anchor.set(0.5, 0.5); priceText.x = 1024; priceText.y = 1300; game.addChild(priceText); marketElements.push(priceText); // Create pickaxe upgrade text var pickaxeText = new Text2('Kazma - Duvarları Kır', { size: 70, fill: 0x00FF00 }); pickaxeText.anchor.set(0.5, 0.5); pickaxeText.x = 1024; pickaxeText.y = 1400; game.addChild(pickaxeText); marketElements.push(pickaxeText); // Create pickaxe price text var pickaxePriceText = new Text2('200 Altın', { size: 60, fill: 0xFFD700 }); pickaxePriceText.anchor.set(0.5, 0.5); pickaxePriceText.x = 1024; pickaxePriceText.y = 1500; game.addChild(pickaxePriceText); marketElements.push(pickaxePriceText); // Create gold frenzy text var goldFrenzyText = new Text2('Altın Çılgınlığı', { size: 70, fill: 0x00FF00 }); goldFrenzyText.anchor.set(1, 0); goldFrenzyText.x = 1900; goldFrenzyText.y = 900; game.addChild(goldFrenzyText); marketElements.push(goldFrenzyText); // Create gold frenzy price text var goldFrenzyPriceText = new Text2('50 Altın', { size: 60, fill: 0xFFD700 }); goldFrenzyPriceText.anchor.set(1, 0); goldFrenzyPriceText.x = 1900; goldFrenzyPriceText.y = 1000; game.addChild(goldFrenzyPriceText); marketElements.push(goldFrenzyPriceText); // Create gold frenzy description var goldFrenzyDesc = new Text2('30 tur 2x altın', { size: 50, fill: 0xFFFFFF }); goldFrenzyDesc.anchor.set(1, 0); goldFrenzyDesc.x = 1900; goldFrenzyDesc.y = 1100; game.addChild(goldFrenzyDesc); marketElements.push(goldFrenzyDesc); // Add gold frenzy purchase handler goldFrenzyPriceText.down = function () { if (coins >= 50) { coins -= 50; goldFrenzyTurns += 30; // Stack the effect goldMultiplier = 2; storage.coins = coins; storage.goldFrenzyTurns = goldFrenzyTurns; coinsTxt.setText('Coins: ' + coins); updateGoldFrenzyDisplay(); hideMarket(); } }; // Add pickaxe purchase handler pickaxePriceText.down = function () { if (coins >= 200) { coins -= 200; pickaxeUses = 10; // Reset pickaxe uses each game storage.coins = coins; coinsTxt.setText('Coins: ' + coins); hideMarket(); } }; // Create close button var closeBtn = new Text2('KAPAT', { size: 50, fill: 0xFF0000 }); closeBtn.anchor.set(0.5, 0.5); closeBtn.x = 1024; closeBtn.y = 1600; game.addChild(closeBtn); marketElements.push(closeBtn); // Add purchase handler priceText.down = function () { if (coins >= 100 && !hasCrownUpgrade) { coins -= 100; hasCrownUpgrade = true; storage.coins = coins; storage.hasCrownUpgrade = hasCrownUpgrade; coinsTxt.setText('Coins: ' + coins); hideMarket(); // Add crowns to existing balls for (var row = 0; row < GRID_SIZE; row++) { for (var col = 0; col < GRID_SIZE; col++) { var cell = grid[row][col]; if (cell.ball && !cell.isBomb && !cell.isWall && cell.ballType) { cell.setBall(cell.ballType); } } } } }; // Add close handler closeBtn.down = function () { hideMarket(); }; } // Hide market screen function hideMarket() { marketVisible = false; for (var i = 0; i < marketElements.length; i++) { game.removeChild(marketElements[i]); } marketElements = []; } // Create market button var marketBtn = new Text2('MARKET', { size: 50, fill: 0x00FF00 }); marketBtn.anchor.set(1, 0); marketBtn.y = 80; LK.gui.topRight.addChild(marketBtn); marketBtn.down = function () { if (!marketVisible) { showMarket(); } }; // Function to show start screen function showStartScreen() { // Set black background game.setBackgroundColor(0x000000); // Create title text "duyguları vur" var titleText = new Text2('DUYGULARI VUR', { size: 120, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0.5); titleText.x = 1024; titleText.y = 1200; game.addChild(titleText); startScreenElements.push(titleText); // Create play button "oyna" var playButton = new Text2('OYNA', { size: 100, fill: 0x00FF00 }); playButton.anchor.set(0.5, 0.5); playButton.x = 1024; playButton.y = 1400; game.addChild(playButton); startScreenElements.push(playButton); // Add click handler for play button playButton.down = function () { startGame(); }; // Create help button (question mark) var helpButton = new Text2('?', { size: 120, fill: 0x00FFFF }); helpButton.anchor.set(0, 0); helpButton.x = 150; helpButton.y = 150; game.addChild(helpButton); startScreenElements.push(helpButton); // Add click handler for help button helpButton.down = function () { showHelpScreen(); }; // Create code entry button var codeButton = new Text2('KOD YAZIN', { size: 60, fill: 0xFFFF00 }); codeButton.anchor.set(0, 1); codeButton.x = 100; codeButton.y = 2600; game.addChild(codeButton); startScreenElements.push(codeButton); // Add click handler for code button codeButton.down = function () { showCodeEntry(); }; // Create crown toggle button only if crown upgrade is purchased if (hasCrownUpgrade) { crownToggleBtn = new Text2(crownEnabled ? 'Kral Tacını Kapat' : 'Kral Tacını Aç', { size: 60, fill: crownEnabled ? 0xFF0000 : 0x00FF00 }); crownToggleBtn.anchor.set(0.5, 1); crownToggleBtn.x = 1024; crownToggleBtn.y = 2600; game.addChild(crownToggleBtn); startScreenElements.push(crownToggleBtn); // Add click handler for crown toggle crownToggleBtn.down = function () { crownEnabled = !crownEnabled; storage.crownEnabled = crownEnabled; crownToggleBtn.setText(crownEnabled ? 'Kral Tacını Kapat' : 'Kral Tacını Aç'); crownToggleBtn.fill = crownEnabled ? 0xFF0000 : 0x00FF00; }; } // Add glow animation to play button tween(playButton, { scaleX: 1.1, scaleY: 1.1 }, { duration: 800, easing: tween.easeInOut, onFinish: function onFinish() { tween(playButton, { scaleX: 1.0, scaleY: 1.0 }, { duration: 800, easing: tween.easeInOut }); } }); } // Function to start the actual game function startGame() { // Remove start screen elements for (var i = 0; i < startScreenElements.length; i++) { game.removeChild(startScreenElements[i]); } startScreenElements = []; // Set game background color game.setBackgroundColor(0x222222); // Hide UI elements during gameplay marketBtn.visible = false; coinsTxt.visible = false; pickaxeTxt.visible = false; goldFrenzyTxt.visible = false; // Initialize game gameStarted = true; pickaxeUses = 0; // Reset pickaxe uses for new game pickaxeTxt.setText('Kazma: ' + pickaxeUses); // Update gold frenzy display for new game updateGoldFrenzyDisplay(); initializeGrid(); } // Initialize grid function initializeGrid() { for (var row = 0; row < GRID_SIZE; row++) { grid[row] = []; for (var col = 0; col < GRID_SIZE; col++) { var cell = new GridCell(row, col); cell.x = GRID_START_X + col * CELL_SIZE + CELL_SIZE / 2; cell.y = GRID_START_Y + row * CELL_SIZE + CELL_SIZE / 2; var randomColor = BALL_COLORS[Math.floor(Math.random() * BALL_COLORS.length)]; cell.setBall(randomColor); grid[row][col] = cell; game.addChild(cell); } } } // Get random ball color function getRandomBallColor() { return BALL_COLORS[Math.floor(Math.random() * BALL_COLORS.length)]; } // Check if two cells are adjacent function areAdjacent(cell1, cell2) { var rowDiff = Math.abs(cell1.row - cell2.row); var colDiff = Math.abs(cell1.col - cell2.col); return rowDiff === 1 && colDiff === 0 || rowDiff === 0 && colDiff === 1; } // Swap balls between two cells function swapBalls(cell1, cell2) { var tempType = cell1.ballType; var tempIsBomb = cell1.isBomb; cell1.setBall(cell2.ballType); cell2.setBall(tempType); } // Check for matches starting from a specific cell function checkMatches() { var matchedCells = []; var fiveBallMatches = []; var visited = []; for (var row = 0; row < GRID_SIZE; row++) { visited[row] = []; for (var col = 0; col < GRID_SIZE; col++) { visited[row][col] = false; } } // Check horizontal matches for (var row = 0; row < GRID_SIZE; row++) { for (var col = 0; col < GRID_SIZE - 2; col++) { var cell = grid[row][col]; if (!cell.ball || cell.isBomb || cell.isWall || visited[row][col]) continue; var matchCount = 1; var matchCells = [cell]; for (var c = col + 1; c < GRID_SIZE; c++) { var nextCell = grid[row][c]; if (nextCell.ball && !nextCell.isBomb && !nextCell.isWall && nextCell.ballType === cell.ballType) { matchCount++; matchCells.push(nextCell); } else { break; } } if (matchCount >= 3) { for (var i = 0; i < matchCells.length; i++) { matchedCells.push(matchCells[i]); visited[matchCells[i].row][matchCells[i].col] = true; } // Check if it's a 5-ball match if (matchCount >= 5) { fiveBallMatches.push({ centerRow: matchCells[Math.floor(matchCells.length / 2)].row, centerCol: matchCells[Math.floor(matchCells.length / 2)].col }); } } } } // Check vertical matches for (var col = 0; col < GRID_SIZE; col++) { for (var row = 0; row < GRID_SIZE - 2; row++) { var cell = grid[row][col]; if (!cell.ball || cell.isBomb || cell.isWall || visited[row][col]) continue; var matchCount = 1; var matchCells = [cell]; for (var r = row + 1; r < GRID_SIZE; r++) { var nextCell = grid[r][col]; if (nextCell.ball && !nextCell.isBomb && !nextCell.isWall && nextCell.ballType === cell.ballType) { matchCount++; matchCells.push(nextCell); } else { break; } } if (matchCount >= 3) { for (var i = 0; i < matchCells.length; i++) { if (!visited[matchCells[i].row][matchCells[i].col]) { matchedCells.push(matchCells[i]); visited[matchCells[i].row][matchCells[i].col] = true; } } // Check if it's a 5-ball match if (matchCount >= 5) { fiveBallMatches.push({ centerRow: matchCells[Math.floor(matchCells.length / 2)].row, centerCol: matchCells[Math.floor(matchCells.length / 2)].col }); } } } } return { matchedCells: matchedCells, fiveBallMatches: fiveBallMatches }; } // Remove matched balls and update score function removeMatches(matchData, fiveBallMatches) { var matchedCells = matchData; if (matchedCells.length === 0) return; LK.setScore(LK.getScore() + matchedCells.length * 10); scoreTxt.setText('Score: ' + LK.getScore()); // Add coins with gold frenzy multiplier var coinsEarned = Math.floor(matchedCells.length / 3) * goldMultiplier; if (coinsEarned > 0) { coins += coinsEarned; storage.coins = coins; coinsTxt.setText('Coins: ' + coins); } // Decrease gold frenzy turns if (goldFrenzyTurns > 0) { goldFrenzyTurns--; if (goldFrenzyTurns <= 0) { goldMultiplier = 1; } storage.goldFrenzyTurns = goldFrenzyTurns; updateGoldFrenzyDisplay(); } // Check if we should spawn walls every 100 points var currentScore = LK.getScore(); if (Math.floor(currentScore / 100) > Math.floor(lastWallSpawnScore / 100)) { lastWallSpawnScore = currentScore; LK.setTimeout(function () { spawnWalls(); }, 400); } for (var i = 0; i < matchedCells.length; i++) { // Create sparkle effect before removing matchedCells[i].createSparkles(); // Add magical disappear animation if (matchedCells[i].ball) { tween(matchedCells[i].ball, { scaleX: 0, scaleY: 0, alpha: 0 }, { duration: 300, easing: tween.easeIn }); } if (matchedCells[i].glowEffect) { tween(matchedCells[i].glowEffect, { scaleX: 2, scaleY: 2, alpha: 0 }, { duration: 300, easing: tween.easeOut }); } // Remove after animation LK.setTimeout(function (cell) { return function () { cell.setBall(null); }; }(matchedCells[i]), 300); } // Create red bombs for 5-ball matches if (fiveBallMatches && fiveBallMatches.length > 0) { LK.setTimeout(function () { for (var j = 0; j < fiveBallMatches.length; j++) { var bombPos = fiveBallMatches[j]; if (grid[bombPos.centerRow] && grid[bombPos.centerRow][bombPos.centerCol]) { grid[bombPos.centerRow][bombPos.centerCol].setBall('red_bomb'); } } }, 350); } LK.getSound('match').play(); } // Explode red bomb in 7x7 area function explodeRedBomb(centerRow, centerCol) { var clearedCells = []; // Create magical explosion wave effect var explosionCenter = grid[centerRow][centerCol]; for (var row = Math.max(0, centerRow - 3); row <= Math.min(GRID_SIZE - 1, centerRow + 3); row++) { for (var col = Math.max(0, centerCol - 3); col <= Math.min(GRID_SIZE - 1, centerCol + 3); col++) { var cell = grid[row][col]; if (cell.ball && !cell.isWall) { clearedCells.push(cell); // Create magical explosion effect var distance = Math.sqrt(Math.pow(row - centerRow, 2) + Math.pow(col - centerCol, 2)); var delay = distance * 80; // Stagger the explosions LK.setTimeout(function (targetCell) { return function () { targetCell.createSparkles(); if (targetCell.ball) { // Create explosive scale effect tween(targetCell.ball, { scaleX: 1.8, scaleY: 1.8 }, { duration: 120, easing: tween.easeOut, onFinish: function onFinish() { tween(targetCell.ball, { scaleX: 0, scaleY: 0, alpha: 0 }, { duration: 180, easing: tween.easeIn }); } }); } if (targetCell.glowEffect) { tween(targetCell.glowEffect, { scaleX: 4, scaleY: 4, alpha: 0 }, { duration: 300, easing: tween.easeOut }); } LK.setTimeout(function () { targetCell.setBall(null); }, 300); }; }(cell), delay); } } } LK.setScore(LK.getScore() + clearedCells.length * 8); scoreTxt.setText('Score: ' + LK.getScore()); // Add coins with gold frenzy multiplier var coinsEarned = Math.floor(clearedCells.length / 2) * goldMultiplier; if (coinsEarned > 0) { coins += coinsEarned; storage.coins = coins; coinsTxt.setText('Coins: ' + coins); } // Check if we should spawn walls every 100 points var currentScore = LK.getScore(); if (Math.floor(currentScore / 100) > Math.floor(lastWallSpawnScore / 100)) { lastWallSpawnScore = currentScore; LK.setTimeout(function () { spawnWalls(); }, 400); } LK.getSound('bomb_explode').play(); } // Explode purple bomb in 5x5 area including walls function explodePurpleBomb(centerRow, centerCol) { var clearedCells = []; // Create magical explosion wave effect var explosionCenter = grid[centerRow][centerCol]; for (var row = Math.max(0, centerRow - 2); row <= Math.min(GRID_SIZE - 1, centerRow + 2); row++) { for (var col = Math.max(0, centerCol - 2); col <= Math.min(GRID_SIZE - 1, centerCol + 2); col++) { var cell = grid[row][col]; if (cell.ball) { clearedCells.push(cell); // Create magical explosion effect var distance = Math.sqrt(Math.pow(row - centerRow, 2) + Math.pow(col - centerCol, 2)); var delay = distance * 60; // Stagger the explosions LK.setTimeout(function (targetCell) { return function () { targetCell.createSparkles(); if (targetCell.ball) { // Create explosive scale effect tween(targetCell.ball, { scaleX: 2.0, scaleY: 2.0 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { tween(targetCell.ball, { scaleX: 0, scaleY: 0, alpha: 0 }, { duration: 150, easing: tween.easeIn }); } }); } if (targetCell.glowEffect) { tween(targetCell.glowEffect, { scaleX: 5, scaleY: 5, alpha: 0 }, { duration: 250, easing: tween.easeOut }); } LK.setTimeout(function () { targetCell.setBall(null); }, 250); }; }(cell), delay); } } } // After clearing area, spawn 5 normal bombs randomly in the 5x5 area LK.setTimeout(function () { var availableCells = []; for (var row = Math.max(0, centerRow - 2); row <= Math.min(GRID_SIZE - 1, centerRow + 2); row++) { for (var col = Math.max(0, centerCol - 2); col <= Math.min(GRID_SIZE - 1, centerCol + 2); col++) { var cell = grid[row][col]; if (!cell.ball || !cell.isWall && !cell.isBomb) { availableCells.push({ row: row, col: col }); } } } // Spawn 5 normal bombs in random positions var bombsToSpawn = Math.min(5, availableCells.length); for (var i = 0; i < bombsToSpawn; i++) { var randomIndex = Math.floor(Math.random() * availableCells.length); var bombPos = availableCells[randomIndex]; // Set a delay for each bomb spawn LK.setTimeout(function (pos) { return function () { grid[pos.row][pos.col].setBall('bomb'); // Add visual effect to show bomb spawning if (grid[pos.row][pos.col].ball) { grid[pos.row][pos.col].ball.scaleX = 0; grid[pos.row][pos.col].ball.scaleY = 0; tween(grid[pos.row][pos.col].ball, { scaleX: 1, scaleY: 1 }, { duration: 300, easing: tween.bounceOut }); } }; }(bombPos), i * 200); availableCells.splice(randomIndex, 1); } }, 300); LK.setScore(LK.getScore() + clearedCells.length * 12); scoreTxt.setText('Score: ' + LK.getScore()); // Add coins with gold frenzy multiplier var coinsEarned = Math.floor(clearedCells.length / 2) * goldMultiplier; if (coinsEarned > 0) { coins += coinsEarned; storage.coins = coins; coinsTxt.setText('Coins: ' + coins); } // Check if we should spawn walls every 100 points var currentScore = LK.getScore(); if (Math.floor(currentScore / 100) > Math.floor(lastWallSpawnScore / 100)) { lastWallSpawnScore = currentScore; LK.setTimeout(function () { spawnWalls(); }, 400); } LK.getSound('bomb_explode').play(); } // Explode yellow bomb - destroys ALL balls and gives 10000 points function explodeYellowBomb(explosionRow, explosionCol) { var clearedCells = []; // Store the explosion score for trail removal yellowBombExplosionScore = LK.getScore(); for (var row = 0; row < GRID_SIZE; row++) { for (var col = 0; col < GRID_SIZE; col++) { var cell = grid[row][col]; if (cell.ball && !cell.isWall) { clearedCells.push(cell); var delay = Math.random() * 500; LK.setTimeout(function (targetCell) { return function () { targetCell.createSparkles(); if (targetCell.ball) { tween(targetCell.ball, { scaleX: 2.5, scaleY: 2.5 }, { duration: 80, easing: tween.easeOut, onFinish: function onFinish() { tween(targetCell.ball, { scaleX: 0, scaleY: 0, alpha: 0 }, { duration: 120, easing: tween.easeIn }); } }); } if (targetCell.glowEffect) { tween(targetCell.glowEffect, { scaleX: 6, scaleY: 6, alpha: 0 }, { duration: 200, easing: tween.easeOut }); } LK.setTimeout(function () { targetCell.setBall(null); }, 200); }; }(cell), delay); } } } // Create green trail at explosion location LK.setTimeout(function () { if (explosionRow !== undefined && explosionCol !== undefined && explosionRow >= 0 && explosionRow < GRID_SIZE && explosionCol >= 0 && explosionCol < GRID_SIZE) { // Remove existing trail if any if (yellowBombTrail) { game.removeChild(yellowBombTrail); } // Create green trail yellowBombTrail = LK.getAsset('green_trail', { anchorX: 0.5, anchorY: 0.5 }); yellowBombTrail.x = GRID_START_X + explosionCol * CELL_SIZE + CELL_SIZE / 2; yellowBombTrail.y = GRID_START_Y + explosionRow * CELL_SIZE + CELL_SIZE / 2; yellowBombTrail.alpha = 0.7; game.addChild(yellowBombTrail); // Add pulsing animation to trail tween(yellowBombTrail, { scaleX: 1.2, scaleY: 1.2, alpha: 0.9 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { if (yellowBombTrail) { tween(yellowBombTrail, { scaleX: 1.0, scaleY: 1.0, alpha: 0.7 }, { duration: 1000, easing: tween.easeInOut }); } } }); } }, 600); LK.setScore(LK.getScore() + 10000); scoreTxt.setText('Score: ' + LK.getScore()); // Add massive coins with gold frenzy multiplier var coinsEarned = 100 * goldMultiplier; coins += coinsEarned; storage.coins = coins; coinsTxt.setText('Coins: ' + coins); LK.getSound('bomb_explode').play(); } // Explode bomb in 3x3 area function explodeBomb(centerRow, centerCol) { var clearedCells = []; // Create magical explosion wave effect var explosionCenter = grid[centerRow][centerCol]; for (var row = Math.max(0, centerRow - 1); row <= Math.min(GRID_SIZE - 1, centerRow + 1); row++) { for (var col = Math.max(0, centerCol - 1); col <= Math.min(GRID_SIZE - 1, centerCol + 1); col++) { var cell = grid[row][col]; if (cell.ball && !cell.isWall) { clearedCells.push(cell); // Create magical explosion effect var distance = Math.sqrt(Math.pow(row - centerRow, 2) + Math.pow(col - centerCol, 2)); var delay = distance * 100; // Stagger the explosions LK.setTimeout(function (targetCell) { return function () { targetCell.createSparkles(); if (targetCell.ball) { // Create explosive scale effect tween(targetCell.ball, { scaleX: 1.5, scaleY: 1.5 }, { duration: 150, easing: tween.easeOut, onFinish: function onFinish() { tween(targetCell.ball, { scaleX: 0, scaleY: 0, alpha: 0 }, { duration: 200, easing: tween.easeIn }); } }); } if (targetCell.glowEffect) { tween(targetCell.glowEffect, { scaleX: 3, scaleY: 3, alpha: 0 }, { duration: 350, easing: tween.easeOut }); } LK.setTimeout(function () { targetCell.setBall(null); }, 350); }; }(cell), delay); } } } LK.setScore(LK.getScore() + clearedCells.length * 5); scoreTxt.setText('Score: ' + LK.getScore()); // Add coins with gold frenzy multiplier var coinsEarned = Math.floor(clearedCells.length / 3) * goldMultiplier; if (coinsEarned > 0) { coins += coinsEarned; storage.coins = coins; coinsTxt.setText('Coins: ' + coins); } // Check if we should spawn walls every 100 points var currentScore = LK.getScore(); if (Math.floor(currentScore / 100) > Math.floor(lastWallSpawnScore / 100)) { lastWallSpawnScore = currentScore; LK.setTimeout(function () { spawnWalls(); }, 400); } LK.getSound('bomb_explode').play(); } // Drop balls down to fill empty spaces function dropBalls() { var moved = false; for (var col = 0; col < GRID_SIZE; col++) { for (var row = GRID_SIZE - 1; row >= 0; row--) { if (!grid[row][col].ball) { // Find the first ball above this empty space for (var r = row - 1; r >= 0; r--) { if (grid[r][col].ball && !grid[r][col].isWall) { grid[row][col].setBall(grid[r][col].ballType); grid[r][col].setBall(null); moved = true; break; } else if (grid[r][col].isWall) { break; } } } } } return moved; } // Fill empty spaces at the top with new balls function fillEmptySpaces() { for (var col = 0; col < GRID_SIZE; col++) { for (var row = 0; row < GRID_SIZE; row++) { if (!grid[row][col].ball) { var randomColor = getRandomBallColor(); grid[row][col].setBall(randomColor); // Add magical appearance delay based on position var delay = row * 50 + Math.random() * 100; if (grid[row][col].ball) { grid[row][col].ball.alpha = 0; grid[row][col].ball.y -= 50; LK.setTimeout(function (cell) { return function () { if (cell.ball) { tween(cell.ball, { alpha: 1, y: cell.ball.y + 50 }, { duration: 400, easing: tween.bounceOut }); } }; }(grid[row][col]), delay); } } } } } // Spawn walls at 5 random positions function spawnWalls() { var availableCells = []; for (var row = 0; row < GRID_SIZE; row++) { for (var col = 0; col < GRID_SIZE; col++) { if (grid[row][col].ball && !grid[row][col].isBomb && !grid[row][col].isWall) { availableCells.push(grid[row][col]); } } } if (availableCells.length >= 5) { for (var i = 0; i < 5; i++) { var randomIndex = Math.floor(Math.random() * availableCells.length); var selectedCell = availableCells[randomIndex]; selectedCell.setBall('wall'); totalWallsCreated++; availableCells.splice(randomIndex, 1); } } // Show win screen with custom text function showWinScreen() { // Create semi-transparent overlay var overlay = LK.getAsset('grid_cell', { anchorX: 0.5, anchorY: 0.5 }); overlay.width = 2048; overlay.height = 2732; overlay.alpha = 0.8; overlay.tint = 0x000000; overlay.x = 1024; overlay.y = 1366; game.addChild(overlay); // Create win text var winText = new Text2('KAZANDIN!', { size: 120, fill: 0x00FF00 }); winText.anchor.set(0.5, 0.5); winText.x = 1024; winText.y = 1200; game.addChild(winText); // Create play again text var playAgainText = new Text2('TEKRAR OYNA', { size: 80, fill: 0xFFFFFF }); playAgainText.anchor.set(0.5, 0.5); playAgainText.x = 1024; playAgainText.y = 1350; game.addChild(playAgainText); // Create bottom message text var bottomText = new Text2('Eğer oyunumu beğendiysen yeni oyunlar gelecek', { size: 60, fill: 0xFFFF00 }); bottomText.anchor.set(0.5, 0.5); bottomText.x = 1024; bottomText.y = 1500; game.addChild(bottomText); // Add click handler for play again playAgainText.down = function () { // Reset game state totalWallsCreated = 0; lastWallSpawnScore = 0; LK.setScore(0); scoreTxt.setText('Score: 0'); gameStarted = false; // Show UI elements again marketBtn.visible = true; coinsTxt.visible = true; pickaxeTxt.visible = true; goldFrenzyTxt.visible = true; // Clear grid for (var row = 0; row < GRID_SIZE; row++) { for (var col = 0; col < GRID_SIZE; col++) { game.removeChild(grid[row][col]); } } grid = []; // Remove win screen elements game.removeChild(overlay); game.removeChild(winText); game.removeChild(playAgainText); game.removeChild(bottomText); // Show start screen again showStartScreen(); }; // Add glow animation to win text tween(winText, { scaleX: 1.1, scaleY: 1.1 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { tween(winText, { scaleX: 1.0, scaleY: 1.0 }, { duration: 1000, easing: tween.easeInOut }); } }); } // Show code entry screen var codeEntryElements = []; var enteredCode = ''; function showCodeEntry() { // Create semi-transparent overlay var overlay = LK.getAsset('grid_cell', { anchorX: 0.5, anchorY: 0.5 }); overlay.width = 2048; overlay.height = 2732; overlay.alpha = 0.9; overlay.tint = 0x000000; overlay.x = 1024; overlay.y = 1366; game.addChild(overlay); codeEntryElements.push(overlay); // Create title text var titleText = new Text2('KOD GIRIN', { size: 80, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0.5); titleText.x = 1024; titleText.y = 800; game.addChild(titleText); codeEntryElements.push(titleText); // Create code display var codeDisplay = new Text2(enteredCode, { size: 100, fill: 0x00FF00 }); codeDisplay.anchor.set(0.5, 0.5); codeDisplay.x = 1024; codeDisplay.y = 1000; game.addChild(codeDisplay); codeEntryElements.push(codeDisplay); // Create number buttons var numbers = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0']; var buttonStartX = 600; var buttonStartY = 1200; var buttonSpacing = 150; for (var i = 0; i < numbers.length; i++) { var numButton = new Text2(numbers[i], { size: 120, fill: 0xFFFFFF }); numButton.anchor.set(0.5, 0.5); numButton.x = buttonStartX + i % 5 * buttonSpacing; numButton.y = buttonStartY + Math.floor(i / 5) * 120; numButton.number = numbers[i]; numButton.down = function () { if (enteredCode.length < 8) { enteredCode += this.number; codeDisplay.setText(enteredCode); } }; game.addChild(numButton); codeEntryElements.push(numButton); } // Create clear button var clearButton = new Text2('TEMİZLE', { size: 60, fill: 0xFF0000 }); clearButton.anchor.set(0.5, 0.5); clearButton.x = 1024; clearButton.y = 1500; clearButton.down = function () { enteredCode = ''; codeDisplay.setText(enteredCode); }; game.addChild(clearButton); codeEntryElements.push(clearButton); // Create submit button var submitButton = new Text2('ONAYLA', { size: 60, fill: 0x00FF00 }); submitButton.anchor.set(0.5, 0.5); submitButton.x = 1024; submitButton.y = 1600; submitButton.down = function () { if (enteredCode === '11012012') { if (codeUsed) { // Show already used message showCodeAlreadyUsed(); } else { coins += 300; codeUsed = true; storage.coins = coins; storage.codeUsed = codeUsed; coinsTxt.setText('Coins: ' + coins); // Show success message but don't close showCodeSuccess(); } } else { // Show error message showCodeError(); } }; game.addChild(submitButton); codeEntryElements.push(submitButton); // Create close button var closeButton = new Text2('KAPAT', { size: 50, fill: 0xFFFFFF }); closeButton.anchor.set(0.5, 0.5); closeButton.x = 1024; closeButton.y = 1700; closeButton.down = function () { hideCodeEntry(); }; game.addChild(closeButton); codeEntryElements.push(closeButton); } // Hide code entry screen function hideCodeEntry() { for (var i = 0; i < codeEntryElements.length; i++) { game.removeChild(codeEntryElements[i]); } codeEntryElements = []; enteredCode = ''; } // Show success message function showCodeSuccess() { var successText = new Text2('300 ALTIN KAZANDINIZ!', { size: 80, fill: 0x00FF00 }); successText.anchor.set(0.5, 0.5); successText.x = 1024; successText.y = 1366; game.addChild(successText); // Remove success message after 2 seconds LK.setTimeout(function () { game.removeChild(successText); }, 2000); } // Show error message function showCodeError() { var errorText = new Text2('YANLIŞ KOD!', { size: 80, fill: 0xFF0000 }); errorText.anchor.set(0.5, 0.5); errorText.x = 1024; errorText.y = 1366; game.addChild(errorText); // Remove error message after 2 seconds LK.setTimeout(function () { game.removeChild(errorText); }, 2000); } // Show already used code message function showCodeAlreadyUsed() { var usedText = new Text2('BU KOD KULLANILDI', { size: 60, fill: 0xFF0000 }); usedText.anchor.set(0.5, 0.5); usedText.x = 1024; usedText.y = 1366; game.addChild(usedText); // Remove message after 2 seconds LK.setTimeout(function () { game.removeChild(usedText); }, 2000); } // Help screen variables var helpScreenElements = []; var helpInfoElements = []; // Show help screen with bomb types function showHelpScreen() { // Create semi-transparent overlay var overlay = LK.getAsset('grid_cell', { anchorX: 0.5, anchorY: 0.5 }); overlay.width = 2048; overlay.height = 2732; overlay.alpha = 0.9; overlay.tint = 0x000000; overlay.x = 1024; overlay.y = 1366; game.addChild(overlay); helpScreenElements.push(overlay); // Create title text var titleText = new Text2('BOMBA REHBERİ', { size: 80, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0.5); titleText.x = 1024; titleText.y = 400; game.addChild(titleText); helpScreenElements.push(titleText); // Create bomb images and labels var bombTypes = [{ asset: 'bomb', name: 'Normal Bomba' }, { asset: 'red_bomb', name: 'Kırmızı Bomba' }, { asset: 'purple_bomb', name: 'Mor Bomba' }, { asset: 'yellow_bomb', name: 'Sarı Bomba' }]; var startY = 600; var spacing = 200; for (var i = 0; i < bombTypes.length; i++) { var bombImg = LK.getAsset(bombTypes[i].asset, { anchorX: 0.5, anchorY: 0.5 }); bombImg.x = 1024; bombImg.y = startY + i * spacing; bombImg.scaleX = 0.8; bombImg.scaleY = 0.8; bombImg.bombType = bombTypes[i].asset; bombImg.down = function () { showBombInfo(this.bombType); }; game.addChild(bombImg); helpScreenElements.push(bombImg); var bombLabel = new Text2(bombTypes[i].name, { size: 60, fill: 0xFFFFFF }); bombLabel.anchor.set(0.5, 0.5); bombLabel.x = 1024; bombLabel.y = startY + i * spacing + 80; bombLabel.bombType = bombTypes[i].asset; bombLabel.down = function () { showBombInfo(this.bombType); }; game.addChild(bombLabel); helpScreenElements.push(bombLabel); } // Create close button var closeBtn = new Text2('KAPAT', { size: 60, fill: 0xFF0000 }); closeBtn.anchor.set(0.5, 0.5); closeBtn.x = 1024; closeBtn.y = 2400; closeBtn.down = function () { hideHelpScreen(); }; game.addChild(closeBtn); helpScreenElements.push(closeBtn); } // Hide help screen function hideHelpScreen() { for (var i = 0; i < helpScreenElements.length; i++) { game.removeChild(helpScreenElements[i]); } helpScreenElements = []; hideHelpInfo(); } // Show detailed bomb information function showBombInfo(bombType) { // Clear previous info hideHelpInfo(); var infoText = ''; var spawnChance = ''; if (bombType === 'bomb') { infoText = 'Normal Bomba\n\n3x3 alanda patlar\n5 top eşleşirse oluşur\nHer 10 saniyede rastgele oluşur'; spawnChance = 'Oluşma: 5 top eşleşmesi\nveya 10 saniye aralıklarla'; } else if (bombType === 'red_bomb') { infoText = 'Kırmızı Bomba\n\n7x7 alanda patlar\n5 top eşleşirse oluşur\nDaha güçlü patlama'; spawnChance = 'Oluşma: 5 top eşleşmesi'; } else if (bombType === 'purple_bomb') { infoText = 'Mor Bomba\n\n5x5 alanda patlar\n5 normal bomba oluşturur\nDuvarları da yok eder'; spawnChance = 'Oluşma: Özel durumlar'; } else if (bombType === 'yellow_bomb') { infoText = 'Sarı Bomba\n\nTÜM topları yok eder\n10000 puan verir\nYeşil iz bırakır'; spawnChance = 'Oluşma: %0.1 şans'; } // Create info background var infoBg = LK.getAsset('grid_cell', { anchorX: 0.5, anchorY: 0.5 }); infoBg.width = 1600; infoBg.height = 800; infoBg.alpha = 0.8; infoBg.tint = 0x333333; infoBg.x = 1024; infoBg.y = 1600; game.addChild(infoBg); helpInfoElements.push(infoBg); // Create info text var infoDisplay = new Text2(infoText, { size: 50, fill: 0xFFFFFF }); infoDisplay.anchor.set(0.5, 0.5); infoDisplay.x = 1024; infoDisplay.y = 1500; game.addChild(infoDisplay); helpInfoElements.push(infoDisplay); // Create spawn chance text var chanceDisplay = new Text2(spawnChance, { size: 45, fill: 0xFFFF00 }); chanceDisplay.anchor.set(0.5, 0.5); chanceDisplay.x = 1024; chanceDisplay.y = 1700; game.addChild(chanceDisplay); helpInfoElements.push(chanceDisplay); } // Hide bomb info function hideHelpInfo() { for (var i = 0; i < helpInfoElements.length; i++) { game.removeChild(helpInfoElements[i]); } helpInfoElements = []; } // Spawn a random bomb on the grid function spawnBomb() { var emptyCells = []; for (var row = 0; row < GRID_SIZE; row++) { for (var col = 0; col < GRID_SIZE; col++) { if (grid[row][col].ball && !grid[row][col].isBomb) { emptyCells.push(grid[row][col]); } } } if (emptyCells.length > 0) { var randomCell = emptyCells[Math.floor(Math.random() * emptyCells.length)]; // 0.1% chance for yellow bomb, 1% chance for purple bomb, 98.9% chance for regular bomb var rand = Math.random(); var bombType; if (rand < 0.001) { bombType = 'yellow_bomb'; } else if (rand < 0.011) { bombType = 'purple_bomb'; } else { bombType = 'bomb'; } randomCell.setBall(bombType); } } // Clear previous selection visual feedback function clearSelectionTint() { if (selectedCell && selectedCell.ball) { selectedCell.ball.tint = 0xffffff; } } // Handle pickaxe use on walls game.down = function (x, y, obj) { if (!gameStarted || isAnimating || !grid || grid.length === 0) return; // Find clicked cell for pickaxe use only for (var row = 0; row < GRID_SIZE; row++) { if (!grid[row]) continue; // Skip if row doesn't exist for (var col = 0; col < GRID_SIZE; col++) { if (!grid[row][col]) continue; // Skip if cell doesn't exist var cell = grid[row][col]; var cellPos = game.toLocal(cell.parent.toGlobal(cell.position)); var distance = Math.sqrt(Math.pow(x - cellPos.x, 2) + Math.pow(y - cellPos.y, 2)); if (distance < CELL_SIZE / 2 && cell.ball) { // Handle pickaxe use on walls if (cell.isWall && pickaxeUses > 0) { pickaxeUses--; pickaxeTxt.setText('Kazma: ' + pickaxeUses); // Create wall destruction effect cell.createSparkles(); if (cell.ball) { tween(cell.ball, { scaleX: 0, scaleY: 0, alpha: 0 }, { duration: 300, easing: tween.easeIn }); } LK.setTimeout(function () { cell.setBall(null); }, 300); return; } break; } } } }; // Check if balls are stuck around walls and create bombs function checkForStuckBalls() { if (!grid || grid.length === 0) return; var stuckAreas = []; // Find all wall positions for (var row = 0; row < GRID_SIZE; row++) { if (!grid[row]) continue; for (var col = 0; col < GRID_SIZE; col++) { if (!grid[row][col]) continue; if (grid[row][col].isWall) { // Check 3x3 area around this wall for stuck balls var surroundingBalls = []; var hasEmptySpace = false; for (var dr = -1; dr <= 1; dr++) { for (var dc = -1; dc <= 1; dc++) { var checkRow = row + dr; var checkCol = col + dc; if (checkRow >= 0 && checkRow < GRID_SIZE && checkCol >= 0 && checkCol < GRID_SIZE && grid[checkRow] && grid[checkRow][checkCol]) { var checkCell = grid[checkRow][checkCol]; if (checkCell.ball && !checkCell.isWall && !checkCell.isBomb) { surroundingBalls.push(checkCell); } else if (!checkCell.ball) { hasEmptySpace = true; } } } } // If there are 6 or more balls around wall with no empty spaces // and no possible matches, consider them stuck if (surroundingBalls.length >= 6 && !hasEmptySpace) { var hasValidMove = false; // Check if any surrounding ball can make a match for (var i = 0; i < surroundingBalls.length; i++) { var ball = surroundingBalls[i]; // Check if this ball has matching neighbors var neighbors = [{ r: ball.row - 1, c: ball.col }, { r: ball.row + 1, c: ball.col }, { r: ball.row, c: ball.col - 1 }, { r: ball.row, c: ball.col + 1 }]; for (var j = 0; j < neighbors.length; j++) { var nr = neighbors[j].r; var nc = neighbors[j].c; if (nr >= 0 && nr < GRID_SIZE && nc >= 0 && nc < GRID_SIZE && grid[nr] && grid[nr][nc]) { var neighborCell = grid[nr][nc]; if (neighborCell.ball && !neighborCell.isWall && neighborCell.ballType === ball.ballType) { hasValidMove = true; break; } } } if (hasValidMove) break; } if (!hasValidMove) { // Find best position for bomb (center of stuck area) var centerRow = Math.round(row); var centerCol = Math.round(col); // Find nearest non-wall cell to place bomb for (var radius = 1; radius <= 3; radius++) { for (var dr = -radius; dr <= radius; dr++) { for (var dc = -radius; dc <= radius; dc++) { var bombRow = centerRow + dr; var bombCol = centerCol + dc; if (bombRow >= 0 && bombRow < GRID_SIZE && bombCol >= 0 && bombCol < GRID_SIZE && grid[bombRow] && grid[bombRow][bombCol]) { var bombCell = grid[bombRow][bombCol]; if (bombCell.ball && !bombCell.isWall && !bombCell.isBomb) { stuckAreas.push({ row: bombRow, col: bombCol }); radius = 4; // Break outer loops break; } } } if (radius > 3) break; } if (radius > 3) break; } } } } } } // Create bombs in stuck areas for (var k = 0; k < stuckAreas.length; k++) { var bombPos = stuckAreas[k]; if (grid[bombPos.row] && grid[bombPos.row][bombPos.col]) { grid[bombPos.row][bombPos.col].setBall('bomb'); // Add visual effect to indicate bomb was created due to stuck situation var bombCell = grid[bombPos.row][bombPos.col]; if (bombCell.ball) { bombCell.ball.tint = 0xff6666; // Reddish tint LK.setTimeout(function (cell) { return function () { if (cell.ball) { cell.ball.tint = 0xffffff; } }; }(bombCell), 1000); } } } } } // Process matches and cascades function processMatches() { var matchResult = checkMatches(); var matchedCells = matchResult.matchedCells; var fiveBallMatches = matchResult.fiveBallMatches; if (matchedCells.length > 0) { removeMatches(matchedCells, fiveBallMatches); LK.setTimeout(function () { dropBalls(); fillEmptySpaces(); LK.setTimeout(function () { processMatches(); // Check for cascade matches }, 200); }, 300); } else { isAnimating = false; } } // Show start screen instead of initializing game immediately showStartScreen(); // Main game loop game.update = function () { if (!gameStarted) return; bombSpawnCounter++; // Spawn bomb every 600 ticks (10 seconds at 60fps) if (bombSpawnCounter >= 600) { spawnBomb(); bombSpawnCounter = 0; } // Check for stuck balls every 300 ticks (5 seconds) if (bombSpawnCounter % 300 === 0) { checkForStuckBalls(); } // Check if green trail should be removed (1000 points after yellow bomb explosion) if (yellowBombTrail && LK.getScore() >= yellowBombExplosionScore + 1000) { // Fade out the trail tween(yellowBombTrail, { alpha: 0, scaleX: 0.5, scaleY: 0.5 }, { duration: 500, easing: tween.easeIn, onFinish: function onFinish() { if (yellowBombTrail) { game.removeChild(yellowBombTrail); yellowBombTrail = null; } } }); } // Check win condition at 15000 points if (LK.getScore() >= 15000) { var winCoins = 20 * goldMultiplier; coins += winCoins; storage.coins = coins; coinsTxt.setText('Coins: ' + coins); LK.showYouWin(); } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var GridCell = Container.expand(function (row, col) {
var self = Container.call(this);
self.row = row;
self.col = col;
self.ballType = null;
self.ball = null;
self.isBomb = false;
self.isWall = false;
self.velocityY = 0;
self.gravity = 0.5;
self.isGrounded = false;
var cellBg = self.attachAsset('grid_cell', {
anchorX: 0.5,
anchorY: 0.5
});
self.setBall = function (ballType) {
if (self.ball) {
self.removeChild(self.ball);
}
if (self.glowEffect) {
self.removeChild(self.glowEffect);
self.glowEffect = null;
}
if (ballType === 'wall') {
self.ball = self.attachAsset('wall', {
anchorX: 0.5,
anchorY: 0.5
});
self.isWall = true;
self.isBomb = false;
self.ballType = ballType;
} else if (ballType === 'bomb' || ballType === 'red_bomb' || ballType === 'purple_bomb' || ballType === 'yellow_bomb') {
var bombAsset = ballType === 'red_bomb' ? 'red_bomb' : ballType === 'purple_bomb' ? 'purple_bomb' : ballType === 'yellow_bomb' ? 'yellow_bomb' : 'bomb';
self.ball = self.attachAsset(bombAsset, {
anchorX: 0.5,
anchorY: 0.5
});
self.isBomb = true;
self.ballType = ballType;
// Add magical pulsing effect to bomb
tween(self.ball, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(self.ball, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 800,
easing: tween.easeInOut
});
}
});
} else if (ballType) {
// Add glow effect behind the ball
self.glowEffect = self.attachAsset('glow_effect', {
anchorX: 0.5,
anchorY: 0.5
});
self.glowEffect.alpha = 0.3;
self.glowEffect.tint = self.getBallColor(ballType);
// Add the main ball
self.ball = self.attachAsset('ball_' + ballType, {
anchorX: 0.5,
anchorY: 0.5
});
self.isBomb = false;
self.ballType = ballType;
// Add crown if upgrade is purchased and enabled
if (hasCrownUpgrade && crownEnabled) {
self.crown = self.attachAsset('crown', {
anchorX: 0.5,
anchorY: 0.5
});
self.crown.y = -40;
}
// Add sparkle entrance effect with gravity
self.ball.scaleX = 0;
self.ball.scaleY = 0;
self.ball.y = -100; // Start above the cell
self.velocityY = 0;
self.isGrounded = false;
tween(self.ball, {
scaleX: 1,
scaleY: 1
}, {
duration: 400,
easing: tween.elasticOut
});
// Add continuous gentle glow pulsing
self.startGlowAnimation();
} else {
self.ball = null;
self.ballType = null;
self.isBomb = false;
self.isWall = false;
}
};
self.down = function (x, y, obj) {
if (self.ball && !self.isWall) {
if (!selectedCell) {
// First selection
selectedCell = self;
// Add visual feedback for selection
if (self.ball) {
self.ball.tint = 0xaaaaaa; // Gray tint to show selection
}
} else if (selectedCell === self) {
// Deselect if clicking same cell
if (selectedCell.ball) {
selectedCell.ball.tint = 0xffffff; // Remove tint
}
selectedCell = null;
} else if (areAdjacent(selectedCell, self)) {
// Valid adjacent swap
secondSelectedCell = self;
// Clear visual feedback
if (selectedCell.ball) {
selectedCell.ball.tint = 0xffffff;
}
// Perform the swap
swapBalls(selectedCell, secondSelectedCell);
// Reset selections
selectedCell = null;
secondSelectedCell = null;
isAnimating = true;
// Check for matches after swap
LK.setTimeout(function () {
processMatches();
}, 100);
} else {
// Select new cell, clear previous selection
if (selectedCell.ball) {
selectedCell.ball.tint = 0xffffff;
}
selectedCell = self;
if (self.ball) {
self.ball.tint = 0xaaaaaa;
}
}
}
};
self.getBallColor = function (ballType) {
var colors = {
'red': 0xff4444,
'blue': 0x4444ff,
'green': 0x44ff44,
'yellow': 0xffff44,
'purple': 0xff44ff,
'orange': 0xff8844
};
return colors[ballType] || 0xffffff;
};
self.startGlowAnimation = function () {
if (self.glowEffect) {
var _pulseGlow = function pulseGlow() {
if (self.glowEffect) {
tween(self.glowEffect, {
alpha: 0.6
}, {
duration: 1500,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (self.glowEffect) {
tween(self.glowEffect, {
alpha: 0.3
}, {
duration: 1500,
easing: tween.easeInOut,
onFinish: _pulseGlow
});
}
}
});
}
};
_pulseGlow();
}
};
self.createSparkles = function () {
for (var i = 0; i < 5; i++) {
var sparkle = self.attachAsset('sparkle', {
anchorX: 0.5,
anchorY: 0.5
});
sparkle.x = (Math.random() - 0.5) * 80;
sparkle.y = (Math.random() - 0.5) * 80;
sparkle.alpha = 0.8;
sparkle.scaleX = 0.5;
sparkle.scaleY = 0.5;
tween(sparkle, {
x: sparkle.x + (Math.random() - 0.5) * 100,
y: sparkle.y + (Math.random() - 0.5) * 100,
alpha: 0,
scaleX: 0,
scaleY: 0
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
if (sparkle.parent) {
sparkle.parent.removeChild(sparkle);
}
}
});
}
};
self.update = function () {
if (self.ball && !self.isWall && !self.isBomb) {
// Apply gravity if not grounded
if (!self.isGrounded) {
self.velocityY += self.gravity;
self.ball.y += self.velocityY;
// Check if ball has reached ground (relative to cell)
if (self.ball.y >= 0) {
self.ball.y = 0;
self.velocityY = 0;
self.isGrounded = true;
}
}
// Add subtle bounce effect when ball lands
if (self.isGrounded && Math.abs(self.velocityY) < 0.1) {
// Add gentle floating animation
if (!self.floatTween) {
self.floatTween = true;
tween(self.ball, {
y: -5
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (self.ball) {
tween(self.ball, {
y: 0
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
self.floatTween = false;
}
});
}
}
});
}
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x222222
});
/****
* Game Code
****/
var GRID_SIZE = 15;
var CELL_SIZE = 160;
var BALL_COLORS = ['red', 'blue', 'green', 'yellow', 'purple', 'orange'];
var GRID_START_X = (2048 - GRID_SIZE * CELL_SIZE) / 2;
var GRID_START_Y = 300;
var grid = [];
var selectedCell = null;
var secondSelectedCell = null;
var isAnimating = false;
var bombSpawnCounter = 0;
var lastWallSpawnScore = 0;
var totalWallsCreated = 0;
var gameStarted = false;
var startScreenElements = [];
var coins = storage.coins || 0;
var hasCrownUpgrade = storage.hasCrownUpgrade || false;
var codeUsed = storage.codeUsed || false;
var marketVisible = false;
var marketElements = [];
var yellowBombTrail = null;
var yellowBombExplosionScore = 0;
var pickaxeUses = 0;
var goldFrenzyTurns = storage.goldFrenzyTurns || 0;
var goldMultiplier = goldFrenzyTurns > 0 ? 2 : 1;
var crownToggleBtn = null;
var crownEnabled = storage.crownEnabled !== undefined ? storage.crownEnabled : true;
// Create score display
var scoreTxt = new Text2('Score: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Create coins display
var coinsTxt = new Text2('Coins: ' + coins, {
size: 60,
fill: 0xFFD700
});
coinsTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(coinsTxt);
// Create pickaxe uses display
var pickaxeTxt = new Text2('Kazma: ' + pickaxeUses, {
size: 50,
fill: 0x8B4513
});
pickaxeTxt.anchor.set(1, 0);
pickaxeTxt.y = 140;
LK.gui.topRight.addChild(pickaxeTxt);
// Create gold frenzy turns display
var goldFrenzyTxt = new Text2('', {
size: 50,
fill: 0xFFD700
});
goldFrenzyTxt.anchor.set(1, 0);
goldFrenzyTxt.y = 200;
LK.gui.topRight.addChild(goldFrenzyTxt);
// Update gold frenzy display
function updateGoldFrenzyDisplay() {
if (goldFrenzyTurns > 0) {
goldFrenzyTxt.setText('Altın Çılgınlığı: ' + goldFrenzyTurns + ' tur');
} else {
goldFrenzyTxt.setText('');
}
}
updateGoldFrenzyDisplay();
// Show market screen
function showMarket() {
marketVisible = true;
// Create semi-transparent overlay
var overlay = LK.getAsset('grid_cell', {
anchorX: 0.5,
anchorY: 0.5
});
overlay.width = 2048;
overlay.height = 2732;
overlay.alpha = 0.9;
overlay.tint = 0x000000;
overlay.x = 1024;
overlay.y = 1366;
game.addChild(overlay);
marketElements.push(overlay);
// Create market title
var marketTitle = new Text2('MARKET', {
size: 100,
fill: 0xFFFFFF
});
marketTitle.anchor.set(0.5, 0.5);
marketTitle.x = 1024;
marketTitle.y = 800;
game.addChild(marketTitle);
marketElements.push(marketTitle);
// Create crown upgrade text
var crownText = new Text2('Tüm Karakterlere Kral Tacı', {
size: 70,
fill: 0x00FF00
});
crownText.anchor.set(0.5, 0.5);
crownText.x = 1024;
crownText.y = 1200;
game.addChild(crownText);
marketElements.push(crownText);
// Create price text
var priceText = new Text2('100 Altın', {
size: 60,
fill: 0xFFD700
});
priceText.anchor.set(0.5, 0.5);
priceText.x = 1024;
priceText.y = 1300;
game.addChild(priceText);
marketElements.push(priceText);
// Create pickaxe upgrade text
var pickaxeText = new Text2('Kazma - Duvarları Kır', {
size: 70,
fill: 0x00FF00
});
pickaxeText.anchor.set(0.5, 0.5);
pickaxeText.x = 1024;
pickaxeText.y = 1400;
game.addChild(pickaxeText);
marketElements.push(pickaxeText);
// Create pickaxe price text
var pickaxePriceText = new Text2('200 Altın', {
size: 60,
fill: 0xFFD700
});
pickaxePriceText.anchor.set(0.5, 0.5);
pickaxePriceText.x = 1024;
pickaxePriceText.y = 1500;
game.addChild(pickaxePriceText);
marketElements.push(pickaxePriceText);
// Create gold frenzy text
var goldFrenzyText = new Text2('Altın Çılgınlığı', {
size: 70,
fill: 0x00FF00
});
goldFrenzyText.anchor.set(1, 0);
goldFrenzyText.x = 1900;
goldFrenzyText.y = 900;
game.addChild(goldFrenzyText);
marketElements.push(goldFrenzyText);
// Create gold frenzy price text
var goldFrenzyPriceText = new Text2('50 Altın', {
size: 60,
fill: 0xFFD700
});
goldFrenzyPriceText.anchor.set(1, 0);
goldFrenzyPriceText.x = 1900;
goldFrenzyPriceText.y = 1000;
game.addChild(goldFrenzyPriceText);
marketElements.push(goldFrenzyPriceText);
// Create gold frenzy description
var goldFrenzyDesc = new Text2('30 tur 2x altın', {
size: 50,
fill: 0xFFFFFF
});
goldFrenzyDesc.anchor.set(1, 0);
goldFrenzyDesc.x = 1900;
goldFrenzyDesc.y = 1100;
game.addChild(goldFrenzyDesc);
marketElements.push(goldFrenzyDesc);
// Add gold frenzy purchase handler
goldFrenzyPriceText.down = function () {
if (coins >= 50) {
coins -= 50;
goldFrenzyTurns += 30; // Stack the effect
goldMultiplier = 2;
storage.coins = coins;
storage.goldFrenzyTurns = goldFrenzyTurns;
coinsTxt.setText('Coins: ' + coins);
updateGoldFrenzyDisplay();
hideMarket();
}
};
// Add pickaxe purchase handler
pickaxePriceText.down = function () {
if (coins >= 200) {
coins -= 200;
pickaxeUses = 10; // Reset pickaxe uses each game
storage.coins = coins;
coinsTxt.setText('Coins: ' + coins);
hideMarket();
}
};
// Create close button
var closeBtn = new Text2('KAPAT', {
size: 50,
fill: 0xFF0000
});
closeBtn.anchor.set(0.5, 0.5);
closeBtn.x = 1024;
closeBtn.y = 1600;
game.addChild(closeBtn);
marketElements.push(closeBtn);
// Add purchase handler
priceText.down = function () {
if (coins >= 100 && !hasCrownUpgrade) {
coins -= 100;
hasCrownUpgrade = true;
storage.coins = coins;
storage.hasCrownUpgrade = hasCrownUpgrade;
coinsTxt.setText('Coins: ' + coins);
hideMarket();
// Add crowns to existing balls
for (var row = 0; row < GRID_SIZE; row++) {
for (var col = 0; col < GRID_SIZE; col++) {
var cell = grid[row][col];
if (cell.ball && !cell.isBomb && !cell.isWall && cell.ballType) {
cell.setBall(cell.ballType);
}
}
}
}
};
// Add close handler
closeBtn.down = function () {
hideMarket();
};
}
// Hide market screen
function hideMarket() {
marketVisible = false;
for (var i = 0; i < marketElements.length; i++) {
game.removeChild(marketElements[i]);
}
marketElements = [];
}
// Create market button
var marketBtn = new Text2('MARKET', {
size: 50,
fill: 0x00FF00
});
marketBtn.anchor.set(1, 0);
marketBtn.y = 80;
LK.gui.topRight.addChild(marketBtn);
marketBtn.down = function () {
if (!marketVisible) {
showMarket();
}
};
// Function to show start screen
function showStartScreen() {
// Set black background
game.setBackgroundColor(0x000000);
// Create title text "duyguları vur"
var titleText = new Text2('DUYGULARI VUR', {
size: 120,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 1200;
game.addChild(titleText);
startScreenElements.push(titleText);
// Create play button "oyna"
var playButton = new Text2('OYNA', {
size: 100,
fill: 0x00FF00
});
playButton.anchor.set(0.5, 0.5);
playButton.x = 1024;
playButton.y = 1400;
game.addChild(playButton);
startScreenElements.push(playButton);
// Add click handler for play button
playButton.down = function () {
startGame();
};
// Create help button (question mark)
var helpButton = new Text2('?', {
size: 120,
fill: 0x00FFFF
});
helpButton.anchor.set(0, 0);
helpButton.x = 150;
helpButton.y = 150;
game.addChild(helpButton);
startScreenElements.push(helpButton);
// Add click handler for help button
helpButton.down = function () {
showHelpScreen();
};
// Create code entry button
var codeButton = new Text2('KOD YAZIN', {
size: 60,
fill: 0xFFFF00
});
codeButton.anchor.set(0, 1);
codeButton.x = 100;
codeButton.y = 2600;
game.addChild(codeButton);
startScreenElements.push(codeButton);
// Add click handler for code button
codeButton.down = function () {
showCodeEntry();
};
// Create crown toggle button only if crown upgrade is purchased
if (hasCrownUpgrade) {
crownToggleBtn = new Text2(crownEnabled ? 'Kral Tacını Kapat' : 'Kral Tacını Aç', {
size: 60,
fill: crownEnabled ? 0xFF0000 : 0x00FF00
});
crownToggleBtn.anchor.set(0.5, 1);
crownToggleBtn.x = 1024;
crownToggleBtn.y = 2600;
game.addChild(crownToggleBtn);
startScreenElements.push(crownToggleBtn);
// Add click handler for crown toggle
crownToggleBtn.down = function () {
crownEnabled = !crownEnabled;
storage.crownEnabled = crownEnabled;
crownToggleBtn.setText(crownEnabled ? 'Kral Tacını Kapat' : 'Kral Tacını Aç');
crownToggleBtn.fill = crownEnabled ? 0xFF0000 : 0x00FF00;
};
}
// Add glow animation to play button
tween(playButton, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(playButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 800,
easing: tween.easeInOut
});
}
});
}
// Function to start the actual game
function startGame() {
// Remove start screen elements
for (var i = 0; i < startScreenElements.length; i++) {
game.removeChild(startScreenElements[i]);
}
startScreenElements = [];
// Set game background color
game.setBackgroundColor(0x222222);
// Hide UI elements during gameplay
marketBtn.visible = false;
coinsTxt.visible = false;
pickaxeTxt.visible = false;
goldFrenzyTxt.visible = false;
// Initialize game
gameStarted = true;
pickaxeUses = 0; // Reset pickaxe uses for new game
pickaxeTxt.setText('Kazma: ' + pickaxeUses);
// Update gold frenzy display for new game
updateGoldFrenzyDisplay();
initializeGrid();
}
// Initialize grid
function initializeGrid() {
for (var row = 0; row < GRID_SIZE; row++) {
grid[row] = [];
for (var col = 0; col < GRID_SIZE; col++) {
var cell = new GridCell(row, col);
cell.x = GRID_START_X + col * CELL_SIZE + CELL_SIZE / 2;
cell.y = GRID_START_Y + row * CELL_SIZE + CELL_SIZE / 2;
var randomColor = BALL_COLORS[Math.floor(Math.random() * BALL_COLORS.length)];
cell.setBall(randomColor);
grid[row][col] = cell;
game.addChild(cell);
}
}
}
// Get random ball color
function getRandomBallColor() {
return BALL_COLORS[Math.floor(Math.random() * BALL_COLORS.length)];
}
// Check if two cells are adjacent
function areAdjacent(cell1, cell2) {
var rowDiff = Math.abs(cell1.row - cell2.row);
var colDiff = Math.abs(cell1.col - cell2.col);
return rowDiff === 1 && colDiff === 0 || rowDiff === 0 && colDiff === 1;
}
// Swap balls between two cells
function swapBalls(cell1, cell2) {
var tempType = cell1.ballType;
var tempIsBomb = cell1.isBomb;
cell1.setBall(cell2.ballType);
cell2.setBall(tempType);
}
// Check for matches starting from a specific cell
function checkMatches() {
var matchedCells = [];
var fiveBallMatches = [];
var visited = [];
for (var row = 0; row < GRID_SIZE; row++) {
visited[row] = [];
for (var col = 0; col < GRID_SIZE; col++) {
visited[row][col] = false;
}
}
// Check horizontal matches
for (var row = 0; row < GRID_SIZE; row++) {
for (var col = 0; col < GRID_SIZE - 2; col++) {
var cell = grid[row][col];
if (!cell.ball || cell.isBomb || cell.isWall || visited[row][col]) continue;
var matchCount = 1;
var matchCells = [cell];
for (var c = col + 1; c < GRID_SIZE; c++) {
var nextCell = grid[row][c];
if (nextCell.ball && !nextCell.isBomb && !nextCell.isWall && nextCell.ballType === cell.ballType) {
matchCount++;
matchCells.push(nextCell);
} else {
break;
}
}
if (matchCount >= 3) {
for (var i = 0; i < matchCells.length; i++) {
matchedCells.push(matchCells[i]);
visited[matchCells[i].row][matchCells[i].col] = true;
}
// Check if it's a 5-ball match
if (matchCount >= 5) {
fiveBallMatches.push({
centerRow: matchCells[Math.floor(matchCells.length / 2)].row,
centerCol: matchCells[Math.floor(matchCells.length / 2)].col
});
}
}
}
}
// Check vertical matches
for (var col = 0; col < GRID_SIZE; col++) {
for (var row = 0; row < GRID_SIZE - 2; row++) {
var cell = grid[row][col];
if (!cell.ball || cell.isBomb || cell.isWall || visited[row][col]) continue;
var matchCount = 1;
var matchCells = [cell];
for (var r = row + 1; r < GRID_SIZE; r++) {
var nextCell = grid[r][col];
if (nextCell.ball && !nextCell.isBomb && !nextCell.isWall && nextCell.ballType === cell.ballType) {
matchCount++;
matchCells.push(nextCell);
} else {
break;
}
}
if (matchCount >= 3) {
for (var i = 0; i < matchCells.length; i++) {
if (!visited[matchCells[i].row][matchCells[i].col]) {
matchedCells.push(matchCells[i]);
visited[matchCells[i].row][matchCells[i].col] = true;
}
}
// Check if it's a 5-ball match
if (matchCount >= 5) {
fiveBallMatches.push({
centerRow: matchCells[Math.floor(matchCells.length / 2)].row,
centerCol: matchCells[Math.floor(matchCells.length / 2)].col
});
}
}
}
}
return {
matchedCells: matchedCells,
fiveBallMatches: fiveBallMatches
};
}
// Remove matched balls and update score
function removeMatches(matchData, fiveBallMatches) {
var matchedCells = matchData;
if (matchedCells.length === 0) return;
LK.setScore(LK.getScore() + matchedCells.length * 10);
scoreTxt.setText('Score: ' + LK.getScore());
// Add coins with gold frenzy multiplier
var coinsEarned = Math.floor(matchedCells.length / 3) * goldMultiplier;
if (coinsEarned > 0) {
coins += coinsEarned;
storage.coins = coins;
coinsTxt.setText('Coins: ' + coins);
}
// Decrease gold frenzy turns
if (goldFrenzyTurns > 0) {
goldFrenzyTurns--;
if (goldFrenzyTurns <= 0) {
goldMultiplier = 1;
}
storage.goldFrenzyTurns = goldFrenzyTurns;
updateGoldFrenzyDisplay();
}
// Check if we should spawn walls every 100 points
var currentScore = LK.getScore();
if (Math.floor(currentScore / 100) > Math.floor(lastWallSpawnScore / 100)) {
lastWallSpawnScore = currentScore;
LK.setTimeout(function () {
spawnWalls();
}, 400);
}
for (var i = 0; i < matchedCells.length; i++) {
// Create sparkle effect before removing
matchedCells[i].createSparkles();
// Add magical disappear animation
if (matchedCells[i].ball) {
tween(matchedCells[i].ball, {
scaleX: 0,
scaleY: 0,
alpha: 0
}, {
duration: 300,
easing: tween.easeIn
});
}
if (matchedCells[i].glowEffect) {
tween(matchedCells[i].glowEffect, {
scaleX: 2,
scaleY: 2,
alpha: 0
}, {
duration: 300,
easing: tween.easeOut
});
}
// Remove after animation
LK.setTimeout(function (cell) {
return function () {
cell.setBall(null);
};
}(matchedCells[i]), 300);
}
// Create red bombs for 5-ball matches
if (fiveBallMatches && fiveBallMatches.length > 0) {
LK.setTimeout(function () {
for (var j = 0; j < fiveBallMatches.length; j++) {
var bombPos = fiveBallMatches[j];
if (grid[bombPos.centerRow] && grid[bombPos.centerRow][bombPos.centerCol]) {
grid[bombPos.centerRow][bombPos.centerCol].setBall('red_bomb');
}
}
}, 350);
}
LK.getSound('match').play();
}
// Explode red bomb in 7x7 area
function explodeRedBomb(centerRow, centerCol) {
var clearedCells = [];
// Create magical explosion wave effect
var explosionCenter = grid[centerRow][centerCol];
for (var row = Math.max(0, centerRow - 3); row <= Math.min(GRID_SIZE - 1, centerRow + 3); row++) {
for (var col = Math.max(0, centerCol - 3); col <= Math.min(GRID_SIZE - 1, centerCol + 3); col++) {
var cell = grid[row][col];
if (cell.ball && !cell.isWall) {
clearedCells.push(cell);
// Create magical explosion effect
var distance = Math.sqrt(Math.pow(row - centerRow, 2) + Math.pow(col - centerCol, 2));
var delay = distance * 80; // Stagger the explosions
LK.setTimeout(function (targetCell) {
return function () {
targetCell.createSparkles();
if (targetCell.ball) {
// Create explosive scale effect
tween(targetCell.ball, {
scaleX: 1.8,
scaleY: 1.8
}, {
duration: 120,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(targetCell.ball, {
scaleX: 0,
scaleY: 0,
alpha: 0
}, {
duration: 180,
easing: tween.easeIn
});
}
});
}
if (targetCell.glowEffect) {
tween(targetCell.glowEffect, {
scaleX: 4,
scaleY: 4,
alpha: 0
}, {
duration: 300,
easing: tween.easeOut
});
}
LK.setTimeout(function () {
targetCell.setBall(null);
}, 300);
};
}(cell), delay);
}
}
}
LK.setScore(LK.getScore() + clearedCells.length * 8);
scoreTxt.setText('Score: ' + LK.getScore());
// Add coins with gold frenzy multiplier
var coinsEarned = Math.floor(clearedCells.length / 2) * goldMultiplier;
if (coinsEarned > 0) {
coins += coinsEarned;
storage.coins = coins;
coinsTxt.setText('Coins: ' + coins);
}
// Check if we should spawn walls every 100 points
var currentScore = LK.getScore();
if (Math.floor(currentScore / 100) > Math.floor(lastWallSpawnScore / 100)) {
lastWallSpawnScore = currentScore;
LK.setTimeout(function () {
spawnWalls();
}, 400);
}
LK.getSound('bomb_explode').play();
}
// Explode purple bomb in 5x5 area including walls
function explodePurpleBomb(centerRow, centerCol) {
var clearedCells = [];
// Create magical explosion wave effect
var explosionCenter = grid[centerRow][centerCol];
for (var row = Math.max(0, centerRow - 2); row <= Math.min(GRID_SIZE - 1, centerRow + 2); row++) {
for (var col = Math.max(0, centerCol - 2); col <= Math.min(GRID_SIZE - 1, centerCol + 2); col++) {
var cell = grid[row][col];
if (cell.ball) {
clearedCells.push(cell);
// Create magical explosion effect
var distance = Math.sqrt(Math.pow(row - centerRow, 2) + Math.pow(col - centerCol, 2));
var delay = distance * 60; // Stagger the explosions
LK.setTimeout(function (targetCell) {
return function () {
targetCell.createSparkles();
if (targetCell.ball) {
// Create explosive scale effect
tween(targetCell.ball, {
scaleX: 2.0,
scaleY: 2.0
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(targetCell.ball, {
scaleX: 0,
scaleY: 0,
alpha: 0
}, {
duration: 150,
easing: tween.easeIn
});
}
});
}
if (targetCell.glowEffect) {
tween(targetCell.glowEffect, {
scaleX: 5,
scaleY: 5,
alpha: 0
}, {
duration: 250,
easing: tween.easeOut
});
}
LK.setTimeout(function () {
targetCell.setBall(null);
}, 250);
};
}(cell), delay);
}
}
}
// After clearing area, spawn 5 normal bombs randomly in the 5x5 area
LK.setTimeout(function () {
var availableCells = [];
for (var row = Math.max(0, centerRow - 2); row <= Math.min(GRID_SIZE - 1, centerRow + 2); row++) {
for (var col = Math.max(0, centerCol - 2); col <= Math.min(GRID_SIZE - 1, centerCol + 2); col++) {
var cell = grid[row][col];
if (!cell.ball || !cell.isWall && !cell.isBomb) {
availableCells.push({
row: row,
col: col
});
}
}
}
// Spawn 5 normal bombs in random positions
var bombsToSpawn = Math.min(5, availableCells.length);
for (var i = 0; i < bombsToSpawn; i++) {
var randomIndex = Math.floor(Math.random() * availableCells.length);
var bombPos = availableCells[randomIndex];
// Set a delay for each bomb spawn
LK.setTimeout(function (pos) {
return function () {
grid[pos.row][pos.col].setBall('bomb');
// Add visual effect to show bomb spawning
if (grid[pos.row][pos.col].ball) {
grid[pos.row][pos.col].ball.scaleX = 0;
grid[pos.row][pos.col].ball.scaleY = 0;
tween(grid[pos.row][pos.col].ball, {
scaleX: 1,
scaleY: 1
}, {
duration: 300,
easing: tween.bounceOut
});
}
};
}(bombPos), i * 200);
availableCells.splice(randomIndex, 1);
}
}, 300);
LK.setScore(LK.getScore() + clearedCells.length * 12);
scoreTxt.setText('Score: ' + LK.getScore());
// Add coins with gold frenzy multiplier
var coinsEarned = Math.floor(clearedCells.length / 2) * goldMultiplier;
if (coinsEarned > 0) {
coins += coinsEarned;
storage.coins = coins;
coinsTxt.setText('Coins: ' + coins);
}
// Check if we should spawn walls every 100 points
var currentScore = LK.getScore();
if (Math.floor(currentScore / 100) > Math.floor(lastWallSpawnScore / 100)) {
lastWallSpawnScore = currentScore;
LK.setTimeout(function () {
spawnWalls();
}, 400);
}
LK.getSound('bomb_explode').play();
}
// Explode yellow bomb - destroys ALL balls and gives 10000 points
function explodeYellowBomb(explosionRow, explosionCol) {
var clearedCells = [];
// Store the explosion score for trail removal
yellowBombExplosionScore = LK.getScore();
for (var row = 0; row < GRID_SIZE; row++) {
for (var col = 0; col < GRID_SIZE; col++) {
var cell = grid[row][col];
if (cell.ball && !cell.isWall) {
clearedCells.push(cell);
var delay = Math.random() * 500;
LK.setTimeout(function (targetCell) {
return function () {
targetCell.createSparkles();
if (targetCell.ball) {
tween(targetCell.ball, {
scaleX: 2.5,
scaleY: 2.5
}, {
duration: 80,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(targetCell.ball, {
scaleX: 0,
scaleY: 0,
alpha: 0
}, {
duration: 120,
easing: tween.easeIn
});
}
});
}
if (targetCell.glowEffect) {
tween(targetCell.glowEffect, {
scaleX: 6,
scaleY: 6,
alpha: 0
}, {
duration: 200,
easing: tween.easeOut
});
}
LK.setTimeout(function () {
targetCell.setBall(null);
}, 200);
};
}(cell), delay);
}
}
}
// Create green trail at explosion location
LK.setTimeout(function () {
if (explosionRow !== undefined && explosionCol !== undefined && explosionRow >= 0 && explosionRow < GRID_SIZE && explosionCol >= 0 && explosionCol < GRID_SIZE) {
// Remove existing trail if any
if (yellowBombTrail) {
game.removeChild(yellowBombTrail);
}
// Create green trail
yellowBombTrail = LK.getAsset('green_trail', {
anchorX: 0.5,
anchorY: 0.5
});
yellowBombTrail.x = GRID_START_X + explosionCol * CELL_SIZE + CELL_SIZE / 2;
yellowBombTrail.y = GRID_START_Y + explosionRow * CELL_SIZE + CELL_SIZE / 2;
yellowBombTrail.alpha = 0.7;
game.addChild(yellowBombTrail);
// Add pulsing animation to trail
tween(yellowBombTrail, {
scaleX: 1.2,
scaleY: 1.2,
alpha: 0.9
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (yellowBombTrail) {
tween(yellowBombTrail, {
scaleX: 1.0,
scaleY: 1.0,
alpha: 0.7
}, {
duration: 1000,
easing: tween.easeInOut
});
}
}
});
}
}, 600);
LK.setScore(LK.getScore() + 10000);
scoreTxt.setText('Score: ' + LK.getScore());
// Add massive coins with gold frenzy multiplier
var coinsEarned = 100 * goldMultiplier;
coins += coinsEarned;
storage.coins = coins;
coinsTxt.setText('Coins: ' + coins);
LK.getSound('bomb_explode').play();
}
// Explode bomb in 3x3 area
function explodeBomb(centerRow, centerCol) {
var clearedCells = [];
// Create magical explosion wave effect
var explosionCenter = grid[centerRow][centerCol];
for (var row = Math.max(0, centerRow - 1); row <= Math.min(GRID_SIZE - 1, centerRow + 1); row++) {
for (var col = Math.max(0, centerCol - 1); col <= Math.min(GRID_SIZE - 1, centerCol + 1); col++) {
var cell = grid[row][col];
if (cell.ball && !cell.isWall) {
clearedCells.push(cell);
// Create magical explosion effect
var distance = Math.sqrt(Math.pow(row - centerRow, 2) + Math.pow(col - centerCol, 2));
var delay = distance * 100; // Stagger the explosions
LK.setTimeout(function (targetCell) {
return function () {
targetCell.createSparkles();
if (targetCell.ball) {
// Create explosive scale effect
tween(targetCell.ball, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(targetCell.ball, {
scaleX: 0,
scaleY: 0,
alpha: 0
}, {
duration: 200,
easing: tween.easeIn
});
}
});
}
if (targetCell.glowEffect) {
tween(targetCell.glowEffect, {
scaleX: 3,
scaleY: 3,
alpha: 0
}, {
duration: 350,
easing: tween.easeOut
});
}
LK.setTimeout(function () {
targetCell.setBall(null);
}, 350);
};
}(cell), delay);
}
}
}
LK.setScore(LK.getScore() + clearedCells.length * 5);
scoreTxt.setText('Score: ' + LK.getScore());
// Add coins with gold frenzy multiplier
var coinsEarned = Math.floor(clearedCells.length / 3) * goldMultiplier;
if (coinsEarned > 0) {
coins += coinsEarned;
storage.coins = coins;
coinsTxt.setText('Coins: ' + coins);
}
// Check if we should spawn walls every 100 points
var currentScore = LK.getScore();
if (Math.floor(currentScore / 100) > Math.floor(lastWallSpawnScore / 100)) {
lastWallSpawnScore = currentScore;
LK.setTimeout(function () {
spawnWalls();
}, 400);
}
LK.getSound('bomb_explode').play();
}
// Drop balls down to fill empty spaces
function dropBalls() {
var moved = false;
for (var col = 0; col < GRID_SIZE; col++) {
for (var row = GRID_SIZE - 1; row >= 0; row--) {
if (!grid[row][col].ball) {
// Find the first ball above this empty space
for (var r = row - 1; r >= 0; r--) {
if (grid[r][col].ball && !grid[r][col].isWall) {
grid[row][col].setBall(grid[r][col].ballType);
grid[r][col].setBall(null);
moved = true;
break;
} else if (grid[r][col].isWall) {
break;
}
}
}
}
}
return moved;
}
// Fill empty spaces at the top with new balls
function fillEmptySpaces() {
for (var col = 0; col < GRID_SIZE; col++) {
for (var row = 0; row < GRID_SIZE; row++) {
if (!grid[row][col].ball) {
var randomColor = getRandomBallColor();
grid[row][col].setBall(randomColor);
// Add magical appearance delay based on position
var delay = row * 50 + Math.random() * 100;
if (grid[row][col].ball) {
grid[row][col].ball.alpha = 0;
grid[row][col].ball.y -= 50;
LK.setTimeout(function (cell) {
return function () {
if (cell.ball) {
tween(cell.ball, {
alpha: 1,
y: cell.ball.y + 50
}, {
duration: 400,
easing: tween.bounceOut
});
}
};
}(grid[row][col]), delay);
}
}
}
}
}
// Spawn walls at 5 random positions
function spawnWalls() {
var availableCells = [];
for (var row = 0; row < GRID_SIZE; row++) {
for (var col = 0; col < GRID_SIZE; col++) {
if (grid[row][col].ball && !grid[row][col].isBomb && !grid[row][col].isWall) {
availableCells.push(grid[row][col]);
}
}
}
if (availableCells.length >= 5) {
for (var i = 0; i < 5; i++) {
var randomIndex = Math.floor(Math.random() * availableCells.length);
var selectedCell = availableCells[randomIndex];
selectedCell.setBall('wall');
totalWallsCreated++;
availableCells.splice(randomIndex, 1);
}
}
// Show win screen with custom text
function showWinScreen() {
// Create semi-transparent overlay
var overlay = LK.getAsset('grid_cell', {
anchorX: 0.5,
anchorY: 0.5
});
overlay.width = 2048;
overlay.height = 2732;
overlay.alpha = 0.8;
overlay.tint = 0x000000;
overlay.x = 1024;
overlay.y = 1366;
game.addChild(overlay);
// Create win text
var winText = new Text2('KAZANDIN!', {
size: 120,
fill: 0x00FF00
});
winText.anchor.set(0.5, 0.5);
winText.x = 1024;
winText.y = 1200;
game.addChild(winText);
// Create play again text
var playAgainText = new Text2('TEKRAR OYNA', {
size: 80,
fill: 0xFFFFFF
});
playAgainText.anchor.set(0.5, 0.5);
playAgainText.x = 1024;
playAgainText.y = 1350;
game.addChild(playAgainText);
// Create bottom message text
var bottomText = new Text2('Eğer oyunumu beğendiysen yeni oyunlar gelecek', {
size: 60,
fill: 0xFFFF00
});
bottomText.anchor.set(0.5, 0.5);
bottomText.x = 1024;
bottomText.y = 1500;
game.addChild(bottomText);
// Add click handler for play again
playAgainText.down = function () {
// Reset game state
totalWallsCreated = 0;
lastWallSpawnScore = 0;
LK.setScore(0);
scoreTxt.setText('Score: 0');
gameStarted = false;
// Show UI elements again
marketBtn.visible = true;
coinsTxt.visible = true;
pickaxeTxt.visible = true;
goldFrenzyTxt.visible = true;
// Clear grid
for (var row = 0; row < GRID_SIZE; row++) {
for (var col = 0; col < GRID_SIZE; col++) {
game.removeChild(grid[row][col]);
}
}
grid = [];
// Remove win screen elements
game.removeChild(overlay);
game.removeChild(winText);
game.removeChild(playAgainText);
game.removeChild(bottomText);
// Show start screen again
showStartScreen();
};
// Add glow animation to win text
tween(winText, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(winText, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 1000,
easing: tween.easeInOut
});
}
});
}
// Show code entry screen
var codeEntryElements = [];
var enteredCode = '';
function showCodeEntry() {
// Create semi-transparent overlay
var overlay = LK.getAsset('grid_cell', {
anchorX: 0.5,
anchorY: 0.5
});
overlay.width = 2048;
overlay.height = 2732;
overlay.alpha = 0.9;
overlay.tint = 0x000000;
overlay.x = 1024;
overlay.y = 1366;
game.addChild(overlay);
codeEntryElements.push(overlay);
// Create title text
var titleText = new Text2('KOD GIRIN', {
size: 80,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 800;
game.addChild(titleText);
codeEntryElements.push(titleText);
// Create code display
var codeDisplay = new Text2(enteredCode, {
size: 100,
fill: 0x00FF00
});
codeDisplay.anchor.set(0.5, 0.5);
codeDisplay.x = 1024;
codeDisplay.y = 1000;
game.addChild(codeDisplay);
codeEntryElements.push(codeDisplay);
// Create number buttons
var numbers = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'];
var buttonStartX = 600;
var buttonStartY = 1200;
var buttonSpacing = 150;
for (var i = 0; i < numbers.length; i++) {
var numButton = new Text2(numbers[i], {
size: 120,
fill: 0xFFFFFF
});
numButton.anchor.set(0.5, 0.5);
numButton.x = buttonStartX + i % 5 * buttonSpacing;
numButton.y = buttonStartY + Math.floor(i / 5) * 120;
numButton.number = numbers[i];
numButton.down = function () {
if (enteredCode.length < 8) {
enteredCode += this.number;
codeDisplay.setText(enteredCode);
}
};
game.addChild(numButton);
codeEntryElements.push(numButton);
}
// Create clear button
var clearButton = new Text2('TEMİZLE', {
size: 60,
fill: 0xFF0000
});
clearButton.anchor.set(0.5, 0.5);
clearButton.x = 1024;
clearButton.y = 1500;
clearButton.down = function () {
enteredCode = '';
codeDisplay.setText(enteredCode);
};
game.addChild(clearButton);
codeEntryElements.push(clearButton);
// Create submit button
var submitButton = new Text2('ONAYLA', {
size: 60,
fill: 0x00FF00
});
submitButton.anchor.set(0.5, 0.5);
submitButton.x = 1024;
submitButton.y = 1600;
submitButton.down = function () {
if (enteredCode === '11012012') {
if (codeUsed) {
// Show already used message
showCodeAlreadyUsed();
} else {
coins += 300;
codeUsed = true;
storage.coins = coins;
storage.codeUsed = codeUsed;
coinsTxt.setText('Coins: ' + coins);
// Show success message but don't close
showCodeSuccess();
}
} else {
// Show error message
showCodeError();
}
};
game.addChild(submitButton);
codeEntryElements.push(submitButton);
// Create close button
var closeButton = new Text2('KAPAT', {
size: 50,
fill: 0xFFFFFF
});
closeButton.anchor.set(0.5, 0.5);
closeButton.x = 1024;
closeButton.y = 1700;
closeButton.down = function () {
hideCodeEntry();
};
game.addChild(closeButton);
codeEntryElements.push(closeButton);
}
// Hide code entry screen
function hideCodeEntry() {
for (var i = 0; i < codeEntryElements.length; i++) {
game.removeChild(codeEntryElements[i]);
}
codeEntryElements = [];
enteredCode = '';
}
// Show success message
function showCodeSuccess() {
var successText = new Text2('300 ALTIN KAZANDINIZ!', {
size: 80,
fill: 0x00FF00
});
successText.anchor.set(0.5, 0.5);
successText.x = 1024;
successText.y = 1366;
game.addChild(successText);
// Remove success message after 2 seconds
LK.setTimeout(function () {
game.removeChild(successText);
}, 2000);
}
// Show error message
function showCodeError() {
var errorText = new Text2('YANLIŞ KOD!', {
size: 80,
fill: 0xFF0000
});
errorText.anchor.set(0.5, 0.5);
errorText.x = 1024;
errorText.y = 1366;
game.addChild(errorText);
// Remove error message after 2 seconds
LK.setTimeout(function () {
game.removeChild(errorText);
}, 2000);
}
// Show already used code message
function showCodeAlreadyUsed() {
var usedText = new Text2('BU KOD KULLANILDI', {
size: 60,
fill: 0xFF0000
});
usedText.anchor.set(0.5, 0.5);
usedText.x = 1024;
usedText.y = 1366;
game.addChild(usedText);
// Remove message after 2 seconds
LK.setTimeout(function () {
game.removeChild(usedText);
}, 2000);
}
// Help screen variables
var helpScreenElements = [];
var helpInfoElements = [];
// Show help screen with bomb types
function showHelpScreen() {
// Create semi-transparent overlay
var overlay = LK.getAsset('grid_cell', {
anchorX: 0.5,
anchorY: 0.5
});
overlay.width = 2048;
overlay.height = 2732;
overlay.alpha = 0.9;
overlay.tint = 0x000000;
overlay.x = 1024;
overlay.y = 1366;
game.addChild(overlay);
helpScreenElements.push(overlay);
// Create title text
var titleText = new Text2('BOMBA REHBERİ', {
size: 80,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 400;
game.addChild(titleText);
helpScreenElements.push(titleText);
// Create bomb images and labels
var bombTypes = [{
asset: 'bomb',
name: 'Normal Bomba'
}, {
asset: 'red_bomb',
name: 'Kırmızı Bomba'
}, {
asset: 'purple_bomb',
name: 'Mor Bomba'
}, {
asset: 'yellow_bomb',
name: 'Sarı Bomba'
}];
var startY = 600;
var spacing = 200;
for (var i = 0; i < bombTypes.length; i++) {
var bombImg = LK.getAsset(bombTypes[i].asset, {
anchorX: 0.5,
anchorY: 0.5
});
bombImg.x = 1024;
bombImg.y = startY + i * spacing;
bombImg.scaleX = 0.8;
bombImg.scaleY = 0.8;
bombImg.bombType = bombTypes[i].asset;
bombImg.down = function () {
showBombInfo(this.bombType);
};
game.addChild(bombImg);
helpScreenElements.push(bombImg);
var bombLabel = new Text2(bombTypes[i].name, {
size: 60,
fill: 0xFFFFFF
});
bombLabel.anchor.set(0.5, 0.5);
bombLabel.x = 1024;
bombLabel.y = startY + i * spacing + 80;
bombLabel.bombType = bombTypes[i].asset;
bombLabel.down = function () {
showBombInfo(this.bombType);
};
game.addChild(bombLabel);
helpScreenElements.push(bombLabel);
}
// Create close button
var closeBtn = new Text2('KAPAT', {
size: 60,
fill: 0xFF0000
});
closeBtn.anchor.set(0.5, 0.5);
closeBtn.x = 1024;
closeBtn.y = 2400;
closeBtn.down = function () {
hideHelpScreen();
};
game.addChild(closeBtn);
helpScreenElements.push(closeBtn);
}
// Hide help screen
function hideHelpScreen() {
for (var i = 0; i < helpScreenElements.length; i++) {
game.removeChild(helpScreenElements[i]);
}
helpScreenElements = [];
hideHelpInfo();
}
// Show detailed bomb information
function showBombInfo(bombType) {
// Clear previous info
hideHelpInfo();
var infoText = '';
var spawnChance = '';
if (bombType === 'bomb') {
infoText = 'Normal Bomba\n\n3x3 alanda patlar\n5 top eşleşirse oluşur\nHer 10 saniyede rastgele oluşur';
spawnChance = 'Oluşma: 5 top eşleşmesi\nveya 10 saniye aralıklarla';
} else if (bombType === 'red_bomb') {
infoText = 'Kırmızı Bomba\n\n7x7 alanda patlar\n5 top eşleşirse oluşur\nDaha güçlü patlama';
spawnChance = 'Oluşma: 5 top eşleşmesi';
} else if (bombType === 'purple_bomb') {
infoText = 'Mor Bomba\n\n5x5 alanda patlar\n5 normal bomba oluşturur\nDuvarları da yok eder';
spawnChance = 'Oluşma: Özel durumlar';
} else if (bombType === 'yellow_bomb') {
infoText = 'Sarı Bomba\n\nTÜM topları yok eder\n10000 puan verir\nYeşil iz bırakır';
spawnChance = 'Oluşma: %0.1 şans';
}
// Create info background
var infoBg = LK.getAsset('grid_cell', {
anchorX: 0.5,
anchorY: 0.5
});
infoBg.width = 1600;
infoBg.height = 800;
infoBg.alpha = 0.8;
infoBg.tint = 0x333333;
infoBg.x = 1024;
infoBg.y = 1600;
game.addChild(infoBg);
helpInfoElements.push(infoBg);
// Create info text
var infoDisplay = new Text2(infoText, {
size: 50,
fill: 0xFFFFFF
});
infoDisplay.anchor.set(0.5, 0.5);
infoDisplay.x = 1024;
infoDisplay.y = 1500;
game.addChild(infoDisplay);
helpInfoElements.push(infoDisplay);
// Create spawn chance text
var chanceDisplay = new Text2(spawnChance, {
size: 45,
fill: 0xFFFF00
});
chanceDisplay.anchor.set(0.5, 0.5);
chanceDisplay.x = 1024;
chanceDisplay.y = 1700;
game.addChild(chanceDisplay);
helpInfoElements.push(chanceDisplay);
}
// Hide bomb info
function hideHelpInfo() {
for (var i = 0; i < helpInfoElements.length; i++) {
game.removeChild(helpInfoElements[i]);
}
helpInfoElements = [];
}
// Spawn a random bomb on the grid
function spawnBomb() {
var emptyCells = [];
for (var row = 0; row < GRID_SIZE; row++) {
for (var col = 0; col < GRID_SIZE; col++) {
if (grid[row][col].ball && !grid[row][col].isBomb) {
emptyCells.push(grid[row][col]);
}
}
}
if (emptyCells.length > 0) {
var randomCell = emptyCells[Math.floor(Math.random() * emptyCells.length)];
// 0.1% chance for yellow bomb, 1% chance for purple bomb, 98.9% chance for regular bomb
var rand = Math.random();
var bombType;
if (rand < 0.001) {
bombType = 'yellow_bomb';
} else if (rand < 0.011) {
bombType = 'purple_bomb';
} else {
bombType = 'bomb';
}
randomCell.setBall(bombType);
}
}
// Clear previous selection visual feedback
function clearSelectionTint() {
if (selectedCell && selectedCell.ball) {
selectedCell.ball.tint = 0xffffff;
}
}
// Handle pickaxe use on walls
game.down = function (x, y, obj) {
if (!gameStarted || isAnimating || !grid || grid.length === 0) return;
// Find clicked cell for pickaxe use only
for (var row = 0; row < GRID_SIZE; row++) {
if (!grid[row]) continue; // Skip if row doesn't exist
for (var col = 0; col < GRID_SIZE; col++) {
if (!grid[row][col]) continue; // Skip if cell doesn't exist
var cell = grid[row][col];
var cellPos = game.toLocal(cell.parent.toGlobal(cell.position));
var distance = Math.sqrt(Math.pow(x - cellPos.x, 2) + Math.pow(y - cellPos.y, 2));
if (distance < CELL_SIZE / 2 && cell.ball) {
// Handle pickaxe use on walls
if (cell.isWall && pickaxeUses > 0) {
pickaxeUses--;
pickaxeTxt.setText('Kazma: ' + pickaxeUses);
// Create wall destruction effect
cell.createSparkles();
if (cell.ball) {
tween(cell.ball, {
scaleX: 0,
scaleY: 0,
alpha: 0
}, {
duration: 300,
easing: tween.easeIn
});
}
LK.setTimeout(function () {
cell.setBall(null);
}, 300);
return;
}
break;
}
}
}
};
// Check if balls are stuck around walls and create bombs
function checkForStuckBalls() {
if (!grid || grid.length === 0) return;
var stuckAreas = [];
// Find all wall positions
for (var row = 0; row < GRID_SIZE; row++) {
if (!grid[row]) continue;
for (var col = 0; col < GRID_SIZE; col++) {
if (!grid[row][col]) continue;
if (grid[row][col].isWall) {
// Check 3x3 area around this wall for stuck balls
var surroundingBalls = [];
var hasEmptySpace = false;
for (var dr = -1; dr <= 1; dr++) {
for (var dc = -1; dc <= 1; dc++) {
var checkRow = row + dr;
var checkCol = col + dc;
if (checkRow >= 0 && checkRow < GRID_SIZE && checkCol >= 0 && checkCol < GRID_SIZE && grid[checkRow] && grid[checkRow][checkCol]) {
var checkCell = grid[checkRow][checkCol];
if (checkCell.ball && !checkCell.isWall && !checkCell.isBomb) {
surroundingBalls.push(checkCell);
} else if (!checkCell.ball) {
hasEmptySpace = true;
}
}
}
}
// If there are 6 or more balls around wall with no empty spaces
// and no possible matches, consider them stuck
if (surroundingBalls.length >= 6 && !hasEmptySpace) {
var hasValidMove = false;
// Check if any surrounding ball can make a match
for (var i = 0; i < surroundingBalls.length; i++) {
var ball = surroundingBalls[i];
// Check if this ball has matching neighbors
var neighbors = [{
r: ball.row - 1,
c: ball.col
}, {
r: ball.row + 1,
c: ball.col
}, {
r: ball.row,
c: ball.col - 1
}, {
r: ball.row,
c: ball.col + 1
}];
for (var j = 0; j < neighbors.length; j++) {
var nr = neighbors[j].r;
var nc = neighbors[j].c;
if (nr >= 0 && nr < GRID_SIZE && nc >= 0 && nc < GRID_SIZE && grid[nr] && grid[nr][nc]) {
var neighborCell = grid[nr][nc];
if (neighborCell.ball && !neighborCell.isWall && neighborCell.ballType === ball.ballType) {
hasValidMove = true;
break;
}
}
}
if (hasValidMove) break;
}
if (!hasValidMove) {
// Find best position for bomb (center of stuck area)
var centerRow = Math.round(row);
var centerCol = Math.round(col);
// Find nearest non-wall cell to place bomb
for (var radius = 1; radius <= 3; radius++) {
for (var dr = -radius; dr <= radius; dr++) {
for (var dc = -radius; dc <= radius; dc++) {
var bombRow = centerRow + dr;
var bombCol = centerCol + dc;
if (bombRow >= 0 && bombRow < GRID_SIZE && bombCol >= 0 && bombCol < GRID_SIZE && grid[bombRow] && grid[bombRow][bombCol]) {
var bombCell = grid[bombRow][bombCol];
if (bombCell.ball && !bombCell.isWall && !bombCell.isBomb) {
stuckAreas.push({
row: bombRow,
col: bombCol
});
radius = 4; // Break outer loops
break;
}
}
}
if (radius > 3) break;
}
if (radius > 3) break;
}
}
}
}
}
}
// Create bombs in stuck areas
for (var k = 0; k < stuckAreas.length; k++) {
var bombPos = stuckAreas[k];
if (grid[bombPos.row] && grid[bombPos.row][bombPos.col]) {
grid[bombPos.row][bombPos.col].setBall('bomb');
// Add visual effect to indicate bomb was created due to stuck situation
var bombCell = grid[bombPos.row][bombPos.col];
if (bombCell.ball) {
bombCell.ball.tint = 0xff6666; // Reddish tint
LK.setTimeout(function (cell) {
return function () {
if (cell.ball) {
cell.ball.tint = 0xffffff;
}
};
}(bombCell), 1000);
}
}
}
}
}
// Process matches and cascades
function processMatches() {
var matchResult = checkMatches();
var matchedCells = matchResult.matchedCells;
var fiveBallMatches = matchResult.fiveBallMatches;
if (matchedCells.length > 0) {
removeMatches(matchedCells, fiveBallMatches);
LK.setTimeout(function () {
dropBalls();
fillEmptySpaces();
LK.setTimeout(function () {
processMatches(); // Check for cascade matches
}, 200);
}, 300);
} else {
isAnimating = false;
}
}
// Show start screen instead of initializing game immediately
showStartScreen();
// Main game loop
game.update = function () {
if (!gameStarted) return;
bombSpawnCounter++;
// Spawn bomb every 600 ticks (10 seconds at 60fps)
if (bombSpawnCounter >= 600) {
spawnBomb();
bombSpawnCounter = 0;
}
// Check for stuck balls every 300 ticks (5 seconds)
if (bombSpawnCounter % 300 === 0) {
checkForStuckBalls();
}
// Check if green trail should be removed (1000 points after yellow bomb explosion)
if (yellowBombTrail && LK.getScore() >= yellowBombExplosionScore + 1000) {
// Fade out the trail
tween(yellowBombTrail, {
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 500,
easing: tween.easeIn,
onFinish: function onFinish() {
if (yellowBombTrail) {
game.removeChild(yellowBombTrail);
yellowBombTrail = null;
}
}
});
}
// Check win condition at 15000 points
if (LK.getScore() >= 15000) {
var winCoins = 20 * goldMultiplier;
coins += winCoins;
storage.coins = coins;
coinsTxt.setText('Coins: ' + coins);
LK.showYouWin();
}
};