/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Tile class: represents a single tile on the board var Tile = Container.expand(function () { var self = Container.call(this); // Properties self.value = 0; // 0 means empty self.row = 0; self.col = 0; self.tileBG = null; self.tileText = null; // Set up tile self.setValue = function (val) { self.value = val; // Remove previous children if any if (self.tileBG) { self.removeChild(self.tileBG); self.tileBG = null; } if (self.tileText) { self.removeChild(self.tileText); self.tileText = null; } // Choose asset based on value var assetId = 'tile'; if (val === 0) { assetId = 'tileBG'; } else if (val === 2) { assetId = 'tile2'; } else if (val === 4) { assetId = 'tile4'; } else if (val === 8) { assetId = 'tile8'; } else if (val === 16) { assetId = 'tile16'; } else if (val === 32) { assetId = 'tile32'; } else if (val === 64) { assetId = 'tile64'; } else if (val === 128) { assetId = 'tile128'; } else if (val === 256) { assetId = 'tile256'; } else if (val === 512) { assetId = 'tile512'; } else if (val === 1024) { assetId = 'tile1024'; } else if (val === 2048) { assetId = 'tile2048'; } self.tileBG = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); if (val > 0) { var textColor = "#776e65"; if (val >= 8) textColor = "#f9f6f2"; self.tileText = new Text2(val + '', { size: 120, fill: textColor }); self.tileText.anchor.set(0.5, 0.5); self.addChild(self.tileText); } }; // Animate pop self.pop = function () { self.scaleX = 0.7; self.scaleY = 0.7; tween(self, { scaleX: 1, scaleY: 1 }, { duration: 120, easing: tween.easeOut }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0xfaf8ef }); /**** * Game Code ****/ // Tiles: We'll use colored boxes for tiles, and white for empty background. // Board constants var GRID_SIZE = 4; var TILE_SIZE = 400; var TILE_MARGIN = 20; var BOARD_SIZE = GRID_SIZE * TILE_SIZE + (GRID_SIZE + 1) * TILE_MARGIN; var BOARD_X = (2048 - BOARD_SIZE) / 2; var BOARD_Y = (2732 - BOARD_SIZE) / 2 + 100; // +100 to avoid top menu // Board background var boardBG = LK.getAsset('boardBG', { anchorX: 0, anchorY: 0, x: BOARD_X, y: BOARD_Y }); game.addChild(boardBG); // 2D array of tiles var tiles = []; // 2D array of tile values (for logic) var tileVals = []; // For swipe detection var touchStartX = 0, touchStartY = 0, touchEndX = 0, touchEndY = 0, isTouching = false; // Score var score = 0; var bestScore = 0; // Score text var scoreTxt = new Text2('0', { size: 120, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); scoreTxt.x = 2048 / 2; scoreTxt.y = 20; LK.gui.top.addChild(scoreTxt); // Best score text var bestScoreTxt = new Text2('BEST: 0', { size: 60, fill: 0xFFFFFF }); bestScoreTxt.anchor.set(0.5, 0); bestScoreTxt.x = 2048 / 2; bestScoreTxt.y = 150; LK.gui.top.addChild(bestScoreTxt); // Initialize board function initBoard() { // Remove old tiles if any for (var r = 0; r < GRID_SIZE; r++) { for (var c = 0; c < GRID_SIZE; c++) { if (tiles[r] && tiles[r][c]) { tiles[r][c].destroy(); } } } tiles = []; tileVals = []; for (var r = 0; r < GRID_SIZE; r++) { tiles[r] = []; tileVals[r] = []; for (var c = 0; c < GRID_SIZE; c++) { var tile = new Tile(); tile.row = r; tile.col = c; tile.setValue(0); // Position tile.x = BOARD_X + TILE_MARGIN + c * (TILE_SIZE + TILE_MARGIN) + TILE_SIZE / 2; tile.y = BOARD_Y + TILE_MARGIN + r * (TILE_SIZE + TILE_MARGIN) + TILE_SIZE / 2; tile.scaleX = 1; tile.scaleY = 1; game.addChild(tile); tiles[r][c] = tile; tileVals[r][c] = 0; } } score = 0; updateScore(); addRandomTile(); addRandomTile(); } // Add a random tile (2 or 4) to an empty spot function addRandomTile() { var empties = []; for (var r = 0; r < GRID_SIZE; r++) { for (var c = 0; c < GRID_SIZE; c++) { if (tileVals[r][c] === 0) { empties.push({ r: r, c: c }); } } } if (empties.length === 0) return; var idx = Math.floor(Math.random() * empties.length); var pos = empties[idx]; var val = Math.random() < 0.9 ? 2 : 4; tileVals[pos.r][pos.c] = val; tiles[pos.r][pos.c].setValue(val); tiles[pos.r][pos.c].pop(); } // Update all tile visuals from tileVals function updateTiles() { for (var r = 0; r < GRID_SIZE; r++) { for (var c = 0; c < GRID_SIZE; c++) { tiles[r][c].setValue(tileVals[r][c]); } } } // Update score display function updateScore() { scoreTxt.setText(score + ''); if (score > bestScore) { bestScore = score; } bestScoreTxt.setText('BEST: ' + bestScore); LK.setScore(score); } // Check if any moves are possible function canMove() { for (var r = 0; r < GRID_SIZE; r++) { for (var c = 0; c < GRID_SIZE; c++) { if (tileVals[r][c] === 0) return true; if (c < GRID_SIZE - 1 && tileVals[r][c] === tileVals[r][c + 1]) return true; if (r < GRID_SIZE - 1 && tileVals[r][c] === tileVals[r + 1][c]) return true; } } return false; } // Check if 2048 tile exists function has2048() { for (var r = 0; r < GRID_SIZE; r++) { for (var c = 0; c < GRID_SIZE; c++) { if (tileVals[r][c] === 2048) return true; } } return false; } // Move logic function move(direction) { // direction: 'left', 'right', 'up', 'down' var moved = false; var merged = []; for (var r = 0; r < GRID_SIZE; r++) { merged[r] = []; for (var c = 0; c < GRID_SIZE; c++) { merged[r][c] = false; } } var start, end, step; if (direction === 'left') { for (var r = 0; r < GRID_SIZE; r++) { for (var c = 1; c < GRID_SIZE; c++) { if (tileVals[r][c] === 0) continue; var target = c; while (target > 0 && tileVals[r][target - 1] === 0) { target--; } if (target > 0 && tileVals[r][target - 1] === tileVals[r][c] && !merged[r][target - 1]) { // Merge tileVals[r][target - 1] *= 2; score += tileVals[r][target - 1]; tileVals[r][c] = 0; merged[r][target - 1] = true; moved = true; tiles[r][target - 1].pop(); } else if (target !== c) { // Move tileVals[r][target] = tileVals[r][c]; tileVals[r][c] = 0; moved = true; } } } } else if (direction === 'right') { for (var r = 0; r < GRID_SIZE; r++) { for (var c = GRID_SIZE - 2; c >= 0; c--) { if (tileVals[r][c] === 0) continue; var target = c; while (target < GRID_SIZE - 1 && tileVals[r][target + 1] === 0) { target++; } if (target < GRID_SIZE - 1 && tileVals[r][target + 1] === tileVals[r][c] && !merged[r][target + 1]) { // Merge tileVals[r][target + 1] *= 2; score += tileVals[r][target + 1]; tileVals[r][c] = 0; merged[r][target + 1] = true; moved = true; tiles[r][target + 1].pop(); } else if (target !== c) { // Move tileVals[r][target] = tileVals[r][c]; tileVals[r][c] = 0; moved = true; } } } } else if (direction === 'up') { for (var c = 0; c < GRID_SIZE; c++) { for (var r = 1; r < GRID_SIZE; r++) { if (tileVals[r][c] === 0) continue; var target = r; while (target > 0 && tileVals[target - 1][c] === 0) { target--; } if (target > 0 && tileVals[target - 1][c] === tileVals[r][c] && !merged[target - 1][c]) { // Merge tileVals[target - 1][c] *= 2; score += tileVals[target - 1][c]; tileVals[r][c] = 0; merged[target - 1][c] = true; moved = true; tiles[target - 1][c].pop(); } else if (target !== r) { // Move tileVals[target][c] = tileVals[r][c]; tileVals[r][c] = 0; moved = true; } } } } else if (direction === 'down') { for (var c = 0; c < GRID_SIZE; c++) { for (var r = GRID_SIZE - 2; r >= 0; r--) { if (tileVals[r][c] === 0) continue; var target = r; while (target < GRID_SIZE - 1 && tileVals[target + 1][c] === 0) { target++; } if (target < GRID_SIZE - 1 && tileVals[target + 1][c] === tileVals[r][c] && !merged[target + 1][c]) { // Merge tileVals[target + 1][c] *= 2; score += tileVals[target + 1][c]; tileVals[r][c] = 0; merged[target + 1][c] = true; moved = true; tiles[target + 1][c].pop(); } else if (target !== r) { // Move tileVals[target][c] = tileVals[r][c]; tileVals[r][c] = 0; moved = true; } } } } if (moved) { addRandomTile(); updateTiles(); updateScore(); if (has2048()) { LK.showYouWin(); } else if (!canMove()) { LK.effects.flashScreen(0xff0000, 1000); LK.showGameOver(); } } } // Touch/drag/swipe handling game.down = function (x, y, obj) { // Only start if inside board area if (x >= BOARD_X && x <= BOARD_X + BOARD_SIZE && y >= BOARD_Y && y <= BOARD_Y + BOARD_SIZE) { touchStartX = x; touchStartY = y; isTouching = true; } }; game.move = function (x, y, obj) { if (!isTouching) return; touchEndX = x; touchEndY = y; }; game.up = function (x, y, obj) { if (!isTouching) return; var dx = touchEndX - touchStartX; var dy = touchEndY - touchStartY; var absDx = Math.abs(dx); var absDy = Math.abs(dy); if (absDx > 50 || absDy > 50) { if (absDx > absDy) { if (dx > 0) { move('right'); } else { move('left'); } } else { if (dy > 0) { move('down'); } else { move('up'); } } } isTouching = false; touchStartX = 0; touchStartY = 0; touchEndX = 0; touchEndY = 0; }; // Reset game on game over or win game.on('reset', function () { initBoard(); }); // Initialize initBoard();
===================================================================
--- original.js
+++ change.js
@@ -125,25 +125,23 @@
var bestScore = 0;
// Score text
var scoreTxt = new Text2('0', {
size: 120,
- fill: 0xBBADA0
+ fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
+scoreTxt.x = 2048 / 2;
+scoreTxt.y = 20;
LK.gui.top.addChild(scoreTxt);
// Best score text
var bestScoreTxt = new Text2('BEST: 0', {
size: 60,
- fill: 0xBBADA0
+ fill: 0xFFFFFF
});
bestScoreTxt.anchor.set(0.5, 0);
-LK.gui.top.addChild(bestScoreTxt);
-bestScoreTxt.y = 130;
-// Position GUI elements
-scoreTxt.x = 2048 / 2;
-scoreTxt.y = 20;
bestScoreTxt.x = 2048 / 2;
bestScoreTxt.y = 150;
+LK.gui.top.addChild(bestScoreTxt);
// Initialize board
function initBoard() {
// Remove old tiles if any
for (var r = 0; r < GRID_SIZE; r++) {