User prompt
Make for every blocks, if we click any block it open a window screen and it says like if i click block_genus_2 it says 6x(block genus score amount) = (6xblock genus score amount)
User prompt
fix 2x assets not double current win
User prompt
put a bit space to data messages under each other
User prompt
put data messages outside right to 5x5 line
User prompt
put data messages outside 5x5 line and under each other
User prompt
Please fix the bug: 'Timeout.tick error: Can't find variable: breakdownSpacing' in or related to this line: 'batch[j].y -= breakdownSpacing * matches.length;' Line Number: 581
User prompt
Put data messages right to 5x5 line
User prompt
put data texts right 5x5 line
User prompt
Make change score amount price put a red - button and a triangle spin amount button and green + button if we click - spin amount will -50 if we click + button spin amount will +50 min amount is 200 max is 4000 and make blocks give score according to spin amount
User prompt
if 2x assets spawned current win will double it. If it doubled add it in data texts
User prompt
fix multis when spin end and if multi spawned. Multi the current win
User prompt
fix data texts under each other make a bit space
User prompt
fix data if blocks break very fast put texts under each other
User prompt
fix multis dont multi
User prompt
make it multis more rare
User prompt
put data text down to total bat
User prompt
fix data
User prompt
add down to how much give data like if 7 block_genus_2 match make text (block_genus_2 assets) break 7x(1 blocks genus 2 score amount)
User prompt
If we got 180 win in game and alr multiplication spawned it not multi the current win. Make it like if current win 180 and 2x spawned it make it 180x2 360
User prompt
please fix multiciplations dont multi the current win
User prompt
fix mustard effect
User prompt
When multiplications spawned firstly dont multiplicate. Wait for end the breakings and last time add mustard effect to current win and multiplications multiplicate the current win to how much them names.
User prompt
make multiplications multiple the current win
User prompt
remove spawn cooldown when clicking spin button
User prompt
remove cooldown in first spin
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Block class: represents a single block in the grid var Block = Container.expand(function () { var self = Container.call(this); // Properties self.genus = 0; // 0-7 self.gridX = 0; // 0-4 self.gridY = 0; // 0-4 // Asset for the block var blockAsset = null; // Set genus and update asset self.setGenus = function (genus) { self.genus = genus; // Remove old asset if present if (blockAsset) { self.removeChild(blockAsset); } // Each genus gets a unique color and shape var colors = [0xffffff, // white 0x222222, // black 0xffeb3b, // yellow 0xff9800, // orange 0x2196f3, // blue 0x4caf50, // green 0x9c27b0, // purple 0xf44336 // red ]; var shapes = ['box', 'ellipse', 'box', 'ellipse', 'box', 'ellipse', 'box', 'ellipse']; blockAsset = self.attachAsset('block_genus_' + genus, { width: blockSize, height: blockSize, color: colors[genus], shape: shapes[genus], anchorX: 0.5, anchorY: 0.5 }); }; // Animate breaking self.breakAnim = function (_onFinish) { tween(self, { scaleX: 1.3, scaleY: 1.3, alpha: 0 }, { duration: 200, easing: tween.cubicOut, onFinish: function onFinish() { self.scaleX = 1; self.scaleY = 1; self.alpha = 1; if (_onFinish) _onFinish(); } }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x222222 }); /**** * Game Code ****/ // --- Constants --- // 8 unique block assets for 8 genus types // white, box // black, ellipse // yellow, box // orange, ellipse // blue, box // green, ellipse // purple, box // red, ellipse function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } var gridSize = 5; var genusCount = 8; var blockSize = 210; // Increased block size for bigger blocks var gridPadding = 22; // Slightly increased padding for visual separation var gridTotalSize = blockSize * gridSize + gridPadding * (gridSize - 1); var gridStartX = Math.floor((2048 - gridTotalSize) / 2) + blockSize / 2; var gridStartY = 400 + blockSize / 2; // leave space for Spin button // --- Fire Effect Background removed --- // --- Background Square (slightly smaller than the 5x5 grid area) --- var bgSquareWidth = gridTotalSize + 12; // background is a bit bigger than grid, but not overflowing var bgSquareHeight = gridTotalSize + 12; var bgSquareX = 2048 / 2; var bgSquareY = gridStartY + gridTotalSize / 2 - blockSize / 2; var bgSquare = LK.getAsset('background_square', { width: bgSquareWidth, height: bgSquareHeight, color: 0x181818, shape: 'box', anchorX: 0.5, anchorY: 0.5, x: bgSquareX, y: bgSquareY }); bgSquare.alpha = 0.92; game.addChild(bgSquare); // --- Current Win Bar UI (above the 5x5 grid) --- var winBarWidth = 320; var winBarHeight = 90; var winBarMax = 5000; // Arbitrary max for full bar, can be tuned var winBarY = gridStartY - blockSize / 2 - 60; // 60px above the grid var winBarBg = LK.getAsset('score_bar_bg', { width: winBarWidth, height: winBarHeight, color: 0x333333, shape: 'box', anchorX: 0.0, anchorY: 0.5, x: gridStartX, // left aligned with grid y: winBarY }); game.addChild(winBarBg); var winBarFill = LK.getAsset('score_bar_fill', { width: 1, height: winBarHeight - 18, color: 0x30a262, shape: 'box', anchorX: 0.0, anchorY: 0.5, x: gridStartX, y: winBarY }); game.addChild(winBarFill); var winBarText = new Text2('0', { size: 60, fill: 0xffffff }); winBarText.anchor.set(0.5, 0.5); winBarText.x = gridStartX + winBarWidth / 2; winBarText.y = winBarY; game.addChild(winBarText); // "Current Win:" label (left of win bar) var winLabel = new Text2('Current Win:', { size: 54, fill: 0xffffff }); winLabel.anchor.set(1, 0.5); winLabel.x = gridStartX - 24; winLabel.y = winBarY; game.addChild(winLabel); // --- Total Score Bar UI (below the 5x5 line, left aligned) --- var scoreBarWidth = 320; var scoreBarHeight = 110; var scoreBarMax = 5000; // Arbitrary max for full bar, can be tuned var scoreBarY = bgSquareY + bgSquareHeight / 2 + 12 + 40; // 12px gap below bg, then 40px (half of old below_5x5_rect height) var scoreBarBg = LK.getAsset('score_bar_bg', { width: scoreBarWidth, height: scoreBarHeight, color: 0x333333, shape: 'box', anchorX: 0.0, anchorY: 0.5, x: gridStartX, y: scoreBarY }); game.addChild(scoreBarBg); var scoreBarFill = LK.getAsset('score_bar_fill', { width: 1, height: scoreBarHeight - 20, color: 0x4caf50, shape: 'box', anchorX: 0.0, anchorY: 0.5, x: gridStartX, y: scoreBarY }); game.addChild(scoreBarFill); var scoreBarText = new Text2('0', { size: 90, fill: 0xffffff }); scoreBarText.anchor.set(0.5, 0.5); scoreBarText.x = gridStartX + scoreBarWidth / 2; scoreBarText.y = scoreBarY; game.addChild(scoreBarText); // "Total Score" label (left of score bar) var scoreLabel = new Text2('Total Score', { size: 54, fill: 0xffffff }); scoreLabel.anchor.set(1, 0.5); scoreLabel.x = gridStartX - 24; scoreLabel.y = scoreBarY; game.addChild(scoreLabel); // (scoreTxt is now handled by scoreBarText above) scoreTxt = scoreBarText; // --- Current Win value tracking --- var currentWin = 0; // --- Rainbow Square Background removed --- // --- State --- var grid = []; // 2D array [y][x] of Block var score = 0; var isSpinning = false; // --- UI Elements --- var spinBtn = null; // --- Score Bar UI --- // (All score bar variables are now initialized above, right after bgSquare) // Helper to update score bar fill and text function updateScoreBar() { // Total Score bar var fillRatio = Math.min(score / scoreBarMax, 1); var targetWidth = Math.floor((scoreBarWidth - 24) * fillRatio); if (scoreBarFill && _typeof(scoreBarFill) === "object") { tween(scoreBarFill, { width: targetWidth }, { duration: 180, easing: tween.cubicOut }); } if (scoreBarText) scoreBarText.setText(score); if (scoreBarBg && scoreBarFill) { scoreBarFill.x = scoreBarBg.x; scoreBarFill.y = scoreBarBg.y; } if (scoreBarBg && scoreBarText) { scoreBarText.x = scoreBarBg.x + scoreBarWidth / 2; scoreBarText.y = scoreBarBg.y; } // Current Win bar var winFillRatio = Math.min(currentWin / winBarMax, 1); var winTargetWidth = Math.floor((winBarWidth - 20) * winFillRatio); if (winBarFill && _typeof(winBarFill) === "object") { tween(winBarFill, { width: winTargetWidth }, { duration: 180, easing: tween.cubicOut }); } if (winBarText) winBarText.setText(currentWin); if (winBarBg && winBarFill) { winBarFill.x = winBarBg.x; winBarFill.y = winBarBg.y; } if (winBarBg && winBarText) { winBarText.x = winBarBg.x + winBarWidth / 2; winBarText.y = winBarBg.y; } } // --- Helper Functions --- // Generate a random genus (0-7) function randomGenus() { return Math.floor(Math.random() * genusCount); } // Place a block at grid[x][y] function placeBlock(x, y, genus) { var block = new Block(); block.setGenus(genus); block.gridX = x; block.gridY = y; block.x = gridStartX + x * (blockSize + gridPadding); block.y = gridStartY + y * (blockSize + gridPadding); block.scaleX = 1; block.scaleY = 1; block.alpha = 1; game.addChild(block); return block; } // Remove a block from the game and grid function removeBlock(block) { if (block) { block.destroy(); } } // Fill the grid with random blocks, destroying old ones function fillGridRandom() { // Remove old blocks and clear grid for (var y = 0; y < gridSize; y++) { for (var x = 0; x < gridSize; x++) { if (grid[y][x]) { removeBlock(grid[y][x]); } grid[y][x] = null; } } // Multiplier spawn logic function getRandomMultiplier() { var r = Math.random() * 100000; if (r < 1) return "x100"; // 0.001% if (r < 4) return "x50"; // 0.003% if (r < 14) return "x25"; // 0.01% if (r < 44) return "x10"; // 0.03% if (r < 244) return "x5"; // 0.2% if (r < 1244) return "x2"; // 1.2% return null; } // Fill with new random blocks for every cell in the 5x5 grid for (var y = 0; y < gridSize; y++) { for (var x = 0; x < gridSize; x++) { if (!grid[y][x]) { // Only fill empty cells var genus = randomGenus(); // Multiplier asset logic var multiplier = getRandomMultiplier(); var block; if (multiplier) { // Multiplier block: use only the multiplier asset, not a normal block block = new Block(); block.genus = -1; // Not a normal genus block.gridX = x; block.gridY = y; block.multiplier = multiplier; // Remove any default asset if (block.children && block.children.length > 0) { for (var ci = block.children.length - 1; ci >= 0; ci--) { block.removeChild(block.children[ci]); } } var multAsset = block.attachAsset(multiplier, { anchorX: 0.5, anchorY: 0.5, x: 0, y: 0, width: blockSize * 0.98, height: blockSize * 0.98 }); multAsset.alpha = 1; block.multAsset = multAsset; block.x = gridStartX + x * (blockSize + gridPadding); block.y = gridStartY + y * (blockSize + gridPadding); block.scaleX = 0.2; block.scaleY = 0.2; block.alpha = 0.2; game.addChild(block); } else { block = placeBlock(x, y, genus); } tween(block, { scaleX: 1, scaleY: 1, alpha: 1 }, { duration: 220, easing: tween.cubicOut }); grid[y][x] = block; } } } } // Find all genus with 7 or more blocks, return array of {genus, blocks: [Block]} function findMatches() { // Count blocks per genus var genusBlocks = []; for (var g = 0; g < genusCount; g++) { genusBlocks[g] = []; } for (var y = 0; y < gridSize; y++) { for (var x = 0; x < gridSize; x++) { var block = grid[y][x]; if (block && typeof block.genus === "number" && block.genus >= 0 && block.genus < genusCount) { genusBlocks[block.genus].push(block); } } } var matches = []; for (var g = 0; g < genusCount; g++) { if (genusBlocks[g].length >= 6) { matches.push({ genus: g, blocks: genusBlocks[g] }); } } return matches; } // Break all matched blocks, animate, update score, and refill function breakAndRefill(matches, _onFinish2) { if (matches.length === 0) { if (_onFinish2) _onFinish2(); return; } var blocksToBreak = []; for (var i = 0; i < matches.length; i++) { blocksToBreak = blocksToBreak.concat(matches[i].blocks); } // Remove duplicates (shouldn't be any, but just in case) var uniqueBlocks = []; var seen = {}; for (var i = 0; i < blocksToBreak.length; i++) { var b = blocksToBreak[i]; var key = b.gridX + ',' + b.gridY; if (!seen[key]) { uniqueBlocks.push(b); seen[key] = true; } } // Animate breaking // --- Stacked breakdown text logic for fast breaks --- if (!breakAndRefill.activeBreakdowns) breakAndRefill.activeBreakdowns = []; var breakdownTextNodes = []; var breakdownSpacing = 68; // Increased spacing for more space between stacked breakdowns var breakdownFontSize = 44; var breakdownDuration = 1200; var breakdownFade = 400; // Arrange breakdowns in a 5x5 grid to the right of the score bar var breakdownGridCols = 5; var breakdownGridRows = 5; var breakdownCellW = 140; var breakdownCellH = 68; var breakdownGridX0 = scoreBarBg.x + scoreBarWidth + 60; var breakdownGridY0 = scoreBarBg.y - breakdownCellH * (breakdownGridRows / 2) + scoreBarHeight / 2 + 38; for (var i = 0; i < matches.length; i++) { var genus = matches[i].genus; var count = matches[i].blocks.length; if (count >= 6) { // Compute grid position for this breakdown var gridIdx = breakAndRefill.activeBreakdowns.length * matches.length + i; var col = gridIdx % breakdownGridCols; var row = Math.floor(gridIdx / breakdownGridCols); if (row >= breakdownGridRows) row = breakdownGridRows - 1; // Clamp to last row if overflow var asset = LK.getAsset('block_genus_' + genus, { width: 54, height: 54, anchorX: 0, anchorY: 0.5, x: breakdownGridX0 + col * breakdownCellW, y: breakdownGridY0 + row * breakdownCellH }); var perBlockScore = Math.floor(10 * (genus + 1) * (spinAmount / 500)); var extraBlockScore = Math.floor(10 * (genus + 1) * (spinAmount / 500)) * Math.max(0, count - 6); var totalScore = perBlockScore * count + extraBlockScore; var text = new Text2(count + "x" + perBlockScore + (count > 6 ? " + " + (count - 6) + "x" + perBlockScore : "") + " = " + totalScore, { size: breakdownFontSize, fill: 0xffffff }); text.anchor.set(0, 0.5); text.x = breakdownGridX0 + col * breakdownCellW + 60; text.y = breakdownGridY0 + row * breakdownCellH + 27; game.addChild(asset); game.addChild(text); breakdownTextNodes.push(asset, text); } } // Track this batch for stacking breakAndRefill.activeBreakdowns.push(breakdownTextNodes); // Remove this batch after duration, and update stacking for remaining var breakdownClearTimeout = LK.setTimeout(function () { // Destroy this batch for (var i = 0; i < breakdownTextNodes.length; i++) { if (breakdownTextNodes[i] && breakdownTextNodes[i].destroy) breakdownTextNodes[i].destroy(); } // Remove this batch from activeBreakdowns var idx = breakAndRefill.activeBreakdowns.indexOf(breakdownTextNodes); if (idx !== -1) breakAndRefill.activeBreakdowns.splice(idx, 1); // Move up any remaining breakdowns for (var b = 0; b < breakAndRefill.activeBreakdowns.length; b++) { var batch = breakAndRefill.activeBreakdowns[b]; for (var j = 0; j < batch.length; j += 2) { // asset is batch[j], text is batch[j+1] if (batch[j]) batch[j].y -= breakdownSpacing * matches.length; if (batch[j + 1]) batch[j + 1].y -= breakdownSpacing * matches.length; } } }, breakdownDuration + breakdownFade); var brokenCount = 0; for (var i = 0; i < uniqueBlocks.length; i++) { (function (block) { block.breakAnim(function () { // Remove from grid grid[block.gridY][block.gridX] = null; removeBlock(block); brokenCount++; // When all blocks are broken, refill if (brokenCount === uniqueBlocks.length) { // Update score: 10 points per block, +10 per extra block above 6, * genus+1 var winScore = 0; var maxMultiplier = 1; var foundMultiplier = null; for (var m = 0; m < matches.length; m++) { var count = matches[m].blocks.length; var genus = matches[m].genus; // --- Sometimes give low scores: 30% chance to halve the score for this break --- var baseScore = (10 * count + 10 * Math.max(0, count - 6)) * (genus + 1); if (Math.random() < 0.3) { baseScore = Math.floor(baseScore * 0.5); } // Check for multiplier in matched blocks for (var b = 0; b < matches[m].blocks.length; b++) { var blk = matches[m].blocks[b]; if (blk.multiplier) { // Only use the highest multiplier in a match var multVal = 1; if (blk.multiplier === "x2") multVal = 2; if (blk.multiplier === "x5") multVal = 5; if (blk.multiplier === "x10") multVal = 10; if (blk.multiplier === "x25") multVal = 25; if (blk.multiplier === "x50") multVal = 50; if (blk.multiplier === "x100") multVal = 100; if (multVal > maxMultiplier) { maxMultiplier = multVal; foundMultiplier = blk.multiplier; } } } score += baseScore; winScore += baseScore; } // Collect multipliers for later application if (!breakAndRefill.pendingMultipliers) breakAndRefill.pendingMultipliers = []; if (!breakAndRefill.pendingWinScore) breakAndRefill.pendingWinScore = 0; if (maxMultiplier > 1 && foundMultiplier) { // Store all multipliers found in this break breakAndRefill.pendingMultipliers.push(maxMultiplier); } breakAndRefill.pendingWinScore += winScore; currentWin += winScore; updateScore(); updateScoreBar(); // Refill broken blocks with new random blocks var dropAnimCount = 0; var dropAnimTotal = 0; for (var y = 0; y < gridSize; y++) { for (var x = 0; x < gridSize; x++) { if (!grid[y][x]) { var genus = randomGenus(); var newBlock = placeBlock(x, y, genus); grid[y][x] = newBlock; // Animate drop from above var targetY = newBlock.y; newBlock.y = targetY - 180; dropAnimTotal++; tween(newBlock, { y: targetY }, { duration: 220, easing: tween.cubicOut, onFinish: function onFinish() { dropAnimCount++; // Only proceed after all drop animations are done if (dropAnimCount === dropAnimTotal) { // After refill, check for new matches recursively // --- BREAK COOLDOWN: Wait before checking for new matches --- LK.setTimeout(function () { var newMatches = findMatches(); if (newMatches.length > 0) { breakAndRefill(newMatches, _onFinish2); } else { // After all breakings and refills, apply all multipliers at once if (breakAndRefill.pendingMultipliers && breakAndRefill.pendingMultipliers.length > 0) { // Multiply currentWin by the product of all multipliers, but only if currentWin is nonzero var totalMultiplier = 1; for (var mi = 0; mi < breakAndRefill.pendingMultipliers.length; mi++) { totalMultiplier *= breakAndRefill.pendingMultipliers[mi]; } // Always multiply the currentWin by the totalMultiplier if currentWin is nonzero if (currentWin > 0) { // If there are two or more x2 multipliers, double currentWin for each x2 var x2Count = 0; for (var mi = 0; mi < breakAndRefill.pendingMultipliers.length; mi++) { if (breakAndRefill.pendingMultipliers[mi] === 2) x2Count++; } if (x2Count >= 2) { var beforeDouble = currentWin; currentWin = currentWin * 2; // Add breakdown text for the doubling var doubleText = new Text2("2x2! Doubled: " + beforeDouble + " β " + currentWin, { size: 44, fill: 0xffdb58 }); doubleText.anchor.set(0, 0.5); doubleText.x = scoreBarBg.x + scoreBarWidth + 60; doubleText.y = scoreBarBg.y + scoreBarHeight / 2 + 38 + breakAndRefill.activeBreakdowns.length * 68; game.addChild(doubleText); // Remove after a short time LK.setTimeout(function () { if (doubleText && doubleText.destroy) doubleText.destroy(); }, 1200); } // Now apply the rest of the multipliers (including the two x2s) var totalMultiplier = 1; for (var mi = 0; mi < breakAndRefill.pendingMultipliers.length; mi++) { totalMultiplier *= breakAndRefill.pendingMultipliers[mi]; } // If we already doubled for two x2s, remove two x2s from the product if (x2Count >= 2) { for (var remove = 0; remove < 2; remove++) { totalMultiplier /= 2; } } if (totalMultiplier > 1) { currentWin = currentWin * totalMultiplier; } } else { // If currentWin is zero, do not apply multiplier (no win to multiply) currentWin = 0; } // Mustard effect: flashObject with mustard yellow, then animate back to original color LK.effects.flashObject(winBarFill, 0xffdb58, 900); tween(winBarFill, { tint: 0x30a262 }, { delay: 900, duration: 180, easing: tween.cubicOut }); } else { // No multipliers, just use the accumulated winScore currentWin = breakAndRefill.pendingWinScore; } // Reset for next break sequence breakAndRefill.pendingMultipliers = []; breakAndRefill.pendingWinScore = 0; updateScoreBar(); if (_onFinish2) _onFinish2(); } }, 320); // 320ms cooldown after drop } } }); } } } // If no blocks needed to drop, continue immediately if (dropAnimTotal === 0) { // --- BREAK COOLDOWN: Wait before checking for new matches --- LK.setTimeout(function () { var newMatches = findMatches(); if (newMatches.length > 0) { breakAndRefill(newMatches, _onFinish2); } else { if (_onFinish2) _onFinish2(); } }, 320); // 320ms cooldown if no drop } // After refill, check for new matches recursively // (removed duplicate immediate check) } }); })(uniqueBlocks[i]); } } // Update score text and LK score function updateScore() { LK.setScore(score); if (scoreBarText) scoreBarText.setText(score); // Update score bar if (typeof updateScoreBar === "function") updateScoreBar(); // Optionally, animate score text for feedback if (scoreBarText) { tween(scoreBarText, { scaleX: 1.18, scaleY: 1.18 }, { duration: 80, easing: tween.cubicOut, onFinish: function onFinish() { tween(scoreBarText, { scaleX: 1, scaleY: 1 }, { duration: 80, easing: tween.cubicIn }); } }); } } // Check if any matches are possible (i.e., if any genus has 6+ blocks) function hasMatches() { var matches = findMatches(); return matches.length > 0; } // Handle Spin button press function onSpin() { if (isSpinning) return; if (score < spinAmount) { // Not enough score to spin, show game over LK.effects.flashScreen(0x000000, 600); LK.showGameOver(); return; } score -= spinAmount; currentWin = 0; updateScore(); updateScoreBar(); isSpinning = true; // Animate all blocks out (optional, for feedback) for (var y = 0; y < gridSize; y++) { for (var x = 0; x < gridSize; x++) { var block = grid[y][x]; if (block) { tween(block, { scaleX: 0.7, scaleY: 0.7, alpha: 0.3 }, { duration: 120, easing: tween.cubicIn }); } } } // Remove cooldown for first spin, add cooldown only after first break if (typeof onSpin.firstSpin === "undefined") { onSpin.firstSpin = true; } var doSpin = function doSpin() { fillGridRandom(); // After refill, check for matches and break recursively var matches = findMatches(); if (matches.length > 0) { // Wrap breakAndRefill to add 3s cooldown after first break breakAndRefill(matches, function () { isSpinning = false; // --- Apply multiplier to currentWin if a multiplier block spawned in this spin --- if (breakAndRefill && breakAndRefill.pendingMultipliers && breakAndRefill.pendingMultipliers.length > 0 && currentWin > 0) { var totalMultiplier = 1; for (var mi = 0; mi < breakAndRefill.pendingMultipliers.length; mi++) { totalMultiplier *= breakAndRefill.pendingMultipliers[mi]; } currentWin = currentWin * totalMultiplier; // Mustard effect: flashObject with mustard yellow, then animate back to original color LK.effects.flashObject(winBarFill, 0xffdb58, 900); tween(winBarFill, { tint: 0x30a262 }, { delay: 900, duration: 180, easing: tween.cubicOut }); // Reset multipliers for next spin breakAndRefill.pendingMultipliers = []; breakAndRefill.pendingWinScore = 0; updateScoreBar(); } // After all matches, check if any more matches are possible if (!hasMatches()) { // Only show game over if score is less than 500, otherwise allow player to spin again if (score < 500) { LK.effects.flashScreen(0x000000, 600); LK.showGameOver(); } } }); } else { isSpinning = false; // If no matches at all, only show game over if score is less than 500 if (score < 500) { LK.effects.flashScreen(0x000000, 600); LK.showGameOver(); } } }; if (onSpin.firstSpin) { // No cooldown for first spin onSpin.firstSpin = false; doSpin(); // immediate, no timeout } else { doSpin(); // immediate, no timeout } } // --- UI Setup --- // --- Spin Amount UI --- // State for spin amount var spinAmount = 500; var spinAmountMin = 200; var spinAmountMax = 4000; var spinAmountStep = 50; // - Button (red) var minusBtn = LK.getAsset('score_bar_bg', { width: 100, height: 100, color: 0xd83318, shape: 'ellipse', anchorX: 0.5, anchorY: 0.5, x: 2048 / 2 - 260, y: gridStartY + gridTotalSize + 140 + 60 }); game.addChild(minusBtn); // - Text var minusText = new Text2('-', { size: 90, fill: 0xffffff }); minusText.anchor.set(0.5, 0.5); minusText.x = minusBtn.x; minusText.y = minusBtn.y; game.addChild(minusText); // + Button (green) var plusBtn = LK.getAsset('score_bar_bg', { width: 100, height: 100, color: 0x30a262, shape: 'ellipse', anchorX: 0.5, anchorY: 0.5, x: 2048 / 2 + 260, y: gridStartY + gridTotalSize + 140 + 60 }); game.addChild(plusBtn); // + Text var plusText = new Text2('+', { size: 90, fill: 0xffffff }); plusText.anchor.set(0.5, 0.5); plusText.x = plusBtn.x; plusText.y = plusBtn.y; game.addChild(plusText); // Spin Amount Button (triangle) var spinAmountBtn = LK.getAsset('score_bar_bg', { width: 120, height: 120, color: 0xf9dd57, shape: 'ellipse', anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: gridStartY + gridTotalSize + 140 + 60 }); game.addChild(spinAmountBtn); // Triangle icon (drawn with text) var triangleText = new Text2('β²', { size: 60, fill: 0x222222 }); triangleText.anchor.set(0.5, 0.5); triangleText.x = spinAmountBtn.x; triangleText.y = spinAmountBtn.y - 30; game.addChild(triangleText); // Spin Amount Value Text var spinAmountText = new Text2(spinAmount + '', { size: 60, fill: 0x222222 }); spinAmountText.anchor.set(0.5, 0.5); spinAmountText.x = spinAmountBtn.x; spinAmountText.y = spinAmountBtn.y + 30; game.addChild(spinAmountText); // Update spin amount text helper function updateSpinAmountText() { spinAmountText.setText(spinAmount + ''); } // - Button logic minusBtn.down = function (x, y, obj) { if (spinAmount > spinAmountMin) { spinAmount -= spinAmountStep; if (spinAmount < spinAmountMin) spinAmount = spinAmountMin; updateSpinAmountText(); // Animate feedback tween(minusBtn, { scaleX: 0.92, scaleY: 0.92 }, { duration: 60, easing: tween.cubicIn, onFinish: function onFinish() { tween(minusBtn, { scaleX: 1, scaleY: 1 }, { duration: 80, easing: tween.cubicOut }); } }); } }; // + Button logic plusBtn.down = function (x, y, obj) { if (spinAmount < spinAmountMax) { spinAmount += spinAmountStep; if (spinAmount > spinAmountMax) spinAmount = spinAmountMax; updateSpinAmountText(); // Animate feedback tween(plusBtn, { scaleX: 0.92, scaleY: 0.92 }, { duration: 60, easing: tween.cubicIn, onFinish: function onFinish() { tween(plusBtn, { scaleX: 1, scaleY: 1 }, { duration: 80, easing: tween.cubicOut }); } }); } }; // Spin Amount Button logic (optional: could cycle through preset values, but here does nothing) spinAmountBtn.down = function (x, y, obj) { // Animate feedback tween(spinAmountBtn, { scaleX: 0.92, scaleY: 0.92 }, { duration: 60, easing: tween.cubicIn, onFinish: function onFinish() { tween(spinAmountBtn, { scaleX: 1, scaleY: 1 }, { duration: 80, easing: tween.cubicOut }); } }); }; // --- Spin Button (circular, below the grid and spin amount UI) --- var spinBtnRadius = 140; spinBtn = LK.getAsset('spinBtn', { width: spinBtnRadius * 2, height: spinBtnRadius * 2, color: 0xf9dd57, shape: 'ellipse', anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: gridStartY + gridTotalSize + spinBtnRadius + 260 // moved below the grid and spin amount UI }); game.addChild(spinBtn); // --- Input Handling --- // Only allow pressing Spin button (not grid) spinBtn.down = function (x, y, obj) { if (isSpinning) return; onSpin(); // Animate button press tween(spinBtn, { scaleX: 0.92, scaleY: 0.92 }, { duration: 60, easing: tween.cubicIn, onFinish: function onFinish() { tween(spinBtn, { scaleX: 1, scaleY: 1 }, { duration: 80, easing: tween.cubicOut }); } }); // Removed spinBtnTxt animation as spinBtnTxt does not exist }; // --- Game Initialization --- // Initialize grid array for (var y = 0; y < gridSize; y++) { grid[y] = []; for (var x = 0; x < gridSize; x++) { grid[y][x] = null; } } // Start with 2000 score, do not fill grid or break until spin is pressed score = 2000; updateScore(); // Do not fillGridRandom or breakAndRefill here; wait for spin button // --- Game Update Loop (not used, but required for LK) --- game.update = function () { // No per-frame logic needed };
===================================================================
--- original.js
+++ change.js
@@ -422,26 +422,31 @@
var breakdownSpacing = 68; // Increased spacing for more space between stacked breakdowns
var breakdownFontSize = 44;
var breakdownDuration = 1200;
var breakdownFade = 400;
- // Calculate Y offset for this batch so each new breakdown appears below previous ones
- var breakdownYStart = scoreBarBg.y + scoreBarHeight / 2 + 38;
- var breakdownX = scoreBarBg.x + scoreBarWidth + 60;
- var stackIndex = breakAndRefill.activeBreakdowns.length;
- var breakdownYOffset = stackIndex * (breakdownSpacing * matches.length);
- // For each genus match, show breakdown asset and text
+ // Arrange breakdowns in a 5x5 grid to the right of the score bar
+ var breakdownGridCols = 5;
+ var breakdownGridRows = 5;
+ var breakdownCellW = 140;
+ var breakdownCellH = 68;
+ var breakdownGridX0 = scoreBarBg.x + scoreBarWidth + 60;
+ var breakdownGridY0 = scoreBarBg.y - breakdownCellH * (breakdownGridRows / 2) + scoreBarHeight / 2 + 38;
for (var i = 0; i < matches.length; i++) {
var genus = matches[i].genus;
var count = matches[i].blocks.length;
if (count >= 6) {
- // Show asset and text: e.g. [block_genus_2 asset] 7x block score = total
+ // Compute grid position for this breakdown
+ var gridIdx = breakAndRefill.activeBreakdowns.length * matches.length + i;
+ var col = gridIdx % breakdownGridCols;
+ var row = Math.floor(gridIdx / breakdownGridCols);
+ if (row >= breakdownGridRows) row = breakdownGridRows - 1; // Clamp to last row if overflow
var asset = LK.getAsset('block_genus_' + genus, {
width: 54,
height: 54,
anchorX: 0,
anchorY: 0.5,
- x: breakdownX,
- y: breakdownYStart + breakdownYOffset
+ x: breakdownGridX0 + col * breakdownCellW,
+ y: breakdownGridY0 + row * breakdownCellH
});
var perBlockScore = Math.floor(10 * (genus + 1) * (spinAmount / 500));
var extraBlockScore = Math.floor(10 * (genus + 1) * (spinAmount / 500)) * Math.max(0, count - 6);
var totalScore = perBlockScore * count + extraBlockScore;
@@ -449,14 +454,13 @@
size: breakdownFontSize,
fill: 0xffffff
});
text.anchor.set(0, 0.5);
- text.x = breakdownX + 60;
- text.y = breakdownYStart + breakdownYOffset + 27;
+ text.x = breakdownGridX0 + col * breakdownCellW + 60;
+ text.y = breakdownGridY0 + row * breakdownCellH + 27;
game.addChild(asset);
game.addChild(text);
breakdownTextNodes.push(asset, text);
- breakdownYOffset += breakdownSpacing;
}
}
// Track this batch for stacking
breakAndRefill.activeBreakdowns.push(breakdownTextNodes);
doner. 2d. High contrast. No shadows
ayran. 2d. High contrast. No shadows
lettuce. 2d. High contrast. No shadows
tomato. 2d. High contrast. No shadows
beef. 2d. High contrast. No shadows
ketchup. 2d. High contrast. No shadows
purple cabbage. 2d. High contrast. No shadows
mayonnaise. 2d. High contrast. No shadows
return symbol
doner kebab master. 2d. Like doner store background
Mustard Bottle, label is x2. In-Game asset. 2d. High contrast. No shadows
Mustard Bottle, label is x5. In-Game asset. 2d. High contrast. No shadows
Mustard Bottle, label is x10. In-Game asset. 2d. High contrast. No shadows
Mustard Bottle, label is x25. In-Game asset. 2d. High contrast. No shadows
Mustard Bottle, label is x50. In-Game asset. 2d. High contrast. No shadows
Mustard Bottle, label is x100. In-Game asset. 2d. High contrast. No shadows
crushed mustard bottle. In-Game asset. 2d. High contrast. No shadows