User prompt
You crate bottomTilesContainer twice, delete the second version. Rewrite the next line as well to make sure you delete the right version
User prompt
bottomTilesContainer should be created and attached before setMergeMode is created
Code edit (1 edits merged)
Please save this source code
User prompt
after defining bottomTilesContainer attach it to self
User prompt
Where you do var bottomTilesContainer = new Container(); self.addChild(bottomTilesContainer); delete var bottomTilesContainer = new Container(); as it's already defined
User prompt
Move var bottomTilesContainer = new Container(); to before self.setMergeMode =
User prompt
Fix Bug: 'TypeError: undefined is not an object (evaluating 'bottomTilesContainer.alpha = mode ? 0.4 : 1')' in this line: 'bottomTilesContainer.alpha = mode ? 0.4 : 1;' Line Number: 220
User prompt
In self.setMergeMode set bottomTilesContainer alpha to .4 if mergeMode is true otherwise set it to 1
User prompt
in tick use setMergeMode instead of setting the value direclty
User prompt
In the code, rather than setting mergeMode directly call setMergeMode
User prompt
add a new convenience method to game that sets mergeMode to true or false
Code edit (4 edits merged)
Please save this source code
User prompt
In game, add a new container for bottom tile elements. Just use a simple container
User prompt
Set highscore text to 24272b with a white drop shadow
User prompt
In cell set the s component of hsv to .25
Code edit (1 edits merged)
Please save this source code
User prompt
before calling self.processMergeAndGameOver(true); in tick. Move all cells from toMerge to toTest
User prompt
when calling processMergeAndGameOver inside the allNotMoving test, set force to true
User prompt
add a force property to processMergeAndGameOver
User prompt
set score color to 96bfc8
User prompt
In the if (self.mergeMode) { test in processMergeAndGameOver set alpha to .4
User prompt
In the if (self.mergeMode) { test in processMergeAndGameOver set alpha to .3
User prompt
in tick, before calling processMergeAndGameOver set all elements of grid (not bggrid) alpha to 1
User prompt
only run the grid.forEach(function (row) { code in processMergeAndGameOver if mergeMode is true
User prompt
at the bottom of processMergeAndGameOver, inside the if (!isAnyRowMoving && !self.mergeMode) { test set the alpha on all grid (not bggrid) elements that does not belong to toMerge to .5
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.3, 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 () {
var isAnyRowMoving = grid.some(row => row.some(cell => cell && cell.isMoving));
if (!isAnyRowMoving && !self.mergeMode) {
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.mergeMode = true;
}
}
grid.forEach(function (row) {
row.forEach(function (cell) {
if (cell && !toMerge.some(function (mergeGroup) {
return mergeGroup.includes(cell);
})) {
cell.alpha = 0.5;
}
});
});
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;
scoreTxt.setText(self.score.toString());
}
}, 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.mergeMode = false;
self.score = 0;
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.mergeMode = false;
self.processMergeAndGameOver();
}
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.addChild(tile);
}
};
var scoreTxt = new Text2('0', {
size: 150,
fill: '#ffffff',
font: 'Impact',
dropShadow: true,
dropShadowColor: '#000000',
dropShadowBlur: 4,
dropShadowAngle: Math.PI / 6,
dropShadowDistance: 6
});
scoreTxt.anchor.set(.5, 0);
LK.gui.topCenter.addChild(scoreTxt);
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.