User prompt
in processMergeAndGameOver if self.mergeMode is false, set score multiplier to 1 and update updateScoreMultiplier
Code edit (9 edits merged)
Please save this source code
User prompt
When changing scoreMultiplier also call updateScoreMultiplier
User prompt
set scoreMultiplierTxt x to -20
User prompt
create a label in the top right corner showing your current score multiplier with the format +x. Create the label during game init
Code edit (1 edits merged)
Please save this source code
User prompt
set scoreMultiplierDisplay.x to -10
User prompt
set anchor on scoreMultiplierDisplay to 1,0
User prompt
Create a label in the top right corner showing your current score multiplier with the format +x
User prompt
Show points multiplier in top right corner with the format +x
User prompt
In cell update alpha twice as fast
User prompt
In highlightOverlappingCells use tile.cells currentHue to calculate the target ting
Code edit (1 edits merged)
Please save this source code
User prompt
in resetBackgroundGridCells use .5 for alpha
User prompt
in highlightOverlappingCells use the tint colors of tile.cells to set tint
User prompt
in highlightOverlappingCells use the tint of the overlappingCells to set tint using setAlphaAndTint
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
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 () {
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;
} else {
var steps = 20;
self.speedX = (x - self.x) / steps;
self.speedY = (y - self.y) / steps;
}
};
self.tick = function (allNotMoving) {
if (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 rotationDifference = self.targetRotation - clockGraphics.rotation;
if (Math.abs(rotationDifference) > 0.01) {
clockGraphics.rotation += rotationDifference * 0.05;
} else {
clockGraphics.rotation = self.targetRotation;
}
}
var alphaDifference = self.targetAlpha - self.alpha;
if (Math.abs(alphaDifference) > 0.01) {
self.alpha += alphaDifference * 0.05;
} else {
self.alpha = self.targetAlpha;
}
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 {
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);
var cellIndex = gridContainer.getChildIndex(cell);
gridContainer.addChildAt(neighborCell, cellIndex - 1);
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 () {
var allNotMoving = toDelete.every(function (cell) {
return !cell.isMoving;
});
if (toDelete.length > 0) {
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();
}
}
}
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.