User prompt
move down mergeModeText by 50px
User prompt
move down mergeModeText by 50px
User prompt
Move down mergeModeText by 50px
User prompt
insert a line break after Tap a tile to merge
User prompt
Update mergemodetext to Tap a tile to merge all tiles into it
User prompt
Move up mergeModeText by 150px
User prompt
with mergeModeText set weight:800
User prompt
Set mergeModeText font size to 130 make color #000000 and add white drop shadow
User prompt
Do not auto hide mergeModeText, instead delete the text when setMergeMode switches back to false
User prompt
set mergeModeText y anchor to 1 and set mergeModeText.y to -40
User prompt
Don't set x or y on mergeModeText
User prompt
Fix Bug: 'TypeError: undefined is not an object (evaluating 'LK.gui.bottomCenter.addChild')' in this line: 'LK.gui.bottomCenter.addChild(mergeModeText);' Line Number: 251
User prompt
The first time the game switches to merge mode, show a text saying "Click tile to merge" at the bottom center of the screen.
User prompt
in while (self.toTest.length > 0) { in processMergeAndGameOver just loop all cells
User prompt
in cell set totalTypes to 6
User prompt
Update totalTypes in Cell to 8
User prompt
update self.score += pointsEarned; to self.score += self.scoreMultiplier
User prompt
Don't allow showGameOver to be called if game is in mergeMode
User prompt
Make point text stroke 12x
User prompt
Remove the random position code from point text
User prompt
Points earned should multiply in connected neighborhoods length
User prompt
Move pointsText before connects neighbors by rewriting the by forEach
User prompt
Add 50px x y random to point text
User prompt
Move up point text by 200px
User prompt
Move up point text by 100px
function hsvToRgb(h, s, v) {
var i = Math.floor(h * 6), f = h * 6 - i, p = v * (1 - s), q = v * (1 - f * s), t = v * (1 - (1 - f) * s), mod = i % 6, r = [v, q, p, p, t, v][mod], g = [t, v, v, q, p, p][mod], b = [p, p, t, v, v, q][mod];
return (r * 255 << 16) + (g * 255 << 8) + b * 255;
}
var Tile = Container.expand(function (type) {
var self = Container.call(this);
var tileGraphics = self.createAsset('tile', 'Grid Tile', .5, .5);
tileGraphics.alpha = 0;
self.targetX = 0;
self.targetY = 0;
self.isMoving = false;
self.totalTypes = 3;
self.type = type || Math.floor(Math.random() * self.totalTypes);
var hue = self.type / self.totalTypes;
var color = hsvToRgb(hue, 0.5, 1);
tileGraphics.tint = color;
self.cells = [];
var cellWidth = 0;
var cellHeight = 0;
self.structure = [];
if (self.type === 0) {
self.structure = [[1, 1]];
var cell1 = new Cell();
var cell2 = new Cell();
cellWidth = cell1.width;
cellHeight = cell1.height;
self.cells.push(cell1);
self.cells.push(cell2);
} else if (self.type === 1) {
self.structure = [[1], [1]];
var cell1 = new Cell();
var cell2 = new Cell();
cellWidth = cell1.width;
cellHeight = cell1.height;
self.cells.push(cell1);
self.cells.push(cell2);
} else if (self.type === 2) {
self.structure = [[1]];
var cell1 = new Cell();
cellWidth = cell1.width;
cellHeight = cell1.height;
self.cells.push(cell1);
}
self.cells.forEach(function (cell, index) {
if (self.type === 0) {
cell.x = index === 0 ? self.x - cellWidth / 2 : self.x + cellWidth / 2;
cell.y = self.y;
} else if (self.type === 1) {
cell.x = self.x;
cell.y = index === 0 ? self.y - cellHeight / 2 : self.y + cellHeight / 2;
}
self.addChild(cell);
});
self.move = function (x, y, instant) {
self.targetX = x;
self.targetY = y;
if (instant) {
self.x = x;
self.y = y;
}
};
self.tick = function () {
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 1) {
self.x += dx * 0.15;
self.y += dy * 0.15;
self.isMoving = true;
} else {
self.x = self.targetX;
self.y = self.targetY;
self.isMoving = false;
}
};
});
var GridBackgroundCell = Container.expand(function () {
var self = Container.call(this);
var bgCellGraphics = self.createAsset('gridCell', 'Background Grid Cell', 0.5, 0.5);
bgCellGraphics.alpha = 0.5;
bgCellGraphics.x += 10;
bgCellGraphics.y += 15;
self.setAlphaAndTint = function (alpha, tint) {
bgCellGraphics.alpha = 0.5;
bgCellGraphics.tint = tint;
};
});
var Cell = Container.expand(function (type) {
var self = Container.call(this);
var cellGraphics = self.createAsset('cell', 'Grid Cell', .5, .5);
var clockGraphics = self.createAsset('clock', 'Clock Graphics', .5, .5);
clockGraphics.y = -8;
clockGraphics.x = -4;
clockGraphics.blendMode = 2;
self.targetX = 0;
self.targetY = 0;
self.isMoving = false;
self.totalTypes = 5;
self.type = type !== undefined ? type : Math.floor(Math.random() * self.totalTypes);
var hue = self.type / self.totalTypes;
var color = hsvToRgb(hue, 0.25, 1);
cellGraphics.tint = color;
clockGraphics.rotation = self.type * (2 * Math.PI / self.totalTypes);
self.move = function (x, y, instant) {
self.targetX = x;
self.targetY = y;
if (instant) {
self.x = x;
self.y = y;
}
};
self.tick = function () {
var acceleration = 1;
self.speedX = self.speedX || 0;
self.speedY = self.speedY || 0;
var threshold = 1;
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
if (Math.abs(dx) < threshold && Math.abs(dy) < threshold) {
self.x = self.targetX;
self.y = self.targetY;
self.isMoving = false;
self.speedX = 0;
self.speedY = 0;
} else {
if (dx !== 0) {
self.speedX += dx > 0 ? acceleration : -acceleration;
}
if (dy !== 0) {
self.speedY += dy > 0 ? acceleration : -acceleration;
}
var nextX = self.x + self.speedX;
var nextY = self.y + self.speedY;
if (self.speedX > 0 && nextX > self.targetX || self.speedX < 0 && nextX < self.targetX) {
nextX = self.targetX;
self.speedX = 0;
}
if (self.speedY > 0 && nextY > self.targetY || self.speedY < 0 && nextY < self.targetY) {
nextY = self.targetY;
self.speedY = 0;
}
self.x = nextX;
self.y = nextY;
self.isMoving = self.x !== self.targetX || self.y !== self.targetY;
}
};
});
var Game = Container.expand(function () {
var self = Container.call(this);
self.processMergeAndGameOver = function (force) {
force = force || false;
var isAnyRowMoving = grid.some(row => row.some(cell => cell && cell.isMoving));
if (!isAnyRowMoving && !self.mergeMode || force) {
while (self.toTest.length > 0) {
var cell = self.toTest.shift();
var colRow = self.findCellColRow(cell);
var connectedNeighbors = self.findConnectedNeighbors(cell);
if (connectedNeighbors.length >= 3) {
toMerge.push(connectedNeighbors);
self.setMergeMode(true);
}
}
if (self.mergeMode) {
grid.forEach(function (row) {
row.forEach(function (cell) {
if (cell && !toMerge.some(function (mergeGroup) {
return mergeGroup.includes(cell);
})) {
cell.alpha = 0.4;
}
});
});
}
var isAnyTileMoving = bottomTiles.some(function (tile) {
return tile.isMoving;
});
isAnyRowMoving = grid.some(row => row.some(cell => cell && cell.isMoving));
if (!isAnyTileMoving && !self.canPlaceAnyTile() && !isAnyRowMoving && toDelete.length === 0) {
LK.showGameOver();
}
}
};
self.addAndHandleCell = function (targetCell) {
gridContainer.addChild(targetCell);
targetCell.on('down', function () {
if (self.mergeMode) {
self.mergeConnectedNeighbors(targetCell);
}
});
};
self.mergeConnectedNeighbors = function (cell) {
var connectedNeighbors = self.findConnectedNeighbors(cell);
if (connectedNeighbors.length >= 3) {
var colRow = self.findCellColRow(cell);
var newType = (cell.type + 1) % cell.totalTypes;
var newCell = new Cell(newType);
newCell.visible = false;
connectedNeighbors.forEach(function (neighborCell) {
var neighborColRow = self.findCellColRow(neighborCell);
if (neighborColRow) {
grid[neighborColRow.col][neighborColRow.row] = null;
neighborCell.isMoving = true;
toDelete.push(neighborCell);
neighborCell.move(cell.x, cell.y);
self.score += 1 * self.scoreMultiplier;
scoreTxt.setText(self.score.toString());
var pointsEarned = 1 * self.scoreMultiplier;
var pointsText = new Text2('+' + pointsEarned, {
size: 180,
fill: '#000000',
weight: '800',
align: 'center',
stroke: '#ffffff',
strokeThickness: 6
});
pointsText.anchor.set(.5, .5);
pointsText.x = cell.x;
pointsText.y = cell.y - 100;
gridContainer.addChild(pointsText);
LK.setTimeout(function () {
pointsText.destroy();
}, 1000);
}
}, this);
if (colRow) {
var targetPos = this.calculateTargetPosition(colRow.col, colRow.row);
newCell.move(targetPos.x, targetPos.y, true);
newCell.isMoving = true;
grid[colRow.col][colRow.row] = newCell;
self.addAndHandleCell(newCell);
}
self.scoreMultiplier += 1;
}
};
var bottomTilesContainer = new Container();
self.setMergeMode = function (mode) {
self.mergeMode = mode;
bottomTilesContainer.alpha = mode ? 0.4 : 1;
};
self.setMergeMode(false);
self.score = 0;
self.scoreMultiplier = 1;
LK.stageContainer.setBackgroundColor(0xffffff);
var backgroundGraphics = self.createAsset('background', 'Background Graphics', .5, .5);
self.addChild(backgroundGraphics);
backgroundGraphics.x = 2048 / 2;
backgroundGraphics.y = 2732 / 2;
backgroundGraphics.alpha = 0.5;
var bottomTileBackground = self.createAsset('bottomTileBackground', 'Bottom Tile Background', .5, 1);
self.addChild(bottomTileBackground);
bottomTileBackground.x = 2048 / 2;
bottomTileBackground.y = 2732;
bottomTileBackground.alpha = 0.5;
self.findCellColRow = function (cell) {
for (var col = 0; col < gridWidth; col++) {
for (var row = 0; row < gridHeight; row++) {
if (grid[col][row] === cell) {
return {
col: col,
row: row
};
}
}
}
return null;
};
self.canPlaceAnyTile = function () {
for (var i = 0; i < bottomTiles.length; i++) {
var tile = bottomTiles[i];
for (var col = 0; col < gridWidth; col++) {
for (var row = 0; row < gridHeight; row++) {
if (self.canPlaceTile(tile, col, row)) {
return true;
}
}
}
}
return false;
};
self.canPlaceTile = function (tile, gridX, gridY) {
for (var row = 0; row < tile.structure.length; row++) {
for (var col = 0; col < tile.structure[row].length; col++) {
if (tile.structure[row][col] === 1) {
var targetCol = gridX + col;
var targetRow = gridY + row;
if (targetCol < 0 || targetCol >= gridWidth || targetRow < 0 || targetRow >= gridHeight) {
return false;
}
if (grid[targetCol][targetRow]) {
return false;
}
}
}
}
return true;
};
self.toTest = [];
this.getOverlappingCells = function (tile) {
var overlappingCells = [];
var shouldReturnEmpty = false;
tile.cells.forEach(function (cell) {
var cellBounds = cell.getBounds();
for (var i = 0; i < gridWidth; i++) {
for (var j = 0; j < gridHeight; j++) {
var bgCell = bgGrid[i][j];
var bgCellBounds = bgCell.getBounds();
if (cellBounds.contains(bgCellBounds.x + bgCellBounds.width / 2, bgCellBounds.y + bgCellBounds.height / 2)) {
if (grid[i][j]) {
shouldReturnEmpty = true;
break;
}
overlappingCells.push(bgCell);
}
}
if (shouldReturnEmpty) {
break;
}
}
});
if (shouldReturnEmpty) {
return [];
}
return overlappingCells;
};
self.resetBackgroundGridCells = function () {
for (var i = 0; i < gridWidth; i++) {
for (var j = 0; j < gridHeight; j++) {
var bgCell = bgGrid[i][j];
bgCell.setAlphaAndTint(0.7, 0xFFFFFF);
}
}
};
var gridWidth = 5;
var gridHeight = 5;
var gridSpacing = 2;
var tempTile = new Tile();
var tileWidth = tempTile.width;
var tileHeight = tempTile.height;
tempTile.destroy();
var tempCell = new Cell();
var cellWidth = 320;
var cellHeight = 320;
tempCell.destroy();
var gridContainer = new Container();
self.addChild(gridContainer);
var totalGridWidth = gridWidth * (cellWidth + gridSpacing) - gridSpacing;
var totalGridHeight = gridHeight * (cellHeight + gridSpacing) - gridSpacing;
gridContainer.x = (2048 - totalGridWidth) / 2 + cellWidth / 2;
gridContainer.y = (2732 - totalGridHeight) / 2 + cellHeight / 2 - 290;
self.calculateTargetPosition = function (col, row) {
return {
x: col * (cellWidth + gridSpacing),
y: row * (cellHeight + gridSpacing)
};
};
self.findConnectedNeighbors = function (cell, connectedNeighbors) {
connectedNeighbors = connectedNeighbors || [];
if (!cell) return [];
var cellType = cell.type;
var cellColRow = self.findCellColRow(cell);
if (cellColRow) {
var directions = [[-1, 0], [1, 0], [0, -1], [0, 1]];
directions.forEach(function (dir) {
var newRow = cellColRow.row + dir[0];
var newCol = cellColRow.col + dir[1];
if (newRow >= 0 && newRow < gridHeight && newCol >= 0 && newCol < gridWidth) {
var neighborCell = grid[newCol][newRow];
if (neighborCell && neighborCell.visible && neighborCell.type === cellType && connectedNeighbors.indexOf(neighborCell) === -1) {
connectedNeighbors.push(neighborCell);
self.findConnectedNeighbors(neighborCell, connectedNeighbors);
}
}
});
}
return connectedNeighbors;
};
self.findBgCellColRow = function (bgCell) {
for (var col = 0; col < gridWidth; col++) {
for (var row = 0; row < gridHeight; row++) {
if (bgGrid[col][row] === bgCell) {
return {
col: col,
row: row
};
}
}
}
return null;
};
var grid = Array(5).fill().map(() => Array(5).fill(null));
var bgGrid = Array(5).fill().map(() => Array(5).fill(null));
for (var i = 0; i < gridWidth; i++) {
for (var j = 0; j < gridHeight; j++) {
var bgCell = new GridBackgroundCell();
var targetPos = self.calculateTargetPosition(i, j);
bgCell.x = targetPos.x;
bgCell.y = targetPos.y;
bgGrid[i][j] = bgCell;
gridContainer.addChild(bgCell);
}
}
for (var k = 0; k < 2; k++) {
var randomCol = Math.floor(Math.random() * gridWidth);
var randomRow = Math.floor(Math.random() * gridHeight);
while (grid[randomCol][randomRow]) {
randomCol = Math.floor(Math.random() * gridWidth);
randomRow = Math.floor(Math.random() * gridHeight);
}
var cell = new Cell();
var targetPos = self.calculateTargetPosition(randomCol, randomRow);
cell.move(targetPos.x, targetPos.y, true);
grid[randomCol][randomRow] = cell;
self.addAndHandleCell(cell);
}
stage.on('move', function (obj) {
if (draggedTile) {
var pos = obj.event.getLocalPosition(self);
draggedTile.x = pos.x;
draggedTile.y = pos.y;
self.highlightOverlappingCells(draggedTile);
}
});
self.highlightOverlappingCells = function (tile) {
self.resetBackgroundGridCells();
var overlappingCells = self.getOverlappingCells(tile);
if (overlappingCells.length !== tile.cells.length) return;
overlappingCells.forEach(function (bgCell) {
bgCell.setAlphaAndTint(1, 0xFFFFFF);
});
};
LK.on('tick', function () {
if (toDelete.length > 0) {
var allNotMoving = toDelete.every(function (cell) {
return !cell.isMoving;
});
if (allNotMoving) {
if (toDelete.length > 0) {
self.setMergeMode(false);
grid.forEach(function (row) {
row.forEach(function (cell) {
if (cell) cell.alpha = 1;
});
});
toMerge.forEach(function (group) {
group.forEach(function (cell) {
self.toTest.push(cell);
});
});
toMerge = [];
self.processMergeAndGameOver(true);
}
toDelete.forEach(function (cell) {
cell.destroy();
});
toDelete = [];
for (var i = 0; i < gridWidth; i++) {
for (var j = 0; j < gridHeight; j++) {
if (grid[i][j] && !grid[i][j].visible) {
grid[i][j].visible = true;
self.toTest.push(grid[i][j]);
}
}
}
} else {
for (var i = 0; i < toDelete.length; i++) {
toDelete[i].tick();
}
}
}
for (var i = 0; i < gridWidth; i++) {
for (var j = 0; j < gridHeight; j++) {
if (grid[i][j]) grid[i][j].tick();
}
}
for (var i = 0; i < bottomTiles.length; i++) {
if (bottomTiles[i] !== draggedTile) {
bottomTiles[i].tick();
}
}
var isAnyRowMoving = grid.some(row => row.some(cell => cell && cell.isMoving));
self.processMergeAndGameOver();
});
var bottomTiles = [];
var toDelete = [];
var toMerge = [];
var draggedTile = null;
self.addBottomTiles = function () {
var numberOfTiles = 3;
var totalTilesWidth = numberOfTiles * tileWidth + (numberOfTiles - 1) * gridSpacing;
var margin = (2048 - totalTilesWidth) / 2;
var spacing = margin + tileWidth / 2;
var posY = 2732 - tileHeight / 2 - margin;
for (var i = 0; i < numberOfTiles; i++) {
var tile = new Tile();
var posX = spacing + i * (tileWidth + gridSpacing);
tile.move(posX, 2732 + tileHeight, true);
tile.move(posX, posY);
bottomTiles[i] = tile;
tile.on('down', function () {
if (self.mergeMode) return;
draggedTile = this;
self.scoreMultiplier = 1;
});
bottomTilesContainer.addChild(tile);
}
};
var scoreTxt = new Text2('0', {
size: 150,
fill: '#24272b',
font: 'Impact',
dropShadow: true,
dropShadowColor: '#ffffff',
dropShadowBlur: 4,
dropShadowAngle: Math.PI / 6,
dropShadowDistance: 6
});
scoreTxt.anchor.set(.5, 0);
LK.gui.topCenter.addChild(scoreTxt);
self.addChild(bottomTilesContainer);
stage.on('up', function (obj) {
self.resetBackgroundGridCells();
if (draggedTile) {
var overlappingCells = self.getOverlappingCells(draggedTile);
if (overlappingCells.length === draggedTile.cells.length) {
overlappingCells.forEach(function (bgCell, index) {
var colRow = self.findBgCellColRow(bgCell);
if (colRow && draggedTile.cells[index]) {
var cell = draggedTile.cells[index];
var targetPos = self.calculateTargetPosition(colRow.col, colRow.row);
cell.move(targetPos.x, targetPos.y, true);
grid[colRow.col][colRow.row] = cell;
self.addAndHandleCell(cell);
self.toTest.push(cell);
}
});
var tileIndex = bottomTiles.indexOf(draggedTile);
if (tileIndex !== -1) {
bottomTiles.splice(tileIndex, 1);
}
draggedTile.destroy();
if (bottomTiles.length === 0) {
self.addBottomTiles();
}
draggedTile = null;
}
}
draggedTile = null;
});
self.addBottomTiles();
});
Simple White square round corners. Vector. No details. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Background for relaxing puzzle game. Pastel colors, flat shaded, vector art. Flowers. Blocks. Relaxing. Clouds Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Simple White square round corners. Vector. No details. Single Game Texture. In-Game asset. 2d. White background. High contrast. No shadows.
Simple black arrow pointing up. Mouse cursor like.