User prompt
in GridBackgroundCell set bgCellGraphics alpha to 0.5
User prompt
in setAlphaAndTint set alpha to the alpha variable passed to the method
User prompt
in GridBackgroundCell set bgCellGraphics.alpha to .6
User prompt
in GridBackgroundCell setAlphaAndTint method set bgCellGraphics alpha to the alpha passed as a variable.
User prompt
in setAlphaAndTint set bgCellGraphics alpha to the alpha passed to the variable
User prompt
in setAlphaAndTint set bgCellGraphics alpha to the alpha passed to the variable
Code edit (1 edits merged)
Please save this source code
User prompt
Make cell fade twice as fast
User prompt
When adding elements to todelete.push, add the neighborCell to it's parent again, with addChildAt, and an index one smaller than cell
User prompt
In cell move, only have 20 steps
User prompt
Do not accelerate self.speedX and self.speedY in cell tick
Code edit (1 edits merged)
Please save this source code
User prompt
when calling move, if not instant, calculate a speed x and speed y that would move the cell to the target with a fixed amount of steps
User prompt
in cell tick, Reverte the if on allNotMoving
Code edit (1 edits merged)
Please save this source code
User prompt
in cell tick, do not run the hue and rotation update code if allNotMoving is true
Code edit (3 edits merged)
Please save this source code
User prompt
in game tick, pass the allNotMoving variable to cell tick
User prompt
remove the isAnyRowMoving line in game tick
User prompt
remove the isAnyRowMoving line
User prompt
define the allNotMoving in tick, outside the toDelete length check. We want to use this variable outside this if statement
Code edit (1 edits merged)
Please save this source code
User prompt
in cell when calling move set isMoving to true
Code edit (1 edits merged)
Please save this source code
User prompt
pass allNotMoving to tick on grid elements
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 ClockIndicator = Container.expand(function () {
var self = Container.call(this);
var indicatorGraphics = self.createAsset('clockIndicator', 'Clock Indicator Graphics', .5, .5);
return self;
});
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 (allNotMoving) {
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;
var indicatorAngles = [270, 330, 30, 90, 150, 210];
var indicatorDistance = 100;
indicatorAngles.forEach(function (angle) {
var radian = angle * (Math.PI / 180);
var indicatorX = clockGraphics.x + Math.cos(radian) * indicatorDistance;
var indicatorY = clockGraphics.y + Math.sin(radian) * indicatorDistance;
var indicator = self.addChild(new ClockIndicator());
indicator.x = indicatorX;
indicator.y = indicatorY;
indicator.rotation = radian;
});
self.targetX = 0;
self.targetY = 0;
self.targetAlpha = 1;
self.isMoving = false;
self.totalTypes = 6;
self.type = type !== undefined ? type : Math.floor(Math.random() * self.totalTypes);
self.realType = self.type;
self.currentHue = self.type / self.totalTypes;
self.targetHue = self.type / self.totalTypes;
self.targetRotation = self.type * (2 * Math.PI / self.totalTypes);
var color = hsvToRgb(self.targetHue, 0.25, 1);
cellGraphics.tint = color;
clockGraphics.rotation = self.targetRotation;
self.changeType = function (newType) {
self.type = newType % self.totalTypes;
self.realType = newType;
self.targetHue = self.realType / self.totalTypes;
self.targetRotation = self.realType * (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 (allNotMoving) {
if (self.currentHue !== self.targetHue) {
var hueDifference = self.targetHue - self.currentHue;
var hueStep = hueDifference * 0.05;
self.currentHue += hueStep;
if (Math.abs(hueDifference) < 0.01) {
self.currentHue = self.targetHue;
}
var color = hsvToRgb(self.currentHue, 0.25, 1);
cellGraphics.tint = color;
}
var alphaDifference = self.targetAlpha - self.alpha;
if (Math.abs(alphaDifference) > 0.01) {
self.alpha += alphaDifference * 0.05;
} else {
self.alpha = self.targetAlpha;
}
var rotationDifference = self.targetRotation - clockGraphics.rotation;
if (Math.abs(rotationDifference) > 0.01) {
clockGraphics.rotation += rotationDifference * 0.05;
} else {
clockGraphics.rotation = self.targetRotation;
}
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) {
grid.forEach(function (row) {
row.forEach(function (cell) {
if (cell) {
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.targetAlpha = 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 && !self.mergeMode) {
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.realType + 1;
var pointsEarned = connectedNeighbors.length * self.scoreMultiplier;
var pointsText = new Text2('+' + pointsEarned, {
size: 180,
fill: '#000000',
weight: '800',
align: 'center',
stroke: '#ffffff',
strokeThickness: 12
});
pointsText.anchor.set(.5, .5);
pointsText.x = cell.x;
pointsText.y = cell.y - 300;
gridContainer.addChild(pointsText);
LK.setTimeout(function () {
pointsText.destroy();
}, 1000);
connectedNeighbors.forEach(function (neighborCell) {
var neighborColRow = self.findCellColRow(neighborCell);
if (neighborColRow) {
if (neighborCell === cell) {
cell.changeType(newType);
gridContainer.removeChild(cell);
gridContainer.addChild(cell);
return;
}
grid[neighborColRow.col][neighborColRow.row] = null;
neighborCell.isMoving = true;
toDelete.push(neighborCell);
neighborCell.move(cell.x, cell.y);
self.score += self.scoreMultiplier;
scoreTxt.setText(self.score.toString());
}
}, this);
self.scoreMultiplier += 1;
}
};
var bottomTilesContainer = new Container();
self.setMergeMode = function (mode) {
self.mergeMode = mode;
bottomTilesContainer.alpha = mode ? 0.4 : 1;
if (!mode && self.mergeModeText) {
self.mergeModeText.destroy();
self.mergeModeText = null;
}
if (mode && !self.mergeModeTextShown) {
var mergeModeText = new Text2('Tap a tile to merge\nall tiles into it', {
size: 130,
fill: '#000000',
weight: '800',
align: 'center',
dropShadow: true,
dropShadowColor: '#ffffff',
dropShadowBlur: 4,
dropShadowAngle: Math.PI / 6,
dropShadowDistance: 6
});
mergeModeText.anchor.set(0.5, 1);
mergeModeText.y = -75;
LK.gui.bottom.addChild(mergeModeText);
self.mergeModeText = mergeModeText;
self.mergeModeTextShown = true;
}
};
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.targetAlpha = 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();
}
}
}
var isAnyRowMoving = grid.some(row => row.some(cell => cell && cell.isMoving));
var allNotMoving = !isAnyRowMoving;
for (var i = 0; i < gridWidth; i++) {
for (var j = 0; j < gridHeight; j++) {
if (grid[i][j]) grid[i][j].tick(allNotMoving);
}
}
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;
bottomTilesContainer.removeChild(this);
bottomTilesContainer.addChild(this);
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.