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
/**** * Classes ****/ var Tile = Container.expand(function (value) { var self = Container.call(this); self.alpha = 0; var fadeIn = function fadeIn() { if (self.alpha < 1) { self.alpha = Math.min(self.alpha + 0.24, 1); self.scale.set(self.alpha); LK.setTimeout(fadeIn, 16.67); } else { self.alpha = 1; self.scale.set(1); } }; fadeIn(); self.value = value || 2; var tileGraphics = self.attachAsset('tile', { anchorX: 0.5, anchorY: 0.5 }); var hsvToRgb = function hsvToRgb(h, s, v) { var r, g, b; var i = Math.floor(h * 6); var f = h * 6 - i; var p = v * (1 - s); var q = v * (1 - f * s); var t = v * (1 - (1 - f) * s); switch (i % 6) { case 0: r = v, g = t, b = p; break; case 1: r = q, g = v, b = p; break; case 2: r = p, g = v, b = t; break; case 3: r = p, g = q, b = v; break; case 4: r = t, g = p, b = v; break; case 5: r = v, g = p, b = q; break; } return (Math.round(r * 255) << 16) + (Math.round(g * 255) << 8) + Math.round(b * 255); }; self.setTint = function () { var hue = (Math.log2(self.value) + 6) % 20 / 20; tileGraphics.tint = hsvToRgb(hue, 0.3, 1); }; self.setTint(); var tileLabel = new Text2(self.value.toString(), { size: 300, fill: '#332d28', font: 'Sans-Serif', weight: '800', strokeThickness: 0 }); tileLabel.anchor.set(0.5, 0.5); tileLabel.x = 0; tileLabel.y = -40; self.addChild(tileLabel); self.setValue = function (value) { self.newValue = value; }; self.updateToRealValue = function () { if (self.newValue) { self.value = self.newValue; tileLabel.setText(self.value.toString()); var textScale = Math.min(1, 350 / (tileLabel.width / tileLabel.scale.x)); tileLabel.scale.set(textScale); self.setTint(); self.newValue = null; self.scale.set(1.2); var scaleDown = function scaleDown() { if (self.scale.x > 1) { self.scale.x -= 0.02; self.scale.y -= 0.02; LK.setTimeout(scaleDown, 16.67); } else { self.scale.set(1); } }; scaleDown(); } }; self.targetX = 0; self.targetY = 0; self.isMoving = false; self.merged = false; self.setPosition = function (x, y, instant) { self.targetX = x * 500 + 250; self.targetY = y * 500 + 250; if (instant) { self.x = self.targetX; self.y = self.targetY; } }; self._move_migrated = function () { var dx = self.targetX - self.x; var dy = self.targetY - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 150) { self.isMoving = true; self.x += dx / distance * 150; self.y += dy / distance * 150; return false; } self.isMoving = false; self.x = self.targetX; self.y = self.targetY; return true; }; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ game.checkPossibleMoves = function () { for (var i = 0; i < gridSize; i++) { for (var j = 0; j < gridSize; j++) { if (squares[i][j] === null) { return true; } if (i < gridSize - 1 && squares[i][j] !== null && squares[i + 1][j] !== null && squares[i][j].value === squares[i + 1][j].value) { return true; } if (j < gridSize - 1 && squares[i][j] !== null && squares[i][j + 1] !== null && squares[i][j].value === squares[i][j + 1].value) { return true; } } } return false; }; var scoreTxt = new Text2('2', { size: 220, fill: '#000000', font: 'Impact', strokeThickness: 0 }); scoreTxt.anchor.set(.5, 0); LK.gui.top.addChild(scoreTxt); var tutorialTxt = new Text2('Swipe to merge & merge', { size: 120, fill: '#000000', font: 'Impact', strokeThickness: 0 }); tutorialTxt.anchor.set(.5, 1); LK.gui.bottom.addChild(tutorialTxt); tutorialTxt.y -= 30; var toBeRemoved = []; game.addRandomTile = function () { var emptyPositions = []; for (var i = 0; i < gridSize; i++) { for (var j = 0; j < gridSize; j++) { if (squares[i][j] === null) { emptyPositions.push({ x: i, y: j }); } } } if (emptyPositions.length > 0) { var randomPosition = emptyPositions[Math.floor(Math.random() * emptyPositions.length)]; var square = new Tile(Math.random() < 0.5 ? 2 : 4); square.setPosition(randomPosition.x, randomPosition.y, true); squares[randomPosition.x][randomPosition.y] = square; gridContainer.addChild(square); } }; game.mergeTiles = function (x1, y1, x2, y2) { if (squares[x1][y1] !== null && squares[x2][y2] !== null && squares[x1][y1].value === squares[x2][y2].value && !squares[x1][y1].merged && !squares[x2][y2].merged) { squares[x2][y2].setValue(squares[x2][y2].value * 2, true); squares[x2][y2].merged = true; squares[x1][y1].targetX = squares[x2][y2].targetX; squares[x1][y1].targetY = squares[x2][y2].targetY; toBeRemoved.push(squares[x1][y1]); squares[x1][y1] = null; gridContainer.removeChild(squares[x2][y2]); gridContainer.addChild(squares[x2][y2]); return true; } return false; }; var gridSize = 4; game.setBackgroundColor(0xD3D3D3); var gridContainer = new Container(); gridContainer.x = 44; gridContainer.y = 400; game.addChild(gridContainer); for (var i = 0; i < gridSize; i++) { for (var j = 0; j < gridSize; j++) { var gridTile = gridContainer.attachAsset('gridTile', { anchorX: 0.5, anchorY: 0.5 }); gridTile.x = i * 500 + 250; gridTile.y = j * 500 + 250; gridTile.alpha = .1; } } var squares = new Array(gridSize).fill().map(function () { return new Array(gridSize).fill(null); }); for (var i = 0; i < gridSize; i++) { for (var j = 0; j < gridSize; j++) { squares[i][j] = null; } } var initialTiles = 2; for (var i = 0; i < initialTiles; i++) { var x, y; do { x = Math.floor(Math.random() * gridSize); y = Math.floor(Math.random() * gridSize); } while (squares[x][y] !== null); var square = new Tile(); square.setPosition(x, y, true); square.alpha = 1; square.scale.set(1); squares[x][y] = square; gridContainer.addChild(square); } var swipeStart = { x: 0, y: 0 }; var swipeEnd = { x: 0, y: 0 }; var boardChanged = false; var winMessageShown = false; game.moveTiles = function (direction) { var dx = (direction === 'right') - (direction === 'left'); var dy = (direction === 'down') - (direction === 'up'); var moved = false; do { moved = false; var iStart = dx > 0 ? gridSize - 1 : 0; var iEnd = dx > 0 ? -1 : gridSize; var iStep = dx > 0 ? -1 : 1; var jStart = dy > 0 ? gridSize - 1 : 0; var jEnd = dy > 0 ? -1 : gridSize; var jStep = dy > 0 ? -1 : 1; for (var i = iStart; i !== iEnd; i += iStep) { for (var j = jStart; j !== jEnd; j += jStep) { var x = i + dx; var y = j + dy; if (x >= 0 && x < gridSize && y >= 0 && y < gridSize && squares[i][j] !== null) { if (squares[x][y] === null) { squares[x][y] = squares[i][j]; squares[i][j] = null; squares[x][y].setPosition(x, y); moved = true; boardChanged = true; } else if (squares[x][y] !== null && squares[i][j] !== null && squares[x][y].value === squares[i][j].value) { moved = game.mergeTiles(i, j, x, y); if (moved) { boardChanged = true; } } } } } } while (moved); for (var i = 0; i < gridSize; i++) { for (var j = 0; j < gridSize; j++) { if (squares[i][j] !== null) { squares[i][j].merged = false; } } } }; game.on('down', function (x, y, obj) { var anyTileMoving = squares.some(function (row) { return row.some(function (tile) { return tile && tile.isMoving; }); }); if (!anyTileMoving) { var pos = game.toLocal(obj.global); swipeStart = { x: pos.x, y: pos.y }; } }); game.on('up', function (x, y, obj) { var pos = game.toLocal(obj.global); swipeEnd = { x: pos.x, y: pos.y }; var dx = swipeEnd.x - swipeStart.x; var dy = swipeEnd.y - swipeStart.y; var threshold = 50; if (Math.abs(dx) > threshold || Math.abs(dy) > threshold) { if (Math.abs(dx) > Math.abs(dy)) { if (dx > 0) { game.moveTiles('right'); } else { game.moveTiles('left'); } } else { if (dy > 0) { game.moveTiles('down'); } else { game.moveTiles('up'); } } if (tutorialTxt) { LK.gui.bottom.removeChild(tutorialTxt); tutorialTxt = null; } } }); LK.on('tick', function () { var allTilesStopped = true; for (var i = 0; i < gridSize; i++) { for (var j = 0; j < gridSize; j++) { if (squares[i][j] !== null) { if (!squares[i][j]._move_migrated()) { allTilesStopped = false; } } } } for (var i = 0; i < toBeRemoved.length; i++) { if (!toBeRemoved[i]._move_migrated()) { allTilesStopped = false; } else { toBeRemoved[i].destroy(); toBeRemoved.splice(i, 1); i--; } } if (allTilesStopped) { for (var i = 0; i < gridSize; i++) { for (var j = 0; j < gridSize; j++) { if (squares[i][j] !== null && squares[i][j].newValue) { squares[i][j].updateToRealValue(); if (squares[i][j].value === 2048 && !winMessageShown) { var winMessage = new Text2('Congratulations\n you win!', { size: 150, fill: '#ffffff', font: 'Sans-Serif', weight: '800', stroke: '#000000', strokeThickness: 25, align: 'center' }); winMessage.anchor.set(0.5, 0.5); LK.gui.center.addChild(winMessage); winMessageShown = true; LK.setTimeout(function () { LK.gui.center.removeChild(winMessage); }, 5000); } } } } if (boardChanged) { game.addRandomTile(); boardChanged = false; var maxTileValue = Math.max.apply(Math, squares.map(function (row) { return Math.max.apply(Math, row.map(function (tile) { return tile ? tile.value : 0; })); })); var newScore = maxTileValue; LK.setScore(newScore); scoreTxt.setText(newScore.toString()); } if (!game.checkPossibleMoves()) { for (var i = 0; i < gridSize; i++) { for (var j = 0; j < gridSize; j++) { if (squares[i][j] !== null) { squares[i][j].alpha = 1; squares[i][j].scale.set(1); } } } LK.showGameOver(); } } });
===================================================================
--- original.js
+++ change.js
@@ -1,704 +1,401 @@
/****
-* 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 Tile = Container.expand(function (value) {
var self = Container.call(this);
- self.size = size || 4;
- self.tileSize = 380;
- self.spacing = 50;
- 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);
- }
+ self.alpha = 0;
+ var fadeIn = function fadeIn() {
+ if (self.alpha < 1) {
+ self.alpha = Math.min(self.alpha + 0.24, 1);
+ self.scale.set(self.alpha);
+ LK.setTimeout(fadeIn, 16.67);
+ } else {
+ self.alpha = 1;
+ self.scale.set(1);
}
};
- // 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;
- }
- }
- }
+ fadeIn();
+ self.value = value || 2;
+ var tileGraphics = self.attachAsset('tile', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ var hsvToRgb = function hsvToRgb(h, s, v) {
+ var r, g, b;
+ var i = Math.floor(h * 6);
+ var f = h * 6 - i;
+ var p = v * (1 - s);
+ var q = v * (1 - f * s);
+ var t = v * (1 - (1 - f) * s);
+ switch (i % 6) {
+ case 0:
+ r = v, g = t, b = p;
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;
- }
- }
- }
+ case 1:
+ r = q, g = v, b = p;
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;
- }
- }
- }
+ case 2:
+ r = p, g = v, b = t;
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;
- }
- }
- }
+ case 3:
+ r = p, g = q, b = v;
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;
+ case 4:
+ r = t, g = p, b = v;
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;
+ case 5:
+ r = v, g = p, b = q;
+ break;
}
- return result;
+ return (Math.round(r * 255) << 16) + (Math.round(g * 255) << 8) + Math.round(b * 255);
};
- // Check if coordinates are within bounds
- self.isWithinBounds = function (x, y) {
- return x >= 0 && x < self.size && y >= 0 && y < self.size;
+ self.setTint = function () {
+ var hue = (Math.log2(self.value) + 6) % 20 / 20;
+ tileGraphics.tint = hsvToRgb(hue, 0.3, 1);
};
- // 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
- });
- }
- }
- }
+ self.setTint();
+ var tileLabel = new Text2(self.value.toString(), {
+ size: 300,
+ fill: '#332d28',
+ font: 'Sans-Serif',
+ weight: '800',
+ strokeThickness: 0
+ });
+ tileLabel.anchor.set(0.5, 0.5);
+ tileLabel.x = 0;
+ tileLabel.y = -40;
+ self.addChild(tileLabel);
+ self.setValue = function (value) {
+ self.newValue = value;
};
- // 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();
+ self.updateToRealValue = function () {
+ if (self.newValue) {
+ self.value = self.newValue;
+ tileLabel.setText(self.value.toString());
+ var textScale = Math.min(1, 350 / (tileLabel.width / tileLabel.scale.x));
+ tileLabel.scale.set(textScale);
+ self.setTint();
+ self.newValue = null;
+ self.scale.set(1.2);
+ var scaleDown = function scaleDown() {
+ if (self.scale.x > 1) {
+ self.scale.x -= 0.02;
+ self.scale.y -= 0.02;
+ LK.setTimeout(scaleDown, 16.67);
+ } else {
+ self.scale.set(1);
}
- 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();
- }
- }
- });
+ };
+ scaleDown();
}
};
- // 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;
- }
- }
+ self.targetX = 0;
+ self.targetY = 0;
+ self.isMoving = false;
+ self.merged = false;
+ self.setPosition = function (x, y, instant) {
+ self.targetX = x * 500 + 250;
+ self.targetY = y * 500 + 250;
+ if (instant) {
+ self.x = self.targetX;
+ self.y = self.targetY;
}
};
- // 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;
- }
- }
+ self._move_migrated = function () {
+ var dx = self.targetX - self.x;
+ var dy = self.targetY - self.y;
+ var distance = Math.sqrt(dx * dx + dy * dy);
+ if (distance > 150) {
+ self.isMoving = true;
+ self.x += dx / distance * 150;
+ self.y += dy / distance * 150;
+ 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;
- }
- }
- }
- }
+ self.isMoving = false;
+ self.x = self.targetX;
+ self.y = self.targetY;
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;
- };
- // Track border crossings and create new blocks
- self.checkBorderCrossings = function () {
- // Define borders (these values will depend on your grid layout)
- var borders = [];
- // Create horizontal and vertical border lines
- for (var i = 0; i <= self.size; i++) {
- // Horizontal borders
- var hBorder = i * (self.tileSize + self.spacing);
- // Vertical borders
- var vBorder = i * (self.tileSize + self.spacing);
- if (i > 0 && i < self.size) {
- borders.push({
- value: hBorder,
- isHorizontal: true
- });
- borders.push({
- value: vBorder,
- isHorizontal: false
- });
- }
- }
- // Check all tiles for border crossings
- for (var y = 0; y < self.size; y++) {
- for (var x = 0; x < self.size; x++) {
- var tile = self.tiles[y][x];
- if (tile) {
- // Check each border
- for (var b = 0; b < borders.length; b++) {
- var border = borders[b];
- if (border.isHorizontal) {
- // Check if tile crossed a horizontal border
- if (tile.lastY < border.value && tile.y >= border.value || tile.lastY > border.value && tile.y <= border.value) {
- // Create a new tile if space available
- self.addRandomTile();
- return; // Only add one tile per check
- }
- } else {
- // Check if tile crossed a vertical border
- if (tile.lastX < border.value && tile.x >= border.value || tile.lastX > border.value && tile.x <= border.value) {
- // Create a new tile if space available
- self.addRandomTile();
- return; // Only add one tile per check
- }
- }
- }
- }
- }
- }
- };
- // Update method for the grid
- self.update = function () {
- self.checkBorderCrossings();
- };
- // 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;
- // Track tile position for border crossing detection
- self.lastX = 0;
- self.lastY = 0;
- // Create background tile
- var background = self.attachAsset('tile', {
- anchorX: 0.5,
- anchorY: 0.5,
- width: 380,
- height: 380
- });
- // 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 ? 180 : self.value < 1000 ? 160 : 140;
- // 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
- });
- }
- });
- };
- // Track position changes
- self.update = function () {
- self.lastX = self.x;
- self.lastY = self.y;
- };
- return self;
-});
/****
* Initialize Game
****/
var game = new LK.Game({
- backgroundColor: 0xFAF8EF
+ backgroundColor: 0x000000
});
/****
* Game Code
****/
-// Game state
-var score = 0;
-var highScore = storage.highScore || 0;
-var isProcessing = false;
-var gameStarted = false;
-var grid;
+game.checkPossibleMoves = function () {
+ for (var i = 0; i < gridSize; i++) {
+ for (var j = 0; j < gridSize; j++) {
+ if (squares[i][j] === null) {
+ return true;
+ }
+ if (i < gridSize - 1 && squares[i][j] !== null && squares[i + 1][j] !== null && squares[i][j].value === squares[i + 1][j].value) {
+ return true;
+ }
+ if (j < gridSize - 1 && squares[i][j] !== null && squares[i][j + 1] !== null && squares[i][j].value === squares[i][j + 1].value) {
+ return true;
+ }
+ }
+ }
+ return false;
+};
+var scoreTxt = new Text2('2', {
+ size: 220,
+ fill: '#000000',
+ font: 'Impact',
+ strokeThickness: 0
+});
+scoreTxt.anchor.set(.5, 0);
+LK.gui.top.addChild(scoreTxt);
+var tutorialTxt = new Text2('Swipe to merge & merge', {
+ size: 120,
+ fill: '#000000',
+ font: 'Impact',
+ strokeThickness: 0
+});
+tutorialTxt.anchor.set(.5, 1);
+LK.gui.bottom.addChild(tutorialTxt);
+tutorialTxt.y -= 30;
+var toBeRemoved = [];
+game.addRandomTile = function () {
+ var emptyPositions = [];
+ for (var i = 0; i < gridSize; i++) {
+ for (var j = 0; j < gridSize; j++) {
+ if (squares[i][j] === null) {
+ emptyPositions.push({
+ x: i,
+ y: j
+ });
+ }
+ }
+ }
+ if (emptyPositions.length > 0) {
+ var randomPosition = emptyPositions[Math.floor(Math.random() * emptyPositions.length)];
+ var square = new Tile(Math.random() < 0.5 ? 2 : 4);
+ square.setPosition(randomPosition.x, randomPosition.y, true);
+ squares[randomPosition.x][randomPosition.y] = square;
+ gridContainer.addChild(square);
+ }
+};
+game.mergeTiles = function (x1, y1, x2, y2) {
+ if (squares[x1][y1] !== null && squares[x2][y2] !== null && squares[x1][y1].value === squares[x2][y2].value && !squares[x1][y1].merged && !squares[x2][y2].merged) {
+ squares[x2][y2].setValue(squares[x2][y2].value * 2, true);
+ squares[x2][y2].merged = true;
+ squares[x1][y1].targetX = squares[x2][y2].targetX;
+ squares[x1][y1].targetY = squares[x2][y2].targetY;
+ toBeRemoved.push(squares[x1][y1]);
+ squares[x1][y1] = null;
+ gridContainer.removeChild(squares[x2][y2]);
+ gridContainer.addChild(squares[x2][y2]);
+ return true;
+ }
+ return false;
+};
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: 180,
- fill: 0x776E65,
- fontWeight: "bold"
- });
- titleTxt.anchor.set(0.5, 0);
- LK.gui.top.addChild(titleTxt);
- titleTxt.y = 30;
- // Create score display
- var scoreLabel = new Text2("SCORE", {
- size: 60,
- fill: 0xEEE4DA,
- fontWeight: "bold"
- });
- scoreLabel.anchor.set(0.5, 0);
- LK.gui.top.addChild(scoreLabel);
- scoreLabel.x = -400;
- scoreLabel.y = 70;
- scoreTxt = new Text2("0", {
- size: 70,
- fill: 0xFFFFFF,
- fontWeight: "bold"
- });
- scoreTxt.anchor.set(0.5, 0);
- LK.gui.top.addChild(scoreTxt);
- scoreTxt.x = -400;
- scoreTxt.y = 120;
- // Create high score display
- var highScoreLabel = new Text2("BEST", {
- size: 60,
- fill: 0xEEE4DA,
- fontWeight: "bold"
- });
- highScoreLabel.anchor.set(0.5, 0);
- LK.gui.top.addChild(highScoreLabel);
- highScoreLabel.x = 400;
- highScoreLabel.y = 70;
- highScoreTxt = new Text2(highScore.toString(), {
- size: 70,
- fill: 0xFFFFFF,
- fontWeight: "bold"
- });
- highScoreTxt.anchor.set(0.5, 0);
- LK.gui.top.addChild(highScoreTxt);
- highScoreTxt.x = 400;
- highScoreTxt.y = 120;
- // Create instructions
- instructionsTxt = new Text2("Swipe to move tiles.\nCombine identical tiles to get to 2048!", {
- size: 40,
- fill: 0x776E65,
- align: "center"
- });
- instructionsTxt.anchor.set(0.5, 0);
- LK.gui.top.addChild(instructionsTxt);
- instructionsTxt.y = 200;
- // 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 = (2732 - grid.height) / 2;
- // Start game with two random tiles
- startGame();
- // Play background music
- LK.playMusic('bgmusic');
+game.setBackgroundColor(0xD3D3D3);
+var gridContainer = new Container();
+gridContainer.x = 44;
+gridContainer.y = 400;
+game.addChild(gridContainer);
+for (var i = 0; i < gridSize; i++) {
+ for (var j = 0; j < gridSize; j++) {
+ var gridTile = gridContainer.attachAsset('gridTile', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ gridTile.x = i * 500 + 250;
+ gridTile.y = j * 500 + 250;
+ gridTile.alpha = .1;
+ }
}
-// 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;
+var squares = new Array(gridSize).fill().map(function () {
+ return new Array(gridSize).fill(null);
+});
+for (var i = 0; i < gridSize; i++) {
+ for (var j = 0; j < gridSize; j++) {
+ squares[i][j] = null;
}
}
-// Handle swipe gestures
-function handleSwipe(startX, startY, endX, endY) {
- if (isProcessing || !gameStarted) {
- return;
+var initialTiles = 2;
+for (var i = 0; i < initialTiles; i++) {
+ var x, y;
+ do {
+ x = Math.floor(Math.random() * gridSize);
+ y = Math.floor(Math.random() * gridSize);
+ } while (squares[x][y] !== null);
+ var square = new Tile();
+ square.setPosition(x, y, true);
+ square.alpha = 1;
+ square.scale.set(1);
+ squares[x][y] = square;
+ gridContainer.addChild(square);
+}
+var swipeStart = {
+ x: 0,
+ y: 0
+};
+var swipeEnd = {
+ x: 0,
+ y: 0
+};
+var boardChanged = false;
+var winMessageShown = false;
+game.moveTiles = function (direction) {
+ var dx = (direction === 'right') - (direction === 'left');
+ var dy = (direction === 'down') - (direction === 'up');
+ var moved = false;
+ do {
+ moved = false;
+ var iStart = dx > 0 ? gridSize - 1 : 0;
+ var iEnd = dx > 0 ? -1 : gridSize;
+ var iStep = dx > 0 ? -1 : 1;
+ var jStart = dy > 0 ? gridSize - 1 : 0;
+ var jEnd = dy > 0 ? -1 : gridSize;
+ var jStep = dy > 0 ? -1 : 1;
+ for (var i = iStart; i !== iEnd; i += iStep) {
+ for (var j = jStart; j !== jEnd; j += jStep) {
+ var x = i + dx;
+ var y = j + dy;
+ if (x >= 0 && x < gridSize && y >= 0 && y < gridSize && squares[i][j] !== null) {
+ if (squares[x][y] === null) {
+ squares[x][y] = squares[i][j];
+ squares[i][j] = null;
+ squares[x][y].setPosition(x, y);
+ moved = true;
+ boardChanged = true;
+ } else if (squares[x][y] !== null && squares[i][j] !== null && squares[x][y].value === squares[i][j].value) {
+ moved = game.mergeTiles(i, j, x, y);
+ if (moved) {
+ boardChanged = true;
+ }
+ }
+ }
+ }
+ }
+ } while (moved);
+ for (var i = 0; i < gridSize; i++) {
+ for (var j = 0; j < gridSize; j++) {
+ if (squares[i][j] !== null) {
+ squares[i][j].merged = false;
+ }
+ }
}
- 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;
+};
+game.on('down', function (x, y, obj) {
+ var anyTileMoving = squares.some(function (row) {
+ return row.some(function (tile) {
+ return tile && tile.isMoving;
+ });
+ });
+ if (!anyTileMoving) {
+ var pos = game.toLocal(obj.global);
+ swipeStart = {
+ x: pos.x,
+ y: pos.y
+ };
}
- 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";
+});
+game.on('up', function (x, y, obj) {
+ var pos = game.toLocal(obj.global);
+ swipeEnd = {
+ x: pos.x,
+ y: pos.y
+ };
+ var dx = swipeEnd.x - swipeStart.x;
+ var dy = swipeEnd.y - swipeStart.y;
+ var threshold = 50;
+ if (Math.abs(dx) > threshold || Math.abs(dy) > threshold) {
+ if (Math.abs(dx) > Math.abs(dy)) {
+ if (dx > 0) {
+ game.moveTiles('right');
+ } else {
+ game.moveTiles('left');
+ }
+ } else {
+ if (dy > 0) {
+ game.moveTiles('down');
+ } else {
+ game.moveTiles('up');
+ }
+ }
+ if (tutorialTxt) {
+ LK.gui.bottom.removeChild(tutorialTxt);
+ tutorialTxt = null;
+ }
}
- // 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);
+});
+LK.on('tick', function () {
+ var allTilesStopped = true;
+ for (var i = 0; i < gridSize; i++) {
+ for (var j = 0; j < gridSize; j++) {
+ if (squares[i][j] !== null) {
+ if (!squares[i][j]._move_migrated()) {
+ allTilesStopped = false;
+ }
}
- // Note: We no longer automatically add a tile here
- // because tiles will be added when crossing borders
- // Check win condition
- if (grid.hasWon()) {
- LK.showYouWin();
- return;
+ }
+ }
+ for (var i = 0; i < toBeRemoved.length; i++) {
+ if (!toBeRemoved[i]._move_migrated()) {
+ allTilesStopped = false;
+ } else {
+ toBeRemoved[i].destroy();
+ toBeRemoved.splice(i, 1);
+ i--;
+ }
+ }
+ if (allTilesStopped) {
+ for (var i = 0; i < gridSize; i++) {
+ for (var j = 0; j < gridSize; j++) {
+ if (squares[i][j] !== null && squares[i][j].newValue) {
+ squares[i][j].updateToRealValue();
+ if (squares[i][j].value === 2048 && !winMessageShown) {
+ var winMessage = new Text2('Congratulations\n you win!', {
+ size: 150,
+ fill: '#ffffff',
+ font: 'Sans-Serif',
+ weight: '800',
+ stroke: '#000000',
+ strokeThickness: 25,
+ align: 'center'
+ });
+ winMessage.anchor.set(0.5, 0.5);
+ LK.gui.center.addChild(winMessage);
+ winMessageShown = true;
+ LK.setTimeout(function () {
+ LK.gui.center.removeChild(winMessage);
+ }, 5000);
+ }
+ }
}
- // Check if game is over
- if (grid.isGameOver()) {
- LK.showGameOver();
- return;
+ }
+ if (boardChanged) {
+ game.addRandomTile();
+ boardChanged = false;
+ var maxTileValue = Math.max.apply(Math, squares.map(function (row) {
+ return Math.max.apply(Math, row.map(function (tile) {
+ return tile ? tile.value : 0;
+ }));
+ }));
+ var newScore = maxTileValue;
+ LK.setScore(newScore);
+ scoreTxt.setText(newScore.toString());
+ }
+ if (!game.checkPossibleMoves()) {
+ for (var i = 0; i < gridSize; i++) {
+ for (var j = 0; j < gridSize; j++) {
+ if (squares[i][j] !== null) {
+ squares[i][j].alpha = 1;
+ squares[i][j].scale.set(1);
+ }
+ }
}
+ LK.showGameOver();
}
- // 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
-};
-// Game update function
-game.update = function () {
- if (grid && !isProcessing && gameStarted) {
- grid.update();
}
-};
-// Initialize the game when loaded
-initializeGame();
-;
\ No newline at end of file
+});
\ No newline at end of file