Code edit (1 edits merged)
Please save this source code
User prompt
pass allNotMoving to tick on grid elements
User prompt
when setting cell.alpha in game, set targetAlpha instead
User prompt
in tick, also animate alpha towards target alpha
User prompt
On cell, add a targetAlpha variable
User prompt
in cell when move is called set isMoving to true
User prompt
Don't run the hue or rotation difference code unless isMoving is false
User prompt
add clockGraphics x and y to indicator x and y
User prompt
add 15 to indicatorDistance
User prompt
we do not need the newCell in mergeConnectedNeighbors anymore remove this creation. Change no other code
User prompt
do not create the newCell in mergeConnectedNeighbors
User prompt
do not make newCell in mergeConnectedNeighbors
User prompt
in mergeConnectedNeighbors when calculating new type use cell.realType
User prompt
when setting type in changeType mod with totalTypes. Do not do this for realType. Leave this alone
User prompt
when setting self.type in changeType mod with totalTypes
User prompt
set self.realType in changeType to newType as well
User prompt
in changeType when setting type mod with totalTypes. do not do this for the variable realType
User prompt
in changeType when setting type mod with totalTypes. do not do this for real type
User prompt
in change type, first set realType to type. Then use realType for targetHue and target Rotation
User prompt
In cell introduce a realType, initialize it initially to the same value as type
User prompt
when calculating newType do not mod with totalTypes
User prompt
in connectedNeighbors when calling changeType re-attach the cell to make sure it renders onto
User prompt
in cell tick, also animate towards target rotation
User prompt
when change type in connectedNeighbors forEach, use the cell method to change type
User prompt
in cell changeType calculate a new targetHue
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 = Math.cos(radian) * indicatorDistance; var indicatorY = 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.isMoving = false; self.totalTypes = 6; self.type = type !== undefined ? type : Math.floor(Math.random() * self.totalTypes); 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.targetHue = self.type / self.totalTypes; self.targetRotation = 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 () { 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 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) { 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.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; 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(); });
===================================================================
--- original.js
+++ change.js
@@ -257,8 +257,10 @@
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;
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.