User prompt
in cell changeType calculate a new targetHue
User prompt
in marge connected neighbors in the foreach of connectedNeighbors, if the neighborCell is the current cell. Set type of cell to new type and return
User prompt
in merge connected neighbors, delete the code that inserts a new tile (Everything inside the colRow test)
User prompt
Fix Bug: 'TypeError: cell.setType is not a function. (In 'cell.setType(newType)', 'cell.setType' is undefined)' in this line: 'cell.setType(newType);' Line Number: 251
Code edit (1 edits merged)
Please save this source code
User prompt
At top of tick, if currentHue is different than targetHue animate currentHue towards target hue
User prompt
for hue, also have a current hue variable. Do not update this in changeType
User prompt
do no update current hue in changeType
User prompt
for hue, also have a current hue variable.
User prompt
At top of cell tick, outside the if statements. if hue or rotation is different than the current values. Animate towards the target values.
User prompt
At top of cell tick, outside the if statements. if hue or rotation is different than the current values. Animate towards the target values
User prompt
Add a new method to cell, that allows a cell to change type. Set type right away. However for hue and clockGraphics rotation. Rather than setting these directly. Create a target hue and target rotation property Do not change the current initialization of hue and rotation you currently do. Additionally do not implement anything in tick just yet.
Code edit (1 edits merged)
Please save this source code
User prompt
after defining changeType call it with the type the tile was initialized as
User prompt
Add a new method to cell, that allows a cell to change type. Set type right away. However for hue and clockGraphics rotation. Rather than setting these directly. Create a target hue and target rotation property
User prompt
When starting drag on a tile, first re attach it to make it render above all other tiles
User prompt
When creating indicators, also rotate them to their angle
User prompt
Rotate indicators as well
User prompt
Increase clock indicator spacing by 50
User prompt
Increase your hand spacing by 40
User prompt
Rotate indicator angles such that the first angle points straight up
User prompt
In cell, after you create clockGraphics create 6 clock indicators equally spaced around the cell, such that they are where the corners of a hexagon would be. Use simple graphics for this.
User prompt
move down mergeModeText by 15px
User prompt
move down mergeModeText by 30px
User prompt
move down mergeModeText by 50px
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 = 6;
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) {
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.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 && !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.type + 1) % cell.totalTypes;
var newCell = new Cell(newType);
newCell.visible = false;
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) {
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);
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;
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 = -40;
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.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.