/****
* 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();
// Play background music
LK.playMusic('arkaplan'); ===================================================================
--- original.js
+++ change.js
@@ -400,5 +400,7 @@
game.on('reset', function () {
initBoard();
});
// Initialize
-initBoard();
\ No newline at end of file
+initBoard();
+// Play background music
+LK.playMusic('arkaplan');
\ No newline at end of file