User prompt
Donan kristal patlayabilir şartlar sağlanıyorsa. Mesela joker kristalini dondurdum. Bir sonraki tur 9 mavi kristal geldi. Totalde 10 edeceği için patlasım.
User prompt
Donan kristal eğer şartlar sağlanırsa patlayabilir
User prompt
Yahu niye ekrandan siliyorsun sonan kristali. Bir tur bekle sonra sil
User prompt
Düzelt o zaman
User prompt
Arkadaşım. Sadece bir tur donacak. İkinci tur donmayı kaldır. Ayrıca patlayabilir donan kristal
User prompt
3 freeze hakkı var. Bir tur kullandıktan sonra seçimi kaldır ve hakkı düşür
User prompt
Ya hayır. Freeze tuşuna bastıktan sonra tıkladığım kristal ekranda sabit duracak.
User prompt
Ekranda sabit duracak.
User prompt
Freeze bastıktan sonra tıkladığım kristal değişmeyecek.
User prompt
Freeze tuşuna bastıktan sonra hangi kristale tıklarsam o kristal donacak. Spine basıldığında tüm kristaller değişirken o kristal değişmeyecek
User prompt
Freeze çalışmıyor. Düzeltir misin. Anlattım nasıl çalışması gerektiğini yüZ defa
User prompt
Freeze tuşu çalışmıyor. Tıklanan bir kristali sabit tutması lazım diğer tur için.
User prompt
Freeze tuşuna bastıktan sonra hangi kristale tıklarsam o kristalin etrafında kare çerçeve oluşsun ve spin tuşuna basıldığında bir tur değişmesin.
User prompt
Freeze tuşu oyun içinde üç defa kullanılabilir ve hangi kristalin üzerine dokunursa oyuncu o kristal spin tuşuna basıldığında bir sonraki tur yerinde kalır ve diğer kristaller değişir sadece
User prompt
Bomb tuşu patlattıktan sonra yukarıdan yeni gelen kristallerin boşluğu doldurması lazım
User prompt
Bomb, freeze ve swap tuşları çalışmıyor. Bomb tuşuna basıldığında hangi kristale tıklarsam etrafındaki kristallerin patlaması gerekiyor. Bu hak oyun içinde sadece bir defa veriliyor
User prompt
Please fix the bug: 'storage.set is not a function' in or related to this line: 'storage.set("dailyMissions", {' Line Number: 197 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Please fix the bug: 'storage.get is not a function' in or related to this line: 'var saved = storage.get("dailyMissions");' Line Number: 175 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Please fix the bug: 'storage is not defined' in or related to this line: 'var saved = storage.get("dailyMissions");' Line Number: 174
User prompt
Her gün 3 rastgele görev oluştur. Görevler örnek olarak: 10 kırmızı kristal patlat 5 joker kristal patlat Görevler tamamlanınca oyuncuya ödül ver.
User prompt
Oyuncu skoruna göre seviye atlayacak. Her 1000 puanda bir seviye artsın ve jokerProbability azalsın.
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading '0')' in or related to this line: 'var crystal = board[r][c];' Line Number: 659
User prompt
"Oyuncuya 3 farklı özel güç butonu ekle: bomb: seçilen kristal ve çevresini yok eder. swap: seçilen iki kristalin yerini değiştirir. freeze: bir kristalin joker olmasını engeller." ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Bir hamlede birden fazla zincirleme patlama (cascade) oluşuyorsa, her ek zincir için skoru comboMultiplier çarpanı ile arttır. İlk patlama x1, ikinci x2, üçüncü x3 vb. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
ya da yanıp sönmeyi sil. patlamadan önce iki saniye titremeye başlasınlar ve sonra patlasınlar.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Crystal class var Crystal = Container.expand(function () { var self = Container.call(this); // type: 'blue', 'yellow', 'red', 'purple', 'white', 'joker' self.type = 'blue'; self.row = 0; self.col = 0; self.popping = false; // Attach correct asset function setAsset() { if (self.asset) self.removeChild(self.asset); var assetId = 'crystal_' + self.type; self.asset = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); } self.setType = function (type) { self.type = type; setAsset(); }; // Animate pop self.pop = function (_onFinish) { if (self.popping) return; self.popping = true; tween(self, { scaleX: 1.4, scaleY: 1.4, alpha: 0 }, { duration: 350, easing: tween.easeOut, onFinish: function onFinish() { if (_onFinish) _onFinish(); } }); LK.getSound('crystal_pop').play(); }; // Reset visual state self.resetVisual = function () { self.scaleX = 1; self.scaleY = 1; self.alpha = 1; self.popping = false; }; setAsset(); return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x181c2c }); /**** * Game Code ****/ // Sound effects (placeholders, actual sound assets will be loaded by LK) // Crystal shapes (box for simplicity, different colors for each type) // --- Game Constants --- var BOARD_COLS = 4; var BOARD_ROWS = 6; var CRYSTAL_SIZE = 300; // px var CRYSTAL_SPACING = 24; // px var BOARD_WIDTH = BOARD_COLS * CRYSTAL_SIZE + (BOARD_COLS - 1) * CRYSTAL_SPACING; var BOARD_HEIGHT = BOARD_ROWS * CRYSTAL_SIZE + (BOARD_ROWS - 1) * CRYSTAL_SPACING; var BOARD_X = (2048 - BOARD_WIDTH) / 2; var BOARD_Y = (2732 - BOARD_HEIGHT) / 2 - 180; // move board up to make space for spin button var CRYSTAL_TYPES = ['blue', 'yellow', 'red', 'purple', 'white', 'joker']; var CRYSTAL_COLORS = { blue: 0x3a8ee6, yellow: 0xf7e14a, red: 0xe64a3a, purple: 0xb44ae6, white: 0xffffff, joker: 0x00e6b8 }; // Score values per crystal type var CRYSTAL_SCORES = { blue: 10, yellow: 12, red: 14, purple: 16, white: 18, joker: 25 }; // --- Game State --- var board = []; // 2D array [row][col] of Crystal or null var poppingCrystals = []; // Crystals currently popping var isCascading = false; var scoreTxt; var cascadeTimeout = null; // --- UI: Score --- scoreTxt = new Text2('0', { size: 120, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // --- Board Initialization --- function createEmptyBoard() { board = []; for (var row = 0; row < BOARD_ROWS; row++) { var rowArr = []; for (var col = 0; col < BOARD_COLS; col++) { rowArr.push(null); } board.push(rowArr); } } function randomCrystalType() { // Joker is rare: 10% chance var r = Math.random(); if (r < 0.10) return 'joker'; var idx = Math.floor(Math.random() * 5); return CRYSTAL_TYPES[idx]; } function spawnCrystal(row, col, type) { var crystal = new Crystal(); crystal.setType(type); crystal.row = row; crystal.col = col; // Position var x = BOARD_X + col * (CRYSTAL_SIZE + CRYSTAL_SPACING) + CRYSTAL_SIZE / 2; var y = BOARD_Y + row * (CRYSTAL_SIZE + CRYSTAL_SPACING) + CRYSTAL_SIZE / 2; crystal.x = x; crystal.y = y; crystal.resetVisual(); game.addChild(crystal); return crystal; } function fillBoardRandom() { for (var row = 0; row < BOARD_ROWS; row++) { for (var col = 0; col < BOARD_COLS; col++) { var type = randomCrystalType(); var crystal = spawnCrystal(row, col, type); board[row][col] = crystal; } } refreshCrystalInteractivity(); } // --- Board Utility --- function getNeighbors(row, col) { // 4-directional neighbors var n = []; if (row > 0) n.push([row - 1, col]); if (row < BOARD_ROWS - 1) n.push([row + 1, col]); if (col > 0) n.push([row, col - 1]); if (col < BOARD_COLS - 1) n.push([row, col + 1]); return n; } // --- Find Groups for Popping --- function findPopGroups() { // Returns: [{type, crystals: [Crystal, ...], jokerCount: n}] var groups = []; // Count all crystals by type (excluding jokers) var typeCounts = {}; var typeCrystals = {}; var jokerCrystals = []; for (var i = 0; i < CRYSTAL_TYPES.length; i++) { var t = CRYSTAL_TYPES[i]; if (t !== 'joker') { typeCounts[t] = 0; typeCrystals[t] = []; } } for (var row = 0; row < BOARD_ROWS; row++) { for (var col = 0; col < BOARD_COLS; col++) { var crystal = board[row][col]; if (!crystal) continue; if (crystal.type === 'joker') { // If frozen, do not count as joker if (!crystal.frozen) { jokerCrystals.push(crystal); } } else { typeCounts[crystal.type]++; typeCrystals[crystal.type].push(crystal); } } } // For each color, see if color+joker >= 10, if so, pop all of that color and enough jokers for (var t in typeCounts) { var total = typeCounts[t] + jokerCrystals.length; if (total >= 10) { // Add all of this color var groupCrystals = []; for (var i = 0; i < typeCrystals[t].length; i++) { groupCrystals.push(typeCrystals[t][i]); } // Add jokers for (var j = 0; j < jokerCrystals.length; j++) { groupCrystals.push(jokerCrystals[j]); } groups.push({ type: t, crystals: groupCrystals, jokerCount: jokerCrystals.length }); } } return groups; } // --- Pop Groups --- function popGroups(groups, onFinish) { if (groups.length === 0) { if (onFinish) onFinish(); return; } isCascading = true; poppingCrystals = []; var popped = {}; // --- Combo Multiplier Logic --- if (typeof comboMultiplier === "undefined") { comboMultiplier = 1; } if (typeof lastCascadeMoveId === "undefined") { lastCascadeMoveId = 0; } if (typeof currentCascadeMoveId === "undefined") { currentCascadeMoveId = 0; } // If this is a new cascade move, reset comboMultiplier if (typeof cascadeMoveActive === "undefined" || !cascadeMoveActive) { comboMultiplier = 1; currentCascadeMoveId = Date.now(); lastCascadeMoveId = currentCascadeMoveId; cascadeMoveActive = true; } else { // If still in the same move, increment comboMultiplier if (currentCascadeMoveId === lastCascadeMoveId) { comboMultiplier++; } else { comboMultiplier = 1; currentCascadeMoveId = Date.now(); lastCascadeMoveId = currentCascadeMoveId; } } // Mark all crystals to pop (avoid double pop) for (var g = 0; g < groups.length; g++) { var group = groups[g]; for (var i = 0; i < group.crystals.length; i++) { var c = group.crystals[i]; var key = c.row + ',' + c.col; if (!popped[key]) { popped[key] = true; poppingCrystals.push(c); } } } // Animate pop with 2s shake before popping var popCount = poppingCrystals.length; var finished = 0; for (var i = 0; i < poppingCrystals.length; i++) { var c = poppingCrystals[i]; (function (crystal) { // Save original position var origX = crystal.x; var origY = crystal.y; var shakeDuration = 2000; var shakeInterval = 30; var elapsed = 0; var shakeTimer = null; function startShake() { shakeTimer = LK.setInterval(function () { // Random shake offset, smaller amplitude for subtle effect var dx = (Math.random() - 0.5) * 24; var dy = (Math.random() - 0.5) * 24; crystal.x = origX + dx; crystal.y = origY + dy; elapsed += shakeInterval; if (elapsed >= shakeDuration) { // End shake, restore position LK.clearInterval(shakeTimer); crystal.x = origX; crystal.y = origY; // Now pop crystal.pop(function () { finished++; if (finished === popCount) { // Remove from board for (var j = 0; j < poppingCrystals.length; j++) { var pc = poppingCrystals[j]; if (board[pc.row][pc.col] === pc) { board[pc.row][pc.col] = null; pc.destroy(); } } poppingCrystals = []; if (onFinish) onFinish(); } }); } }, shakeInterval); } startShake(); })(c); } // Score with combo multiplier for (var g = 0; g < groups.length; g++) { var group = groups[g]; var baseScore = 0; for (var i = 0; i < group.crystals.length; i++) { var c = group.crystals[i]; var t = c.type === 'joker' ? group.type : c.type; baseScore += CRYSTAL_SCORES[t]; } LK.setScore(LK.getScore() + baseScore * comboMultiplier); } scoreTxt.setText(LK.getScore()); LK.getSound('cascade').play(); LK.effects.flashObject(scoreTxt, 0xffff00, 400); } // --- Cascade: Drop Crystals Down and Fill --- function cascadeBoard(onFinish) { // For each column, drop crystals down to fill empty spaces var changed = false; for (var col = 0; col < BOARD_COLS; col++) { var emptyRows = []; for (var row = BOARD_ROWS - 1; row >= 0; row--) { if (!board[row][col]) { emptyRows.push(row); } else if (emptyRows.length > 0) { // Move crystal down var targetRow = emptyRows.shift(); var crystal = board[row][col]; board[targetRow][col] = crystal; board[row][col] = null; crystal.row = targetRow; crystal.col = col; // Animate drop var newY = BOARD_Y + targetRow * (CRYSTAL_SIZE + CRYSTAL_SPACING) + CRYSTAL_SIZE / 2; tween(crystal, { y: newY }, { duration: 220, easing: tween.cubicOut }); emptyRows.push(row); changed = true; } } } // Fill empty spaces at the top for (var col = 0; col < BOARD_COLS; col++) { for (var row = 0; row < BOARD_ROWS; row++) { if (!board[row][col]) { var type = randomCrystalType(); var crystal = spawnCrystal(row, col, type); board[row][col] = crystal; // Drop from above var startY = BOARD_Y - CRYSTAL_SIZE; crystal.y = startY; var targetY = BOARD_Y + row * (CRYSTAL_SIZE + CRYSTAL_SPACING) + CRYSTAL_SIZE / 2; tween(crystal, { y: targetY }, { duration: 220, easing: tween.cubicOut }); changed = true; } } } // Wait for animation, then call onFinish LK.setTimeout(function () { refreshCrystalInteractivity(); if (onFinish) onFinish(); }, 250); } // --- Main Game Loop: Cascade, Pop, Repeat --- function startCascadeLoop() { if (cascadeTimeout) { LK.clearTimeout(cascadeTimeout); cascadeTimeout = null; } var groups = findPopGroups(); if (groups.length === 0) { isCascading = false; return; } popGroups(groups, function () { cascadeBoard(function () { // Chain reaction! cascadeTimeout = LK.setTimeout(function () { startCascadeLoop(); }, 120); }); }); } // --- Start New Game --- function startGame() { LK.setScore(2000); scoreTxt.setText('2000'); // Reset combo multiplier state for new game comboMultiplier = 1; cascadeMoveActive = false; // Remove all crystals for (var row = 0; row < BOARD_ROWS; row++) { for (var col = 0; col < BOARD_COLS; col++) { if (board[row] && board[row][col]) { board[row][col].frozen = false; board[row][col].alpha = 1; board[row][col].destroy(); } } } createEmptyBoard(); fillBoardRandom(); refreshCrystalInteractivity(); LK.setTimeout(function () { startCascadeLoop(); }, 400); } // --- Karıştır Button --- var shuffleBtn = new Text2('Karıştır', { size: 110, fill: 0x00E6B8, font: "Arial Black" }); shuffleBtn.anchor.set(0.5, 1); shuffleBtn.x = LK.gui.width / 2; shuffleBtn.y = LK.gui.height - 60 - 140; // Move up to make space for spin button shuffleBtn.interactive = true; shuffleBtn.buttonMode = true; LK.gui.bottom.addChild(shuffleBtn); function reshuffleBoardWithFall() { if (isCascading) return; // Reset combo multiplier state for new move comboMultiplier = 1; cascadeMoveActive = false; // Remove all crystals for (var row = 0; row < BOARD_ROWS; row++) { for (var col = 0; col < BOARD_COLS; col++) { if (board[row][col]) { board[row][col].frozen = false; board[row][col].alpha = 1; board[row][col].destroy(); } } } createEmptyBoard(); // Fill board with new crystals, but spawn them above and animate falling for (var row = 0; row < BOARD_ROWS; row++) { for (var col = 0; col < BOARD_COLS; col++) { var type = randomCrystalType(); var crystal = spawnCrystal(row, col, type); board[row][col] = crystal; // Start above the board var targetY = crystal.y; crystal.y = BOARD_Y - CRYSTAL_SIZE * 2; tween(crystal, { y: targetY }, { duration: 3000, easing: tween.cubicOut }); } } refreshCrystalInteractivity(); LK.setTimeout(function () { startCascadeLoop(); }, 3100); } // Button event shuffleBtn.down = function (x, y, obj) { reshuffleBoardWithFall(); }; // --- Spin Button (visible, below crystals) --- var spinBtnContainer = new Container(); var spinBtnBg = LK.getAsset('spin_btn_shape', { anchorX: 0.5, anchorY: 0.5 }); spinBtnContainer.addChild(spinBtnBg); var spinBtnText = new Text2('Spin', { size: 90, fill: 0xffffff, font: "Arial Black" }); spinBtnText.anchor.set(0.5, 0.5); spinBtnText.x = 0; spinBtnText.y = 0; spinBtnContainer.addChild(spinBtnText); // Position: just below the board, centered horizontally spinBtnContainer.x = 2048 / 2; spinBtnContainer.y = BOARD_Y + BOARD_HEIGHT + 100 + spinBtnBg.height / 2; // Make interactive spinBtnContainer.interactive = true; spinBtnContainer.buttonMode = true; spinBtnContainer.down = function (x, y, obj) { if (isCascading) return; var currentCoins = LK.getScore(); if (currentCoins < 100) { // Not enough coins, flash red for feedback LK.effects.flashObject(spinBtnBg, 0xff0000, 300); return; } // Reset combo multiplier state for new move comboMultiplier = 1; cascadeMoveActive = false; LK.setScore(currentCoins - 100); scoreTxt.setText(LK.getScore()); reshuffleBoardWithFall(); // Optional: flash the button for feedback LK.effects.flashObject(spinBtnBg, 0xffffff, 200); }; // Add to game scene (not GUI, so it stays relative to board) game.addChild(spinBtnContainer); // --- Special Power Buttons --- // State for power selection var powerMode = null; // "bomb", "swap", "freeze" or null var swapFirstCrystal = null; // Helper to clear power mode UI state function clearPowerMode() { powerMode = null; swapFirstCrystal = null; bombBtnBg.alpha = 1; swapBtnBg.alpha = 1; freezeBtnBg.alpha = 1; } // --- Bomb Button --- var bombBtnContainer = new Container(); var bombBtnBg = LK.getAsset('spin_btn_shape', { anchorX: 0.5, anchorY: 0.5 }); bombBtnBg.tint = 0xff4444; bombBtnContainer.addChild(bombBtnBg); var bombBtnText = new Text2('Bomb', { size: 70, fill: 0xffffff, font: "Arial Black" }); bombBtnText.anchor.set(0.5, 0.5); bombBtnText.x = 0; bombBtnText.y = 0; bombBtnContainer.addChild(bombBtnText); bombBtnContainer.x = spinBtnContainer.x - 500; bombBtnContainer.y = spinBtnContainer.y; bombBtnContainer.interactive = true; bombBtnContainer.buttonMode = true; bombBtnContainer.down = function () { clearPowerMode(); powerMode = "bomb"; bombBtnBg.alpha = 0.7; }; // --- Swap Button --- var swapBtnContainer = new Container(); var swapBtnBg = LK.getAsset('spin_btn_shape', { anchorX: 0.5, anchorY: 0.5 }); swapBtnBg.tint = 0x44aaff; swapBtnContainer.addChild(swapBtnBg); var swapBtnText = new Text2('Swap', { size: 70, fill: 0xffffff, font: "Arial Black" }); swapBtnText.anchor.set(0.5, 0.5); swapBtnText.x = 0; swapBtnText.y = 0; swapBtnContainer.addChild(swapBtnText); swapBtnContainer.x = spinBtnContainer.x; swapBtnContainer.y = spinBtnContainer.y + 220; swapBtnContainer.interactive = true; swapBtnContainer.buttonMode = true; swapBtnContainer.down = function () { clearPowerMode(); powerMode = "swap"; swapBtnBg.alpha = 0.7; }; // --- Freeze Button --- var freezeBtnContainer = new Container(); var freezeBtnBg = LK.getAsset('spin_btn_shape', { anchorX: 0.5, anchorY: 0.5 }); freezeBtnBg.tint = 0x44ffd0; freezeBtnContainer.addChild(freezeBtnBg); var freezeBtnText = new Text2('Freeze', { size: 70, fill: 0x222222, font: "Arial Black" }); freezeBtnText.anchor.set(0.5, 0.5); freezeBtnText.x = 0; freezeBtnText.y = 0; freezeBtnContainer.addChild(freezeBtnText); freezeBtnContainer.x = spinBtnContainer.x + 500; freezeBtnContainer.y = spinBtnContainer.y; freezeBtnContainer.interactive = true; freezeBtnContainer.buttonMode = true; freezeBtnContainer.down = function () { clearPowerMode(); powerMode = "freeze"; freezeBtnBg.alpha = 0.7; }; // Add to game game.addChild(bombBtnContainer); game.addChild(swapBtnContainer); game.addChild(freezeBtnContainer); // --- Power Button Crystal Selection Logic --- for (var row = 0; row < BOARD_ROWS; row++) { if (!board[row]) continue; for (var col = 0; col < BOARD_COLS; col++) { (function (r, c) { if (!board[r]) return; var crystal = board[r][c]; if (!crystal) return; crystal.interactive = true; crystal.buttonMode = true; crystal.down = function () { if (isCascading) return; // Bomb: destroy selected and neighbors if (powerMode === "bomb") { var targets = [[r, c]]; var neighbors = getNeighbors(r, c); for (var i = 0; i < neighbors.length; i++) { var nr = neighbors[i][0], nc = neighbors[i][1]; if (board[nr][nc]) targets.push([nr, nc]); } for (var i = 0; i < targets.length; i++) { var tr = targets[i][0], tc = targets[i][1]; if (board[tr][tc]) { board[tr][tc].pop(function () { if (board[tr][tc]) board[tr][tc].destroy(); board[tr][tc] = null; }); } } clearPowerMode(); LK.setTimeout(function () { startCascadeLoop(); }, 400); } // Swap: select two, then swap else if (powerMode === "swap") { if (!swapFirstCrystal) { swapFirstCrystal = { row: r, col: c }; tween(crystal, { scaleX: 1.2, scaleY: 1.2 }, { duration: 200, easing: tween.easeOut }); } else { var c1 = swapFirstCrystal; var c2 = { row: r, col: c }; if (c1.row === c2.row && c1.col === c2.col) { // Same crystal, ignore return; } // Swap types var tempType = board[c1.row][c1.col].type; board[c1.row][c1.col].setType(board[c2.row][c2.col].type); board[c2.row][c2.col].setType(tempType); // Animate swap var c1x = board[c1.row][c1.col].x, c1y = board[c1.row][c1.col].y; var c2x = board[c2.row][c2.col].x, c2y = board[c2.row][c2.col].y; tween(board[c1.row][c1.col], { x: c2x, y: c2y }, { duration: 220, easing: tween.cubicOut }); tween(board[c2.row][c2.col], { x: c1x, y: c1y }, { duration: 220, easing: tween.cubicOut }); // Swap positions in board array var tmp = board[c1.row][c1.col]; board[c1.row][c1.col] = board[c2.row][c2.col]; board[c2.row][c2.col] = tmp; // Update row/col board[c1.row][c1.col].row = c1.row; board[c1.row][c1.col].col = c1.col; board[c2.row][c2.col].row = c2.row; board[c2.row][c2.col].col = c2.col; clearPowerMode(); LK.setTimeout(function () { startCascadeLoop(); }, 400); } } // Freeze: prevent joker from acting as joker else if (powerMode === "freeze") { var crystal = board[r][c]; if (crystal && crystal.type === "joker") { crystal.frozen = true; tween(crystal, { alpha: 0.5 }, { duration: 300, easing: tween.easeOut }); } clearPowerMode(); } }; })(row, col); } } // --- Patch: When filling board, re-apply crystal interactivity for powers --- function refreshCrystalInteractivity() { for (var row = 0; row < BOARD_ROWS; row++) { if (!board[row]) continue; for (var col = 0; col < BOARD_COLS; col++) { var crystal = board[row][col]; if (!crystal) continue; crystal.interactive = true; crystal.buttonMode = true; crystal.down = function () {}; } } } // --- Touch to Spin/Reshuffle (tap anywhere else, fallback for desktop) --- // Removed global tap-to-reshuffle so only Spin button restarts the game // --- Game Over/Win (not used, slot is endless) --- // --- Game Update (not needed, all logic is event/cascade driven) --- game.update = function () { // No per-frame logic needed }; // --- Start the game --- startGame(); ;
===================================================================
--- original.js
+++ change.js
@@ -612,10 +612,12 @@
game.addChild(swapBtnContainer);
game.addChild(freezeBtnContainer);
// --- Power Button Crystal Selection Logic ---
for (var row = 0; row < BOARD_ROWS; row++) {
+ if (!board[row]) continue;
for (var col = 0; col < BOARD_COLS; col++) {
(function (r, c) {
+ if (!board[r]) return;
var crystal = board[r][c];
if (!crystal) return;
crystal.interactive = true;
crystal.buttonMode = true;
@@ -727,8 +729,9 @@
}
// --- Patch: When filling board, re-apply crystal interactivity for powers ---
function refreshCrystalInteractivity() {
for (var row = 0; row < BOARD_ROWS; row++) {
+ if (!board[row]) continue;
for (var col = 0; col < BOARD_COLS; col++) {
var crystal = board[row][col];
if (!crystal) continue;
crystal.interactive = true;