User prompt
change the name of the game to Cloud Pop Puzzle
User prompt
The puzzle pieces should be a little more to the left
User prompt
There should be more space between the puzzle pieces and they should be a little higher
User prompt
Add a 1x2 overlapping puzzle piece to the game
User prompt
Reposition the asset named tray background so that the top left corner is in the center.
User prompt
add a sound asset for pop
User prompt
add animation make the puzzle pieces dance in a slow circular motion ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
The puzzle pieces dance in a circular motion. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
The puzzle pieces dance in a slow circular motion.
User prompt
Center the puzzle pieces on the tray
User prompt
add a setting so we can turn the music on and off
User prompt
make game_music2 is game music
User prompt
restore the image when you hold the puzzle pieces
User prompt
Center the puzzle pieces visually around their geometric center. only apply this while waiting on the tray before placing it on the game board
User prompt
center the puzzle pieces
User prompt
delete cloud1 cloud2 cloud3 assets
User prompt
Center the center of the puzzle pieces to the pool where they were before placing them.
User prompt
The puzzle pieces should be at most 4 pieces
User prompt
The puzzle pieces should be at most 5 pieces
User prompt
fix hex_green asset
User prompt
fix
User prompt
make asset for tray pieces background. name ''tray background''
User prompt
Before placing, keep the pieces waiting in the pool further away from each other.
User prompt
Increase the size of parts and slots by 50%
User prompt
Increase parts and slots by 50%
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // --- HexTile: A single hexagon on the board --- var HexTile = Container.expand(function () { var self = Container.call(this); // Color: 'pink', 'blue', 'yellow', 'green', 'purple', 'orange' self.color = 'pink'; self.gridQ = 0; // axial q self.gridR = 0; // axial r self.occupied = false; self.face = null; // Attach hex asset self.setColor = function (color) { self.color = color; if (self.hex) self.removeChild(self.hex); self.hex = self.attachAsset('hex_' + color, { anchorX: 0.5, anchorY: 0.5 }); // Add face if (self.face) self.removeChild(self.face); self.face = self.attachAsset('face', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 0, scaleX: 0.7, scaleY: 0.7 }); }; self.setEmpty = function () { self.occupied = false; if (self.hex) self.hex.visible = false; if (self.face) self.face.visible = false; }; self.setFilled = function (color) { self.occupied = true; self.setColor(color); self.hex.visible = true; self.face.visible = true; }; // Pop animation self.pop = function () { if (!self.occupied) return; self.setEmpty(); }; return self; }); // --- Piece: A draggable group of 1-5 hexes in a shape --- var Piece = Container.expand(function () { var self = Container.call(this); // Shape: array of {q, r, color} self.shape = []; self.hexes = []; self.dragging = false; self.valid = true; // is current placement valid // Generate a piece from a shape definition self.setShape = function (shape) { self.shape = shape; // Remove old hexes for (var i = 0; i < self.hexes.length; ++i) self.removeChild(self.hexes[i]); self.hexes = []; // Add new hexes for (var i = 0; i < shape.length; ++i) { var hex = self.attachAsset('hex_' + shape[i].color, { anchorX: 0.5, anchorY: 0.5, x: 0, y: 0 }); // Add face var face = self.attachAsset('face', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 0, scaleX: 0.7, scaleY: 0.7 }); hex.addChild(face); self.hexes.push(hex); } // Position hexes for (var i = 0; i < shape.length; ++i) { var pos = axialToPixel(shape[i].q, shape[i].r, pieceHexSize); self.hexes[i].x = pos.x; self.hexes[i].y = pos.y; } }; // Highlight for valid/invalid placement self.setValid = function (valid) { self.valid = valid; for (var i = 0; i < self.hexes.length; ++i) { self.hexes[i].alpha = valid ? 1 : 0.4; } }; return self; }); /**** * Initialize Game ****/ /**** * Helper Functions ****/ // Hex math var game = new LK.Game({ // No title, no description // Always backgroundColor is black backgroundColor: 0x000000 }); /**** * Game Code ****/ // --- Add main background image --- var bgImg = LK.getAsset('Background', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, scaleX: 1, scaleY: 1, alpha: 1 }); game.addChild(bgImg); // Play game music LK.playMusic('game_music2'); // --- Add dreamy cloud background --- // Hex tile shapes (pastel colors) // Cloud background (large, white, semi-transparent ellipses) // Faces (as colored ellipses for now, can be replaced with images later) // Pop effect // Sound effects /**** * Helper Functions ****/ // Hex math function _typeof6(o) { "@babel/helpers - typeof"; return _typeof6 = "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; }, _typeof6(o); } function _typeof5(o) { "@babel/helpers - typeof"; return _typeof5 = "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; }, _typeof5(o); } function _typeof4(o) { "@babel/helpers - typeof"; return _typeof4 = "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; }, _typeof4(o); } function _typeof3(o) { "@babel/helpers - typeof"; return _typeof3 = "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; }, _typeof3(o); } function _typeof2(o) { "@babel/helpers - typeof"; return _typeof2 = "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; }, _typeof2(o); } 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 sqrt3 = Math.sqrt(3); function axialToPixel(q, r, size) { // Flat-topped hex var x = size * (3 / 2 * q); var y = size * (sqrt3 * (r + q / 2)); return { x: x, y: y }; } function pixelToAxial(x, y, size) { var q = 2 / 3 * x / size; var r = (-1 / 3 * x + sqrt3 / 3 * y) / size; return hexRound(q, r); } function hexRound(q, r) { var x = q; var z = r; var y = -x - z; var rx = Math.round(x); var ry = Math.round(y); var rz = Math.round(z); var x_diff = Math.abs(rx - x); var y_diff = Math.abs(ry - y); var z_diff = Math.abs(rz - z); if (x_diff > y_diff && x_diff > z_diff) rx = -ry - rz;else if (y_diff > z_diff) ry = -rx - rz;else rz = -rx - ry; return { q: rx, r: rz }; } // Generate random color function randomColor() { var arr = ['pink', 'blue', 'yellow', 'green', 'purple', 'orange']; return arr[Math.floor(Math.random() * arr.length)]; } // Piece shape library (axial coordinates, always includes 0,0) // Only allow shapes with at most 4 hexes var pieceShapes = [ // Single [{ q: 0, r: 0 }], // Line 2 [{ q: 0, r: 0 }, { q: 1, r: 0 }], // Line 3 [{ q: 0, r: 0 }, { q: 1, r: 0 }, { q: 2, r: 0 }], // L shape [{ q: 0, r: 0 }, { q: 1, r: 0 }, { q: 1, r: 1 }], // Triangle [{ q: 0, r: 0 }, { q: 1, r: 0 }, { q: 0, r: 1 }], // Line 4 [{ q: 0, r: 0 }, { q: 1, r: 0 }, { q: 2, r: 0 }, { q: 3, r: 0 }], // Big L (4) [{ q: 0, r: 0 }, { q: 1, r: 0 }, { q: 2, r: 0 }, { q: 2, r: 1 }]]; // Generate a random piece shape with random colors function randomPieceShape() { var base = pieceShapes[Math.floor(Math.random() * pieceShapes.length)]; var color = randomColor(); var arr = []; for (var i = 0; i < base.length; ++i) { arr.push({ q: base[i].q, r: base[i].r, color: color }); } return arr; } /**** * Game Board Setup ****/ // Board size var boardRadius = 5; // 5 rings from center (total diameter 11) var boardHexSize = 90; // px, for board tiles (increased by 50%) var pieceHexSize = boardHexSize; // px, for piece tiles (match board tile size) // Board center in pixels var boardCenterX = 2048 / 2; var boardCenterY = 1200; // Board data: array of {q, r, tile} var boardTiles = []; // Build board: all hexes with |q|+|r|+|s| <= boardRadius for (var q = -boardRadius; q <= boardRadius; ++q) { for (var r = -boardRadius; r <= boardRadius; ++r) { var s = -q - r; if (Math.abs(q) <= boardRadius && Math.abs(r) <= boardRadius && Math.abs(s) <= boardRadius) { // Create tile var tile = new HexTile(); tile.gridQ = q; tile.gridR = r; tile.setEmpty(); var pos = axialToPixel(q, r, boardHexSize); tile.x = boardCenterX + pos.x; tile.y = boardCenterY + pos.y; // Add a unique asset for every cell (behind the tile) with entity name 'cell_background2' var cellAsset = LK.getAsset('cell_background', { anchorX: 0.5, anchorY: 0.5, x: tile.x, y: tile.y, scaleX: boardHexSize / 100, scaleY: boardHexSize / 100, alpha: 0.22, entityName: 'cell_background2' }); game.addChild(cellAsset); boardTiles.push({ q: q, r: r, tile: tile }); } } } // Helper: find tile at q,r function getTile(q, r) { for (var i = 0; i < boardTiles.length; ++i) { if (boardTiles[i].q === q && boardTiles[i].r === r) return boardTiles[i].tile; } return null; } // --- Add game board image '1' behind tiles --- var boardImg1 = LK.getAsset('1', { anchorX: 0.5, anchorY: 0.5, x: boardCenterX, y: boardCenterY, scaleX: 12, scaleY: 12, alpha: 0.18 }); game.addChild(boardImg1); // --- Add board tiles to game --- for (var i = 0; i < boardTiles.length; ++i) { game.addChild(boardTiles[i].tile); } // --- Score display --- var score = 0; var scoreTxt = new Text2('0', { size: 120, fill: "#fff" }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // --- Piece tray (bottom center) --- var trayY = 2732 - 350; var trayX = 2048 / 2; var traySpacing = 480; // Increased spacing between tray pieces var trayPieces = [null, null, null]; // 3 pieces at a time // --- Generate new pieces in tray --- function refillTray() { for (var i = 0; i < 3; ++i) { if (trayPieces[i]) { trayPieces[i].destroy(); trayPieces[i] = null; } // Add tray background behind each piece var trayBg = LK.getAsset('tray_background', { anchorX: 0.5, anchorY: 0.5, x: trayX + (i - 1) * traySpacing, y: trayY, scaleX: pieceHexSize / 100 * 1.5, scaleY: pieceHexSize / 100 * 1.5, alpha: 0.5 }); game.addChild(trayBg); var piece = new Piece(); piece.setShape(randomPieceShape()); piece.x = trayX + (i - 1) * traySpacing; piece.y = trayY; trayPieces[i] = piece; game.addChild(piece); } } refillTray(); // --- Drag and drop logic --- var draggingPiece = null; var dragOffsetX = 0; var dragOffsetY = 0; var dragStartX = 0; var dragStartY = 0; // Helper: get board position under a pixel function getBoardPosUnder(x, y) { // Convert to board-local var px = x - boardCenterX; var py = y - boardCenterY; var axial = pixelToAxial(px, py, boardHexSize); return axial; } // Helper: can place piece at board q,r function canPlacePiece(piece, q, r) { for (var i = 0; i < piece.shape.length; ++i) { var dq = piece.shape[i].q; var dr = piece.shape[i].r; var tile = getTile(q + dq, r + dr); if (!tile || tile.occupied) return false; } return true; } // Helper: place piece at board q,r function placePiece(piece, q, r) { for (var i = 0; i < piece.shape.length; ++i) { var dq = piece.shape[i].q; var dr = piece.shape[i].r; var color = piece.shape[i].color; var tile = getTile(q + dq, r + dr); if (tile) { tile.setFilled(color); // Add entity name '1' to this slot tile.entityName = '1'; } } // Play combo sound when a piece is placed LK.getSound('combo').play(); } // Helper: remove piece from tray function removePieceFromTray(piece) { for (var i = 0; i < 3; ++i) { if (trayPieces[i] === piece) { trayPieces[i].destroy(); trayPieces[i] = null; } } } // --- Game move events --- game.down = function (x, y, obj) { // Check if a piece in tray is touched for (var i = 0; i < 3; ++i) { var piece = trayPieces[i]; if (!piece) continue; var local = piece.toLocal(game.toGlobal({ x: x, y: y })); // Check if touch is within piece bounds for (var j = 0; j < piece.hexes.length; ++j) { var hx = piece.hexes[j].x; var hy = piece.hexes[j].y; var dx = local.x - hx; var dy = local.y - hy; if (dx * dx + dy * dy < pieceHexSize * pieceHexSize * 0.6) { draggingPiece = piece; dragStartX = piece.x; dragStartY = piece.y; dragOffsetX = x - piece.x; dragOffsetY = y - piece.y; piece.dragging = true; piece.setValid(true); // Bring to front game.addChild(piece); return; } } } }; game.move = function (x, y, obj) { if (!draggingPiece) return; // Move piece draggingPiece.x = x - dragOffsetX; draggingPiece.y = y - dragOffsetY; // Snap to board if close var pos = getBoardPosUnder(draggingPiece.x, draggingPiece.y); var canPlace = canPlacePiece(draggingPiece, pos.q, pos.r); draggingPiece.setValid(canPlace); // Snap visual to nearest hex if close enough if (canPlace) { var snapPos = axialToPixel(pos.q, pos.r, boardHexSize); draggingPiece.x = boardCenterX + snapPos.x; draggingPiece.y = boardCenterY + snapPos.y; } }; game.up = function (x, y, obj) { if (!draggingPiece) return; // Try to place var pos = getBoardPosUnder(draggingPiece.x, draggingPiece.y); if (canPlacePiece(draggingPiece, pos.q, pos.r)) { // Snap piece visually to the grid before placing var snapPos = axialToPixel(pos.q, pos.r, boardHexSize); draggingPiece.x = boardCenterX + snapPos.x; draggingPiece.y = boardCenterY + snapPos.y; // Place placePiece(draggingPiece, pos.q, pos.r); removePieceFromTray(draggingPiece); draggingPiece.destroy(); draggingPiece = null; // Check for matches and refill tray if all used checkAndPopMatches(); if (trayPieces.every(function (p) { return !p; })) { refillTray(); } // Check for game over if (!canAnyPieceBePlaced()) { LK.showGameOver(); } } else { // Return to tray (center to tray position) var trayIndex = -1; for (var i = 0; i < 3; ++i) { if (trayPieces[i] === draggingPiece) { trayIndex = i; break; } } var trayTargetX = trayX + (trayIndex - 1) * traySpacing; var trayTargetY = trayY; tween(draggingPiece, { x: trayTargetX, y: trayTargetY }, { duration: 200, easing: tween.easeOut }); draggingPiece.setValid(true); draggingPiece.dragging = false; draggingPiece = null; } }; // --- Line clearing logic --- // Find all full lines (horizontal or vertical), clear them, and chain function checkAndPopMatches() { var popped = false; var combos = 0; var linesToClear = []; // Helper: get all q/r/s values present on the board var qSet = {}; var rSet = {}; var sSet = {}; for (var i = 0; i < boardTiles.length; ++i) { var t = boardTiles[i]; qSet[t.q] = true; rSet[t.r] = true; sSet[-t.q - t.r] = true; } // Helper: get all tiles in a line (by q, r, or s) function getLineTiles(axis, value) { var arr = []; for (var i = 0; i < boardTiles.length; ++i) { var t = boardTiles[i]; if (axis === 'q' && t.q === value || axis === 'r' && t.r === value || axis === 's' && -t.q - t.r === value) { arr.push(t.tile); } } return arr; } // Check all q lines (vertical) for (var q in qSet) { var tiles = getLineTiles('q', parseInt(q)); if (tiles.length === 0) continue; var allOccupied = true; for (var i = 0; i < tiles.length; ++i) { if (!tiles[i].occupied) { allOccupied = false; break; } } if (allOccupied) { linesToClear.push(tiles); } } // Check all r lines (diagonal) for (var r in rSet) { var tiles = getLineTiles('r', parseInt(r)); if (tiles.length === 0) continue; var allOccupied = true; for (var i = 0; i < tiles.length; ++i) { if (!tiles[i].occupied) { allOccupied = false; break; } } if (allOccupied) { linesToClear.push(tiles); } } // Check all s lines (other diagonal) for (var s in sSet) { var tiles = getLineTiles('s', parseInt(s)); if (tiles.length === 0) continue; var allOccupied = true; for (var i = 0; i < tiles.length; ++i) { if (!tiles[i].occupied) { allOccupied = false; break; } } if (allOccupied) { linesToClear.push(tiles); } } // Remove duplicates (tiles may be in multiple lines) var clearedTiles = {}; for (var i = 0; i < linesToClear.length; ++i) { for (var j = 0; j < linesToClear[i].length; ++j) { clearedTiles[linesToClear[i][j].gridQ + ',' + linesToClear[i][j].gridR] = linesToClear[i][j]; } } var clearedArr = []; for (var k in clearedTiles) clearedArr.push(clearedTiles[k]); if (clearedArr.length > 0) { for (var i = 0; i < clearedArr.length; ++i) { clearedArr[i].pop(); } score += clearedArr.length; popped = true; combos = linesToClear.length; } if (popped) { scoreTxt.setText(score); if (combos > 1) { LK.getSound('combo').play(); } // Chain: after pop, check again after short delay LK.setTimeout(checkAndPopMatches, 400); } } // --- Can any piece be placed? --- function canAnyPieceBePlaced() { for (var i = 0; i < 3; ++i) { var piece = trayPieces[i]; if (!piece) continue; // Try all board positions for (var j = 0; j < boardTiles.length; ++j) { var q = boardTiles[j].q; var r = boardTiles[j].r; if (canPlacePiece(piece, q, r)) return true; } } return false; } // --- Game update (not used for now) --- game.update = function () { // No per-frame logic needed };
===================================================================
--- original.js
+++ change.js
@@ -82,34 +82,17 @@
y: 0,
scaleX: 0.7,
scaleY: 0.7
});
- face.visible = true; // Always show face when in tray or dragging
hex.addChild(face);
self.hexes.push(hex);
}
- // Compute geometric center of all hexes
- var minX = Infinity,
- maxX = -Infinity,
- minY = Infinity,
- maxY = -Infinity;
- var positions = [];
+ // Position hexes
for (var i = 0; i < shape.length; ++i) {
var pos = axialToPixel(shape[i].q, shape[i].r, pieceHexSize);
- positions.push(pos);
- if (pos.x < minX) minX = pos.x;
- if (pos.x > maxX) maxX = pos.x;
- if (pos.y < minY) minY = pos.y;
- if (pos.y > maxY) maxY = pos.y;
+ self.hexes[i].x = pos.x;
+ self.hexes[i].y = pos.y;
}
- // Center offset (geometric center)
- var centerX = (minX + maxX) / 2;
- var centerY = (minY + maxY) / 2;
- // Position hexes, centered
- for (var i = 0; i < shape.length; ++i) {
- self.hexes[i].x = positions[i].x - centerX;
- self.hexes[i].y = positions[i].y - centerY;
- }
};
// Highlight for valid/invalid placement
self.setValid = function (valid) {
self.valid = valid;
@@ -146,8 +129,10 @@
scaleY: 1,
alpha: 1
});
game.addChild(bgImg);
+// Play game music
+LK.playMusic('game_music2');
// --- Add dreamy cloud background ---
// Hex tile shapes (pastel colors)
// Cloud background (large, white, semi-transparent ellipses)
// Faces (as colored ellipses for now, can be replaced with images later)
@@ -520,14 +505,8 @@
}
};
game.move = function (x, y, obj) {
if (!draggingPiece) return;
- // Always show faces when dragging
- for (var i = 0; i < draggingPiece.hexes.length; ++i) {
- if (draggingPiece.hexes[i].children && draggingPiece.hexes[i].children.length > 0) {
- draggingPiece.hexes[i].children[0].visible = true;
- }
- }
// Move piece
draggingPiece.x = x - dragOffsetX;
draggingPiece.y = y - dragOffsetY;
// Snap to board if close
cloud. In-Game asset. 2d. High contrast. No shadows
cloud pink. In-Game asset. 2d. High contrast. No shadows
cloud orange. In-Game asset. 2d. High contrast. No shadows
cloud green. In-Game asset. 2d. High contrast. No shadows
cloud purple. In-Game asset. 2d. High contrast. No shadows
cloud yellow. In-Game asset. 2d. High contrast. No shadows
Background for relaxing puzzle game. In-Game asset. 2d. High contrast. No shadows
linear features cute face frameless. In-Game asset. 2d. High contrast. No shadows
White square with tight round corners, flat shaded, hyper casual game. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.. In-Game asset. 2d. High contrast. No shadows
White hexagon with tight round corners, flat shaded, hyper casual game. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.. In-Game asset. 2d. High contrast. No shadows