Code edit (1 edits merged)
Please save this source code
User prompt
her geçişte 1 blok oluşturulsun
User prompt
tüm ekranı kaplasın
User prompt
biraz daha büyük
User prompt
biraz ddaha büyüt
Code edit (1 edits merged)
Please save this source code
User prompt
2048 Challenge
Initial prompt
bana bir 2048 oyunu yap
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
highScore: 0
});
/****
* Classes
****/
var Grid = Container.expand(function (size) {
var self = Container.call(this);
self.size = size || 4;
self.tileSize = 120;
self.spacing = 15;
self.width = self.size * self.tileSize + (self.size + 1) * self.spacing;
self.height = self.size * self.tileSize + (self.size + 1) * self.spacing;
// The grid of tiles
self.tiles = [];
// Keep track of tile positions for animations
self.positions = [];
// Initialize the grid background
var background = self.attachAsset('emptyTile', {
anchorX: 0,
anchorY: 0,
width: self.width,
height: self.height
});
background.tint = 0xBBADA0;
// Create empty cells
self.createEmptyCells = function () {
for (var y = 0; y < self.size; y++) {
for (var x = 0; x < self.size; x++) {
var posX = x * (self.tileSize + self.spacing) + self.spacing;
var posY = y * (self.tileSize + self.spacing) + self.spacing;
var emptyCell = LK.getAsset('emptyTile', {
anchorX: 0,
anchorY: 0,
width: self.tileSize,
height: self.tileSize,
x: posX,
y: posY
});
self.addChild(emptyCell);
}
}
};
// Initialize the tiles array
self.initializeTiles = function () {
self.tiles = [];
for (var y = 0; y < self.size; y++) {
self.tiles[y] = [];
for (var x = 0; x < self.size; x++) {
self.tiles[y][x] = null;
}
}
};
// Get position for a tile at grid coordinates
self.getPositionForTile = function (x, y) {
return {
x: x * (self.tileSize + self.spacing) + self.spacing + self.tileSize / 2,
y: y * (self.tileSize + self.spacing) + self.spacing + self.tileSize / 2
};
};
// Add a new tile to the grid
self.addTile = function (x, y, value) {
var tile = new Tile(value);
var position = self.getPositionForTile(x, y);
tile.x = position.x;
tile.y = position.y;
self.tiles[y][x] = tile;
self.addChild(tile);
return tile;
};
// Add a random tile to the grid
self.addRandomTile = function () {
var emptyCells = [];
// Find all empty cells
for (var y = 0; y < self.size; y++) {
for (var x = 0; x < self.size; x++) {
if (!self.tiles[y][x]) {
emptyCells.push({
x: x,
y: y
});
}
}
}
// If there are no empty cells, return
if (emptyCells.length === 0) {
return null;
}
// Choose a random empty cell
var randomCell = emptyCells[Math.floor(Math.random() * emptyCells.length)];
// 90% chance of 2, 10% chance of 4
var value = Math.random() < 0.9 ? 2 : 4;
// Add the new tile and animate it appearing
var tile = self.addTile(randomCell.x, randomCell.y, value);
tile.appear();
return tile;
};
// Move tiles in a specific direction
self.moveTiles = function (direction, callback) {
var moved = false;
var score = 0;
// Save positions before moving for animations
self.saveTilePositions();
// Reset merged status for all tiles
self.resetMergedStatus();
switch (direction) {
case "up":
for (var x = 0; x < self.size; x++) {
for (var y = 1; y < self.size; y++) {
if (self.tiles[y][x]) {
var result = self.moveTileInDirection(x, y, 0, -1);
moved = moved || result.moved;
score += result.score;
}
}
}
break;
case "right":
for (var y = 0; y < self.size; y++) {
for (var x = self.size - 2; x >= 0; x--) {
if (self.tiles[y][x]) {
var result = self.moveTileInDirection(x, y, 1, 0);
moved = moved || result.moved;
score += result.score;
}
}
}
break;
case "down":
for (var x = 0; x < self.size; x++) {
for (var y = self.size - 2; y >= 0; y--) {
if (self.tiles[y][x]) {
var result = self.moveTileInDirection(x, y, 0, 1);
moved = moved || result.moved;
score += result.score;
}
}
}
break;
case "left":
for (var y = 0; y < self.size; y++) {
for (var x = 1; x < self.size; x++) {
if (self.tiles[y][x]) {
var result = self.moveTileInDirection(x, y, -1, 0);
moved = moved || result.moved;
score += result.score;
}
}
}
break;
}
// Animate tile movements
self.animateTileMovements(function () {
if (callback) {
callback(moved, score);
}
});
return {
moved: moved,
score: score
};
};
// Move a single tile in the specified direction
self.moveTileInDirection = function (x, y, dx, dy) {
var tile = self.tiles[y][x];
var result = {
moved: false,
score: 0
};
if (!tile) {
return result;
}
var nextX = x + dx;
var nextY = y + dy;
// Keep moving while in bounds and either finding empty space or matching tile
while (self.isWithinBounds(nextX, nextY) && (self.tiles[nextY][nextX] === null || self.tiles[nextY][nextX].value === tile.value && !self.tiles[nextY][nextX].merged)) {
// Move tile
self.tiles[y][x] = null;
// Check if we can merge
if (self.tiles[nextY][nextX] !== null) {
// Merge tiles
var mergeValue = tile.value * 2;
self.tiles[nextY][nextX].value = mergeValue;
self.tiles[nextY][nextX].merged = true;
self.tiles[nextY][nextX].updateAppearance();
// Remove the merged tile
self.removeChild(tile);
result.score = mergeValue;
result.moved = true;
break;
} else {
// Move tile to empty space
self.tiles[nextY][nextX] = tile;
result.moved = true;
}
// Update coordinates
y = nextY;
x = nextX;
// Calculate next position
nextX += dx;
nextY += dy;
}
return result;
};
// Check if coordinates are within bounds
self.isWithinBounds = function (x, y) {
return x >= 0 && x < self.size && y >= 0 && y < self.size;
};
// Save current positions of all tiles for animation
self.saveTilePositions = function () {
self.positions = [];
for (var y = 0; y < self.size; y++) {
for (var x = 0; x < self.size; x++) {
if (self.tiles[y][x]) {
self.positions.push({
tile: self.tiles[y][x],
prevX: self.tiles[y][x].x,
prevY: self.tiles[y][x].y,
targetX: self.getPositionForTile(x, y).x,
targetY: self.getPositionForTile(x, y).y
});
}
}
}
};
// Animate tile movements based on saved positions
self.animateTileMovements = function (callback) {
var animationsCompleted = 0;
var totalAnimations = self.positions.length;
if (totalAnimations === 0) {
if (callback) {
callback();
}
return;
}
// Animate each tile
for (var i = 0; i < self.positions.length; i++) {
var pos = self.positions[i];
var tile = pos.tile;
// If tile hasn't moved, just increment counter
if (pos.prevX === pos.targetX && pos.prevY === pos.targetY) {
animationsCompleted++;
if (animationsCompleted === totalAnimations && callback) {
callback();
}
continue;
}
// Check if this tile has been merged
var merged = false;
for (var y = 0; y < self.size; y++) {
for (var x = 0; x < self.size; x++) {
if (self.tiles[y][x] === tile && tile.merged) {
merged = true;
break;
}
}
if (merged) {
break;
}
}
// Animate tile movement
tween(tile, {
x: pos.targetX,
y: pos.targetY
}, {
duration: 150,
easing: tween.easeOutQuad,
onFinish: function onFinish() {
animationsCompleted++;
// If tile was merged, animate the merge effect
if (merged) {
tile.mergeTile(function () {
if (animationsCompleted === totalAnimations && callback) {
callback();
}
});
} else if (animationsCompleted === totalAnimations && callback) {
callback();
}
}
});
}
};
// Reset merged status for all tiles
self.resetMergedStatus = function () {
for (var y = 0; y < self.size; y++) {
for (var x = 0; x < self.size; x++) {
if (self.tiles[y][x]) {
self.tiles[y][x].merged = false;
}
}
}
};
// Check if game is over (no more valid moves)
self.isGameOver = function () {
// Check if there are any empty cells
for (var y = 0; y < self.size; y++) {
for (var x = 0; x < self.size; x++) {
if (!self.tiles[y][x]) {
return false;
}
}
}
// Check if any adjacent tiles can be merged
for (var y = 0; y < self.size; y++) {
for (var x = 0; x < self.size; x++) {
var tile = self.tiles[y][x];
// Check adjacent cells
var directions = [{
dx: 0,
dy: -1
}, {
dx: 1,
dy: 0
}, {
dx: 0,
dy: 1
}, {
dx: -1,
dy: 0
}];
for (var i = 0; i < directions.length; i++) {
var nextX = x + directions[i].dx;
var nextY = y + directions[i].dy;
if (self.isWithinBounds(nextX, nextY) && self.tiles[nextY][nextX] && self.tiles[nextY][nextX].value === tile.value) {
return false;
}
}
}
}
return true;
};
// Check if player has won (has a 2048 tile)
self.hasWon = function () {
for (var y = 0; y < self.size; y++) {
for (var x = 0; x < self.size; x++) {
if (self.tiles[y][x] && self.tiles[y][x].value >= 2048) {
return true;
}
}
}
return false;
};
// Initialize the grid
self.initialize = function () {
self.createEmptyCells();
self.initializeTiles();
};
// Initialize the grid on creation
self.initialize();
return self;
});
var Tile = Container.expand(function (value) {
var self = Container.call(this);
self.value = value || 0;
self.merged = false;
// Create background tile
var background = self.attachAsset('tile', {
anchorX: 0.5,
anchorY: 0.5,
width: 120,
height: 120
});
// Set tile color based on value
self.updateAppearance = function () {
var colors = {
0: 0xCDC1B4,
// Empty
2: 0xEEE4DA,
4: 0xEDE0C8,
8: 0xF2B179,
16: 0xF59563,
32: 0xF67C5F,
64: 0xF65E3B,
128: 0xEDCF72,
256: 0xEDCC61,
512: 0xEDC850,
1024: 0xEDC53F,
2048: 0xEDC22E
};
var textColors = {
2: 0x776E65,
4: 0x776E65,
8: 0xFFFFFF,
16: 0xFFFFFF,
32: 0xFFFFFF,
64: 0xFFFFFF,
128: 0xFFFFFF,
256: 0xFFFFFF,
512: 0xFFFFFF,
1024: 0xFFFFFF,
2048: 0xFFFFFF
};
// Set tile color
background.tint = self.value in colors ? colors[self.value] : 0xEDC22E;
// Remove old text if it exists
if (self.text) {
self.removeChild(self.text);
}
// Only create text if tile has a value
if (self.value > 0) {
// Text size decreases for larger numbers
var textSize = self.value < 100 ? 60 : self.value < 1000 ? 50 : 40;
// Create text for tile
self.text = new Text2(self.value.toString(), {
size: textSize,
fill: textColors[self.value] || "#FFFFFF",
fontWeight: "bold"
});
self.text.anchor.set(0.5, 0.5);
self.addChild(self.text);
}
};
// Set initial appearance
self.updateAppearance();
// Animate tile appearing
self.appear = function () {
self.scale.x = 0;
self.scale.y = 0;
tween(self.scale, {
x: 1,
y: 1
}, {
duration: 200,
easing: tween.easeOutQuad
});
};
// Animate tile merging
self.mergeTile = function (callback) {
tween(self.scale, {
x: 1.2,
y: 1.2
}, {
duration: 100,
easing: tween.easeOutQuad,
onFinish: function onFinish() {
tween(self.scale, {
x: 1,
y: 1
}, {
duration: 100,
easing: tween.easeInQuad,
onFinish: callback
});
}
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xFAF8EF
});
/****
* Game Code
****/
// Game state
var score = 0;
var highScore = storage.highScore || 0;
var isProcessing = false;
var gameStarted = false;
var grid;
var gridSize = 4;
var swipeStartX = 0;
var swipeStartY = 0;
var minSwipeDistance = 50;
// UI elements
var scoreTxt;
var highScoreTxt;
var titleTxt;
var instructionsTxt;
// Initialize the game
function initializeGame() {
// Create game title
titleTxt = new Text2("2048", {
size: 100,
fill: 0x776E65,
fontWeight: "bold"
});
titleTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(titleTxt);
titleTxt.y = 80;
// Create score display
var scoreLabel = new Text2("SCORE", {
size: 30,
fill: 0xEEE4DA,
fontWeight: "bold"
});
scoreLabel.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreLabel);
scoreLabel.x = -200;
scoreLabel.y = 110;
scoreTxt = new Text2("0", {
size: 40,
fill: 0xFFFFFF,
fontWeight: "bold"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
scoreTxt.x = -200;
scoreTxt.y = 150;
// Create high score display
var highScoreLabel = new Text2("BEST", {
size: 30,
fill: 0xEEE4DA,
fontWeight: "bold"
});
highScoreLabel.anchor.set(0.5, 0);
LK.gui.top.addChild(highScoreLabel);
highScoreLabel.x = 200;
highScoreLabel.y = 110;
highScoreTxt = new Text2(highScore.toString(), {
size: 40,
fill: 0xFFFFFF,
fontWeight: "bold"
});
highScoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(highScoreTxt);
highScoreTxt.x = 200;
highScoreTxt.y = 150;
// Create instructions
instructionsTxt = new Text2("Swipe to move tiles.\nCombine identical tiles to get to 2048!", {
size: 30,
fill: 0x776E65,
align: "center"
});
instructionsTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(instructionsTxt);
instructionsTxt.y = 220;
// Create game grid
grid = new Grid(gridSize);
game.addChild(grid);
// Center the grid horizontally and position vertically
grid.x = (2048 - grid.width) / 2;
grid.y = 400;
// Start game with two random tiles
startGame();
// Play background music
LK.playMusic('bgmusic');
}
// Start or restart the game
function startGame() {
// Reset score
score = 0;
updateScore(0);
// Clear the grid
grid.initializeTiles();
// Add initial tiles
grid.addRandomTile();
grid.addRandomTile();
gameStarted = true;
isProcessing = false;
}
// Update the score display
function updateScore(points) {
score += points;
scoreTxt.setText(score.toString());
// Update high score if needed
if (score > highScore) {
highScore = score;
highScoreTxt.setText(highScore.toString());
storage.highScore = highScore;
}
}
// Handle swipe gestures
function handleSwipe(startX, startY, endX, endY) {
if (isProcessing || !gameStarted) {
return;
}
var dx = endX - startX;
var dy = endY - startY;
var absDx = Math.abs(dx);
var absDy = Math.abs(dy);
// Ensure minimum swipe distance
if (Math.max(absDx, absDy) < minSwipeDistance) {
return;
}
var direction = "";
// Determine swipe direction based on which axis had greater movement
if (absDx > absDy) {
direction = dx > 0 ? "right" : "left";
} else {
direction = dy > 0 ? "down" : "up";
}
// Prevent multiple moves while processing
isProcessing = true;
// Move tiles in the selected direction
var result = grid.moveTiles(direction, function (moved, points) {
if (moved) {
// Play swipe sound
LK.getSound('swipe').play();
// Update score
if (points > 0) {
// Play merge sound for points
LK.getSound('merge').play();
updateScore(points);
}
// Add a new random tile
grid.addRandomTile();
// Check win condition
if (grid.hasWon()) {
LK.showYouWin();
return;
}
// Check if game is over
if (grid.isGameOver()) {
LK.showGameOver();
return;
}
}
// Ready for next move
isProcessing = false;
});
}
// Input handlers
game.down = function (x, y, obj) {
swipeStartX = x;
swipeStartY = y;
};
game.up = function (x, y, obj) {
handleSwipe(swipeStartX, swipeStartY, x, y);
};
game.move = function (x, y, obj) {
// We don't need anything in move for this game
};
// Initialize the game when loaded
initializeGame(); ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,636 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+var storage = LK.import("@upit/storage.v1", {
+ highScore: 0
+});
+
+/****
+* Classes
+****/
+var Grid = Container.expand(function (size) {
+ var self = Container.call(this);
+ self.size = size || 4;
+ self.tileSize = 120;
+ self.spacing = 15;
+ self.width = self.size * self.tileSize + (self.size + 1) * self.spacing;
+ self.height = self.size * self.tileSize + (self.size + 1) * self.spacing;
+ // The grid of tiles
+ self.tiles = [];
+ // Keep track of tile positions for animations
+ self.positions = [];
+ // Initialize the grid background
+ var background = self.attachAsset('emptyTile', {
+ anchorX: 0,
+ anchorY: 0,
+ width: self.width,
+ height: self.height
+ });
+ background.tint = 0xBBADA0;
+ // Create empty cells
+ self.createEmptyCells = function () {
+ for (var y = 0; y < self.size; y++) {
+ for (var x = 0; x < self.size; x++) {
+ var posX = x * (self.tileSize + self.spacing) + self.spacing;
+ var posY = y * (self.tileSize + self.spacing) + self.spacing;
+ var emptyCell = LK.getAsset('emptyTile', {
+ anchorX: 0,
+ anchorY: 0,
+ width: self.tileSize,
+ height: self.tileSize,
+ x: posX,
+ y: posY
+ });
+ self.addChild(emptyCell);
+ }
+ }
+ };
+ // Initialize the tiles array
+ self.initializeTiles = function () {
+ self.tiles = [];
+ for (var y = 0; y < self.size; y++) {
+ self.tiles[y] = [];
+ for (var x = 0; x < self.size; x++) {
+ self.tiles[y][x] = null;
+ }
+ }
+ };
+ // Get position for a tile at grid coordinates
+ self.getPositionForTile = function (x, y) {
+ return {
+ x: x * (self.tileSize + self.spacing) + self.spacing + self.tileSize / 2,
+ y: y * (self.tileSize + self.spacing) + self.spacing + self.tileSize / 2
+ };
+ };
+ // Add a new tile to the grid
+ self.addTile = function (x, y, value) {
+ var tile = new Tile(value);
+ var position = self.getPositionForTile(x, y);
+ tile.x = position.x;
+ tile.y = position.y;
+ self.tiles[y][x] = tile;
+ self.addChild(tile);
+ return tile;
+ };
+ // Add a random tile to the grid
+ self.addRandomTile = function () {
+ var emptyCells = [];
+ // Find all empty cells
+ for (var y = 0; y < self.size; y++) {
+ for (var x = 0; x < self.size; x++) {
+ if (!self.tiles[y][x]) {
+ emptyCells.push({
+ x: x,
+ y: y
+ });
+ }
+ }
+ }
+ // If there are no empty cells, return
+ if (emptyCells.length === 0) {
+ return null;
+ }
+ // Choose a random empty cell
+ var randomCell = emptyCells[Math.floor(Math.random() * emptyCells.length)];
+ // 90% chance of 2, 10% chance of 4
+ var value = Math.random() < 0.9 ? 2 : 4;
+ // Add the new tile and animate it appearing
+ var tile = self.addTile(randomCell.x, randomCell.y, value);
+ tile.appear();
+ return tile;
+ };
+ // Move tiles in a specific direction
+ self.moveTiles = function (direction, callback) {
+ var moved = false;
+ var score = 0;
+ // Save positions before moving for animations
+ self.saveTilePositions();
+ // Reset merged status for all tiles
+ self.resetMergedStatus();
+ switch (direction) {
+ case "up":
+ for (var x = 0; x < self.size; x++) {
+ for (var y = 1; y < self.size; y++) {
+ if (self.tiles[y][x]) {
+ var result = self.moveTileInDirection(x, y, 0, -1);
+ moved = moved || result.moved;
+ score += result.score;
+ }
+ }
+ }
+ break;
+ case "right":
+ for (var y = 0; y < self.size; y++) {
+ for (var x = self.size - 2; x >= 0; x--) {
+ if (self.tiles[y][x]) {
+ var result = self.moveTileInDirection(x, y, 1, 0);
+ moved = moved || result.moved;
+ score += result.score;
+ }
+ }
+ }
+ break;
+ case "down":
+ for (var x = 0; x < self.size; x++) {
+ for (var y = self.size - 2; y >= 0; y--) {
+ if (self.tiles[y][x]) {
+ var result = self.moveTileInDirection(x, y, 0, 1);
+ moved = moved || result.moved;
+ score += result.score;
+ }
+ }
+ }
+ break;
+ case "left":
+ for (var y = 0; y < self.size; y++) {
+ for (var x = 1; x < self.size; x++) {
+ if (self.tiles[y][x]) {
+ var result = self.moveTileInDirection(x, y, -1, 0);
+ moved = moved || result.moved;
+ score += result.score;
+ }
+ }
+ }
+ break;
+ }
+ // Animate tile movements
+ self.animateTileMovements(function () {
+ if (callback) {
+ callback(moved, score);
+ }
+ });
+ return {
+ moved: moved,
+ score: score
+ };
+ };
+ // Move a single tile in the specified direction
+ self.moveTileInDirection = function (x, y, dx, dy) {
+ var tile = self.tiles[y][x];
+ var result = {
+ moved: false,
+ score: 0
+ };
+ if (!tile) {
+ return result;
+ }
+ var nextX = x + dx;
+ var nextY = y + dy;
+ // Keep moving while in bounds and either finding empty space or matching tile
+ while (self.isWithinBounds(nextX, nextY) && (self.tiles[nextY][nextX] === null || self.tiles[nextY][nextX].value === tile.value && !self.tiles[nextY][nextX].merged)) {
+ // Move tile
+ self.tiles[y][x] = null;
+ // Check if we can merge
+ if (self.tiles[nextY][nextX] !== null) {
+ // Merge tiles
+ var mergeValue = tile.value * 2;
+ self.tiles[nextY][nextX].value = mergeValue;
+ self.tiles[nextY][nextX].merged = true;
+ self.tiles[nextY][nextX].updateAppearance();
+ // Remove the merged tile
+ self.removeChild(tile);
+ result.score = mergeValue;
+ result.moved = true;
+ break;
+ } else {
+ // Move tile to empty space
+ self.tiles[nextY][nextX] = tile;
+ result.moved = true;
+ }
+ // Update coordinates
+ y = nextY;
+ x = nextX;
+ // Calculate next position
+ nextX += dx;
+ nextY += dy;
+ }
+ return result;
+ };
+ // Check if coordinates are within bounds
+ self.isWithinBounds = function (x, y) {
+ return x >= 0 && x < self.size && y >= 0 && y < self.size;
+ };
+ // Save current positions of all tiles for animation
+ self.saveTilePositions = function () {
+ self.positions = [];
+ for (var y = 0; y < self.size; y++) {
+ for (var x = 0; x < self.size; x++) {
+ if (self.tiles[y][x]) {
+ self.positions.push({
+ tile: self.tiles[y][x],
+ prevX: self.tiles[y][x].x,
+ prevY: self.tiles[y][x].y,
+ targetX: self.getPositionForTile(x, y).x,
+ targetY: self.getPositionForTile(x, y).y
+ });
+ }
+ }
+ }
+ };
+ // Animate tile movements based on saved positions
+ self.animateTileMovements = function (callback) {
+ var animationsCompleted = 0;
+ var totalAnimations = self.positions.length;
+ if (totalAnimations === 0) {
+ if (callback) {
+ callback();
+ }
+ return;
+ }
+ // Animate each tile
+ for (var i = 0; i < self.positions.length; i++) {
+ var pos = self.positions[i];
+ var tile = pos.tile;
+ // If tile hasn't moved, just increment counter
+ if (pos.prevX === pos.targetX && pos.prevY === pos.targetY) {
+ animationsCompleted++;
+ if (animationsCompleted === totalAnimations && callback) {
+ callback();
+ }
+ continue;
+ }
+ // Check if this tile has been merged
+ var merged = false;
+ for (var y = 0; y < self.size; y++) {
+ for (var x = 0; x < self.size; x++) {
+ if (self.tiles[y][x] === tile && tile.merged) {
+ merged = true;
+ break;
+ }
+ }
+ if (merged) {
+ break;
+ }
+ }
+ // Animate tile movement
+ tween(tile, {
+ x: pos.targetX,
+ y: pos.targetY
+ }, {
+ duration: 150,
+ easing: tween.easeOutQuad,
+ onFinish: function onFinish() {
+ animationsCompleted++;
+ // If tile was merged, animate the merge effect
+ if (merged) {
+ tile.mergeTile(function () {
+ if (animationsCompleted === totalAnimations && callback) {
+ callback();
+ }
+ });
+ } else if (animationsCompleted === totalAnimations && callback) {
+ callback();
+ }
+ }
+ });
+ }
+ };
+ // Reset merged status for all tiles
+ self.resetMergedStatus = function () {
+ for (var y = 0; y < self.size; y++) {
+ for (var x = 0; x < self.size; x++) {
+ if (self.tiles[y][x]) {
+ self.tiles[y][x].merged = false;
+ }
+ }
+ }
+ };
+ // Check if game is over (no more valid moves)
+ self.isGameOver = function () {
+ // Check if there are any empty cells
+ for (var y = 0; y < self.size; y++) {
+ for (var x = 0; x < self.size; x++) {
+ if (!self.tiles[y][x]) {
+ return false;
+ }
+ }
+ }
+ // Check if any adjacent tiles can be merged
+ for (var y = 0; y < self.size; y++) {
+ for (var x = 0; x < self.size; x++) {
+ var tile = self.tiles[y][x];
+ // Check adjacent cells
+ var directions = [{
+ dx: 0,
+ dy: -1
+ }, {
+ dx: 1,
+ dy: 0
+ }, {
+ dx: 0,
+ dy: 1
+ }, {
+ dx: -1,
+ dy: 0
+ }];
+ for (var i = 0; i < directions.length; i++) {
+ var nextX = x + directions[i].dx;
+ var nextY = y + directions[i].dy;
+ if (self.isWithinBounds(nextX, nextY) && self.tiles[nextY][nextX] && self.tiles[nextY][nextX].value === tile.value) {
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+ };
+ // Check if player has won (has a 2048 tile)
+ self.hasWon = function () {
+ for (var y = 0; y < self.size; y++) {
+ for (var x = 0; x < self.size; x++) {
+ if (self.tiles[y][x] && self.tiles[y][x].value >= 2048) {
+ return true;
+ }
+ }
+ }
+ return false;
+ };
+ // Initialize the grid
+ self.initialize = function () {
+ self.createEmptyCells();
+ self.initializeTiles();
+ };
+ // Initialize the grid on creation
+ self.initialize();
+ return self;
+});
+var Tile = Container.expand(function (value) {
+ var self = Container.call(this);
+ self.value = value || 0;
+ self.merged = false;
+ // Create background tile
+ var background = self.attachAsset('tile', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ width: 120,
+ height: 120
+ });
+ // Set tile color based on value
+ self.updateAppearance = function () {
+ var colors = {
+ 0: 0xCDC1B4,
+ // Empty
+ 2: 0xEEE4DA,
+ 4: 0xEDE0C8,
+ 8: 0xF2B179,
+ 16: 0xF59563,
+ 32: 0xF67C5F,
+ 64: 0xF65E3B,
+ 128: 0xEDCF72,
+ 256: 0xEDCC61,
+ 512: 0xEDC850,
+ 1024: 0xEDC53F,
+ 2048: 0xEDC22E
+ };
+ var textColors = {
+ 2: 0x776E65,
+ 4: 0x776E65,
+ 8: 0xFFFFFF,
+ 16: 0xFFFFFF,
+ 32: 0xFFFFFF,
+ 64: 0xFFFFFF,
+ 128: 0xFFFFFF,
+ 256: 0xFFFFFF,
+ 512: 0xFFFFFF,
+ 1024: 0xFFFFFF,
+ 2048: 0xFFFFFF
+ };
+ // Set tile color
+ background.tint = self.value in colors ? colors[self.value] : 0xEDC22E;
+ // Remove old text if it exists
+ if (self.text) {
+ self.removeChild(self.text);
+ }
+ // Only create text if tile has a value
+ if (self.value > 0) {
+ // Text size decreases for larger numbers
+ var textSize = self.value < 100 ? 60 : self.value < 1000 ? 50 : 40;
+ // Create text for tile
+ self.text = new Text2(self.value.toString(), {
+ size: textSize,
+ fill: textColors[self.value] || "#FFFFFF",
+ fontWeight: "bold"
+ });
+ self.text.anchor.set(0.5, 0.5);
+ self.addChild(self.text);
+ }
+ };
+ // Set initial appearance
+ self.updateAppearance();
+ // Animate tile appearing
+ self.appear = function () {
+ self.scale.x = 0;
+ self.scale.y = 0;
+ tween(self.scale, {
+ x: 1,
+ y: 1
+ }, {
+ duration: 200,
+ easing: tween.easeOutQuad
+ });
+ };
+ // Animate tile merging
+ self.mergeTile = function (callback) {
+ tween(self.scale, {
+ x: 1.2,
+ y: 1.2
+ }, {
+ duration: 100,
+ easing: tween.easeOutQuad,
+ onFinish: function onFinish() {
+ tween(self.scale, {
+ x: 1,
+ y: 1
+ }, {
+ duration: 100,
+ easing: tween.easeInQuad,
+ onFinish: callback
+ });
+ }
+ });
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0xFAF8EF
+});
+
+/****
+* Game Code
+****/
+// Game state
+var score = 0;
+var highScore = storage.highScore || 0;
+var isProcessing = false;
+var gameStarted = false;
+var grid;
+var gridSize = 4;
+var swipeStartX = 0;
+var swipeStartY = 0;
+var minSwipeDistance = 50;
+// UI elements
+var scoreTxt;
+var highScoreTxt;
+var titleTxt;
+var instructionsTxt;
+// Initialize the game
+function initializeGame() {
+ // Create game title
+ titleTxt = new Text2("2048", {
+ size: 100,
+ fill: 0x776E65,
+ fontWeight: "bold"
+ });
+ titleTxt.anchor.set(0.5, 0);
+ LK.gui.top.addChild(titleTxt);
+ titleTxt.y = 80;
+ // Create score display
+ var scoreLabel = new Text2("SCORE", {
+ size: 30,
+ fill: 0xEEE4DA,
+ fontWeight: "bold"
+ });
+ scoreLabel.anchor.set(0.5, 0);
+ LK.gui.top.addChild(scoreLabel);
+ scoreLabel.x = -200;
+ scoreLabel.y = 110;
+ scoreTxt = new Text2("0", {
+ size: 40,
+ fill: 0xFFFFFF,
+ fontWeight: "bold"
+ });
+ scoreTxt.anchor.set(0.5, 0);
+ LK.gui.top.addChild(scoreTxt);
+ scoreTxt.x = -200;
+ scoreTxt.y = 150;
+ // Create high score display
+ var highScoreLabel = new Text2("BEST", {
+ size: 30,
+ fill: 0xEEE4DA,
+ fontWeight: "bold"
+ });
+ highScoreLabel.anchor.set(0.5, 0);
+ LK.gui.top.addChild(highScoreLabel);
+ highScoreLabel.x = 200;
+ highScoreLabel.y = 110;
+ highScoreTxt = new Text2(highScore.toString(), {
+ size: 40,
+ fill: 0xFFFFFF,
+ fontWeight: "bold"
+ });
+ highScoreTxt.anchor.set(0.5, 0);
+ LK.gui.top.addChild(highScoreTxt);
+ highScoreTxt.x = 200;
+ highScoreTxt.y = 150;
+ // Create instructions
+ instructionsTxt = new Text2("Swipe to move tiles.\nCombine identical tiles to get to 2048!", {
+ size: 30,
+ fill: 0x776E65,
+ align: "center"
+ });
+ instructionsTxt.anchor.set(0.5, 0);
+ LK.gui.top.addChild(instructionsTxt);
+ instructionsTxt.y = 220;
+ // Create game grid
+ grid = new Grid(gridSize);
+ game.addChild(grid);
+ // Center the grid horizontally and position vertically
+ grid.x = (2048 - grid.width) / 2;
+ grid.y = 400;
+ // Start game with two random tiles
+ startGame();
+ // Play background music
+ LK.playMusic('bgmusic');
+}
+// Start or restart the game
+function startGame() {
+ // Reset score
+ score = 0;
+ updateScore(0);
+ // Clear the grid
+ grid.initializeTiles();
+ // Add initial tiles
+ grid.addRandomTile();
+ grid.addRandomTile();
+ gameStarted = true;
+ isProcessing = false;
+}
+// Update the score display
+function updateScore(points) {
+ score += points;
+ scoreTxt.setText(score.toString());
+ // Update high score if needed
+ if (score > highScore) {
+ highScore = score;
+ highScoreTxt.setText(highScore.toString());
+ storage.highScore = highScore;
+ }
+}
+// Handle swipe gestures
+function handleSwipe(startX, startY, endX, endY) {
+ if (isProcessing || !gameStarted) {
+ return;
+ }
+ var dx = endX - startX;
+ var dy = endY - startY;
+ var absDx = Math.abs(dx);
+ var absDy = Math.abs(dy);
+ // Ensure minimum swipe distance
+ if (Math.max(absDx, absDy) < minSwipeDistance) {
+ return;
+ }
+ var direction = "";
+ // Determine swipe direction based on which axis had greater movement
+ if (absDx > absDy) {
+ direction = dx > 0 ? "right" : "left";
+ } else {
+ direction = dy > 0 ? "down" : "up";
+ }
+ // Prevent multiple moves while processing
+ isProcessing = true;
+ // Move tiles in the selected direction
+ var result = grid.moveTiles(direction, function (moved, points) {
+ if (moved) {
+ // Play swipe sound
+ LK.getSound('swipe').play();
+ // Update score
+ if (points > 0) {
+ // Play merge sound for points
+ LK.getSound('merge').play();
+ updateScore(points);
+ }
+ // Add a new random tile
+ grid.addRandomTile();
+ // Check win condition
+ if (grid.hasWon()) {
+ LK.showYouWin();
+ return;
+ }
+ // Check if game is over
+ if (grid.isGameOver()) {
+ LK.showGameOver();
+ return;
+ }
+ }
+ // Ready for next move
+ isProcessing = false;
+ });
+}
+// Input handlers
+game.down = function (x, y, obj) {
+ swipeStartX = x;
+ swipeStartY = y;
+};
+game.up = function (x, y, obj) {
+ handleSwipe(swipeStartX, swipeStartY, x, y);
+};
+game.move = function (x, y, obj) {
+ // We don't need anything in move for this game
+};
+// Initialize the game when loaded
+initializeGame();
\ No newline at end of file