/**** * Classes ****/ var Cell = Container.expand(function (type, totalTypes) { var self = Container.call(this); self.targetX = 0; self.targetY = 0; self.isMoving = false; self.totalTypes = totalTypes; self.type = typeof type === 'undefined' ? Math.floor(Math.random() * self.totalTypes) : type; var assetName = 'cellType' + self.type; var cellBackground = self.attachAsset('cellBackground', { anchorX: 0.5, anchorY: 0.5 }); cellBackground.alpha = 0; var cellGraphics = self.createAsset(assetName, { anchorX: 0.5, anchorY: 0.5 }); self._move_migrated = function (x, y, instant) { self.targetX = x; self.targetY = y; if (instant) { self.x = x; self.y = y; } }; self.tick = function () { var acceleration = 2; 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; LK.getSound('bounce').play(); } if (self.speedY > 0 && nextY > self.targetY || self.speedY < 0 && nextY < self.targetY) { nextY = self.targetY; self.speedY = 0; LK.getSound('bounce').play(); } self.x = nextX; self.y = nextY; self.isMoving = self.x !== self.targetX || self.y !== self.targetY; } }; }); var Heart = Container.expand(function () { var self = Container.call(this); var heartBackground = self.attachAsset('heartBackground', { anchorX: 0.5, anchorY: 0.5 }); heartBackground.blendMode = 1; var heartGraphics = self.attachAsset('heart', { anchorX: 0.5, anchorY: 0.5 }); }); var HomeScreen = Container.expand(function () { var self = Container.call(this); // Add candy land background var background = self.attachAsset('candyLandBackground', { anchorX: 0.5, anchorY: 0.5 }); background.alpha = 0.7; // Create title text var titleText = new Text2("CANDY MATCH", { size: 180, fill: 0xFFFFFF, weight: '800', dropShadow: true, dropShadowColor: '#000000', dropShadowBlur: 4, dropShadowAngle: Math.PI / 6, dropShadowDistance: 9, stroke: '#000000', strokeThickness: 12 }); titleText.anchor.set(0.5, 0.5); titleText.y = -300; self.addChild(titleText); // Create play button var playButton = new Container(); var buttonBg = LK.getAsset('cellBackground', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.5, scaleY: 1.2 }); buttonBg.tint = 0x4d9e53; var playText = new Text2("PLAY", { size: 100, fill: 0xFFFFFF, weight: '800' }); playText.anchor.set(0.5, 0.5); playButton.addChild(buttonBg); playButton.addChild(playText); playButton.y = 100; // Add button press events playButton.interactive = true; playButton.on('down', function () { buttonBg.tint = 0x377a3c; playButton.y += 5; }); playButton.on('up', function () { buttonBg.tint = 0x4d9e53; playButton.y -= 5; self.onPlayPressed(); }); self.addChild(playButton); // Create candy decorations around the screen var candyCount = 16; for (var i = 0; i < candyCount; i++) { var candyType = i % 8; var candy = LK.getAsset('cellType' + candyType, { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.8 }); var angle = i / candyCount * Math.PI * 2; var radius = 600; candy.x = Math.cos(angle) * radius; candy.y = Math.sin(angle) * radius - 100; // Add rotation animation var rotationSpeed = Math.random() * 0.02 - 0.01; candy.rotationSpeed = rotationSpeed; candy.orbit = angle; candy.orbitSpeed = 0.003 + Math.random() * 0.002; candy.update = function () { this.rotation += this.rotationSpeed; this.orbit += this.orbitSpeed; this.x = Math.cos(this.orbit) * radius; this.y = Math.sin(this.orbit) * radius - 100; }; self.addChild(candy); } // Add floating candy particles for (var i = 0; i < 20; i++) { var particle = LK.getAsset('particle', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.5 + Math.random() * 0.5, scaleY: 0.5 + Math.random() * 0.5 }); // Random colors for candy particles var colors = [0xF06292, 0x9575CD, 0x4FC3F7, 0x81C784, 0xFFD54F, 0xFF8A65]; particle.tint = colors[Math.floor(Math.random() * colors.length)]; // Random position within screen bounds particle.x = (Math.random() - 0.5) * 1800; particle.y = (Math.random() - 0.5) * 1800; // Random movement pattern particle.speedX = (Math.random() - 0.5) * 2; particle.speedY = (Math.random() - 0.5) * 2; particle.update = function () { this.x += this.speedX; this.y += this.speedY; // Bounce off invisible boundaries if (Math.abs(this.x) > 900) { this.speedX *= -1; } if (Math.abs(this.y) > 900) { this.speedY *= -1; } }; self.addChild(particle); } // Callback for when play button is pressed self.onPlayPressed = function () { self.destroy(); game.startGame(); }; // Update function for animations self.update = function () { for (var i = 0; i < self.children.length; i++) { var child = self.children[i]; if (child.update) { child.update(); } } }; return self; }); var LifeIndicator = Container.expand(function (initialLives) { var self = Container.call(this); LifeIndicator.prototype.triggerLifeLostParticles = function (x, y) { var particleColors = [0xff0000, 0xff4500, 0xff6347]; for (var i = 0; i < 5; i++) { var color = particleColors[Math.floor(Math.random() * particleColors.length)]; var particle = new Particle(color, 0); particle.x = x; particle.y = y; particles.push(particle); this.addChild(particle); } }; self.lives = initialLives; self.hearts = []; var heartWidth = 110; var totalWidth = (self.lives - 1) * (heartWidth + 10); var startX = -totalWidth / 2; for (var i = 0; i < self.lives; i++) { var heart = new Heart(); heart.x = startX + i * (heartWidth + 10); self.hearts.push(heart); self.addChild(heart); } self.updateLives = function (lives) { lives = Math.max(0, lives); while (self.hearts.length > lives) { var heart = self.hearts.pop(); if (heart) { self.triggerLifeLostParticles(heart.x, heart.y); heart.destroy(); } } while (self.hearts.length < lives) { var newHeart = new Heart(); var heartWidth = 100; newHeart.x = startX + self.hearts.length * (heartWidth + 10); self.hearts.push(newHeart); self.addChild(newHeart); } self.lives = lives; }; }); var Particle = Container.expand(function (color, gravityMultiplier) { var self = Container.call(this); gravityMultiplier = typeof gravityMultiplier === 'undefined' ? 1 : gravityMultiplier; self.gravityMultiplier = gravityMultiplier; self.graphics = self.attachAsset('particle', { anchorX: 0.5, anchorY: 0.5 }); self.graphics.tint = color; self.speedX = (Math.random() - 0.5) * 10; self.speedY = (Math.random() - 0.5) * 10; self.scaleX = self.scaleY = Math.random() * 0.5 + 0.5; self.alpha = 1; self.tick = function () { self.x += self.speedX; self.speedY += 0.7 * self.gravityMultiplier; self.y += self.speedY; self.alpha -= 0.02; if (self.alpha <= 0) { var index = particles.indexOf(self); if (index > -1) { particles.splice(index, 1); } self.destroy(); } }; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x4e338c }); /**** * Game Code ****/ 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 particles = []; var homeScreen; var isGameStarted = false; // Create home screen at start function showHomeScreen() { homeScreen = new HomeScreen(); homeScreen.x = 2048 / 2; homeScreen.y = 2732 / 2; game.addChild(homeScreen); } // Initialize home screen when game starts showHomeScreen(); game.startGame = function () { isGameStarted = true; // Remove the background that may have been added in the home screen game.removeChildren(); // Initialize game components game.initializeGameComponents(); }; game.initializeGameComponents = function () { var background = game.attachAsset('background', { anchorX: 0.5, anchorY: 0.5 }); background.x = 2048 / 2; background.y = 2732 / 2; game.addChild(background); // Initialize grid container and board gridContainer = new Container(); game.addChild(gridContainer); boardBackground = game.attachAsset('boardBackground', { anchorX: 0.5, anchorY: 0.5 }); boardBackground.alpha = 0.7; gridContainer.addChildAt(boardBackground, 0); var totalGridWidth = gridWidth * (cellWidth + gridSpacing) - gridSpacing; var totalGridHeight = gridHeight * (cellHeight + gridSpacing) - gridSpacing; gridContainer.x = (2048 - totalGridWidth) / 2 + cellWidth / 2 + 3; gridContainer.y = (2732 - totalGridHeight) / 2 + cellHeight / 2 + 90; boardBackground.x = totalGridWidth / 2 - cellWidth / 2; boardBackground.y = totalGridHeight / 2 - cellHeight / 2 + 30; // Initialize score text scoreText = new Text2(score.toString(), { size: 150, fill: 0xFFFFFF, weight: '800', dropShadow: true, dropShadowColor: '#000000', dropShadowBlur: 4, dropShadowAngle: Math.PI / 6, dropShadowDistance: 9, stroke: '#000000', strokeThickness: 12 }); scoreText.anchor.set(.5, 0); LK.gui.top.addChild(scoreText); // Initialize life indicator lifeIndicator = new LifeIndicator(3); lifeIndicator.y = 260; LK.gui.top.addChild(lifeIndicator); // Initialize grid for (var i = 0; i < gridWidth; i++) { grid[i] = []; for (var j = 0; j < gridHeight; j++) { var cell = new Cell(undefined, game.totalCellTypes); var targetPos = game.calculateTargetPosition(i, j); cell._move_migrated(targetPos.x, targetPos.y, true); game.attachCellListeners(cell); grid[i][j] = cell; gridContainer.addChild(cell); } } }; game.createParticleEffect = function (x, y, type) { var fixedColors = [0x82d756, 0x5ecde9, 0xf8a4a0, 0x921d2a, 0x7719f9, 0xffffff, 0xefa63b, 0x7dd6a4]; var color = fixedColors[type % fixedColors.length]; for (var i = 0; i < 10; i++) { var particle = new Particle(color); particle.x = x + gridContainer.x; particle.y = y + gridContainer.y; particles.push(particle); this.addChild(particle); } }; game.totalCellTypes = 2; var score = 0; game.hasPossibleMoves = function () { for (var col = 0; col < gridWidth; col++) { for (var row = 0; row < gridHeight; row++) { var cell = grid[col][row]; if (cell) { var neighbors = [{ x: col - 1, y: row }, { x: col + 1, y: row }, { x: col, y: row - 1 }, { x: col, y: row + 1 }]; for (var i = 0; i < neighbors.length; i++) { var pos = neighbors[i]; if (pos.x >= 0 && pos.x < gridWidth && pos.y >= 0 && pos.y < gridHeight) { var neighborCell = grid[pos.x][pos.y]; if (neighborCell && neighborCell.type === cell.type) { return true; } } } } } } return false; }; game.resetBoard = function () { grid.forEach(function (column, colIndex) { column.forEach(function (cell, rowIndex) { if (cell) { game.deleteCell(cell); } var newCell = new Cell(undefined, game.totalCellTypes); var targetPos = game.calculateTargetPosition(colIndex, rowIndex); newCell._move_migrated(targetPos.x, targetPos.y, true); game.attachCellListeners(newCell); newCell.y = -100; grid[colIndex][rowIndex] = newCell; gridContainer.addChild(newCell); }); }); }; // Background is created in initializeGameComponents // Game element definitions var gridWidth = 8; var gridHeight = 8; var gridSpacing = 8; var cellWidth = 200; var cellHeight = 200; var gridContainer; var boardBackground; var grid = []; var scoreText; var lifeIndicator; game.calculateTargetPosition = function (col, row) { return { x: col * (cellWidth + gridSpacing), y: row * (cellHeight + gridSpacing) }; }; game.findConnectedNeighbors = function (cell, connectedNeighbors) { connectedNeighbors = connectedNeighbors || []; if (!cell) { return []; } var cellType = cell.type; var cellColRow = game.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.type === cellType && connectedNeighbors.indexOf(neighborCell) === -1) { connectedNeighbors.push(neighborCell); game.findConnectedNeighbors(neighborCell, connectedNeighbors); } } }); } return connectedNeighbors; }; game.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; }; game.deleteCell = function (cell) { var colRow = game.findCellColRow(cell); if (colRow) { grid[colRow.col][colRow.row] = null; game.createParticleEffect(cell.x, cell.y, cell.type); cell.destroy(); } }; game.attachCellListeners = function (cell) { cell.on('down', function (x, y, obj) { var connectedNeighbors = game.findConnectedNeighbors(cell); if (connectedNeighbors.length > 0) { score += 10 * connectedNeighbors.length + (connectedNeighbors.length - 2) * 5; LK.setScore(score); scoreText.setText(score.toString()); var cellsToDestroy = [cell].concat(connectedNeighbors); cellsToDestroy.forEach(function (cell) { game.deleteCell(cell); }); game.moveToEmptySpace('down', false); game.moveToEmptySpace('left', true); LK.getSound('pop').play(); } else { // If no matches are found, lose a life lifeIndicator.updateLives(lifeIndicator.lives - 1); // Check if game is over if (lifeIndicator.lives <= 0) { LK.getSound('gameOverJingle').play(); LK.showGameOver(); } } }); cell.on('up', function (x, y, obj) {}); cell.on('move', function (x, y, obj) {}); }; // Grid is initialized in the startGame method game.moveToEmptySpace = function (direction, rowMode) { var moved; do { moved = false; var dx = direction === 'left' ? 1 : direction === 'right' ? -1 : 0; var dy = direction === 'up' ? 1 : direction === 'down' ? -1 : 0; for (var col = 0; col < gridWidth; col++) { for (var row = 0; row < gridHeight; row++) { if (!grid[col][row]) { var isRowOrColumnEmpty = true; if (rowMode) { for (var checkIndex = 0; checkIndex < (direction === 'left' || direction === 'right' ? gridHeight : gridWidth); checkIndex++) { isRowOrColumnEmpty = isRowOrColumnEmpty && !grid[direction === 'left' || direction === 'right' ? col : checkIndex][direction === 'up' || direction === 'down' ? row : checkIndex]; } } if (isRowOrColumnEmpty) { if (rowMode) { for (var checkIndex = 0; checkIndex < (direction === 'left' || direction === 'right' ? gridHeight : gridWidth); checkIndex++) { var targetCol = direction === 'left' || direction === 'right' ? col : checkIndex; var targetRow = direction === 'up' || direction === 'down' ? row : checkIndex; if (targetCol + dx >= 0 && targetCol + dx < gridWidth && targetRow + dy >= 0 && targetRow + dy < gridHeight && grid[targetCol + dx][targetRow + dy]) { var targetCell = grid[targetCol + dx][targetRow + dy]; var targetPos = game.calculateTargetPosition(targetCol, targetRow); targetCell._move_migrated(targetPos.x, targetPos.y); grid[targetCol][targetRow] = targetCell; grid[targetCol + dx][targetRow + dy] = null; moved = true; } } } else { var targetCol = col + dx; var targetRow = row + dy; if (targetCol >= 0 && targetCol < gridWidth && targetRow >= 0 && targetRow < gridHeight && grid[targetCol][targetRow]) { var targetCell = grid[targetCol][targetRow]; var targetPos = game.calculateTargetPosition(col, row); targetCell._move_migrated(targetPos.x, targetPos.y); grid[col][row] = targetCell; grid[targetCol][targetRow] = null; moved = true; } } } } } } } while (moved); }; LK.on('tick', function () { // Update home screen if it exists if (homeScreen && !isGameStarted) { homeScreen.update(); return; } // Only run game logic if game has started if (isGameStarted) { for (var i = 0; i < gridWidth; i++) { for (var j = 0; j < gridHeight; j++) { if (grid[i][j]) { grid[i][j].tick(); } } } // Update all particles for (var i = particles.length - 1; i >= 0; i--) { particles[i].tick(); } var cellsAreMoving = grid.some(function (column) { return column.some(function (cell) { return cell && cell.isMoving; }); }); if (!cellsAreMoving && !game.hasPossibleMoves()) { game.totalCellTypes = Math.min(8, 3 + Math.floor(score / 2000)); var tilesLeft = grid.reduce(function (acc, column) { return acc + column.filter(function (cell) { return cell !== null; }).length; }, 0); lifeIndicator.updateLives(lifeIndicator.lives - tilesLeft); if (lifeIndicator.lives <= 0) { LK.getSound('gameOverJingle').play(); LK.showGameOver(); } else { game.resetBoard(); } } } });
/****
* Classes
****/
var Cell = Container.expand(function (type, totalTypes) {
var self = Container.call(this);
self.targetX = 0;
self.targetY = 0;
self.isMoving = false;
self.totalTypes = totalTypes;
self.type = typeof type === 'undefined' ? Math.floor(Math.random() * self.totalTypes) : type;
var assetName = 'cellType' + self.type;
var cellBackground = self.attachAsset('cellBackground', {
anchorX: 0.5,
anchorY: 0.5
});
cellBackground.alpha = 0;
var cellGraphics = self.createAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
self._move_migrated = function (x, y, instant) {
self.targetX = x;
self.targetY = y;
if (instant) {
self.x = x;
self.y = y;
}
};
self.tick = function () {
var acceleration = 2;
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;
LK.getSound('bounce').play();
}
if (self.speedY > 0 && nextY > self.targetY || self.speedY < 0 && nextY < self.targetY) {
nextY = self.targetY;
self.speedY = 0;
LK.getSound('bounce').play();
}
self.x = nextX;
self.y = nextY;
self.isMoving = self.x !== self.targetX || self.y !== self.targetY;
}
};
});
var Heart = Container.expand(function () {
var self = Container.call(this);
var heartBackground = self.attachAsset('heartBackground', {
anchorX: 0.5,
anchorY: 0.5
});
heartBackground.blendMode = 1;
var heartGraphics = self.attachAsset('heart', {
anchorX: 0.5,
anchorY: 0.5
});
});
var HomeScreen = Container.expand(function () {
var self = Container.call(this);
// Add candy land background
var background = self.attachAsset('candyLandBackground', {
anchorX: 0.5,
anchorY: 0.5
});
background.alpha = 0.7;
// Create title text
var titleText = new Text2("CANDY MATCH", {
size: 180,
fill: 0xFFFFFF,
weight: '800',
dropShadow: true,
dropShadowColor: '#000000',
dropShadowBlur: 4,
dropShadowAngle: Math.PI / 6,
dropShadowDistance: 9,
stroke: '#000000',
strokeThickness: 12
});
titleText.anchor.set(0.5, 0.5);
titleText.y = -300;
self.addChild(titleText);
// Create play button
var playButton = new Container();
var buttonBg = LK.getAsset('cellBackground', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.5,
scaleY: 1.2
});
buttonBg.tint = 0x4d9e53;
var playText = new Text2("PLAY", {
size: 100,
fill: 0xFFFFFF,
weight: '800'
});
playText.anchor.set(0.5, 0.5);
playButton.addChild(buttonBg);
playButton.addChild(playText);
playButton.y = 100;
// Add button press events
playButton.interactive = true;
playButton.on('down', function () {
buttonBg.tint = 0x377a3c;
playButton.y += 5;
});
playButton.on('up', function () {
buttonBg.tint = 0x4d9e53;
playButton.y -= 5;
self.onPlayPressed();
});
self.addChild(playButton);
// Create candy decorations around the screen
var candyCount = 16;
for (var i = 0; i < candyCount; i++) {
var candyType = i % 8;
var candy = LK.getAsset('cellType' + candyType, {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8
});
var angle = i / candyCount * Math.PI * 2;
var radius = 600;
candy.x = Math.cos(angle) * radius;
candy.y = Math.sin(angle) * radius - 100;
// Add rotation animation
var rotationSpeed = Math.random() * 0.02 - 0.01;
candy.rotationSpeed = rotationSpeed;
candy.orbit = angle;
candy.orbitSpeed = 0.003 + Math.random() * 0.002;
candy.update = function () {
this.rotation += this.rotationSpeed;
this.orbit += this.orbitSpeed;
this.x = Math.cos(this.orbit) * radius;
this.y = Math.sin(this.orbit) * radius - 100;
};
self.addChild(candy);
}
// Add floating candy particles
for (var i = 0; i < 20; i++) {
var particle = LK.getAsset('particle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5 + Math.random() * 0.5,
scaleY: 0.5 + Math.random() * 0.5
});
// Random colors for candy particles
var colors = [0xF06292, 0x9575CD, 0x4FC3F7, 0x81C784, 0xFFD54F, 0xFF8A65];
particle.tint = colors[Math.floor(Math.random() * colors.length)];
// Random position within screen bounds
particle.x = (Math.random() - 0.5) * 1800;
particle.y = (Math.random() - 0.5) * 1800;
// Random movement pattern
particle.speedX = (Math.random() - 0.5) * 2;
particle.speedY = (Math.random() - 0.5) * 2;
particle.update = function () {
this.x += this.speedX;
this.y += this.speedY;
// Bounce off invisible boundaries
if (Math.abs(this.x) > 900) {
this.speedX *= -1;
}
if (Math.abs(this.y) > 900) {
this.speedY *= -1;
}
};
self.addChild(particle);
}
// Callback for when play button is pressed
self.onPlayPressed = function () {
self.destroy();
game.startGame();
};
// Update function for animations
self.update = function () {
for (var i = 0; i < self.children.length; i++) {
var child = self.children[i];
if (child.update) {
child.update();
}
}
};
return self;
});
var LifeIndicator = Container.expand(function (initialLives) {
var self = Container.call(this);
LifeIndicator.prototype.triggerLifeLostParticles = function (x, y) {
var particleColors = [0xff0000, 0xff4500, 0xff6347];
for (var i = 0; i < 5; i++) {
var color = particleColors[Math.floor(Math.random() * particleColors.length)];
var particle = new Particle(color, 0);
particle.x = x;
particle.y = y;
particles.push(particle);
this.addChild(particle);
}
};
self.lives = initialLives;
self.hearts = [];
var heartWidth = 110;
var totalWidth = (self.lives - 1) * (heartWidth + 10);
var startX = -totalWidth / 2;
for (var i = 0; i < self.lives; i++) {
var heart = new Heart();
heart.x = startX + i * (heartWidth + 10);
self.hearts.push(heart);
self.addChild(heart);
}
self.updateLives = function (lives) {
lives = Math.max(0, lives);
while (self.hearts.length > lives) {
var heart = self.hearts.pop();
if (heart) {
self.triggerLifeLostParticles(heart.x, heart.y);
heart.destroy();
}
}
while (self.hearts.length < lives) {
var newHeart = new Heart();
var heartWidth = 100;
newHeart.x = startX + self.hearts.length * (heartWidth + 10);
self.hearts.push(newHeart);
self.addChild(newHeart);
}
self.lives = lives;
};
});
var Particle = Container.expand(function (color, gravityMultiplier) {
var self = Container.call(this);
gravityMultiplier = typeof gravityMultiplier === 'undefined' ? 1 : gravityMultiplier;
self.gravityMultiplier = gravityMultiplier;
self.graphics = self.attachAsset('particle', {
anchorX: 0.5,
anchorY: 0.5
});
self.graphics.tint = color;
self.speedX = (Math.random() - 0.5) * 10;
self.speedY = (Math.random() - 0.5) * 10;
self.scaleX = self.scaleY = Math.random() * 0.5 + 0.5;
self.alpha = 1;
self.tick = function () {
self.x += self.speedX;
self.speedY += 0.7 * self.gravityMultiplier;
self.y += self.speedY;
self.alpha -= 0.02;
if (self.alpha <= 0) {
var index = particles.indexOf(self);
if (index > -1) {
particles.splice(index, 1);
}
self.destroy();
}
};
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x4e338c
});
/****
* Game Code
****/
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 particles = [];
var homeScreen;
var isGameStarted = false;
// Create home screen at start
function showHomeScreen() {
homeScreen = new HomeScreen();
homeScreen.x = 2048 / 2;
homeScreen.y = 2732 / 2;
game.addChild(homeScreen);
}
// Initialize home screen when game starts
showHomeScreen();
game.startGame = function () {
isGameStarted = true;
// Remove the background that may have been added in the home screen
game.removeChildren();
// Initialize game components
game.initializeGameComponents();
};
game.initializeGameComponents = function () {
var background = game.attachAsset('background', {
anchorX: 0.5,
anchorY: 0.5
});
background.x = 2048 / 2;
background.y = 2732 / 2;
game.addChild(background);
// Initialize grid container and board
gridContainer = new Container();
game.addChild(gridContainer);
boardBackground = game.attachAsset('boardBackground', {
anchorX: 0.5,
anchorY: 0.5
});
boardBackground.alpha = 0.7;
gridContainer.addChildAt(boardBackground, 0);
var totalGridWidth = gridWidth * (cellWidth + gridSpacing) - gridSpacing;
var totalGridHeight = gridHeight * (cellHeight + gridSpacing) - gridSpacing;
gridContainer.x = (2048 - totalGridWidth) / 2 + cellWidth / 2 + 3;
gridContainer.y = (2732 - totalGridHeight) / 2 + cellHeight / 2 + 90;
boardBackground.x = totalGridWidth / 2 - cellWidth / 2;
boardBackground.y = totalGridHeight / 2 - cellHeight / 2 + 30;
// Initialize score text
scoreText = new Text2(score.toString(), {
size: 150,
fill: 0xFFFFFF,
weight: '800',
dropShadow: true,
dropShadowColor: '#000000',
dropShadowBlur: 4,
dropShadowAngle: Math.PI / 6,
dropShadowDistance: 9,
stroke: '#000000',
strokeThickness: 12
});
scoreText.anchor.set(.5, 0);
LK.gui.top.addChild(scoreText);
// Initialize life indicator
lifeIndicator = new LifeIndicator(3);
lifeIndicator.y = 260;
LK.gui.top.addChild(lifeIndicator);
// Initialize grid
for (var i = 0; i < gridWidth; i++) {
grid[i] = [];
for (var j = 0; j < gridHeight; j++) {
var cell = new Cell(undefined, game.totalCellTypes);
var targetPos = game.calculateTargetPosition(i, j);
cell._move_migrated(targetPos.x, targetPos.y, true);
game.attachCellListeners(cell);
grid[i][j] = cell;
gridContainer.addChild(cell);
}
}
};
game.createParticleEffect = function (x, y, type) {
var fixedColors = [0x82d756, 0x5ecde9, 0xf8a4a0, 0x921d2a, 0x7719f9, 0xffffff, 0xefa63b, 0x7dd6a4];
var color = fixedColors[type % fixedColors.length];
for (var i = 0; i < 10; i++) {
var particle = new Particle(color);
particle.x = x + gridContainer.x;
particle.y = y + gridContainer.y;
particles.push(particle);
this.addChild(particle);
}
};
game.totalCellTypes = 2;
var score = 0;
game.hasPossibleMoves = function () {
for (var col = 0; col < gridWidth; col++) {
for (var row = 0; row < gridHeight; row++) {
var cell = grid[col][row];
if (cell) {
var neighbors = [{
x: col - 1,
y: row
}, {
x: col + 1,
y: row
}, {
x: col,
y: row - 1
}, {
x: col,
y: row + 1
}];
for (var i = 0; i < neighbors.length; i++) {
var pos = neighbors[i];
if (pos.x >= 0 && pos.x < gridWidth && pos.y >= 0 && pos.y < gridHeight) {
var neighborCell = grid[pos.x][pos.y];
if (neighborCell && neighborCell.type === cell.type) {
return true;
}
}
}
}
}
}
return false;
};
game.resetBoard = function () {
grid.forEach(function (column, colIndex) {
column.forEach(function (cell, rowIndex) {
if (cell) {
game.deleteCell(cell);
}
var newCell = new Cell(undefined, game.totalCellTypes);
var targetPos = game.calculateTargetPosition(colIndex, rowIndex);
newCell._move_migrated(targetPos.x, targetPos.y, true);
game.attachCellListeners(newCell);
newCell.y = -100;
grid[colIndex][rowIndex] = newCell;
gridContainer.addChild(newCell);
});
});
};
// Background is created in initializeGameComponents
// Game element definitions
var gridWidth = 8;
var gridHeight = 8;
var gridSpacing = 8;
var cellWidth = 200;
var cellHeight = 200;
var gridContainer;
var boardBackground;
var grid = [];
var scoreText;
var lifeIndicator;
game.calculateTargetPosition = function (col, row) {
return {
x: col * (cellWidth + gridSpacing),
y: row * (cellHeight + gridSpacing)
};
};
game.findConnectedNeighbors = function (cell, connectedNeighbors) {
connectedNeighbors = connectedNeighbors || [];
if (!cell) {
return [];
}
var cellType = cell.type;
var cellColRow = game.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.type === cellType && connectedNeighbors.indexOf(neighborCell) === -1) {
connectedNeighbors.push(neighborCell);
game.findConnectedNeighbors(neighborCell, connectedNeighbors);
}
}
});
}
return connectedNeighbors;
};
game.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;
};
game.deleteCell = function (cell) {
var colRow = game.findCellColRow(cell);
if (colRow) {
grid[colRow.col][colRow.row] = null;
game.createParticleEffect(cell.x, cell.y, cell.type);
cell.destroy();
}
};
game.attachCellListeners = function (cell) {
cell.on('down', function (x, y, obj) {
var connectedNeighbors = game.findConnectedNeighbors(cell);
if (connectedNeighbors.length > 0) {
score += 10 * connectedNeighbors.length + (connectedNeighbors.length - 2) * 5;
LK.setScore(score);
scoreText.setText(score.toString());
var cellsToDestroy = [cell].concat(connectedNeighbors);
cellsToDestroy.forEach(function (cell) {
game.deleteCell(cell);
});
game.moveToEmptySpace('down', false);
game.moveToEmptySpace('left', true);
LK.getSound('pop').play();
} else {
// If no matches are found, lose a life
lifeIndicator.updateLives(lifeIndicator.lives - 1);
// Check if game is over
if (lifeIndicator.lives <= 0) {
LK.getSound('gameOverJingle').play();
LK.showGameOver();
}
}
});
cell.on('up', function (x, y, obj) {});
cell.on('move', function (x, y, obj) {});
};
// Grid is initialized in the startGame method
game.moveToEmptySpace = function (direction, rowMode) {
var moved;
do {
moved = false;
var dx = direction === 'left' ? 1 : direction === 'right' ? -1 : 0;
var dy = direction === 'up' ? 1 : direction === 'down' ? -1 : 0;
for (var col = 0; col < gridWidth; col++) {
for (var row = 0; row < gridHeight; row++) {
if (!grid[col][row]) {
var isRowOrColumnEmpty = true;
if (rowMode) {
for (var checkIndex = 0; checkIndex < (direction === 'left' || direction === 'right' ? gridHeight : gridWidth); checkIndex++) {
isRowOrColumnEmpty = isRowOrColumnEmpty && !grid[direction === 'left' || direction === 'right' ? col : checkIndex][direction === 'up' || direction === 'down' ? row : checkIndex];
}
}
if (isRowOrColumnEmpty) {
if (rowMode) {
for (var checkIndex = 0; checkIndex < (direction === 'left' || direction === 'right' ? gridHeight : gridWidth); checkIndex++) {
var targetCol = direction === 'left' || direction === 'right' ? col : checkIndex;
var targetRow = direction === 'up' || direction === 'down' ? row : checkIndex;
if (targetCol + dx >= 0 && targetCol + dx < gridWidth && targetRow + dy >= 0 && targetRow + dy < gridHeight && grid[targetCol + dx][targetRow + dy]) {
var targetCell = grid[targetCol + dx][targetRow + dy];
var targetPos = game.calculateTargetPosition(targetCol, targetRow);
targetCell._move_migrated(targetPos.x, targetPos.y);
grid[targetCol][targetRow] = targetCell;
grid[targetCol + dx][targetRow + dy] = null;
moved = true;
}
}
} else {
var targetCol = col + dx;
var targetRow = row + dy;
if (targetCol >= 0 && targetCol < gridWidth && targetRow >= 0 && targetRow < gridHeight && grid[targetCol][targetRow]) {
var targetCell = grid[targetCol][targetRow];
var targetPos = game.calculateTargetPosition(col, row);
targetCell._move_migrated(targetPos.x, targetPos.y);
grid[col][row] = targetCell;
grid[targetCol][targetRow] = null;
moved = true;
}
}
}
}
}
}
} while (moved);
};
LK.on('tick', function () {
// Update home screen if it exists
if (homeScreen && !isGameStarted) {
homeScreen.update();
return;
}
// Only run game logic if game has started
if (isGameStarted) {
for (var i = 0; i < gridWidth; i++) {
for (var j = 0; j < gridHeight; j++) {
if (grid[i][j]) {
grid[i][j].tick();
}
}
}
// Update all particles
for (var i = particles.length - 1; i >= 0; i--) {
particles[i].tick();
}
var cellsAreMoving = grid.some(function (column) {
return column.some(function (cell) {
return cell && cell.isMoving;
});
});
if (!cellsAreMoving && !game.hasPossibleMoves()) {
game.totalCellTypes = Math.min(8, 3 + Math.floor(score / 2000));
var tilesLeft = grid.reduce(function (acc, column) {
return acc + column.filter(function (cell) {
return cell !== null;
}).length;
}, 0);
lifeIndicator.updateLives(lifeIndicator.lives - tilesLeft);
if (lifeIndicator.lives <= 0) {
LK.getSound('gameOverJingle').play();
LK.showGameOver();
} else {
game.resetBoard();
}
}
}
});
Cartoon Christmas candy cane Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
White square. Narrow round corners. Background element. Flat. Vector. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Simple Cartoon Christmas particle. White. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Vibrant Green striped cartoon candy. Game asset. 2d. Blank background. High contrast. No shadows.
Blue circular candy
Vibrant cartoon candy gold star. Game asset. 2d. Blank background. High contrast. No shadows.
Vibrant cartoon candy white marshmallow. Game asset. 2d. Blank background. High contrast. No shadows.
Vibrant teal candy. cartoon. Sugar ring. Game asset. 2d. Blank background. High contrast. No shadows.
Vibrant red candy heart. cartoon. Sugar. Game asset. 2d. Blank background. High contrast. No shadows.
Simple Casual game background cartoon candy.