User prompt
yeni gelen şekerler buglanıyor bunu düzelt en başta spawnlanan şekerler gibi değil çok buglu ve tahtayı doldururken diğer şekerlerin içine geçiyorlar bunu engelle eğer iç içe geçen şeker olmasını engelle ama eğerki gene olursa bir tane şekeri yok et ve gene boşluklar oluşuyor eğer boşluk oluşmasını engelleyemiyorsan boşluk oluşunca otomatik olarak oraya şeker spawnla
User prompt
oyun çok buglu sana tüm hatları söyleyeceğim hepsini düzelt 1. Oyunda boş yerler kalıyor yani o boş yere şekerleri hareket ettirebiliyorsun bunu engelle yani boş alan olmayak tüm yerlere şeker gelecek şekilde ayarla 2. Şekerler iç içe geçebiliyor bunuda engelle 3. Rastgele bir şekeri patlatınca diğer şekerler patlıyor bu çok büyük bir sorun çünkü adam rastgele tıklayarak score kazanabiliyor
User prompt
gene rastgele iki şekerin yerini değiştiriyorum diğer şekerler patlıyor bunu engelle artık sadece ilk hamlede bu çalışıyor diğer hamlelerde bu çalışmıyor
User prompt
yapamıyorusn sana çok basit bir kural söyleyecem sadece bunu uygulayacaksın eğer yan yana aynı renkte şekerler gelirse sadece onlar patlayacak diğerleri değil ve eğer yan yana farklı şekerler gelirse buna izin vermeyeceksin ve Movesden yiyecek bu
User prompt
tamam en başta işe yarıyor fakat oyun devam ettikçe gene rastgele şeker yer değiştirsem bile bazı şekerler patlıyor bunuda komple engelle ve level yazısını boardın altına koy
User prompt
rastgele işe yaramayan şekeri hareket ettirsem bile rastgele şekerler patlıyor bunu engelle Sadece uyumlu şekerler yan yana gelirse patlasın
User prompt
oyunu bozdun eski haline getir gene şekerler rastgele patlıyor ve combo yapıldığında sağ tarafda combo x1 gibi yazılar çıkart ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
bazı şekerler birbirinin içerisine giriyor veya orada spawnlanıyor bunuda düzelt
User prompt
boardda yani şekerleri geldiği yerlerde boşluklar oluşuyor onları engelle sadece şekerler olacak ve rastgele işe yaramayan şekeri hareket ettirsem bile rastgele şekerler patlıyor bunu engelle Sadece uyumlu şekerler yan yana gelirse patlasın
User prompt
bazı şekerler birbirinin içerisinde girebiliyor bunu düzelt ve her şeker patladığında ekrana efekt çıkart
User prompt
There are some things that need to be fixed. Newly added candies leave gaps between them — those gaps should be filled so the board is seamless. Also, add a combo system: when matches happen consecutively, it should count as a combo. Each combo should trigger visual effects on the screen. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'toGlobal')' in or related to this line: 'var local = game.toLocal(obj.parent.toGlobal(obj.position));' Line Number: 482
Code edit (1 edits merged)
Please save this source code
User prompt
Candy Cascade Saga
Initial prompt
Create a full mobile puzzle game similar to Candy Crush Saga. The game should be a colorful and addictive match-3 puzzle game where players swap adjacent items on a grid to match 3 or more of the same type. The grid should be made up of colorful candies or gems with distinct shapes and colors. Game Mechanics: Players can swipe adjacent pieces to make horizontal or vertical matches of 3 or more. Matching 4 creates a special piece that clears a row or column. Matching 5 in a row creates a "color bomb" that clears all pieces of that color. L-shaped or T-shaped matches create an "explosive candy" that clears a 3x3 area. Cascading matches (combos) happen automatically when new pieces fall down. Each level has limited moves and specific objectives like "clear all jelly", "collect ingredients", or "reach a score target". Progression: The game should have a level map system (like a world map) where players unlock new stages as they win. Difficulty increases gradually with new obstacles such as chocolate blocks, licorice, locked tiles, and timed bombs. Include boosters such as lollipop hammer, extra moves, color switch, and others. Graphics and Style: Use a bright and cheerful cartoon style. Candies should look glossy and colorful. Smooth animations for swaps, matches, and explosions. Satisfying sound effects for matching and completing levels. UI / UX: Simple and intuitive drag-and-swap controls. A clear level objective screen before each level starts. In-game pause menu with options to retry or quit. Progress bar and move counter in-game. Other Features: Daily rewards system (coins, boosters, lives). A heart/life system: players lose a life on failure, regenerate over time. Option to connect with friends to send/receive lives. Include animations and particle effects for major combos or wins. Please make sure the gameplay is addictive, satisfying, and polished. Prioritize smooth feedback loops and game feel.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { level: 1 }); /**** * Classes ****/ // Candy class var Candy = Container.expand(function () { var self = Container.call(this); // Properties self.type = null; // 0-5 for normal, 'stripedH', 'stripedV', 'bomb' self.row = 0; self.col = 0; self.special = null; // null, 'stripedH', 'stripedV', 'bomb' self.selected = false; // Attach asset self.setType = function (type, special) { // Remove previous asset if any if (self.candyAsset) { self.removeChild(self.candyAsset); } self.type = type; self.special = special || null; var assetId; if (special === 'stripedH') assetId = 'candyStripedH';else if (special === 'stripedV') assetId = 'candyStripedV';else if (special === 'bomb') assetId = 'candyBomb';else { assetId = ['candyRed', 'candyGreen', 'candyBlue', 'candyYellow', 'candyPurple', 'candyOrange'][type]; } self.candyAsset = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); // Tint for special candies if (special === 'stripedH') self.candyAsset.tint = 0xccccff; if (special === 'stripedV') self.candyAsset.tint = 0xffcccc; if (special === 'bomb') self.candyAsset.tint = 0x222222; }; // Highlight self.setSelected = function (sel) { self.selected = sel; if (self.candyAsset) { self.candyAsset.alpha = sel ? 0.7 : 1; if (sel) { tween(self.candyAsset, { scaleX: 1.15, scaleY: 1.15 }, { duration: 120, easing: tween.easeOut }); } else { tween(self.candyAsset, { scaleX: 1, scaleY: 1 }, { duration: 120, easing: tween.easeOut }); } } }; // Animate removal self.animateRemove = function (cb) { if (self.candyAsset) { tween(self.candyAsset, { scaleX: 0, scaleY: 0, alpha: 0 }, { duration: 180, easing: tween.cubicIn, onFinish: cb }); } else if (cb) cb(); }; // Animate drop self.animateDrop = function (targetY, cb) { tween(self, { y: targetY }, { duration: 180, easing: tween.cubicOut, onFinish: cb }); }; // Animate swap self.animateSwap = function (targetX, targetY, cb) { tween(self, { x: targetX, y: targetY }, { duration: 120, easing: tween.cubicInOut, onFinish: cb }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x181830 }); /**** * Game Code ****/ // Music // Sound effects // Board background // Special candies // Candies: 6 types, each a colored ellipse // Board config var BOARD_SIZE = 9; var CELL_SIZE = 180; var BOARD_OFFSET_X = (2048 - BOARD_SIZE * CELL_SIZE) / 2; var BOARD_OFFSET_Y = 350; var CANDY_TYPES = 6; // Game state var board = []; // 2D array [row][col] of Candy var selectedCandy = null; var isSwapping = false; var isAnimating = false; var movesLeft = 20; var score = 0; var level = storage.level || 1; var targetScore = 2000 + (level - 1) * 500; // UI var scoreTxt = new Text2('Score: 0', { size: 90, fill: '#fff' }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); var movesTxt = new Text2('Moves: 20', { size: 70, fill: '#fff' }); movesTxt.anchor.set(0.5, 0); LK.gui.top.addChild(movesTxt); movesTxt.y = 110; var levelTxt = new Text2('Level 1', { size: 60, fill: '#fff' }); levelTxt.anchor.set(0.5, 0); // Place level text below the board levelTxt.x = 2048 / 2; levelTxt.y = BOARD_OFFSET_Y + BOARD_SIZE * CELL_SIZE + 40; game.addChild(levelTxt); // Board background var boardBg = LK.getAsset('boardBg', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: BOARD_OFFSET_Y + BOARD_SIZE * CELL_SIZE / 2 }); game.addChild(boardBg); // Helper: get board position function getCandyPos(row, col) { return { x: BOARD_OFFSET_X + col * CELL_SIZE + CELL_SIZE / 2, y: BOARD_OFFSET_Y + row * CELL_SIZE + CELL_SIZE / 2 }; } // Helper: random candy type function randomCandyType() { return Math.floor(Math.random() * CANDY_TYPES); } // Helper: check if two candies are adjacent function areAdjacent(c1, c2) { return Math.abs(c1.row - c2.row) + Math.abs(c1.col - c2.col) === 1; } // Helper: swap candies in board array function swapCandies(c1, c2) { var temp = board[c1.row][c1.col]; board[c1.row][c1.col] = board[c2.row][c2.col]; board[c2.row][c2.col] = temp; // Update row/col var trow = c1.row, tcol = c1.col; c1.row = c2.row; c1.col = c2.col; c2.row = trow; c2.col = tcol; } // Helper: find all matches (returns array of arrays of candies) function findMatches() { var matches = []; // Horizontal for (var r = 0; r < BOARD_SIZE; r++) { var run = [board[r][0]]; for (var c = 1; c < BOARD_SIZE; c++) { var prev = board[r][c - 1], curr = board[r][c]; // Only match if both are normal candies and same type if (curr && prev && typeof curr.type === "number" && typeof prev.type === "number" && curr.type === prev.type) { run.push(curr); } else { if (run.length >= 3) matches.push(run.slice()); run = [curr]; } } if (run.length >= 3) matches.push(run.slice()); } // Vertical for (var c = 0; c < BOARD_SIZE; c++) { var run = [board[0][c]]; for (var r = 1; r < BOARD_SIZE; r++) { var prev = board[r - 1][c], curr = board[r][c]; // Only match if both are normal candies and same type if (curr && prev && typeof curr.type === "number" && typeof prev.type === "number" && curr.type === prev.type) { run.push(curr); } else { if (run.length >= 3) matches.push(run.slice()); run = [curr]; } } if (run.length >= 3) matches.push(run.slice()); } return matches; } // Helper: check if board has any possible moves function hasPossibleMoves() { // Try swapping every adjacent pair, see if it creates a match for (var r = 0; r < BOARD_SIZE; r++) { for (var c = 0; c < BOARD_SIZE; c++) { var curr = board[r][c]; // Right if (c < BOARD_SIZE - 1) { swapCandies(curr, board[r][c + 1]); if (findMatches().length > 0) { swapCandies(curr, board[r][c + 1]); return true; } swapCandies(curr, board[r][c + 1]); } // Down if (r < BOARD_SIZE - 1) { swapCandies(curr, board[r + 1][c]); if (findMatches().length > 0) { swapCandies(curr, board[r + 1][c]); return true; } swapCandies(curr, board[r + 1][c]); } } } return false; } // Helper: refill board (drop candies, fill new) function refillBoard(cb) { var dropping = 0; for (var c = 0; c < BOARD_SIZE; c++) { // Collect all candies in this column, compacting them to the bottom var colCandies = []; for (var r = BOARD_SIZE - 1; r >= 0; r--) { if (board[r][c]) { colCandies.push(board[r][c]); board[r][c] = null; } } // Place candies at the bottom, filling from bottom up var r = BOARD_SIZE - 1; for (var i = 0; i < colCandies.length; i++, r--) { var candy = colCandies[i]; board[r][c] = candy; var oldRow = candy.row; candy.row = r; candy.col = c; var pos = getCandyPos(candy.row, candy.col); if (oldRow !== candy.row) { dropping++; candy.animateDrop(pos.y, function () { dropping--; if (dropping === 0 && cb) cb(); }); } else { // No animation needed if not moved candy.y = pos.y; } } // Fill new candies at the top for (; r >= 0; r--) { // Defensive: Only place a new candy if the cell is empty (should always be, but double check) if (!board[r][c]) { var newCandy = new Candy(); var type = randomCandyType(); newCandy.setType(type); newCandy.row = r; newCandy.col = c; var pos = getCandyPos(r, c); newCandy.x = pos.x; // Place new candy well above the board, so it drops down and never overlaps newCandy.y = pos.y - CELL_SIZE * (BOARD_SIZE + 2); // Always above the board, so no overlap board[r][c] = newCandy; game.addChild(newCandy); dropping++; newCandy.animateDrop(pos.y, function () { dropping--; if (dropping === 0 && cb) cb(); }); } } // Defensive: After refill, ensure no empty spaces remain in this column and no overlaps for (var rr = 0; rr < BOARD_SIZE; rr++) { // Remove any extra candies in this cell (should never happen, but just in case) if (Array.isArray(board[rr][c])) { // If for some reason multiple candies are in the same cell, keep only the last one while (board[rr][c].length > 1) { var extra = board[rr][c].shift(); if (extra && extra.destroy) extra.destroy(); } board[rr][c] = board[rr][c][0]; } // Check for overlapping candies (should never happen, but just in case) for (var checkR = 0; checkR < BOARD_SIZE; checkR++) { if (checkR !== rr && board[rr][c] && board[checkR][c] && board[rr][c] === board[checkR][c]) { // Overlap detected, destroy one of them if (board[rr][c].destroy) board[rr][c].destroy(); board[rr][c] = null; } } if (!board[rr][c]) { // If any empty, fill with a new candy var fillCandy = new Candy(); var fillType = randomCandyType(); fillCandy.setType(fillType); fillCandy.row = rr; fillCandy.col = c; var fillPos = getCandyPos(rr, c); fillCandy.x = fillPos.x; fillCandy.y = fillPos.y - CELL_SIZE * (BOARD_SIZE + 2); board[rr][c] = fillCandy; game.addChild(fillCandy); dropping++; fillCandy.animateDrop(fillPos.y, function () { dropping--; if (dropping === 0 && cb) cb(); }); } } } if (dropping === 0 && cb) cb(); } // Helper: remove matched candies function removeMatches(matches, cb) { var removing = 0; for (var i = 0; i < matches.length; i++) { var group = matches[i]; for (var j = 0; j < group.length; j++) { var candy = group[j]; if (board[candy.row][candy.col]) { board[candy.row][candy.col] = null; removing++; // Visual effect for popping var popEffect = new Text2('💥', { size: 110, fill: '#fff' }); popEffect.anchor.set(0.5, 0.5); var pos = getCandyPos(candy.row, candy.col); popEffect.x = pos.x; popEffect.y = pos.y; popEffect.alpha = 1; game.addChild(popEffect); tween(popEffect, { scaleX: 1.7, scaleY: 1.7, alpha: 0 }, { duration: 350, easing: tween.cubicOut, onFinish: function onFinish() { popEffect.destroy(); } }); candy.animateRemove(function () { candy.destroy(); removing--; if (removing === 0 && cb) cb(); }); } } } if (removing === 0 && cb) cb(); } // Helper: clear selection function clearSelection() { if (selectedCandy) { selectedCandy.setSelected(false); selectedCandy = null; } } // Helper: update UI function updateUI() { scoreTxt.setText('Score: ' + score); movesTxt.setText('Moves: ' + movesLeft); levelTxt.setText('Level ' + level); } // Helper: check win/lose function checkEnd() { if (score >= targetScore) { LK.getSound('win').play(); storage.level = level + 1; LK.showYouWin(); return true; } if (movesLeft <= 0) { LK.getSound('fail').play(); LK.showGameOver(); return true; } return false; } // Helper: shuffle board function shuffleBoard() { // Remove all candies for (var r = 0; r < BOARD_SIZE; r++) { for (var c = 0; c < BOARD_SIZE; c++) { if (board[r][c]) { board[r][c].destroy(); board[r][c] = null; } } } // Refill for (var r = 0; r < BOARD_SIZE; r++) { for (var c = 0; c < BOARD_SIZE; c++) { // Defensive: Only place a new candy if the cell is empty (should always be, but double check) if (!board[r][c]) { var candy = new Candy(); var type = randomCandyType(); candy.setType(type); candy.row = r; candy.col = c; var pos = getCandyPos(r, c); candy.x = pos.x; candy.y = pos.y; board[r][c] = candy; game.addChild(candy); } } } } // Initialize board function initBoard() { // Remove old candies for (var r = 0; r < BOARD_SIZE; r++) { for (var c = 0; c < BOARD_SIZE; c++) { if (board[r] && board[r][c]) { board[r][c].destroy(); } } } board = []; for (var r = 0; r < BOARD_SIZE; r++) { board[r] = []; for (var c = 0; c < BOARD_SIZE; c++) { // Defensive: Only place a new candy if the cell is empty (should always be, but double check) if (!board[r][c]) { var candy = new Candy(); var type = randomCandyType(); candy.setType(type); candy.row = r; candy.col = c; var pos = getCandyPos(r, c); candy.x = pos.x; candy.y = pos.y; board[r][c] = candy; game.addChild(candy); } } } // Defensive: After init, ensure no empty spaces or overlaps for (var r = 0; r < BOARD_SIZE; r++) { for (var c = 0; c < BOARD_SIZE; c++) { // Remove any extra candies in this cell (should never happen, but just in case) if (Array.isArray(board[r][c])) { while (board[r][c].length > 1) { var extra = board[r][c].shift(); if (extra && extra.destroy) extra.destroy(); } board[r][c] = board[r][c][0]; } // Check for overlapping candies (should never happen, but just in case) for (var checkR = 0; checkR < BOARD_SIZE; checkR++) { for (var checkC = 0; checkC < BOARD_SIZE; checkC++) { if ((checkR !== r || checkC !== c) && board[r][c] && board[checkR][checkC] && board[r][c] === board[checkR][checkC]) { // Overlap detected, destroy one of them if (board[r][c].destroy) board[r][c].destroy(); board[r][c] = null; } } } if (!board[r][c]) { // If any empty, fill with a new candy var fillCandy = new Candy(); var fillType = randomCandyType(); fillCandy.setType(fillType); fillCandy.row = r; fillCandy.col = c; var fillPos = getCandyPos(r, c); fillCandy.x = fillPos.x; fillCandy.y = fillPos.y; board[r][c] = fillCandy; game.addChild(fillCandy); } } } // Remove initial matches var initialMatches = findMatches(); while (initialMatches.length > 0) { removeMatches(initialMatches, function () {}); refillBoard(function () {}); initialMatches = findMatches(); } } // Start new level/game function startGame() { level = storage.level || 1; targetScore = 2000 + (level - 1) * 500; movesLeft = 20 + Math.floor(level / 2); score = 0; updateUI(); clearSelection(); initBoard(); LK.playMusic('bgmusic', { loop: true, fade: { start: 0, end: 0.7, duration: 800 } }); } // Handle candy selection/swapping function handleCandyDown(x, y, obj) { if (isAnimating || isSwapping) return; // Find which candy was pressed // Defensive: Use event coordinates directly, as obj.parent or obj.position may be undefined var row = Math.floor((y - BOARD_OFFSET_Y) / CELL_SIZE); var col = Math.floor((x - BOARD_OFFSET_X) / CELL_SIZE); if (row < 0 || row >= BOARD_SIZE || col < 0 || col >= BOARD_SIZE) return; var candy = board[row][col]; if (!candy) return; if (!selectedCandy) { selectedCandy = candy; candy.setSelected(true); } else if (candy === selectedCandy) { clearSelection(); } else if (areAdjacent(selectedCandy, candy)) { // Swap isSwapping = true; selectedCandy.setSelected(false); var c1 = selectedCandy, c2 = candy; var pos1 = getCandyPos(c1.row, c1.col); var pos2 = getCandyPos(c2.row, c2.col); c1.animateSwap(pos2.x, pos2.y, function () {}); c2.animateSwap(pos1.x, pos1.y, function () { swapCandies(c1, c2); LK.getSound('swap').play(); // Check for matches var matches = findMatches(); if (matches.length > 0) { movesLeft--; updateUI(); processMatches(matches); } else { // No matches, swap back and decrement moves movesLeft--; updateUI(); c1.animateSwap(pos1.x, pos1.y, function () {}); c2.animateSwap(pos2.x, pos2.y, function () { swapCandies(c1, c2); isSwapping = false; }); } clearSelection(); }); } else { selectedCandy.setSelected(false); selectedCandy = candy; candy.setSelected(true); } } // Process matches and cascades // Combo system variables (global scope) if (typeof comboCount === "undefined") { var comboCount = 0; var comboTimer = null; } // Visual effect for combo (global helper) function showComboEffect(comboNum) { if (comboNum <= 1) return; var comboText = new Text2('Combo x' + comboNum, { size: 110, fill: '#fffa00', font: "'GillSans-Bold',Impact,'Arial Black',Tahoma" }); comboText.anchor.set(1, 0); // right-top comboText.x = 2048 - 80; comboText.y = 350; comboText.alpha = 1; LK.gui.topRight.addChild(comboText); tween(comboText, { y: comboText.y - 80, alpha: 0 }, { duration: 700, easing: tween.cubicOut, onFinish: function onFinish() { comboText.destroy(); } }); } function processMatches(matches) { isAnimating = true; LK.getSound('match').play(); // Combo logic if (typeof comboCount === "undefined") comboCount = 0; comboCount++; showComboEffect(comboCount); // Score var points = 0; for (var i = 0; i < matches.length; i++) { points += matches[i].length * 60 * comboCount; } score += points; updateUI(); // Remove matches, refill, and check for cascades removeMatches(matches, function () { refillBoard(function () { // Only allow further matches if they are valid (no random pops) var newMatches = findMatches(); // Only process if the new matches are valid (length >= 3) var validMatches = []; for (var i = 0; i < newMatches.length; i++) { if (newMatches[i].length >= 3) validMatches.push(newMatches[i]); } // Defensive: Only process matches if they are a result of a cascade (not random) if (validMatches.length > 0) { LK.getSound('cascade').play(); // Reset combo timer if running if (comboTimer) LK.clearTimeout(comboTimer); processMatches(validMatches); } else { // Combo chain ends, reset after a short delay if (comboTimer) LK.clearTimeout(comboTimer); comboTimer = LK.setTimeout(function () { comboCount = 0; }, 900); isAnimating = false; isSwapping = false; if (!hasPossibleMoves()) { shuffleBoard(); } checkEnd(); } }); }); } // Touch/mouse events game.down = function (x, y, obj) { if (isAnimating || isSwapping) return; // Only allow selection inside board area if (x < BOARD_OFFSET_X || x > BOARD_OFFSET_X + BOARD_SIZE * CELL_SIZE || y < BOARD_OFFSET_Y || y > BOARD_OFFSET_Y + BOARD_SIZE * CELL_SIZE) return; handleCandyDown(x, y, obj); }; game.move = function (x, y, obj) { // No drag/swipe for MVP }; game.up = function (x, y, obj) { // No drag/swipe for MVP }; // Main update loop (not used for logic in MVP) game.update = function () { // No per-frame logic needed for MVP }; // Start game startGame();
===================================================================
--- original.js
+++ change.js
@@ -319,8 +319,16 @@
if (extra && extra.destroy) extra.destroy();
}
board[rr][c] = board[rr][c][0];
}
+ // Check for overlapping candies (should never happen, but just in case)
+ for (var checkR = 0; checkR < BOARD_SIZE; checkR++) {
+ if (checkR !== rr && board[rr][c] && board[checkR][c] && board[rr][c] === board[checkR][c]) {
+ // Overlap detected, destroy one of them
+ if (board[rr][c].destroy) board[rr][c].destroy();
+ board[rr][c] = null;
+ }
+ }
if (!board[rr][c]) {
// If any empty, fill with a new candy
var fillCandy = new Candy();
var fillType = randomCandyType();
@@ -470,8 +478,44 @@
game.addChild(candy);
}
}
}
+ // Defensive: After init, ensure no empty spaces or overlaps
+ for (var r = 0; r < BOARD_SIZE; r++) {
+ for (var c = 0; c < BOARD_SIZE; c++) {
+ // Remove any extra candies in this cell (should never happen, but just in case)
+ if (Array.isArray(board[r][c])) {
+ while (board[r][c].length > 1) {
+ var extra = board[r][c].shift();
+ if (extra && extra.destroy) extra.destroy();
+ }
+ board[r][c] = board[r][c][0];
+ }
+ // Check for overlapping candies (should never happen, but just in case)
+ for (var checkR = 0; checkR < BOARD_SIZE; checkR++) {
+ for (var checkC = 0; checkC < BOARD_SIZE; checkC++) {
+ if ((checkR !== r || checkC !== c) && board[r][c] && board[checkR][checkC] && board[r][c] === board[checkR][checkC]) {
+ // Overlap detected, destroy one of them
+ if (board[r][c].destroy) board[r][c].destroy();
+ board[r][c] = null;
+ }
+ }
+ }
+ if (!board[r][c]) {
+ // If any empty, fill with a new candy
+ var fillCandy = new Candy();
+ var fillType = randomCandyType();
+ fillCandy.setType(fillType);
+ fillCandy.row = r;
+ fillCandy.col = c;
+ var fillPos = getCandyPos(r, c);
+ fillCandy.x = fillPos.x;
+ fillCandy.y = fillPos.y;
+ board[r][c] = fillCandy;
+ game.addChild(fillCandy);
+ }
+ }
+ }
// Remove initial matches
var initialMatches = findMatches();
while (initialMatches.length > 0) {
removeMatches(initialMatches, function () {});
blue candy. In-Game asset. 2d. High contrast. No shadows
black candy bomb. In-Game asset. 2d. High contrast. No shadows
candy green. In-Game asset. 2d. High contrast. No shadows
candy orange. In-Game asset. 2d. High contrast. No shadows
candy purple. In-Game asset. 2d. High contrast. No shadows
candy red. In-Game asset. 2d. High contrast. No shadows
yellow candy. In-Game asset. 2d. High contrast. No shadows