User prompt
Fix sound when move squares and collect them
User prompt
Fix sound on the game
User prompt
Fix a happy sound when collect 3 squares och it changes to one new color
User prompt
More shaders like 3d on squares and more happy skybox background
User prompt
Make more manga eyes and smile more on face on squares
User prompt
Please fix the bug: 'Cannot use 'in' operator to search for 'block_black' in undefined' in or related to this line: 'var smile = LK.getAsset('block_black' in LK.assets ? 'block_black' : 'block_blue', {' Line Number: 82
User prompt
Make more cute squares with face on
User prompt
Not working it stops when collected 3 squares
Code edit (1 edits merged)
Please save this source code
User prompt
Color Merge Cascade
Initial prompt
Generate a whole new fun satisfying puzzle game
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Block class: represents a block on the grid or in the draggable area var Block = Container.expand(function () { var self = Container.call(this); // Block color index: 0=red, 1=green, 2=blue, 3=yellow, 4=purple, 5=white self.colorIndex = 0; self.gridX = -1; // grid position, -1 if not on grid self.gridY = -1; self.isOnGrid = false; // Attach asset based on colorIndex self.setColor = function (idx) { self.colorIndex = idx; if (self.blockAsset) { self.removeChild(self.blockAsset); } if (self.faceAsset) { self.removeChild(self.faceAsset); } var colorNames = ['red', 'green', 'blue', 'yellow', 'purple', 'white']; var assetId = 'block_' + colorNames[idx]; self.blockAsset = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); // --- Add 3D-like shading and highlights --- // Main highlight (top left) var highlight = LK.getAsset('block_white', { width: 60, height: 60, anchorX: 0.2, anchorY: 0.2, x: -36, y: -36, alpha: 0.18 }); self.addChild(highlight); // Side shadow (bottom right) var shadow = LK.getAsset('block_black', { width: 80, height: 80, anchorX: 0.8, anchorY: 0.8, x: 36, y: 36, alpha: 0.10 }); self.addChild(shadow); // Edge highlight (top edge) var edgeHighlight = LK.getAsset('block_white', { width: 80, height: 16, anchorX: 0.5, anchorY: 0.5, x: 0, y: -44, alpha: 0.10 }); self.addChild(edgeHighlight); // Edge shadow (bottom edge) var edgeShadow = LK.getAsset('block_black', { width: 80, height: 16, anchorX: 0.5, anchorY: 0.5, x: 0, y: 44, alpha: 0.08 }); self.addChild(edgeShadow); // Add a cute manga face overlay (big manga eyes, highlights, and a bigger smile) self.faceAsset = new Container(); // Manga left eye (big white) var eyeL = LK.getAsset('block_white', { width: 36, height: 36, anchorX: 0.5, anchorY: 0.5, x: -36, y: -22, alpha: 0.98 }); // Manga right eye (big white) var eyeR = LK.getAsset('block_white', { width: 36, height: 36, anchorX: 0.5, anchorY: 0.5, x: 36, y: -22, alpha: 0.98 }); // Left eye pupil (black) var pupilL = LK.getAsset('block_black', { width: 16, height: 16, anchorX: 0.5, anchorY: 0.5, x: -36, y: -22, alpha: 0.95 }); // Right eye pupil (black) var pupilR = LK.getAsset('block_black', { width: 16, height: 16, anchorX: 0.5, anchorY: 0.5, x: 36, y: -22, alpha: 0.95 }); // Left eye highlight (white) var eyeHL = LK.getAsset('block_white', { width: 7, height: 7, anchorX: 0.5, anchorY: 0.5, x: -40, y: -28, alpha: 0.85 }); // Right eye highlight (white) var eyeHR = LK.getAsset('block_white', { width: 7, height: 7, anchorX: 0.5, anchorY: 0.5, x: 32, y: -28, alpha: 0.85 }); // Cheeks var cheekL = LK.getAsset('block_red', { width: 18, height: 10, anchorX: 0.5, anchorY: 0.5, x: -38, y: 18, alpha: 0.18 }); var cheekR = LK.getAsset('block_red', { width: 18, height: 10, anchorX: 0.5, anchorY: 0.5, x: 38, y: 18, alpha: 0.18 }); // Big smile var smileAssetId = typeof LK.assets !== "undefined" && LK.assets && typeof LK.assets['block_black'] !== "undefined" ? 'block_black' : 'block_blue'; var smile = LK.getAsset(smileAssetId, { width: 60, height: 16, anchorX: 0.5, anchorY: 0.5, x: 0, y: 22, alpha: 0.8, rotation: 0.08 }); // Smile highlight (white, for manga shine) var smileHL = LK.getAsset('block_white', { width: 18, height: 4, anchorX: 0.5, anchorY: 0.5, x: 0, y: 18, alpha: 0.18, rotation: 0.08 }); self.faceAsset.addChild(eyeL); self.faceAsset.addChild(eyeR); self.faceAsset.addChild(pupilL); self.faceAsset.addChild(pupilR); self.faceAsset.addChild(eyeHL); self.faceAsset.addChild(eyeHR); self.faceAsset.addChild(cheekL); self.faceAsset.addChild(cheekR); self.faceAsset.addChild(smile); self.faceAsset.addChild(smileHL); self.addChild(self.faceAsset); }; self.setColor(0); // Animate merge self.animateMerge = function (_onFinish) { tween(self, { scaleX: 1.3, scaleY: 1.3 }, { duration: 120, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 120, easing: tween.easeIn, onFinish: _onFinish }); } }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x222233 }); /**** * Game Code ****/ // Sound for merge // Merged block (final color) // We'll use 5 colors: red, green, blue, yellow, purple // Define block shapes for each color and merged color // --- Game Constants --- var GRID_COLS = 6; var GRID_ROWS = 7; var CELL_SIZE = 200; // px var GRID_OFFSET_X = Math.floor((2048 - GRID_COLS * CELL_SIZE) / 2); var GRID_OFFSET_Y = 350; var COLORS = [0, 1, 2, 3, 4]; // 0=red, 1=green, 2=blue, 3=yellow, 4=purple var COLOR_NAMES = ['red', 'green', 'blue', 'yellow', 'purple', 'white']; var MAX_COLOR_INDEX = 5; // 0-4 normal, 5=white (final, can't merge further) var BLOCK_DROP_Y = 2200; // y position for blocks that fall off // --- Game State --- var grid = []; // 2D array [col][row] of Block or null for (var c = 0; c < GRID_COLS; c++) { grid[c] = []; for (var r = 0; r < GRID_ROWS; r++) { grid[c][r] = null; } } var draggingBlock = null; var dragOffsetX = 0; var dragOffsetY = 0; var nextBlocks = []; // Array of next blocks to place var score = 0; var scoreTxt = null; var isProcessing = false; // Prevent input during merges // --- GUI Elements --- scoreTxt = new Text2('0', { size: 120, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // --- Draw Happy Skybox Background Gradient --- var skybox = LK.getAsset('block_blue', { width: 2048, height: 2732, anchorX: 0, anchorY: 0, x: 0, y: 0, alpha: 1 }); game.addChild(skybox); // Add a white "sun" circle for extra cuteness var sun = LK.getAsset('block_white', { width: 420, height: 420, anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 180, alpha: 0.18 }); game.addChild(sun); // Add some "clouds" using white blocks with low alpha for (var i = 0; i < 4; i++) { var cloud = LK.getAsset('block_white', { width: 320 + Math.random() * 120, height: 90 + Math.random() * 40, anchorX: 0.5, anchorY: 0.5, x: 300 + i * 420 + Math.random() * 80, y: 120 + Math.random() * 60, alpha: 0.10 + Math.random() * 0.08 }); game.addChild(cloud); } // --- Draw Grid Background --- for (var c = 0; c < GRID_COLS; c++) { for (var r = 0; r < GRID_ROWS; r++) { var cell = LK.getAsset('block_white', { anchorX: 0.5, anchorY: 0.5, x: GRID_OFFSET_X + c * CELL_SIZE + CELL_SIZE / 2, y: GRID_OFFSET_Y + r * CELL_SIZE + CELL_SIZE / 2, alpha: 0.08 }); game.addChild(cell); } } // --- Helper Functions --- // Get grid cell from x,y (game coordinates) function getGridCellFromPos(x, y) { var gx = Math.floor((x - GRID_OFFSET_X) / CELL_SIZE); var gy = Math.floor((y - GRID_OFFSET_Y) / CELL_SIZE); if (gx < 0 || gx >= GRID_COLS || gy < 0 || gy >= GRID_ROWS) return null; return { col: gx, row: gy }; } // Get position (x,y) for grid cell function getPosForCell(col, row) { return { x: GRID_OFFSET_X + col * CELL_SIZE + CELL_SIZE / 2, y: GRID_OFFSET_Y + row * CELL_SIZE + CELL_SIZE / 2 }; } // Generate a random color index (0-4) function randomColorIndex() { return COLORS[Math.floor(Math.random() * COLORS.length)]; } // Create a new block for the "next" area function createNextBlock(idx) { var block = new Block(); block.setColor(idx); block.x = 2048 / 2 + (nextBlocks.length - 1) * 220; block.y = 220; block.scaleX = block.scaleY = 1; block.isOnGrid = false; block.gridX = -1; block.gridY = -1; game.addChild(block); return block; } // Fill nextBlocks to always have 3 blocks function refillNextBlocks() { while (nextBlocks.length < 3) { var idx = randomColorIndex(); var block = createNextBlock(idx); nextBlocks.push(block); } // Position them nicely for (var i = 0; i < nextBlocks.length; i++) { var bx = 2048 / 2 + (i - 1) * 220; tween(nextBlocks[i], { x: bx, y: 220 }, { duration: 180, easing: tween.easeInOut }); } } // Remove a block from nextBlocks and shift others function popNextBlock(block) { var idx = nextBlocks.indexOf(block); if (idx >= 0) { nextBlocks.splice(idx, 1); } refillNextBlocks(); } // Place block on grid function placeBlockOnGrid(block, col, row) { block.isOnGrid = true; block.gridX = col; block.gridY = row; grid[col][row] = block; var pos = getPosForCell(col, row); tween(block, { x: pos.x, y: pos.y, scaleX: 1, scaleY: 1 }, { duration: 120, easing: tween.easeOut }); } // Remove block from grid function removeBlockFromGrid(col, row) { var block = grid[col][row]; if (block) { grid[col][row] = null; } } // Find all connected blocks of the same color (DFS) function findConnectedBlocks(col, row, colorIndex, visited) { if (col < 0 || col >= GRID_COLS || row < 0 || row >= GRID_ROWS) return []; if (visited[col + "," + row]) return []; var block = grid[col][row]; if (!block || block.colorIndex !== colorIndex) return []; visited[col + "," + row] = true; var result = [{ col: col, row: row, block: block }]; // 4 directions var dirs = [[1, 0], [-1, 0], [0, 1], [0, -1]]; for (var i = 0; i < dirs.length; i++) { var nc = col + dirs[i][0]; var nr = row + dirs[i][1]; result = result.concat(findConnectedBlocks(nc, nr, colorIndex, visited)); } return result; } // Check if any moves are possible (empty cell exists) function hasMoves() { for (var c = 0; c < GRID_COLS; c++) { for (var r = 0; r < GRID_ROWS; r++) { if (!grid[c][r]) return true; } } return false; } // --- Game Logic --- // Handle block drop onto grid function tryPlaceBlock(block, x, y) { var cell = getGridCellFromPos(x, y); if (!cell) return false; var col = cell.col, row = cell.row; if (grid[col][row]) return false; // occupied // Place block placeBlockOnGrid(block, col, row); popNextBlock(block); // After placement, check for merges processMerges(col, row, function () { // After all merges and cascades, check for game over if (!hasMoves()) { LK.showGameOver(); } }); return true; } // Process merges and cascades starting from (col,row) function processMerges(col, row, onFinish) { if (isProcessing) return; isProcessing = true; var block = grid[col][row]; if (!block) { isProcessing = false; if (onFinish) onFinish(); return; } var colorIdx = block.colorIndex; if (colorIdx >= MAX_COLOR_INDEX) { isProcessing = false; if (onFinish) onFinish(); return; } // Find all connected blocks of same color var connected = findConnectedBlocks(col, row, colorIdx, {}); if (connected.length >= 3) { // Play happy merge sound only on actual merge LK.getSound('merge').play(); // Merge! for (var i = 0; i < connected.length; i++) { var b = connected[i].block; if (b !== block) { // Animate and remove (function (bref) { tween(bref, { scaleX: 0, scaleY: 0, alpha: 0 }, { duration: 120, easing: tween.easeIn, onFinish: function onFinish() { bref.destroy(); } }); })(b); removeBlockFromGrid(b.gridX, b.gridY); } } // Upgrade block color var newColor = colorIdx + 1; if (newColor > MAX_COLOR_INDEX) newColor = MAX_COLOR_INDEX; block.setColor(newColor); // Play happy merge sound exactly when 3 or more squares merge and upgrade color LK.getSound('merge').play(); block.animateMerge(function () { // After animation, check for further merges (cascade) // We need to check if the upgraded block can merge again LK.setTimeout(function () { // Find new connected blocks after upgrade var newConnected = findConnectedBlocks(col, row, block.colorIndex, {}); if (newConnected.length >= 3) { // Chain reaction: process again processMerges(col, row, onFinish); } else { // No more merges, finish isProcessing = false; if (onFinish) onFinish(); } }, 180); }); // Update score var points = 10 * connected.length * (colorIdx + 1); score += points; scoreTxt.setText(score); } else { isProcessing = false; if (onFinish) onFinish(); } } // --- Input Handling --- // Only allow dragging from nextBlocks game.down = function (x, y, obj) { if (isProcessing) return; for (var i = 0; i < nextBlocks.length; i++) { var block = nextBlocks[i]; // Check if touch is inside block var dx = x - block.x; var dy = y - block.y; if (Math.abs(dx) < 90 && Math.abs(dy) < 90) { draggingBlock = block; dragOffsetX = dx; dragOffsetY = dy; // Bring to front game.addChild(block); tween(block, { scaleX: 1.15, scaleY: 1.15 }, { duration: 80, easing: tween.easeOut }); break; } } }; game.move = function (x, y, obj) { if (!draggingBlock) return; draggingBlock.x = x - dragOffsetX; draggingBlock.y = y - dragOffsetY; }; game.up = function (x, y, obj) { if (!draggingBlock) return; // Try to place on grid var placed = tryPlaceBlock(draggingBlock, draggingBlock.x, draggingBlock.y); if (!placed) { // Snap back to next area var idx = nextBlocks.indexOf(draggingBlock); var bx = 2048 / 2 + (idx - 1) * 220; tween(draggingBlock, { x: bx, y: 220, scaleX: 1, scaleY: 1 }, { duration: 120, easing: tween.easeInOut }); } else { // Block is now on grid, don't need to do anything } draggingBlock = null; }; // --- Game Update Loop --- game.update = function () { // Animate blocks falling off (if any) for (var c = 0; c < GRID_COLS; c++) { for (var r = 0; r < GRID_ROWS; r++) { var block = grid[c][r]; if (block && block.y > BLOCK_DROP_Y) { block.destroy(); grid[c][r] = null; } } } }; // --- Game Start --- score = 0; scoreTxt.setText(score); refillNextBlocks(); // --- Game Over / Reset handled by LK engine ---
===================================================================
--- original.js
+++ change.js
@@ -462,8 +462,10 @@
}
// Find all connected blocks of same color
var connected = findConnectedBlocks(col, row, colorIdx, {});
if (connected.length >= 3) {
+ // Play happy merge sound only on actual merge
+ LK.getSound('merge').play();
// Merge!
for (var i = 0; i < connected.length; i++) {
var b = connected[i].block;
if (b !== block) {
@@ -487,10 +489,11 @@
// Upgrade block color
var newColor = colorIdx + 1;
if (newColor > MAX_COLOR_INDEX) newColor = MAX_COLOR_INDEX;
block.setColor(newColor);
+ // Play happy merge sound exactly when 3 or more squares merge and upgrade color
+ LK.getSound('merge').play();
block.animateMerge(function () {
- LK.getSound('merge').play();
// After animation, check for further merges (cascade)
// We need to check if the upgraded block can merge again
LK.setTimeout(function () {
// Find new connected blocks after upgrade