User prompt
Add animation to the face of the fruits ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Let the grill be black
User prompt
Put the grill in the box
User prompt
Let it be a little more clear, the grill color should not cover the outer edges.
User prompt
Please fix the bug: 'null is not an object (evaluating 't.length')' in or related to this line: 'var lineAsset = LK.getAsset(null, {' Line Number: 348
User prompt
Add a transparent grill in gray among the fruits
User prompt
Let it all be different explosion animation ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Show the explosion effect
User prompt
Please fix the bug: 'TypeError: null is not an object (evaluating 'tile.destroy')' in or related to this line: 'tile.destroy();' Line Number: 505
User prompt
When combined, let the fruits explode ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Let them all have different dance animations ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Add dancing animation to fruits ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Remove the names from the fruits
User prompt
Make the background white and make it a little bigger
User prompt
Remove the transparent fruits on the back
User prompt
Make the theme fruits
User prompt
Please fix the bug: 'LK.hasAsset is not a function. (In 'LK.hasAsset(assetId)', 'LK.hasAsset' is undefined)' in or related to this line: 'if (!LK.hasAsset(assetId)) {' Line Number: 43
Code edit (1 edits merged)
Please save this source code
User prompt
Galactic 2048: Space Merge
Initial prompt
Space themed 2048 game
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Tile class for each grid cell var Tile = Container.expand(function () { var self = Container.call(this); // Properties self.value = 2; // Default value self.row = 0; self.col = 0; self.asset = null; self.text = null; // Set tile value and update appearance self.setValue = function (val) { self.value = val; // Remove old asset if exists if (self.asset) { self.removeChild(self.asset); } // Choose asset by value var assetId = 'tile' + val; var supportedAssets = { 'tile2': true, 'tile4': true, 'tile8': true, 'tile16': true, 'tile32': true, 'tile64': true, 'tile128': true, 'tile256': true, 'tile512': true, 'tile1024': true, 'tile2048': true }; if (!supportedAssets[assetId]) assetId = 'tile2048'; // fallback self.asset = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); // Animate the face of the fruit (asset) with a playful scale and rotation tween if (self.asset) { var faceDanceUp = function faceDanceUp() { tween(self.asset, { scaleX: anim.sx, scaleY: anim.sy, rotation: anim.rot }, { duration: anim.dur, easing: anim.ease, onFinish: faceDanceDown }); }; var faceDanceDown = function faceDanceDown() { tween(self.asset, { scaleX: 1, scaleY: 1, rotation: 0 }, { duration: anim.dur, easing: anim.ease, onFinish: faceDanceUp }); }; // Cancel any previous tweens on the asset's scale/rotation tween.stop(self.asset, { scaleX: true, scaleY: true, rotation: true }); // Pick a unique animation per value var faceAnims = { 2: { sx: 1.08, sy: 0.92, rot: 0.08, dur: 320, ease: tween.sineInOut }, 4: { sx: 1.12, sy: 0.88, rot: -0.10, dur: 340, ease: tween.bounceIn }, 8: { sx: 0.95, sy: 1.10, rot: 0.13, dur: 300, ease: tween.elasticIn }, 16: { sx: 1.15, sy: 0.85, rot: -0.12, dur: 280, ease: tween.cubicOut }, 32: { sx: 1.10, sy: 1.10, rot: 0.10, dur: 350, ease: tween.quarticInOut }, 64: { sx: 1.18, sy: 0.95, rot: -0.15, dur: 320, ease: tween.sineOut }, 128: { sx: 0.92, sy: 1.12, rot: 0.16, dur: 370, ease: tween.elasticInOut }, 256: { sx: 1.20, sy: 0.80, rot: -0.18, dur: 300, ease: tween.bounceOut }, 512: { sx: 1.10, sy: 1.05, rot: 0.12, dur: 340, ease: tween.cubicIn }, 1024: { sx: 1.22, sy: 0.92, rot: -0.20, dur: 360, ease: tween.quinticIn }, 2048: { sx: 1.30, sy: 0.70, rot: 0.22, dur: 400, ease: tween.expoIn } }; var anim = faceAnims[self.value] || faceAnims[2]; faceDanceUp(); } // Remove old text if exists if (self.text) { self.removeChild(self.text); } // Add value text (empty label, no fruit names) var label = ''; self.text = new Text2(label, { size: 60, fill: 0xFFFFFF, align: "center" }); self.text.anchor.set(0.5, 0.5); self.text.y = 0; self.text.x = 0; self.addChild(self.text); // Restart dancing after value change if (self.startDancing) self.startDancing(); }; // Animate merge self.animateMerge = function () { tween(self, { scaleX: 1.2, scaleY: 1.2 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 100, easing: tween.easeIn, onFinish: function onFinish() { if (self.startDancing) self.startDancing(); } }); } }); }; // Animate spawn self.animateSpawn = function () { self.scaleX = 0.2; self.scaleY = 0.2; tween(self, { scaleX: 1, scaleY: 1 }, { duration: 150, easing: tween.easeOut, onFinish: function onFinish() { if (self.startDancing) self.startDancing(); } }); }; // Set position on grid self.setGridPos = function (row, col, cellSize, gridX, gridY) { self.row = row; self.col = col; self.x = gridX + col * cellSize + cellSize / 2; self.y = gridY + row * cellSize + cellSize / 2; }; // Add dancing animation (continuous, unique per value) self.startDancing = function () { // Cancel any previous tweens on scale tween.stop(self, { scaleX: true, scaleY: true }); // Unique dance parameters per value var dances = { 2: { sx1: 1.10, sy1: 0.90, sx2: 0.90, sy2: 1.10, dur1: 220, dur2: 220, ease1: tween.easeInOut, ease2: tween.easeInOut }, 4: { sx1: 1.15, sy1: 0.85, sx2: 0.85, sy2: 1.15, dur1: 180, dur2: 180, ease1: tween.bounceIn, ease2: tween.bounceOut }, 8: { sx1: 1.08, sy1: 1.08, sx2: 0.92, sy2: 0.92, dur1: 260, dur2: 260, ease1: tween.elasticIn, ease2: tween.elasticOut }, 16: { sx1: 1.20, sy1: 0.80, sx2: 0.80, sy2: 1.20, dur1: 150, dur2: 150, ease1: tween.cubicOut, ease2: tween.cubicIn }, 32: { sx1: 1.05, sy1: 1.15, sx2: 1.15, sy2: 1.05, dur1: 200, dur2: 200, ease1: tween.quarticInOut, ease2: tween.quarticInOut }, 64: { sx1: 1.18, sy1: 0.95, sx2: 0.95, sy2: 1.18, dur1: 170, dur2: 170, ease1: tween.sineIn, ease2: tween.sineOut }, 128: { sx1: 1.12, sy1: 1.12, sx2: 0.88, sy2: 0.88, dur1: 250, dur2: 250, ease1: tween.elasticInOut, ease2: tween.elasticInOut }, 256: { sx1: 1.25, sy1: 0.75, sx2: 0.75, sy2: 1.25, dur1: 140, dur2: 140, ease1: tween.bounceOut, ease2: tween.bounceIn }, 512: { sx1: 1.10, sy1: 1.05, sx2: 1.05, sy2: 1.10, dur1: 210, dur2: 210, ease1: tween.cubicIn, ease2: tween.cubicOut }, 1024: { sx1: 1.22, sy1: 0.92, sx2: 0.92, sy2: 1.22, dur1: 160, dur2: 160, ease1: tween.quinticIn, ease2: tween.quinticOut }, 2048: { sx1: 1.30, sy1: 0.70, sx2: 0.70, sy2: 1.30, dur1: 120, dur2: 120, ease1: tween.expoIn, ease2: tween.expoOut } }; var dance = dances[self.value] || dances[2]; function danceUp() { tween(self, { scaleX: dance.sx1, scaleY: dance.sy1 }, { duration: dance.dur1, easing: dance.ease1, onFinish: function onFinish() { danceDown(); } }); } function danceDown() { tween(self, { scaleX: dance.sx2, scaleY: dance.sy2 }, { duration: dance.dur2, easing: dance.ease2, onFinish: function onFinish() { danceUp(); } }); } // Start the loop danceUp(); }; // Stop dancing animation self.stopDancing = function () { tween.stop(self, { scaleX: true, scaleY: true }); self.scaleX = 1; self.scaleY = 1; }; // Start dancing by default self.startDancing(); return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0xffffff }); /**** * Game Code ****/ // Optionally, a subtle grid background // 2: Asteroid (gray), 4: Moon (light blue), 8: Planet (blue), 16: Star (yellow), 32: Red Giant (red), 64: Neutron Star (purple), 128: Black Hole (black), 256: Nebula (pink), 512: Galaxy (cyan), 1024: Quasar (orange), 2048: Universe (white) // Space tile assets: We'll use colored ellipses for different tile values // --- Grid and Layout --- var gridSize = 4; var cellSize = 370; // 370*4=1480, bigger board var gridPadding = 28; var gridWidth = cellSize * gridSize + gridPadding * (gridSize + 1); var gridHeight = cellSize * gridSize + gridPadding * (gridSize + 1); var gridX = Math.floor((2048 - gridWidth) / 2); var gridY = Math.floor((2732 - gridHeight) / 2); // --- Game State --- var grid = []; // 2D array of tiles or null var tiles = []; // All tile objects for easy management var score = 0; var scoreTxt = null; var isMoving = false; // Prevent input during animation // --- GUI: Score --- scoreTxt = new Text2('0', { size: 120, fill: "#fff" }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // --- Draw grid background --- var gridBg = LK.getAsset('gridBg', { anchorX: 0, anchorY: 0, x: gridX, y: gridY, width: gridWidth, height: gridHeight }); game.addChild(gridBg); // --- Draw transparent gray grill overlay --- var grillContainer = new Container(); var grillLineColor = 0x000000; var grillAlpha = 0.25; var grillLineWidth = 12; // The grill lines should not cover the outer grid edges, so lines are drawn only between cells // The vertical lines go from the top inner padding to the bottom inner padding var grillInnerHeight = cellSize * gridSize + gridPadding * (gridSize - 1); var grillInnerWidth = cellSize * gridSize + gridPadding * (gridSize - 1); // Vertical lines (between columns, not at the very left/right) for (var c = 1; c < gridSize; c++) { var x = gridX + gridPadding + c * cellSize + (c - 0.5) * gridPadding; var lineAsset = LK.getAsset('shape', { width: grillLineWidth, height: grillInnerHeight, color: grillLineColor, shape: 'box', anchorX: 0.5, anchorY: 0, alpha: grillAlpha, x: x, y: gridY + gridPadding }); grillContainer.addChild(lineAsset); } // Horizontal lines (between rows, not at the very top/bottom) for (var r = 1; r < gridSize; r++) { var y = gridY + gridPadding + r * cellSize + (r - 0.5) * gridPadding; var lineAsset = LK.getAsset('shape', { width: grillInnerWidth, height: grillLineWidth, color: grillLineColor, shape: 'box', anchorX: 0, anchorY: 0.5, alpha: grillAlpha, x: gridX + gridPadding, y: y }); grillContainer.addChild(lineAsset); } game.addChild(grillContainer); // --- Draw grid cell backgrounds --- // (Removed transparent fruit tiles on the back) // --- Initialize grid state --- function resetGrid() { grid = []; for (var r = 0; r < gridSize; r++) { var row = []; for (var c = 0; c < gridSize; c++) { row.push(null); } grid.push(row); } // Remove all tiles from game for (var i = 0; i < tiles.length; i++) { tiles[i].destroy(); } tiles = []; score = 0; scoreTxt.setText(score); } // --- Add a new tile (2 or 4) at random empty position --- function addRandomTile() { var empties = []; for (var r = 0; r < gridSize; r++) { for (var c = 0; c < gridSize; c++) { if (!grid[r][c]) empties.push({ r: r, c: c }); } } if (empties.length === 0) return false; var idx = Math.floor(Math.random() * empties.length); var pos = empties[idx]; var val = Math.random() < 0.9 ? 2 : 4; var tile = new Tile(); tile.setValue(val); tile.setGridPos(pos.r, pos.c, cellSize, gridX + gridPadding, gridY + gridPadding); tile.animateSpawn(); grid[pos.r][pos.c] = tile; tiles.push(tile); game.addChild(tile); return true; } // --- Move/merge logic --- function canMove() { // Check for any empty cell for (var r = 0; r < gridSize; r++) { for (var c = 0; c < gridSize; c++) { if (!grid[r][c]) return true; } } // Check for any mergeable neighbor for (var r = 0; r < gridSize; r++) { for (var c = 0; c < gridSize; c++) { var tile = grid[r][c]; if (!tile) continue; // Right if (c + 1 < gridSize && grid[r][c + 1] && grid[r][c + 1].value === tile.value) return true; // Down if (r + 1 < gridSize && grid[r + 1][c] && grid[r + 1][c].value === tile.value) return true; } } return false; } // Returns true if any tile reached 2048 function has2048() { for (var r = 0; r < gridSize; r++) { for (var c = 0; c < gridSize; c++) { if (grid[r][c] && grid[r][c].value === 2048) return true; } } return false; } // Move tiles in a direction: 'up', 'down', 'left', 'right' function moveTiles(dir) { if (isMoving) return; isMoving = true; var moved = false; var mergedThisMove = []; // Helper to reset merged flags function resetMerged() { for (var i = 0; i < tiles.length; i++) { tiles[i].merged = false; } } resetMerged(); // For each direction, set up iteration order var startR = 0, endR = gridSize, stepR = 1; var startC = 0, endC = gridSize, stepC = 1; if (dir === 'up') { startR = 1; endR = gridSize; stepR = 1; } if (dir === 'down') { startR = gridSize - 2; endR = -1; stepR = -1; } if (dir === 'left') { startC = 1; endC = gridSize; stepC = 1; } if (dir === 'right') { startC = gridSize - 2; endC = -1; stepC = -1; } // Move/merge logic var movedTiles = []; if (dir === 'up' || dir === 'down') { for (var c = 0; c < gridSize; c++) { for (var r = startR; r != endR; r += stepR) { var tile = grid[r][c]; if (!tile) continue; var tr = r; while (true) { var nr = tr + (dir === 'up' ? -1 : 1); if (nr < 0 || nr >= gridSize) break; if (!grid[nr][c]) { // Move grid[nr][c] = tile; grid[tr][c] = null; tr = nr; moved = true; } else if (grid[nr][c].value === tile.value && !grid[nr][c].merged && !tile.merged) { // Merge grid[nr][c].setValue(tile.value * 2); grid[nr][c].animateMerge(); grid[nr][c].merged = true; score += tile.value * 2; scoreTxt.setText(score); // Explode animation for merged tile tile.stopDancing && tile.stopDancing(); // Show explosion effect // Unique explosion animation per value var explosionAnims = { 2: { scale: 1.6, alpha: 0, duration: 180, easing: tween.bounceOut, tint: 0xE0E0E0 }, 4: { scale: 2.0, alpha: 0, duration: 220, easing: tween.elasticOut, tint: 0xB0E0FF }, 8: { scale: 1.7, alpha: 0, duration: 200, easing: tween.cubicOut, tint: 0x6CA0FF }, 16: { scale: 2.2, alpha: 0, duration: 240, easing: tween.quarticInOut, tint: 0xFFF700 }, 32: { scale: 1.9, alpha: 0, duration: 210, easing: tween.sineOut, tint: 0xFF3A3A }, 64: { scale: 2.3, alpha: 0, duration: 250, easing: tween.elasticInOut, tint: 0xB000FF }, 128: { scale: 2.0, alpha: 0, duration: 230, easing: tween.bounceIn, tint: 0x000000 }, 256: { scale: 2.5, alpha: 0, duration: 260, easing: tween.cubicIn, tint: 0xFF7EB9 }, 512: { scale: 2.1, alpha: 0, duration: 200, easing: tween.quinticOut, tint: 0x00FFF7 }, 1024: { scale: 2.4, alpha: 0, duration: 270, easing: tween.expoIn, tint: 0xFFB84C }, 2048: { scale: 2.8, alpha: 0, duration: 300, easing: tween.expoOut, tint: 0xFFFFFF } }; var exp = explosionAnims[tile.value] || explosionAnims[2]; LK.effects.flashObject(tile, exp.tint, Math.min(180, exp.duration)); tween(tile, { scaleX: exp.scale, scaleY: exp.scale, alpha: exp.alpha }, { duration: exp.duration, easing: exp.easing, onFinish: function onFinish() { if (tile && typeof tile.destroy === "function") { tile.destroy(); } } }); tiles.splice(tiles.indexOf(tile), 1); grid[tr][c] = null; moved = true; break; } else { break; } } // Animate move if (tile && tr !== r) { tile.setGridPos(tr, c, cellSize, gridX + gridPadding, gridY + gridPadding); movedTiles.push(tile); } } } } else { for (var r = 0; r < gridSize; r++) { for (var c = startC; c != endC; c += stepC) { var tile = grid[r][c]; if (!tile) continue; var tc = c; while (true) { var nc = tc + (dir === 'left' ? -1 : 1); if (nc < 0 || nc >= gridSize) break; if (!grid[r][nc]) { // Move grid[r][nc] = tile; grid[r][tc] = null; tc = nc; moved = true; } else if (grid[r][nc].value === tile.value && !grid[r][nc].merged && !tile.merged) { // Merge grid[r][nc].setValue(tile.value * 2); grid[r][nc].animateMerge(); grid[r][nc].merged = true; score += tile.value * 2; scoreTxt.setText(score); // Explode animation for merged tile tile.stopDancing && tile.stopDancing(); // Show explosion effect // Unique explosion animation per value var explosionAnims = { 2: { scale: 1.6, alpha: 0, duration: 180, easing: tween.bounceOut, tint: 0xE0E0E0 }, 4: { scale: 2.0, alpha: 0, duration: 220, easing: tween.elasticOut, tint: 0xB0E0FF }, 8: { scale: 1.7, alpha: 0, duration: 200, easing: tween.cubicOut, tint: 0x6CA0FF }, 16: { scale: 2.2, alpha: 0, duration: 240, easing: tween.quarticInOut, tint: 0xFFF700 }, 32: { scale: 1.9, alpha: 0, duration: 210, easing: tween.sineOut, tint: 0xFF3A3A }, 64: { scale: 2.3, alpha: 0, duration: 250, easing: tween.elasticInOut, tint: 0xB000FF }, 128: { scale: 2.0, alpha: 0, duration: 230, easing: tween.bounceIn, tint: 0x000000 }, 256: { scale: 2.5, alpha: 0, duration: 260, easing: tween.cubicIn, tint: 0xFF7EB9 }, 512: { scale: 2.1, alpha: 0, duration: 200, easing: tween.quinticOut, tint: 0x00FFF7 }, 1024: { scale: 2.4, alpha: 0, duration: 270, easing: tween.expoIn, tint: 0xFFB84C }, 2048: { scale: 2.8, alpha: 0, duration: 300, easing: tween.expoOut, tint: 0xFFFFFF } }; var exp = explosionAnims[tile.value] || explosionAnims[2]; LK.effects.flashObject(tile, exp.tint, Math.min(180, exp.duration)); tween(tile, { scaleX: exp.scale, scaleY: exp.scale, alpha: exp.alpha }, { duration: exp.duration, easing: exp.easing, onFinish: function onFinish() { if (tile && typeof tile.destroy === "function") { tile.destroy(); } } }); tiles.splice(tiles.indexOf(tile), 1); grid[r][tc] = null; moved = true; break; } else { break; } } // Animate move if (tile && tc !== c) { tile.setGridPos(r, tc, cellSize, gridX + gridPadding, gridY + gridPadding); movedTiles.push(tile); } } } } // Animate all moved tiles var animCount = movedTiles.length; if (animCount === 0) { isMoving = false; afterMove(moved); } else { for (var i = 0; i < movedTiles.length; i++) { var t = movedTiles[i]; tween(t, { x: t.x, y: t.y }, { duration: 100, easing: tween.easeInOut, onFinish: function onFinish() { animCount--; if (animCount === 0) { isMoving = false; afterMove(moved); } } }); } } if (animCount === 0) { // No animation, call afterMove immediately afterMove(moved); } } // After move: add new tile, check win/lose function afterMove(moved) { if (moved) { addRandomTile(); } if (has2048()) { LK.showYouWin(); return; } if (!canMove()) { LK.showGameOver(); return; } } // --- Input: Swipe detection --- // We'll use game.down, game.move, game.up to detect swipe direction var touchStartX = 0, touchStartY = 0, touchMoved = false; game.down = function (x, y, obj) { if (isMoving) return; touchStartX = x; touchStartY = y; touchMoved = false; }; game.move = function (x, y, obj) { if (isMoving) return; if (touchStartX === undefined) return; var dx = x - touchStartX; var dy = y - touchStartY; if (!touchMoved && (Math.abs(dx) > 40 || Math.abs(dy) > 40)) { touchMoved = true; // Determine direction if (Math.abs(dx) > Math.abs(dy)) { if (dx > 0) moveTiles('right');else moveTiles('left'); } else { if (dy > 0) moveTiles('down');else moveTiles('up'); } // Reset to prevent multiple moves per swipe touchStartX = undefined; touchStartY = undefined; } }; game.up = function (x, y, obj) { touchStartX = undefined; touchStartY = undefined; touchMoved = false; }; // --- Game update (not used, but required for tick-based games) --- game.update = function () { // No per-frame logic needed }; // --- Start game --- function startGame() { resetGrid(); addRandomTile(); addRandomTile(); scoreTxt.setText(score); } startGame();
===================================================================
--- original.js
+++ change.js
@@ -41,8 +41,121 @@
self.asset = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
+ // Animate the face of the fruit (asset) with a playful scale and rotation tween
+ if (self.asset) {
+ var faceDanceUp = function faceDanceUp() {
+ tween(self.asset, {
+ scaleX: anim.sx,
+ scaleY: anim.sy,
+ rotation: anim.rot
+ }, {
+ duration: anim.dur,
+ easing: anim.ease,
+ onFinish: faceDanceDown
+ });
+ };
+ var faceDanceDown = function faceDanceDown() {
+ tween(self.asset, {
+ scaleX: 1,
+ scaleY: 1,
+ rotation: 0
+ }, {
+ duration: anim.dur,
+ easing: anim.ease,
+ onFinish: faceDanceUp
+ });
+ };
+ // Cancel any previous tweens on the asset's scale/rotation
+ tween.stop(self.asset, {
+ scaleX: true,
+ scaleY: true,
+ rotation: true
+ });
+ // Pick a unique animation per value
+ var faceAnims = {
+ 2: {
+ sx: 1.08,
+ sy: 0.92,
+ rot: 0.08,
+ dur: 320,
+ ease: tween.sineInOut
+ },
+ 4: {
+ sx: 1.12,
+ sy: 0.88,
+ rot: -0.10,
+ dur: 340,
+ ease: tween.bounceIn
+ },
+ 8: {
+ sx: 0.95,
+ sy: 1.10,
+ rot: 0.13,
+ dur: 300,
+ ease: tween.elasticIn
+ },
+ 16: {
+ sx: 1.15,
+ sy: 0.85,
+ rot: -0.12,
+ dur: 280,
+ ease: tween.cubicOut
+ },
+ 32: {
+ sx: 1.10,
+ sy: 1.10,
+ rot: 0.10,
+ dur: 350,
+ ease: tween.quarticInOut
+ },
+ 64: {
+ sx: 1.18,
+ sy: 0.95,
+ rot: -0.15,
+ dur: 320,
+ ease: tween.sineOut
+ },
+ 128: {
+ sx: 0.92,
+ sy: 1.12,
+ rot: 0.16,
+ dur: 370,
+ ease: tween.elasticInOut
+ },
+ 256: {
+ sx: 1.20,
+ sy: 0.80,
+ rot: -0.18,
+ dur: 300,
+ ease: tween.bounceOut
+ },
+ 512: {
+ sx: 1.10,
+ sy: 1.05,
+ rot: 0.12,
+ dur: 340,
+ ease: tween.cubicIn
+ },
+ 1024: {
+ sx: 1.22,
+ sy: 0.92,
+ rot: -0.20,
+ dur: 360,
+ ease: tween.quinticIn
+ },
+ 2048: {
+ sx: 1.30,
+ sy: 0.70,
+ rot: 0.22,
+ dur: 400,
+ ease: tween.expoIn
+ }
+ };
+ var anim = faceAnims[self.value] || faceAnims[2];
+ faceDanceUp();
+ }
// Remove old text if exists
if (self.text) {
self.removeChild(self.text);
}
@@ -275,12 +388,12 @@
/****
* Game Code
****/
-// --- Grid and Layout ---
-// Space tile assets: We'll use colored ellipses for different tile values
-// 2: Asteroid (gray), 4: Moon (light blue), 8: Planet (blue), 16: Star (yellow), 32: Red Giant (red), 64: Neutron Star (purple), 128: Black Hole (black), 256: Nebula (pink), 512: Galaxy (cyan), 1024: Quasar (orange), 2048: Universe (white)
// Optionally, a subtle grid background
+// 2: Asteroid (gray), 4: Moon (light blue), 8: Planet (blue), 16: Star (yellow), 32: Red Giant (red), 64: Neutron Star (purple), 128: Black Hole (black), 256: Nebula (pink), 512: Galaxy (cyan), 1024: Quasar (orange), 2048: Universe (white)
+// Space tile assets: We'll use colored ellipses for different tile values
+// --- Grid and Layout ---
var gridSize = 4;
var cellSize = 370; // 370*4=1480, bigger board
var gridPadding = 28;
var gridWidth = cellSize * gridSize + gridPadding * (gridSize + 1);
Furit King!. In-Game asset. 2d. High contrast. No shadows
Orange with face. In-Game asset. 2d. High contrast. No shadows
Cherry with face. In-Game asset. 2d. High contrast. No shadows
Grape with face. In-Game asset. 2d. High contrast. No shadows
Lemon with face. In-Game asset. 2d. High contrast. No shadows
Pear with face. In-Game asset. 2d. High contrast. No shadows
Mango with face. In-Game asset. 2d. High contrast. No shadows
Apple with face. In-Game asset. 2d. High contrast. No shadows
Watermelon with face. In-Game asset. 2d. High contrast. No shadows
Strawberry with face. In-Game asset. 2d. High contrast. No shadows
Banana with face. In-Game asset. 2d. High contrast. No shadows
Let the clouds in the back move. In-Game asset. 2d. High contrast. No shadows