User prompt
make blocks and background a bit bigger but blocks dont overflow to background
User prompt
blocks a bit smaller
User prompt
a new rectangle assets to below 5x5
User prompt
put a rectangle assest below the 5x5 line background
User prompt
make 5x5 line and the background a bit smaller
User prompt
add calculating score bar put it up to 5x5 line and put background to calculating score bar
User prompt
Please fix the bug: 'null is not an object (evaluating 'spinBtn.y')' in or related to this line: 'var scoreBarY = spinBtn.y + spinBtnRadius + 20; // Just behind the score numbers' Line Number: 154
User prompt
make score bar background smaller and make it background the score numbers
User prompt
make a square the background assest and make it fully background to 5x5 line
User prompt
make background 1 assest remove the fire and rainbow effects
User prompt
remove block_genus_0 image in background. It should be only in spawning blocks
User prompt
make score calculating bar bigger and remove the / 5000
User prompt
add new assets and make it the background square. Put up to the score bar and make bigger
User prompt
in the first spin no cooldown after first break add 3 second cooldown
User prompt
change break count 5 to 7 same genus blocks
User prompt
add 3 second cooldown to block spawn
User prompt
add score calculating bar up to 5x5 line with text βͺπ‘ Consider importing and using the following plugins: @upit/tween.v1
User prompt
Put spin button below 5x5 line and add fire effect background
User prompt
put the screent into a rainbow square and make spin button a circle assets and put spin button below the blocks screen
User prompt
add different 8 block assest for 8 different genus blocks to spawn
User prompt
add break cooldown. make a algorithm sometimes game give low scores βͺπ‘ Consider importing and using the following plugins: @upit/tween.v1
User prompt
add slowly,break and drop down animation to blocks. Change block colours 8 genus blocks to 8 different color. Add score bar while game contiune βͺπ‘ Consider importing and using the following plugins: @upit/tween.v1
Code edit (1 edits merged)
Please save this source code
User prompt
Spin & Match: Genus Block Breaker
Initial prompt
Make me a screen 5 line 5 column and put a spin button to down the 5 line 5 column screen. There comes random 25 blocks. In game will have 8 genus block, and if in the screens 5 or more blocks same genus, them will break and comes again random blocks. If white blocks break points give 1 x white block number, black blocks give 2 x black block number, yellow blocks give 3 x yellow block number, orange blocks give 4 x orange block number etc. Put point bar to below spin button. Block always spam to when no more 5 same genus block. And when we click the spin button game again give 25 random block and game started.
/**** * 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 ****/ // red, ellipse // purple, box // green, ellipse // blue, box // orange, ellipse // yellow, box // black, ellipse // white, box // 8 unique block assets for 8 genus types // --- Constants --- var gridSize = 5; var genusCount = 8; var blockSize = 220; // 5 blocks * 220 = 1100, smaller for more margin var gridPadding = 18; 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 - 48; // shrink by 48px (24px margin on each side) var bgSquareHeight = gridTotalSize - 48; 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); // --- Rainbow Square Background removed --- // --- State --- var grid = []; // 2D array [y][x] of Block var score = 0; var isSpinning = false; // --- UI Elements --- var spinBtn = null; var scoreTxt = null; // --- Score Bar UI --- var scoreBarBg = null; var scoreBarFill = null; var scoreBarText = null; var scoreBarMax = 5000; // Arbitrary max for full bar, can be tuned var scoreBarWidth = 320; var scoreBarHeight = 110; // Score bar UI will be initialized after spinBtn is created, see below // Helper to update score bar fill and text function updateScoreBar() { var fillRatio = Math.min(score / scoreBarMax, 1); var targetWidth = Math.floor((scoreBarWidth - 24) * fillRatio); // Animate fill width tween(scoreBarFill, { width: targetWidth }, { duration: 180, easing: tween.cubicOut }); scoreBarText.setText(score); } // --- 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 for (var y = 0; y < gridSize; y++) { for (var x = 0; x < gridSize; x++) { if (grid[y][x]) { removeBlock(grid[y][x]); } } } // Fill with new blocks for (var y = 0; y < gridSize; y++) { for (var x = 0; x < gridSize; x++) { var genus = randomGenus(); var block = placeBlock(x, y, genus); block.scaleX = 0.2; block.scaleY = 0.2; block.alpha = 0.2; 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]; genusBlocks[block.genus].push(block); } } var matches = []; for (var g = 0; g < genusCount; g++) { if (genusBlocks[g].length >= 7) { 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 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 5, * genus+1 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 - 5)) * (genus + 1); if (Math.random() < 0.3) { baseScore = Math.floor(baseScore * 0.5); } score += baseScore; } updateScore(); // 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 { 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); scoreTxt.setText(score); // Update score bar if (typeof updateScoreBar === "function") updateScoreBar(); // Optionally, animate score text for feedback tween(scoreTxt, { scaleX: 1.18, scaleY: 1.18 }, { duration: 80, easing: tween.cubicOut, onFinish: function onFinish() { tween(scoreTxt, { scaleX: 1, scaleY: 1 }, { duration: 80, easing: tween.cubicIn }); } }); } // Check if any matches are possible (i.e., if any genus has 5+ blocks) function hasMatches() { var matches = findMatches(); return matches.length > 0; } // Handle Spin button press function onSpin() { if (isSpinning) return; 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; // After all matches, check if any more matches are possible if (!hasMatches()) { // Game over LK.effects.flashScreen(0x000000, 600); LK.showGameOver(); } }); } else { isSpinning = false; // If no matches at all, game over LK.effects.flashScreen(0x000000, 600); LK.showGameOver(); } }; if (onSpin.firstSpin) { // No cooldown for first spin onSpin.firstSpin = false; LK.setTimeout(function () { doSpin(); }, 180); } else { // Add 3 second cooldown after first break LK.setTimeout(function () { LK.setTimeout(function () { doSpin(); }, 180); }, 3000); } } // --- UI Setup --- // Spin Button (circular, below the grid) 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 + 60 // moved below the grid }); game.addChild(spinBtn); // Spin Button Text var spinBtnTxt = new Text2('SPIN', { size: 90, fill: 0x222222 }); spinBtnTxt.anchor.set(0.5, 0.5); spinBtnTxt.x = spinBtn.x; spinBtnTxt.y = spinBtn.y; game.addChild(spinBtnTxt); // --- Score Bar UI (moved above the 5x5 grid, with background) --- var scoreBarY = gridStartY - scoreBarHeight - 40; // Place above the grid scoreBarBg = LK.getAsset('score_bar_bg', { width: scoreBarWidth, height: scoreBarHeight, color: 0x333333, shape: 'box', anchorX: 0.5, anchorY: 0, x: 2048 / 2, y: scoreBarY }); LK.gui.top.addChild(scoreBarBg); // Score bar fill (animated, colored, inside the smaller bar) scoreBarFill = LK.getAsset('score_bar_fill', { width: 1, height: scoreBarHeight - 20, color: 0x4caf50, shape: 'box', anchorX: 0.5, anchorY: 0, x: 2048 / 2, y: scoreBarY + 10 }); LK.gui.top.addChild(scoreBarFill); // Score bar text (centered above bar, on top of background) scoreBarText = new Text2('0', { size: 110, fill: 0xffffff }); scoreBarText.anchor.set(0.5, 0); scoreBarText.x = 2048 / 2; scoreBarText.y = scoreBarY + 18; LK.gui.top.addChild(scoreBarText); // (scoreTxt is now handled by scoreBarText above) scoreTxt = scoreBarText; // --- 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 }); } }); tween(spinBtnTxt, { scaleX: 0.92, scaleY: 0.92 }, { duration: 60, easing: tween.cubicIn, onFinish: function onFinish() { tween(spinBtnTxt, { scaleX: 1, scaleY: 1 }, { duration: 80, easing: tween.cubicOut }); } }); }; // --- 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 a random grid and score 0 score = 0; updateScore(); fillGridRandom(); // On game start, immediately break and refill if there are matches var initialMatches = findMatches(); if (initialMatches.length > 0) { breakAndRefill(initialMatches, function () { // Ready for first spin }); } // --- Game Update Loop (not used, but required for LK) --- game.update = function () { // No per-frame logic needed };
===================================================================
--- original.js
+++ change.js
@@ -90,17 +90,17 @@
// 8 unique block assets for 8 genus types
// --- Constants ---
var gridSize = 5;
var genusCount = 8;
-var blockSize = 260; // 5 blocks * 260 = 1300, fits well in 2048 width with margin
-var gridPadding = 24;
+var blockSize = 220; // 5 blocks * 220 = 1100, smaller for more margin
+var gridPadding = 18;
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 (covers exactly the 5x5 grid area) ---
-var bgSquareWidth = gridTotalSize;
-var bgSquareHeight = gridTotalSize;
+// --- Background Square (slightly smaller than the 5x5 grid area) ---
+var bgSquareWidth = gridTotalSize - 48; // shrink by 48px (24px margin on each side)
+var bgSquareHeight = gridTotalSize - 48;
var bgSquareX = 2048 / 2;
var bgSquareY = gridStartY + gridTotalSize / 2 - blockSize / 2;
var bgSquare = LK.getAsset('background_square', {
width: bgSquareWidth,
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