User prompt
Please fix the bug: 'Script error.' in or related to this line: 'candy2.moveTo(tempGridX1, tempGridY1, 200);' Line Number: 2288 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Şeker patlama sesi çalışmıyor
User prompt
Settings den çıkınca arka planda gözüküyor
User prompt
Settings den çıkınca oyuna girmiyor
User prompt
Menu start basınca oyun geçsin
User prompt
Menuye ayarlar ekle ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Menuyu güzelleştir ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Oyuna menu ekle
User prompt
Kırmızı şeker ekle
User prompt
Sadece yeşil mavi turuncu yeşil sarı şekerler olsun diğerlerini sil
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'candy1.moveTo(tempGridX2, tempGridY2, 200);' Line Number: 1425 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Yer değiştirsiğinde diğer şekerde yer değişsin ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please fix the bug: 'Timeout.tick error: grid[writeY][x].moveTo is not a function. (In 'grid[writeY][x].moveTo(x, writeY, animDuration)', 'grid[writeY][x].moveTo' is undefined)' in or related to this line: 'grid[writeY][x].moveTo(x, writeY, animDuration);' Line Number: 1348 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Seviyeleri zorlaştır
User prompt
Seviyeyi zorlaştır
User prompt
Turuncu sarı mavi yeşil kırmızı şekerleri olsun diğer şekerleri kaldır
User prompt
Şekerler turuncu mavi mor yeşil kırmızı olsun
User prompt
Oyunu candy crush saga oynanış tarzına çevir ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Şekerin yeri sadece patlıyacağı zaman değişsin
User prompt
Şekerler sadece 3 yan yana gelirse yeri değişsin
User prompt
Please fix the bug: 'Timeout.tick error: null is not an object (evaluating 'candy1.gridY')' in or related to this line: 'grid[candy1.gridY][candy1.gridX] = candy2;' Line Number: 861
User prompt
Şekerlere şeker resmi koy
User prompt
Patlama sesi çıkmıyor
User prompt
Bölümleri zorlaştır
User prompt
Şekerler patlayınca patlama sesi versin
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Candy = Container.expand(function (type, gridX, gridY) {
var self = Container.call(this);
self.candyType = type;
self.gridX = gridX;
self.gridY = gridY;
self.isMoving = false;
self.isMarkedForDestroy = false;
var candyGraphics = self.attachAsset('candy_' + type, {
anchorX: 0.5,
anchorY: 0.5
});
self.moveTo = function (newGridX, newGridY, duration) {
self.gridX = newGridX;
self.gridY = newGridY;
self.isMoving = true;
var targetX = GRID_START_X + newGridX * CELL_SIZE + CELL_SIZE / 2;
var targetY = GRID_START_Y + newGridY * CELL_SIZE + CELL_SIZE / 2;
// Add slight anticipation before movement for falling candies
var isVerticalMove = Math.abs(self.y - targetY) > Math.abs(self.x - targetX);
if (isVerticalMove && targetY > self.y) {
// Falling motion - use bounce easing
tween(self, {
x: targetX,
y: targetY
}, {
duration: duration || 300,
easing: tween.easeOut,
onFinish: function onFinish() {
// Add subtle landing effect
tween(self, {
scaleX: 1.1,
scaleY: 0.9
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
self.isMoving = false;
}
});
}
});
}
});
} else {
// Horizontal movement or upward movement
tween(self, {
x: targetX,
y: targetY
}, {
duration: duration || 300,
easing: tween.easeInOut,
onFinish: function onFinish() {
self.isMoving = false;
}
});
}
};
self.destroy = function () {
self.isMarkedForDestroy = true;
tween(self, {
scaleX: 0,
scaleY: 0,
alpha: 0
}, {
duration: 200,
easing: tween.easeIn,
onFinish: function onFinish() {
if (self.parent) {
self.parent.removeChild(self);
}
}
});
};
return self;
});
var GridCell = Container.expand(function (gridX, gridY) {
var self = Container.call(this);
self.gridX = gridX;
self.gridY = gridY;
var cellGraphics = self.attachAsset('grid_cell', {
anchorX: 0.5,
anchorY: 0.5
});
cellGraphics.alpha = 0.3;
return self;
});
var HoneyCandy = Container.expand(function (type, gridX, gridY) {
var self = Container.call(this);
self.candyType = type;
self.gridX = gridX;
self.gridY = gridY;
self.isMoving = false;
self.isMarkedForDestroy = false;
self.isSticky = true;
self.movesSlowly = true;
var candyGraphics = self.attachAsset('candy_' + type, {
anchorX: 0.5,
anchorY: 0.5
});
var honeyOverlay = self.attachAsset('honey_overlay', {
anchorX: 0.5,
anchorY: 0.5
});
honeyOverlay.alpha = 0.4;
self.moveTo = function (newGridX, newGridY, duration) {
self.gridX = newGridX;
self.gridY = newGridY;
self.isMoving = true;
var targetX = GRID_START_X + newGridX * CELL_SIZE + CELL_SIZE / 2;
var targetY = GRID_START_Y + newGridY * CELL_SIZE + CELL_SIZE / 2;
// Honey moves slower
var slowDuration = (duration || 300) * 1.5;
tween(self, {
x: targetX,
y: targetY
}, {
duration: slowDuration,
easing: tween.easeInOut,
onFinish: function onFinish() {
self.isMoving = false;
}
});
};
self.destroy = function () {
self.isMarkedForDestroy = true;
tween(self, {
scaleX: 0,
scaleY: 0,
alpha: 0
}, {
duration: 200,
easing: tween.easeIn,
onFinish: function onFinish() {
if (self.parent) {
self.parent.removeChild(self);
}
}
});
};
return self;
});
var LockedCandy = Container.expand(function (type, gridX, gridY, lockLevel) {
var self = Container.call(this);
self.candyType = type;
self.gridX = gridX;
self.gridY = gridY;
self.isMoving = false;
self.isMarkedForDestroy = false;
self.isLocked = true;
self.lockLevel = lockLevel || 1; // How many matches needed to unlock
var candyGraphics = self.attachAsset('candy_' + type, {
anchorX: 0.5,
anchorY: 0.5
});
var lockOverlay = self.attachAsset('locked_candy', {
anchorX: 0.5,
anchorY: 0.5
});
lockOverlay.alpha = 0.7;
self.unlock = function () {
self.lockLevel--;
if (self.lockLevel <= 0) {
self.isLocked = false;
tween(lockOverlay, {
alpha: 0,
scaleX: 0,
scaleY: 0
}, {
duration: 300,
easing: tween.easeOut
});
}
};
self.destroy = function () {
self.isMarkedForDestroy = true;
tween(self, {
scaleX: 0,
scaleY: 0,
alpha: 0
}, {
duration: 200,
easing: tween.easeIn,
onFinish: function onFinish() {
if (self.parent) {
self.parent.removeChild(self);
}
}
});
};
return self;
});
var StoneBlock = Container.expand(function (gridX, gridY, durability) {
var self = Container.call(this);
self.gridX = gridX;
self.gridY = gridY;
self.isMoving = false;
self.isMarkedForDestroy = false;
self.isObstacle = true;
self.durability = durability || 2;
var stoneGraphics = self.attachAsset('stone_block', {
anchorX: 0.5,
anchorY: 0.5
});
self.hit = function () {
self.durability--;
// Visual feedback for hit
tween(self, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100,
easing: tween.easeIn
});
}
});
if (self.durability <= 0) {
self.destroy();
}
};
self.destroy = function () {
self.isMarkedForDestroy = true;
createExplosionEffect(self.x, self.y);
tween(self, {
scaleX: 0,
scaleY: 0,
alpha: 0
}, {
duration: 300,
easing: tween.easeIn,
onFinish: function onFinish() {
if (self.parent) {
self.parent.removeChild(self);
}
}
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2a1810
});
/****
* Game Code
****/
// Decorative elements
// Beautiful gradient background layers
// Create beautiful gradient background
var backgroundContainer = new Container();
game.addChild(backgroundContainer);
// Create multiple layers for depth
var bgLayer1 = LK.getAsset('bg_gradient1', {
width: 2048,
height: 2732,
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
});
var bgLayer2 = LK.getAsset('bg_gradient2', {
width: 2048,
height: 2732,
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
});
var bgLayer3 = LK.getAsset('bg_pattern', {
width: 2048,
height: 2732,
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
});
backgroundContainer.addChild(bgLayer1);
backgroundContainer.addChild(bgLayer2);
backgroundContainer.addChild(bgLayer3);
// Set transparency for layering effect
bgLayer2.alpha = 0.7;
bgLayer3.alpha = 0.3;
var GRID_WIDTH = 10;
var GRID_HEIGHT = 10;
var CELL_SIZE = 150;
var GRID_START_X = (2048 - GRID_WIDTH * CELL_SIZE) / 2;
var GRID_START_Y = 650;
var CANDY_TYPES = ['green', 'blue', 'orange', 'yellow', 'red'];
var grid = [];
var candies = [];
var selectedCandy = null;
var draggedCandy = null;
var isDragging = false;
var dragStartX = 0;
var dragStartY = 0;
var movesLeft = 20;
var currentScore = 0;
var targetScore = 1000;
var isProcessing = false;
var currentLevel = 1;
var maxLevel = 1;
var gameState = 'menu'; // 'menu', 'playing', 'settings'
var menuContainer = null;
var settingsContainer = null;
var soundEnabled = true;
var musicEnabled = true;
var masterVolume = 1.0;
// Level configurations with challenging obstacles and requirements
var levelConfigs = [{
level: 1,
targetScore: 1500,
moves: 18,
gridSize: 10,
obstacles: {
stoneBlocks: 2,
lockedCandies: 0,
honeyCandies: 0
}
}, {
level: 2,
targetScore: 2200,
moves: 16,
gridSize: 10,
obstacles: {
stoneBlocks: 3,
lockedCandies: 2,
honeyCandies: 0
}
}, {
level: 3,
targetScore: 3000,
moves: 15,
gridSize: 10,
obstacles: {
stoneBlocks: 4,
lockedCandies: 3,
honeyCandies: 2
}
}, {
level: 4,
targetScore: 3800,
moves: 14,
gridSize: 10,
obstacles: {
stoneBlocks: 5,
lockedCandies: 4,
honeyCandies: 3
}
}, {
level: 5,
targetScore: 4600,
moves: 13,
gridSize: 10,
obstacles: {
stoneBlocks: 6,
lockedCandies: 5,
honeyCandies: 4
}
}, {
level: 6,
targetScore: 5500,
moves: 12,
gridSize: 10,
obstacles: {
stoneBlocks: 7,
lockedCandies: 6,
honeyCandies: 5
}
}, {
level: 7,
targetScore: 6500,
moves: 11,
gridSize: 10,
obstacles: {
stoneBlocks: 8,
lockedCandies: 7,
honeyCandies: 6
}
}, {
level: 8,
targetScore: 7600,
moves: 10,
gridSize: 10,
obstacles: {
stoneBlocks: 9,
lockedCandies: 8,
honeyCandies: 7
}
}, {
level: 9,
targetScore: 8800,
moves: 9,
gridSize: 10,
obstacles: {
stoneBlocks: 10,
lockedCandies: 9,
honeyCandies: 8
}
}, {
level: 10,
targetScore: 10000,
moves: 8,
gridSize: 10,
obstacles: {
stoneBlocks: 12,
lockedCandies: 10,
honeyCandies: 10
}
}];
// Initialize grid cells
for (var y = 0; y < GRID_HEIGHT; y++) {
grid[y] = [];
for (var x = 0; x < GRID_WIDTH; x++) {
var cell = new GridCell(x, y);
cell.x = GRID_START_X + x * CELL_SIZE + CELL_SIZE / 2;
cell.y = GRID_START_Y + y * CELL_SIZE + CELL_SIZE / 2;
game.addChild(cell);
grid[y][x] = null;
}
}
// UI Elements - Score with button background
var scoreButtonBorder = LK.getAsset('score_button_border', {
anchorX: 0.5,
anchorY: 0.5
});
var scoreButtonBg = LK.getAsset('score_button_bg', {
anchorX: 0.5,
anchorY: 0.5
});
var scoreButtonHighlight = LK.getAsset('score_button_highlight', {
anchorX: 0.5,
anchorY: 0.5
});
// Create score button container
var scoreButtonContainer = new Container();
scoreButtonContainer.addChild(scoreButtonBorder);
scoreButtonContainer.addChild(scoreButtonBg);
scoreButtonContainer.addChild(scoreButtonHighlight);
// Position button elements
scoreButtonBorder.y = 0;
scoreButtonBg.y = -2;
scoreButtonHighlight.y = -5;
scoreButtonHighlight.alpha = 0.6;
// Add gradient effect with tween
tween(scoreButtonHighlight, {
alpha: 0.3
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(scoreButtonHighlight, {
alpha: 0.6
}, {
duration: 2000,
easing: tween.easeInOut
});
}
});
var scoreText = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0.5);
scoreButtonContainer.addChild(scoreText);
LK.gui.top.addChild(scoreButtonContainer);
scoreButtonContainer.y = 90;
// UI Elements - Moves with button background
var movesButtonBorder = LK.getAsset('score_button_border', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8
});
var movesButtonBg = LK.getAsset('score_button_bg', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8
});
var movesButtonHighlight = LK.getAsset('score_button_highlight', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8
});
// Create moves button container
var movesButtonContainer = new Container();
movesButtonContainer.addChild(movesButtonBorder);
movesButtonContainer.addChild(movesButtonBg);
movesButtonContainer.addChild(movesButtonHighlight);
// Position button elements
movesButtonBorder.y = 0;
movesButtonBg.y = -2;
movesButtonHighlight.y = -5;
movesButtonHighlight.alpha = 0.6;
// Add gradient effect with tween
tween(movesButtonHighlight, {
alpha: 0.3
}, {
duration: 2200,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(movesButtonHighlight, {
alpha: 0.6
}, {
duration: 2200,
easing: tween.easeInOut
});
}
});
var movesText = new Text2('Moves: ' + movesLeft, {
size: 50,
fill: 0xFFFFFF
});
movesText.anchor.set(0.5, 0.5);
movesButtonContainer.addChild(movesText);
LK.gui.top.addChild(movesButtonContainer);
movesButtonContainer.y = 180;
// UI Elements - Target with button background
var targetButtonBorder = LK.getAsset('score_button_border', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.7,
scaleY: 0.7
});
var targetButtonBg = LK.getAsset('score_button_bg', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.7,
scaleY: 0.7
});
var targetButtonHighlight = LK.getAsset('score_button_highlight', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.7,
scaleY: 0.7
});
// Create target button container
var targetButtonContainer = new Container();
targetButtonContainer.addChild(targetButtonBorder);
targetButtonContainer.addChild(targetButtonBg);
targetButtonContainer.addChild(targetButtonHighlight);
// Position button elements
targetButtonBorder.y = 0;
targetButtonBg.y = -2;
targetButtonHighlight.y = -5;
targetButtonHighlight.alpha = 0.6;
// Add gradient effect with tween
tween(targetButtonHighlight, {
alpha: 0.3
}, {
duration: 2400,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(targetButtonHighlight, {
alpha: 0.6
}, {
duration: 2400,
easing: tween.easeInOut
});
}
});
var targetText = new Text2('Target: ' + targetScore, {
size: 40,
fill: 0xFFDD44
});
targetText.anchor.set(0.5, 0.5);
targetButtonContainer.addChild(targetText);
LK.gui.top.addChild(targetButtonContainer);
targetButtonContainer.y = 260;
// UI Elements - Level with button background
var levelButtonBorder = LK.getAsset('score_button_border', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.6,
scaleY: 0.6
});
var levelButtonBg = LK.getAsset('score_button_bg', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.6,
scaleY: 0.6
});
var levelButtonHighlight = LK.getAsset('score_button_highlight', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.6,
scaleY: 0.6
});
// Create level button container
var levelButtonContainer = new Container();
levelButtonContainer.addChild(levelButtonBorder);
levelButtonContainer.addChild(levelButtonBg);
levelButtonContainer.addChild(levelButtonHighlight);
// Position button elements
levelButtonBorder.y = 0;
levelButtonBg.y = -2;
levelButtonHighlight.y = -5;
levelButtonHighlight.alpha = 0.6;
// Add gradient effect with tween
tween(levelButtonHighlight, {
alpha: 0.3
}, {
duration: 2600,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(levelButtonHighlight, {
alpha: 0.6
}, {
duration: 2600,
easing: tween.easeInOut
});
}
});
var levelText = new Text2('Level: ' + currentLevel, {
size: 50,
fill: 0x00FF00
});
levelText.anchor.set(0.5, 0.5);
levelButtonContainer.addChild(levelText);
LK.gui.top.addChild(levelButtonContainer);
levelButtonContainer.y = 330;
// Menu button
var menuButtonBorder = LK.getAsset('menu_button_border', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.4,
scaleY: 0.4
});
var menuButton = LK.getAsset('menu_button', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.4,
scaleY: 0.4
});
var menuButtonContainer = new Container();
menuButtonContainer.addChild(menuButtonBorder);
menuButtonContainer.addChild(menuButton);
var menuButtonText = new Text2('MENU', {
size: 40,
fill: 0xFFFFFF
});
menuButtonText.anchor.set(0.5, 0.5);
menuButtonContainer.addChild(menuButtonText);
menuButtonContainer.down = function (x, y, obj) {
showMenu();
};
LK.gui.top.addChild(menuButtonContainer);
menuButtonContainer.y = 400;
function getRandomCandyType() {
return CANDY_TYPES[Math.floor(Math.random() * CANDY_TYPES.length)];
}
function loadProgress() {
var savedLevel = storage.currentLevel;
var savedMaxLevel = storage.maxLevel;
if (savedLevel) {
currentLevel = parseInt(savedLevel);
}
if (savedMaxLevel) {
maxLevel = parseInt(savedMaxLevel);
}
// Load settings
var savedSoundEnabled = storage.soundEnabled;
var savedMusicEnabled = storage.musicEnabled;
var savedMasterVolume = storage.masterVolume;
if (savedSoundEnabled !== undefined) {
soundEnabled = savedSoundEnabled === 'true';
}
if (savedMusicEnabled !== undefined) {
musicEnabled = savedMusicEnabled === 'true';
}
if (savedMasterVolume !== undefined) {
masterVolume = parseFloat(savedMasterVolume);
}
}
function saveProgress() {
storage.currentLevel = currentLevel.toString();
storage.maxLevel = maxLevel.toString();
}
function getCurrentLevelConfig() {
if (currentLevel <= levelConfigs.length) {
return levelConfigs[currentLevel - 1];
}
// For levels beyond predefined configs, generate dynamic difficulty with increasing obstacles
var obstacleCount = Math.min(15, currentLevel);
return {
level: currentLevel,
targetScore: 1000 + (currentLevel - 1) * 900,
moves: Math.max(6, 20 - Math.floor(currentLevel / 1.5)),
gridSize: 10,
obstacles: {
stoneBlocks: Math.min(15, obstacleCount),
lockedCandies: Math.min(12, Math.floor(obstacleCount * 0.8)),
honeyCandies: Math.min(10, Math.floor(obstacleCount * 0.6))
}
};
}
function createMenu() {
if (menuContainer) {
game.removeChild(menuContainer);
}
menuContainer = new Container();
game.addChild(menuContainer);
// Menu overlay background with gradient effect
var menuOverlay = LK.getAsset('menu_overlay', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0,
alpha: 0.8
});
menuContainer.addChild(menuOverlay);
// Add floating animated background candies
for (var i = 0; i < 12; i++) {
var floatingCandy = LK.getAsset('candy_' + CANDY_TYPES[i % CANDY_TYPES.length], {
anchorX: 0.5,
anchorY: 0.5,
x: Math.random() * 2048,
y: Math.random() * 2732,
scaleX: 0.4 + Math.random() * 0.3,
scaleY: 0.4 + Math.random() * 0.3,
rotation: Math.random() * Math.PI * 2
});
floatingCandy.alpha = 0.15 + Math.random() * 0.2;
menuContainer.addChild(floatingCandy);
// Animate floating motion
var animDuration = 4000 + Math.random() * 3000;
var targetX = Math.random() * 2048;
var targetY = Math.random() * 2732;
tween(floatingCandy, {
x: targetX,
y: targetY,
rotation: floatingCandy.rotation + Math.PI * 2
}, {
duration: animDuration,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Continue animation loop
var newTargetX = Math.random() * 2048;
var newTargetY = Math.random() * 2732;
tween(floatingCandy, {
x: newTargetX,
y: newTargetY,
rotation: floatingCandy.rotation + Math.PI * 2
}, {
duration: animDuration,
easing: tween.easeInOut
});
}
});
}
// Add animated sparkles
for (var j = 0; j < 20; j++) {
var sparkle = LK.getAsset('sparkle', {
anchorX: 0.5,
anchorY: 0.5,
x: Math.random() * 2048,
y: Math.random() * 2732,
scaleX: 0.2 + Math.random() * 0.3,
scaleY: 0.2 + Math.random() * 0.3
});
sparkle.alpha = 0.3 + Math.random() * 0.4;
menuContainer.addChild(sparkle);
// Twinkling animation
var twinkleDuration = 1500 + Math.random() * 2000;
tween(sparkle, {
alpha: 0.1,
scaleX: sparkle.scaleX * 0.3,
scaleY: sparkle.scaleY * 0.3
}, {
duration: twinkleDuration,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(sparkle, {
alpha: 0.3 + Math.random() * 0.4,
scaleX: 0.2 + Math.random() * 0.3,
scaleY: 0.2 + Math.random() * 0.3
}, {
duration: twinkleDuration,
easing: tween.easeInOut
});
}
});
}
// Game title with enhanced styling
var titleText = new Text2('CANDY CRUSH', {
size: 140,
fill: 0xFFD700
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 2048 / 2;
titleText.y = 400;
titleText.scaleX = 0;
titleText.scaleY = 0;
menuContainer.addChild(titleText);
// Animate title entrance
tween(titleText, {
scaleX: 1.2,
scaleY: 1.2,
alpha: 1
}, {
duration: 800,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(titleText, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 300,
easing: tween.easeInOut
});
}
});
// Add pulsing glow effect
tween(titleText, {
scaleX: 1.05,
scaleY: 1.05
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(titleText, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 2000,
easing: tween.easeInOut
});
}
});
// Start game button with enhanced styling
var startButtonBorder = LK.getAsset('menu_button_border', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.2
});
var startButton = LK.getAsset('menu_button', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.2
});
var startButtonHighlight = LK.getAsset('score_button_highlight', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.15,
scaleY: 1.15
});
var startButtonContainer = new Container();
startButtonContainer.addChild(startButtonBorder);
startButtonContainer.addChild(startButton);
startButtonContainer.addChild(startButtonHighlight);
startButtonContainer.x = 2048 / 2;
startButtonContainer.y = 800;
startButtonContainer.scaleX = 0;
startButtonContainer.scaleY = 0;
// Position button elements
startButtonBorder.y = 0;
startButton.y = -3;
startButtonHighlight.y = -6;
startButtonHighlight.alpha = 0.4;
var startText = new Text2('START GAME', {
size: 70,
fill: 0xFFFFFF
});
startText.anchor.set(0.5, 0.5);
startButtonContainer.addChild(startText);
// Animate button entrance
tween(startButtonContainer, {
scaleX: 1.0,
scaleY: 1.0,
alpha: 1
}, {
duration: 600,
delay: 400,
easing: tween.easeOut
});
// Add pulsing highlight effect
tween(startButtonHighlight, {
alpha: 0.7
}, {
duration: 1500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(startButtonHighlight, {
alpha: 0.4
}, {
duration: 1500,
easing: tween.easeInOut
});
}
});
// Start button interaction with press animation
startButtonContainer.down = function (x, y, obj) {
tween(startButtonContainer, {
scaleX: 0.95,
scaleY: 0.95
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(startButtonContainer, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
startGame();
}
});
}
});
};
menuContainer.addChild(startButtonContainer);
// Level selection with enhanced styling
var levelSelectText = new Text2('SELECT LEVEL', {
size: 90,
fill: 0xFFDD44
});
levelSelectText.anchor.set(0.5, 0.5);
levelSelectText.x = 2048 / 2;
levelSelectText.y = 1000;
levelSelectText.scaleX = 0;
levelSelectText.scaleY = 0;
menuContainer.addChild(levelSelectText);
// Animate level select text
tween(levelSelectText, {
scaleX: 1.0,
scaleY: 1.0,
alpha: 1
}, {
duration: 500,
delay: 800,
easing: tween.easeOut
});
// Add subtle glow animation
tween(levelSelectText, {
scaleX: 1.05,
scaleY: 1.05
}, {
duration: 2500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(levelSelectText, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 2500,
easing: tween.easeInOut
});
}
});
// Create level buttons with enhanced styling (show up to maxLevel)
var buttonsPerRow = 5;
var buttonSize = 120;
var buttonSpacing = 150;
var startX = 2048 / 2 - (buttonsPerRow - 1) * buttonSpacing / 2;
var startY = 1200;
for (var i = 1; i <= Math.min(maxLevel, 15); i++) {
var row = Math.floor((i - 1) / buttonsPerRow);
var col = (i - 1) % buttonsPerRow;
var levelButtonBorder = LK.getAsset('menu_button_border', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.35,
scaleY: 0.35
});
var levelButton = LK.getAsset('menu_button', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.35,
scaleY: 0.35
});
var levelButtonHighlight = LK.getAsset('score_button_highlight', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.33,
scaleY: 0.33
});
var levelButtonContainer = new Container();
levelButtonContainer.addChild(levelButtonBorder);
levelButtonContainer.addChild(levelButton);
levelButtonContainer.addChild(levelButtonHighlight);
levelButtonContainer.x = startX + col * buttonSpacing;
levelButtonContainer.y = startY + row * 100;
levelButtonContainer.scaleX = 0;
levelButtonContainer.scaleY = 0;
// Position button elements
levelButtonBorder.y = 0;
levelButton.y = -2;
levelButtonHighlight.y = -4;
levelButtonHighlight.alpha = 0.3;
var levelNumText = new Text2(i.toString(), {
size: 45,
fill: i === currentLevel ? 0xFFDD44 : 0xFFFFFF
});
levelNumText.anchor.set(0.5, 0.5);
levelButtonContainer.addChild(levelNumText);
// Animate button entrance with stagger
var animDelay = 1000 + (i - 1) * 80;
tween(levelButtonContainer, {
scaleX: 1.0,
scaleY: 1.0,
alpha: 1
}, {
duration: 300,
delay: animDelay,
easing: tween.easeOut
});
// Add gentle hover glow for current level
if (i === currentLevel) {
tween(levelButtonHighlight, {
alpha: 0.6
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(levelButtonHighlight, {
alpha: 0.3
}, {
duration: 1000,
easing: tween.easeInOut
});
}
});
}
// Store level number for button click
levelButtonContainer.levelNum = i;
levelButtonContainer.down = function (x, y, obj) {
// Add press animation
tween(this, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function () {
tween(this, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function () {
currentLevel = this.levelNum;
startGame();
}.bind(this)
});
}.bind(this)
});
};
menuContainer.addChild(levelButtonContainer);
}
// Settings button with enhanced styling
var settingsButtonBorder = LK.getAsset('settings_button_border', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.0,
scaleY: 1.0
});
var settingsButton = LK.getAsset('settings_button', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.0,
scaleY: 1.0
});
var settingsButtonHighlight = LK.getAsset('score_button_highlight', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.95,
scaleY: 0.95
});
var settingsButtonContainer = new Container();
settingsButtonContainer.addChild(settingsButtonBorder);
settingsButtonContainer.addChild(settingsButton);
settingsButtonContainer.addChild(settingsButtonHighlight);
settingsButtonContainer.x = 2048 / 2;
settingsButtonContainer.y = 2000;
settingsButtonContainer.scaleX = 0;
settingsButtonContainer.scaleY = 0;
// Position button elements
settingsButtonBorder.y = 0;
settingsButton.y = -3;
settingsButtonHighlight.y = -6;
settingsButtonHighlight.alpha = 0.3;
var settingsText = new Text2('SETTINGS', {
size: 50,
fill: 0xFFFFFF
});
settingsText.anchor.set(0.5, 0.5);
settingsButtonContainer.addChild(settingsText);
// Animate button entrance
tween(settingsButtonContainer, {
scaleX: 1.0,
scaleY: 1.0,
alpha: 1
}, {
duration: 400,
delay: 1400,
easing: tween.easeOut
});
// Add gentle glow animation
tween(settingsButtonHighlight, {
alpha: 0.6
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(settingsButtonHighlight, {
alpha: 0.3
}, {
duration: 2000,
easing: tween.easeInOut
});
}
});
// Settings button interaction
settingsButtonContainer.down = function (x, y, obj) {
tween(settingsButtonContainer, {
scaleX: 0.95,
scaleY: 0.95
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(settingsButtonContainer, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
showSettings();
}
});
}
});
};
menuContainer.addChild(settingsButtonContainer);
gameState = 'menu';
}
function startGame() {
if (menuContainer) {
game.removeChild(menuContainer);
menuContainer = null;
}
if (settingsContainer) {
game.removeChild(settingsContainer);
settingsContainer = null;
}
gameState = 'playing';
// Reset any custom event handlers from settings
game.move = null;
game.up = null;
initializeLevel();
}
function showMenu() {
gameState = 'menu';
// Reset game event handlers when returning to menu
game.move = null;
game.up = null;
// Remove settings container if it exists
if (settingsContainer) {
game.removeChild(settingsContainer);
settingsContainer = null;
}
createMenu();
}
function showSettings() {
gameState = 'settings';
createSettingsMenu();
}
function createSettingsMenu() {
if (settingsContainer) {
game.removeChild(settingsContainer);
}
settingsContainer = new Container();
game.addChild(settingsContainer);
// Settings overlay background
var settingsOverlay = LK.getAsset('menu_overlay', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0,
alpha: 0.9
});
settingsContainer.addChild(settingsOverlay);
// Settings title
var settingsTitle = new Text2('SETTINGS', {
size: 120,
fill: 0xFFD700
});
settingsTitle.anchor.set(0.5, 0.5);
settingsTitle.x = 2048 / 2;
settingsTitle.y = 400;
settingsTitle.scaleX = 0;
settingsTitle.scaleY = 0;
settingsContainer.addChild(settingsTitle);
// Animate title entrance
tween(settingsTitle, {
scaleX: 1.0,
scaleY: 1.0,
alpha: 1
}, {
duration: 600,
easing: tween.easeOut
});
var yPosition = 700;
var spacing = 150;
// Sound toggle
createToggleOption('SOUND EFFECTS', soundEnabled, yPosition, function (enabled) {
soundEnabled = enabled;
storage.soundEnabled = enabled.toString();
});
yPosition += spacing;
// Music toggle
createToggleOption('MUSIC', musicEnabled, yPosition, function (enabled) {
musicEnabled = enabled;
storage.musicEnabled = enabled.toString();
});
yPosition += spacing;
// Master volume slider
createVolumeSlider('MASTER VOLUME', masterVolume, yPosition, function (volume) {
masterVolume = volume;
storage.masterVolume = volume.toString();
});
yPosition += spacing + 100;
// Back button
var backButtonBorder = LK.getAsset('menu_button_border', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8
});
var backButton = LK.getAsset('menu_button', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8
});
var backButtonContainer = new Container();
backButtonContainer.addChild(backButtonBorder);
backButtonContainer.addChild(backButton);
backButtonContainer.x = 2048 / 2;
backButtonContainer.y = yPosition;
backButtonContainer.scaleX = 0;
backButtonContainer.scaleY = 0;
var backText = new Text2('BACK', {
size: 60,
fill: 0xFFFFFF
});
backText.anchor.set(0.5, 0.5);
backButtonContainer.addChild(backText);
// Animate back button
tween(backButtonContainer, {
scaleX: 1.0,
scaleY: 1.0,
alpha: 1
}, {
duration: 400,
delay: 800,
easing: tween.easeOut
});
backButtonContainer.down = function (x, y, obj) {
tween(backButtonContainer, {
scaleX: 0.75,
scaleY: 0.75
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(backButtonContainer, {
scaleX: 0.8,
scaleY: 0.8
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
showMenu();
}
});
}
});
};
settingsContainer.addChild(backButtonContainer);
function createToggleOption(label, currentValue, yPos, callback) {
// Label text
var labelText = new Text2(label, {
size: 60,
fill: 0xFFFFFF
});
labelText.anchor.set(0, 0.5);
labelText.x = 400;
labelText.y = yPos;
labelText.alpha = 0;
settingsContainer.addChild(labelText);
// Toggle button
var toggleBorder = LK.getAsset('settings_button_border', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.4,
scaleY: 0.6
});
var toggleButton = LK.getAsset(currentValue ? 'toggle_button_on' : 'toggle_button_off', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.4,
scaleY: 0.6
});
var toggleContainer = new Container();
toggleContainer.addChild(toggleBorder);
toggleContainer.addChild(toggleButton);
toggleContainer.x = 1500;
toggleContainer.y = yPos;
toggleContainer.alpha = 0;
var toggleText = new Text2(currentValue ? 'ON' : 'OFF', {
size: 40,
fill: 0xFFFFFF
});
toggleText.anchor.set(0.5, 0.5);
toggleContainer.addChild(toggleText);
// Animate entrance
tween(labelText, {
alpha: 1
}, {
duration: 400,
delay: 400,
easing: tween.easeOut
});
tween(toggleContainer, {
alpha: 1
}, {
duration: 400,
delay: 500,
easing: tween.easeOut
});
toggleContainer.down = function (x, y, obj) {
var newValue = !currentValue;
currentValue = newValue;
// Update visual
toggleContainer.removeChild(toggleButton);
toggleButton = LK.getAsset(newValue ? 'toggle_button_on' : 'toggle_button_off', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.4,
scaleY: 0.6
});
toggleContainer.addChild(toggleButton);
toggleText.setText(newValue ? 'ON' : 'OFF');
// Animate press
tween(toggleContainer, {
scaleX: 0.95,
scaleY: 0.95
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(toggleContainer, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100,
easing: tween.easeOut
});
}
});
callback(newValue);
};
settingsContainer.addChild(toggleContainer);
}
function createVolumeSlider(label, currentValue, yPos, callback) {
// Label text
var labelText = new Text2(label, {
size: 60,
fill: 0xFFFFFF
});
labelText.anchor.set(0, 0.5);
labelText.x = 400;
labelText.y = yPos;
labelText.alpha = 0;
settingsContainer.addChild(labelText);
// Slider track
var sliderTrack = LK.getAsset('slider_track', {
anchorX: 0.5,
anchorY: 0.5
});
sliderTrack.x = 1400;
sliderTrack.y = yPos;
sliderTrack.alpha = 0;
settingsContainer.addChild(sliderTrack);
// Slider handle
var sliderHandle = LK.getAsset('slider_handle', {
anchorX: 0.5,
anchorY: 0.5
});
sliderHandle.x = 1400 - 100 + 200 * currentValue;
sliderHandle.y = yPos;
sliderHandle.alpha = 0;
settingsContainer.addChild(sliderHandle);
// Volume percentage text
var volumeText = new Text2(Math.round(currentValue * 100) + '%', {
size: 45,
fill: 0xFFDD44
});
volumeText.anchor.set(0.5, 0.5);
volumeText.x = 1600;
volumeText.y = yPos;
volumeText.alpha = 0;
settingsContainer.addChild(volumeText);
// Animate entrance
tween(labelText, {
alpha: 1
}, {
duration: 400,
delay: 400,
easing: tween.easeOut
});
tween(sliderTrack, {
alpha: 1
}, {
duration: 400,
delay: 500,
easing: tween.easeOut
});
tween(sliderHandle, {
alpha: 1
}, {
duration: 400,
delay: 600,
easing: tween.easeOut
});
tween(volumeText, {
alpha: 1
}, {
duration: 400,
delay: 700,
easing: tween.easeOut
});
var isDraggingSlider = false;
sliderHandle.down = function (x, y, obj) {
isDraggingSlider = true;
tween(sliderHandle, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 100,
easing: tween.easeOut
});
};
game.move = function (x, y, obj) {
if (isDraggingSlider) {
var sliderX = Math.max(1300, Math.min(1500, x));
sliderHandle.x = sliderX;
var newValue = (sliderX - 1300) / 200;
volumeText.setText(Math.round(newValue * 100) + '%');
callback(newValue);
}
};
game.up = function (x, y, obj) {
if (isDraggingSlider) {
isDraggingSlider = false;
tween(sliderHandle, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100,
easing: tween.easeOut
});
}
};
}
}
function initializeLevel() {
var config = getCurrentLevelConfig();
targetScore = config.targetScore;
movesLeft = config.moves;
currentScore = 0;
// Update UI
levelText.setText('Level: ' + currentLevel);
scoreText.setText('Score: 0');
movesText.setText('Moves: ' + movesLeft);
targetText.setText('Target: ' + targetScore);
// Clear existing candies
for (var i = candies.length - 1; i >= 0; i--) {
var candy = candies[i];
if (candy.parent) {
candy.parent.removeChild(candy);
}
}
candies = [];
// Reset grid
for (var y = 0; y < GRID_HEIGHT; y++) {
for (var x = 0; x < GRID_WIDTH; x++) {
grid[y][x] = null;
}
}
// Initialize new grid
initializeGrid();
// Set up game event handlers for playing state
setupGameHandlers();
}
function completeLevel() {
if (currentLevel >= maxLevel) {
maxLevel = currentLevel + 1;
}
currentLevel++;
saveProgress();
// Show level complete message briefly before starting next level
var levelCompleteText = new Text2('Level Complete!', {
size: 80,
fill: 0x00FF00
});
levelCompleteText.anchor.set(0.5, 0.5);
levelCompleteText.x = 2048 / 2;
levelCompleteText.y = 2732 / 2;
game.addChild(levelCompleteText);
// Animate text
levelCompleteText.scaleX = 0;
levelCompleteText.scaleY = 0;
tween(levelCompleteText, {
scaleX: 1,
scaleY: 1,
alpha: 1
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(levelCompleteText, {
scaleX: 0,
scaleY: 0,
alpha: 0
}, {
duration: 500,
delay: 1000,
easing: tween.easeIn,
onFinish: function onFinish() {
if (levelCompleteText.parent) {
levelCompleteText.parent.removeChild(levelCompleteText);
}
initializeLevel();
}
});
}
});
}
function createCandy(x, y, type) {
type = type || getRandomCandyType();
var candy = new Candy(type, x, y);
candy.x = GRID_START_X + x * CELL_SIZE + CELL_SIZE / 2;
candy.y = GRID_START_Y + y * CELL_SIZE + CELL_SIZE / 2;
game.addChild(candy);
candies.push(candy);
grid[y][x] = candy;
return candy;
}
function placeObstacles(config) {
if (!config.obstacles) return;
var obstacles = config.obstacles;
var placedPositions = [];
var totalObstacles = obstacles.stoneBlocks + obstacles.lockedCandies + obstacles.honeyCandies;
// Place stone blocks first (highest priority)
for (var i = 0; i < obstacles.stoneBlocks; i++) {
var placed = false;
var attempts = 0;
while (!placed && attempts < 50) {
var x = Math.floor(Math.random() * GRID_WIDTH);
var y = Math.floor(Math.random() * GRID_HEIGHT);
var posKey = x + ',' + y;
// Avoid corners and center, prefer edges and strategic positions
if (!placedPositions[posKey] && grid[y][x] && !(x < 2 && y < 2) && !(x > GRID_WIDTH - 3 && y < 2) && !(x < 2 && y > GRID_HEIGHT - 3) && !(x > GRID_WIDTH - 3 && y > GRID_HEIGHT - 3)) {
// Remove existing candy
var existingCandy = grid[y][x];
if (existingCandy && existingCandy.parent) {
existingCandy.parent.removeChild(existingCandy);
var candyIndex = candies.indexOf(existingCandy);
if (candyIndex > -1) {
candies.splice(candyIndex, 1);
}
}
// Create stone block
var stone = new StoneBlock(x, y, 1 + Math.floor(currentLevel / 3));
stone.x = GRID_START_X + x * CELL_SIZE + CELL_SIZE / 2;
stone.y = GRID_START_Y + y * CELL_SIZE + CELL_SIZE / 2;
game.addChild(stone);
grid[y][x] = stone;
placedPositions[posKey] = true;
placed = true;
}
attempts++;
}
}
// Place locked candies
for (var j = 0; j < obstacles.lockedCandies; j++) {
var placed = false;
var attempts = 0;
while (!placed && attempts < 50) {
var x = Math.floor(Math.random() * GRID_WIDTH);
var y = Math.floor(Math.random() * GRID_HEIGHT);
var posKey = x + ',' + y;
if (!placedPositions[posKey] && grid[y][x] && !grid[y][x].isObstacle) {
// Convert existing candy to locked candy
var existingCandy = grid[y][x];
var type = existingCandy.candyType;
if (existingCandy.parent) {
existingCandy.parent.removeChild(existingCandy);
var candyIndex = candies.indexOf(existingCandy);
if (candyIndex > -1) {
candies.splice(candyIndex, 1);
}
}
var lockedCandy = new LockedCandy(type, x, y, 1 + Math.floor(currentLevel / 4));
lockedCandy.x = GRID_START_X + x * CELL_SIZE + CELL_SIZE / 2;
lockedCandy.y = GRID_START_Y + y * CELL_SIZE + CELL_SIZE / 2;
game.addChild(lockedCandy);
candies.push(lockedCandy);
grid[y][x] = lockedCandy;
placedPositions[posKey] = true;
placed = true;
}
attempts++;
}
}
// Place honey candies
for (var k = 0; k < obstacles.honeyCandies; k++) {
var placed = false;
var attempts = 0;
while (!placed && attempts < 50) {
var x = Math.floor(Math.random() * GRID_WIDTH);
var y = Math.floor(Math.random() * GRID_HEIGHT);
var posKey = x + ',' + y;
if (!placedPositions[posKey] && grid[y][x] && !grid[y][x].isObstacle && !grid[y][x].isLocked) {
// Convert existing candy to honey candy
var existingCandy = grid[y][x];
var type = existingCandy.candyType;
if (existingCandy.parent) {
existingCandy.parent.removeChild(existingCandy);
var candyIndex = candies.indexOf(existingCandy);
if (candyIndex > -1) {
candies.splice(candyIndex, 1);
}
}
var honeyCandy = new HoneyCandy(type, x, y);
honeyCandy.x = GRID_START_X + x * CELL_SIZE + CELL_SIZE / 2;
honeyCandy.y = GRID_START_Y + y * CELL_SIZE + CELL_SIZE / 2;
game.addChild(honeyCandy);
candies.push(honeyCandy);
grid[y][x] = honeyCandy;
placedPositions[posKey] = true;
placed = true;
}
attempts++;
}
}
}
function getLevelSpecificCandyType(x, y, level) {
// Define specific patterns for each level
switch (level) {
case 1:
// Level 1: More green and blue candies in corners
if (x < 3 && y < 3 || x > 6 && y > 6) {
return Math.random() < 0.6 ? Math.random() < 0.5 ? 'green' : 'blue' : getRandomCandyType();
}
break;
case 2:
// Level 2: Checkerboard pattern influence with green and yellow
if ((x + y) % 2 === 0) {
return Math.random() < 0.5 ? Math.random() < 0.5 ? 'green' : 'yellow' : getRandomCandyType();
}
break;
case 3:
// Level 3: Center focus with purple and orange
var centerDistance = Math.abs(x - 4.5) + Math.abs(y - 4.5);
if (centerDistance < 4) {
return Math.random() < 0.7 ? Math.random() < 0.5 ? 'purple' : 'orange' : getRandomCandyType();
}
break;
case 4:
// Level 4: Diagonal pattern with orange, green, and red
if (Math.abs(x - y) < 2 || Math.abs(x + y - 9) < 2) {
var candyChoice = Math.random();
if (candyChoice < 0.33) return 'orange';else if (candyChoice < 0.66) return 'green';else if (candyChoice < 0.8) return 'red';else return getRandomCandyType();
}
break;
case 5:
// Level 5: Border emphasis with blue and yellow
if (x < 2 || x > 7 || y < 2 || y > 7) {
return Math.random() < 0.7 ? Math.random() < 0.5 ? 'blue' : 'yellow' : getRandomCandyType();
}
break;
case 6:
// Level 6: Cross pattern with blue, orange, and red
if (x === 4 || x === 5 || y === 4 || y === 5) {
var candyChoice = Math.random();
if (candyChoice < 0.33) return 'blue';else if (candyChoice < 0.66) return 'orange';else if (candyChoice < 0.8) return 'red';else return getRandomCandyType();
}
break;
case 7:
// Level 7: Ring pattern with orange and green
var ringDistance = Math.max(Math.abs(x - 4.5), Math.abs(y - 4.5));
if (ringDistance > 2 && ringDistance < 5) {
return Math.random() < 0.6 ? Math.random() < 0.5 ? 'orange' : 'green' : getRandomCandyType();
}
break;
case 8:
// Level 8: Spiral influence with blue and yellow
var spiralValue = (x * 3 + y * 2) % 7;
if (spiralValue < 3) {
return Math.random() < 0.7 ? Math.random() < 0.5 ? 'blue' : 'yellow' : getRandomCandyType();
}
break;
case 9:
// Level 9: Scattered clusters with yellow, green, and red
if (x % 3 === 0 && y % 3 === 0 || x % 3 === 2 && y % 3 === 2) {
var candyChoice = Math.random();
if (candyChoice < 0.33) return 'yellow';else if (candyChoice < 0.66) return 'green';else if (candyChoice < 0.8) return 'red';else return getRandomCandyType();
}
break;
case 10:
// Level 10: Complex pattern with all colors but emphasis on green and orange
if ((x + y) % 4 < 2) {
return Math.random() < 0.5 ? Math.random() < 0.5 ? 'green' : 'orange' : getRandomCandyType();
}
break;
default:
// For levels beyond 10, create dynamic patterns based on level number
var patternType = level % 5;
switch (patternType) {
case 0:
// Diagonal emphasis
if (Math.abs(x - y) < 3) {
return Math.random() < 0.6 ? CANDY_TYPES[level % CANDY_TYPES.length] : getRandomCandyType();
}
break;
case 1:
// Corner concentration
if (x < 3 && y < 3 || x > 6 && y > 6 || x < 3 && y > 6 || x > 6 && y < 3) {
return Math.random() < 0.7 ? CANDY_TYPES[(level + 1) % CANDY_TYPES.length] : getRandomCandyType();
}
break;
case 2:
// Center ring
var centerDist = Math.max(Math.abs(x - 4.5), Math.abs(y - 4.5));
if (centerDist > 1 && centerDist < 4) {
return Math.random() < 0.6 ? CANDY_TYPES[(level + 2) % CANDY_TYPES.length] : getRandomCandyType();
}
break;
case 3:
// Checkerboard influence
if ((x + y + level) % 3 === 0) {
return Math.random() < 0.7 ? CANDY_TYPES[(level + 3) % CANDY_TYPES.length] : getRandomCandyType();
}
break;
case 4:
// Random clusters
if ((x * y + level) % 11 < 4) {
return Math.random() < 0.6 ? CANDY_TYPES[(level + 4) % CANDY_TYPES.length] : getRandomCandyType();
}
break;
}
break;
}
return getRandomCandyType();
}
function initializeGrid() {
for (var y = 0; y < GRID_HEIGHT; y++) {
for (var x = 0; x < GRID_WIDTH; x++) {
var type;
var attempts = 0;
do {
// Use level-specific candy type generation
type = getLevelSpecificCandyType(x, y, currentLevel);
attempts++;
if (attempts > 10) {
// Fallback to completely random if level pattern is too restrictive
type = getRandomCandyType();
break;
}
} while (wouldCreateMatch(x, y, type));
createCandy(x, y, type);
}
}
// Place obstacles after initial candy generation
var config = getCurrentLevelConfig();
placeObstacles(config);
}
function wouldCreateMatch(x, y, type) {
var horizontalCount = 1;
var verticalCount = 1;
// Check horizontal
var i = x - 1;
while (i >= 0 && grid[y][i] && grid[y][i].candyType === type) {
horizontalCount++;
i--;
}
i = x + 1;
while (i < GRID_WIDTH && grid[y][i] && grid[y][i].candyType === type) {
horizontalCount++;
i++;
}
// Check vertical
i = y - 1;
while (i >= 0 && grid[i][x] && grid[i][x].candyType === type) {
verticalCount++;
i--;
}
i = y + 1;
while (i < GRID_HEIGHT && grid[i][x] && grid[i][x].candyType === type) {
verticalCount++;
i++;
}
return horizontalCount >= 3 || verticalCount >= 3;
}
function findMatches() {
var matches = [];
var processed = [];
for (var y = 0; y < GRID_HEIGHT; y++) {
processed[y] = [];
for (var x = 0; x < GRID_WIDTH; x++) {
processed[y][x] = false;
}
}
// Find horizontal matches
for (var y = 0; y < GRID_HEIGHT; y++) {
for (var x = 0; x < GRID_WIDTH - 2; x++) {
if (!grid[y][x] || processed[y][x]) continue;
var type = grid[y][x].candyType;
var matchLength = 1;
var startX = x;
while (x + matchLength < GRID_WIDTH && grid[y][x + matchLength] && grid[y][x + matchLength].candyType === type) {
matchLength++;
}
if (matchLength >= 3) {
for (var i = 0; i < matchLength; i++) {
if (!processed[y][startX + i]) {
matches.push(grid[y][startX + i]);
processed[y][startX + i] = true;
}
}
}
}
}
// Find vertical matches
for (var x = 0; x < GRID_WIDTH; x++) {
for (var y = 0; y < GRID_HEIGHT - 2; y++) {
if (!grid[y][x] || processed[y][x]) continue;
var type = grid[y][x].candyType;
var matchLength = 1;
var startY = y;
while (y + matchLength < GRID_HEIGHT && grid[y + matchLength][x] && grid[y + matchLength][x].candyType === type) {
matchLength++;
}
if (matchLength >= 3) {
for (var i = 0; i < matchLength; i++) {
if (!processed[startY + i][x]) {
matches.push(grid[startY + i][x]);
processed[startY + i][x] = true;
}
}
}
}
}
return matches;
}
function createExplosionEffect(x, y) {
// Create multiple particles for explosion effect
var particleCount = 8 + Math.floor(Math.random() * 4);
for (var i = 0; i < particleCount; i++) {
var particle = LK.getAsset('explosion_particle', {
anchorX: 0.5,
anchorY: 0.5,
x: x,
y: y,
scaleX: 0.8 + Math.random() * 0.4,
scaleY: 0.8 + Math.random() * 0.4
});
game.addChild(particle);
// Random direction and distance
var angle = Math.PI * 2 * i / particleCount + (Math.random() - 0.5) * 0.5;
var distance = 60 + Math.random() * 40;
var targetX = x + Math.cos(angle) * distance;
var targetY = y + Math.sin(angle) * distance;
// Animate particle explosion
tween(particle, {
x: targetX,
y: targetY,
scaleX: 0,
scaleY: 0,
alpha: 0
}, {
duration: 400 + Math.random() * 200,
easing: tween.easeOut,
onFinish: function onFinish() {
if (particle.parent) {
particle.parent.removeChild(particle);
}
}
});
}
// Create star particles for extra sparkle
var starCount = 4 + Math.floor(Math.random() * 3);
for (var j = 0; j < starCount; j++) {
var star = LK.getAsset('explosion_star', {
anchorX: 0.5,
anchorY: 0.5,
x: x + (Math.random() - 0.5) * 40,
y: y + (Math.random() - 0.5) * 40,
rotation: Math.random() * Math.PI * 2
});
game.addChild(star);
// Animate star particles
tween(star, {
scaleX: 1.5,
scaleY: 1.5,
alpha: 0,
rotation: star.rotation + Math.PI * 2
}, {
duration: 600,
easing: tween.easeOut,
onFinish: function onFinish() {
if (star.parent) {
star.parent.removeChild(star);
}
}
});
}
}
function createEnhancedExplosionEffect(x, y) {
// Create larger, more intense explosion for special matches
var particleCount = 15 + Math.floor(Math.random() * 8);
for (var i = 0; i < particleCount; i++) {
var particle = LK.getAsset('explosion_particle', {
anchorX: 0.5,
anchorY: 0.5,
x: x,
y: y,
scaleX: 1.2 + Math.random() * 0.8,
scaleY: 1.2 + Math.random() * 0.8
});
game.addChild(particle);
// Random direction and larger distance
var angle = Math.PI * 2 * i / particleCount + (Math.random() - 0.5) * 0.7;
var distance = 80 + Math.random() * 60;
var targetX = x + Math.cos(angle) * distance;
var targetY = y + Math.sin(angle) * distance;
// Animate particle explosion with more dramatic effect
tween(particle, {
x: targetX,
y: targetY,
scaleX: 0,
scaleY: 0,
alpha: 0
}, {
duration: 600 + Math.random() * 300,
easing: tween.easeOut,
onFinish: function onFinish() {
if (particle.parent) {
particle.parent.removeChild(particle);
}
}
});
}
// Create more star particles
var starCount = 8 + Math.floor(Math.random() * 6);
for (var j = 0; j < starCount; j++) {
var star = LK.getAsset('explosion_star', {
anchorX: 0.5,
anchorY: 0.5,
x: x + (Math.random() - 0.5) * 80,
y: y + (Math.random() - 0.5) * 80,
rotation: Math.random() * Math.PI * 2,
scaleX: 1.5,
scaleY: 1.5
});
game.addChild(star);
// Animate star particles with more dramatic effect
tween(star, {
scaleX: 2.5,
scaleY: 2.5,
alpha: 0,
rotation: star.rotation + Math.PI * 4
}, {
duration: 800,
easing: tween.easeOut,
onFinish: function onFinish() {
if (star.parent) {
star.parent.removeChild(star);
}
}
});
}
}
function showScorePopup(score, isSpecial) {
var scorePopup = new Text2('+' + score, {
size: isSpecial ? 100 : 70,
fill: isSpecial ? 0xFFD700 : 0x00FF00
});
scorePopup.anchor.set(0.5, 0.5);
scorePopup.x = 2048 / 2 + (Math.random() - 0.5) * 200;
scorePopup.y = 2732 / 2 + (Math.random() - 0.5) * 200;
scorePopup.scaleX = 0;
scorePopup.scaleY = 0;
game.addChild(scorePopup);
// Animate score popup
tween(scorePopup, {
scaleX: 1.2,
scaleY: 1.2,
y: scorePopup.y - 100,
alpha: 1
}, {
duration: 400,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(scorePopup, {
scaleX: 0,
scaleY: 0,
alpha: 0
}, {
duration: 300,
delay: 400,
easing: tween.easeIn,
onFinish: function onFinish() {
if (scorePopup.parent) {
scorePopup.parent.removeChild(scorePopup);
}
}
});
}
});
}
function clearMatches(matches) {
if (matches.length === 0) return;
// Play explosion sound when candies are cleared
if (soundEnabled) {
LK.getSound('explosion').play();
}
if (soundEnabled) {
LK.getSound('match').play();
}
// Handle matches with combo multiplier
var baseScore = matches.length * 50;
var comboMultiplier = game.comboMultiplier || 1;
var bonusScore = baseScore * comboMultiplier;
currentScore += bonusScore;
scoreText.setText('Score: ' + currentScore);
// Show score popup for significant matches
if (matches.length >= 4 || comboMultiplier > 1) {
showScorePopup(bonusScore, matches.length >= 4);
}
for (var i = 0; i < matches.length; i++) {
var candy = matches[i];
// Handle locked candies - unlock instead of destroying
if (candy.isLocked) {
candy.unlock();
if (candy.lockLevel > 0) {
continue; // Don't destroy if still locked
}
}
// Create enhanced explosion effect for larger matches
if (matches.length >= 4) {
createEnhancedExplosionEffect(candy.x, candy.y);
} else {
createExplosionEffect(candy.x, candy.y);
}
// Check adjacent cells for obstacles to damage
var adjacentPositions = [{
x: candy.gridX - 1,
y: candy.gridY
}, {
x: candy.gridX + 1,
y: candy.gridY
}, {
x: candy.gridX,
y: candy.gridY - 1
}, {
x: candy.gridX,
y: candy.gridY + 1
}];
for (var j = 0; j < adjacentPositions.length; j++) {
var pos = adjacentPositions[j];
if (pos.x >= 0 && pos.x < GRID_WIDTH && pos.y >= 0 && pos.y < GRID_HEIGHT) {
var adjacentCell = grid[pos.y][pos.x];
if (adjacentCell && adjacentCell.isObstacle && adjacentCell.hit) {
adjacentCell.hit();
if (adjacentCell.isMarkedForDestroy) {
grid[pos.y][pos.x] = null;
}
}
}
}
grid[candy.gridY][candy.gridX] = null;
candy.destroy();
// Remove from candies array
var index = candies.indexOf(candy);
if (index > -1) {
candies.splice(index, 1);
}
}
}
function applyGravity() {
var moved = false;
var animationsToWait = [];
for (var x = 0; x < GRID_WIDTH; x++) {
var writeY = GRID_HEIGHT - 1;
for (var y = GRID_HEIGHT - 1; y >= 0; y--) {
if (grid[y][x] && !grid[y][x].isMarkedForDestroy) {
if (y !== writeY) {
grid[writeY][x] = grid[y][x];
grid[y][x] = null;
var fallDistance = writeY - y;
var animDuration = 150 + fallDistance * 50; // Longer fall = longer animation
if (grid[writeY][x] && grid[writeY][x].moveTo) {
grid[writeY][x].moveTo(x, writeY, animDuration);
}
moved = true;
}
writeY--;
}
}
// Fill empty spaces at top with staggered animation
for (var emptyY = writeY; emptyY >= 0; emptyY--) {
var newCandy = createCandy(x, emptyY, getRandomCandyType());
var dropDistance = writeY - emptyY + 1;
newCandy.y = GRID_START_Y - dropDistance * CELL_SIZE + CELL_SIZE / 2;
var dropAnimDuration = 200 + dropDistance * 60;
newCandy.moveTo(x, emptyY, dropAnimDuration);
// Add bounce effect for new candies
tween(newCandy, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: dropAnimDuration / 2,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(newCandy, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: dropAnimDuration / 2,
easing: tween.easeIn
});
}
});
moved = true;
}
}
return moved;
}
function areAdjacent(candy1, candy2) {
// Check if candies are valid before checking adjacency
if (!candy1 || !candy2 || candy1.isMarkedForDestroy || candy2.isMarkedForDestroy) {
return false;
}
var dx = Math.abs(candy1.gridX - candy2.gridX);
var dy = Math.abs(candy1.gridY - candy2.gridY);
return dx === 1 && dy === 0 || dx === 0 && dy === 1;
}
function swapCandies(candy1, candy2) {
// Check if candies are valid before swapping
if (!candy1 || !candy2 || candy1.isMarkedForDestroy || candy2.isMarkedForDestroy) {
return false;
}
// Additional safety checks for candy properties
if (typeof candy1.gridX === 'undefined' || typeof candy1.gridY === 'undefined' || typeof candy2.gridX === 'undefined' || typeof candy2.gridY === 'undefined') {
return false;
}
// Temporarily swap in grid to test for matches
var tempGridX1 = candy1.gridX;
var tempGridY1 = candy1.gridY;
var tempGridX2 = candy2.gridX;
var tempGridY2 = candy2.gridY;
// Update grid positions temporarily
grid[candy1.gridY][candy1.gridX] = candy2;
grid[candy2.gridY][candy2.gridX] = candy1;
candy1.gridX = tempGridX2;
candy1.gridY = tempGridY2;
candy2.gridX = tempGridX1;
candy2.gridY = tempGridY1;
// Check if this swap creates matches
var matches = findMatches();
var willCreateMatches = matches.length > 0;
// If no matches will be created, revert the temporary swap
if (!willCreateMatches) {
grid[tempGridY1][tempGridX1] = candy1;
grid[tempGridY2][tempGridX2] = candy2;
candy1.gridX = tempGridX1;
candy1.gridY = tempGridY1;
candy2.gridX = tempGridX2;
candy2.gridY = tempGridY2;
return false;
}
// If matches will be created, perform the actual visual swap for both candies
if (candy1 && candy1.moveTo) {
candy1.moveTo(tempGridX2, tempGridY2, 200);
}
if (candy2 && candy2.moveTo) {
candy2.moveTo(tempGridX1, tempGridY1, 200);
}
return true;
}
function processMatches() {
if (isProcessing) return;
isProcessing = true;
// Track combo multiplier
if (!game.comboMultiplier) game.comboMultiplier = 1;
if (!game.comboCount) game.comboCount = 0;
LK.setTimeout(function () {
var matches = findMatches();
if (matches.length > 0) {
// Increase combo count for cascading matches
game.comboCount++;
if (game.comboCount > 1) {
game.comboMultiplier = Math.min(game.comboCount, 5); // Max 5x multiplier
// Show combo text
showComboText(game.comboMultiplier);
}
clearMatches(matches);
LK.setTimeout(function () {
if (applyGravity()) {
LK.setTimeout(function () {
isProcessing = false;
processMatches(); // Check for cascading matches
}, 500); // Slightly longer delay for better visual flow
} else {
isProcessing = false;
// Reset combo after no more matches
game.comboMultiplier = 1;
game.comboCount = 0;
checkGameState();
}
}, 350); // Longer delay between match clearing and gravity
} else {
isProcessing = false;
// Reset combo when no matches found
game.comboMultiplier = 1;
game.comboCount = 0;
checkGameState();
}
}, 200); // Faster initial processing
}
function showComboText(multiplier) {
var comboText = new Text2('COMBO x' + multiplier + '!', {
size: 80,
fill: 0xFFD700
});
comboText.anchor.set(0.5, 0.5);
comboText.x = 2048 / 2;
comboText.y = 2732 / 2 - 200;
comboText.scaleX = 0;
comboText.scaleY = 0;
game.addChild(comboText);
// Animate combo text
tween(comboText, {
scaleX: 1.5,
scaleY: 1.5,
alpha: 1
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(comboText, {
scaleX: 0,
scaleY: 0,
alpha: 0
}, {
duration: 400,
delay: 500,
easing: tween.easeIn,
onFinish: function onFinish() {
if (comboText.parent) {
comboText.parent.removeChild(comboText);
}
}
});
}
});
}
function checkGameState() {
if (currentScore >= targetScore) {
completeLevel();
return;
}
if (movesLeft <= 0) {
// Show game over and then return to menu
LK.setTimeout(function () {
showMenu();
}, 2000);
LK.showGameOver();
return;
}
}
function setupGameHandlers() {
// Set up the main game event handlers
game.down = function (x, y, obj) {
if (isProcessing) return;
var gridX = Math.floor((x - GRID_START_X) / CELL_SIZE);
var gridY = Math.floor((y - GRID_START_Y) / CELL_SIZE);
if (gridX < 0 || gridX >= GRID_WIDTH || gridY < 0 || gridY >= GRID_HEIGHT) {
selectedCandy = null;
return;
}
var clickedCandy = grid[gridY][gridX];
if (!clickedCandy || clickedCandy.isMoving || clickedCandy.isMarkedForDestroy) {
selectedCandy = null;
return;
}
// Start drag functionality
draggedCandy = clickedCandy;
isDragging = false;
dragStartX = x;
dragStartY = y;
if (selectedCandy === null) {
selectedCandy = clickedCandy;
selectedCandy.scaleX = 1.1;
selectedCandy.scaleY = 1.1;
} else if (selectedCandy === clickedCandy) {
selectedCandy.scaleX = 1.0;
selectedCandy.scaleY = 1.0;
selectedCandy = null;
} else if (areAdjacent(selectedCandy, clickedCandy)) {
selectedCandy.scaleX = 1.0;
selectedCandy.scaleY = 1.0;
// Try swap - only proceed if it will create matches
var swapSuccessful = swapCandies(selectedCandy, clickedCandy);
if (swapSuccessful) {
if (soundEnabled) {
LK.getSound('swap').play();
}
LK.setTimeout(function () {
movesLeft--;
movesText.setText('Moves: ' + movesLeft);
processMatches();
selectedCandy = null;
}, 250);
} else {
// No swap occurred because no matches would be created
selectedCandy = null;
}
} else {
selectedCandy.scaleX = 1.0;
selectedCandy.scaleY = 1.0;
selectedCandy = clickedCandy;
selectedCandy.scaleX = 1.1;
selectedCandy.scaleY = 1.1;
}
};
game.move = function (x, y, obj) {
if (!draggedCandy || isProcessing) return;
var dragDistance = Math.sqrt((x - dragStartX) * (x - dragStartX) + (y - dragStartY) * (y - dragStartY));
if (dragDistance > 30 && !isDragging) {
isDragging = true;
// Scale up dragged candy for visual feedback
tween(draggedCandy, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 150,
easing: tween.easeOut
});
}
if (isDragging) {
// Move candy with finger/mouse
draggedCandy.x = GRID_START_X + draggedCandy.gridX * CELL_SIZE + CELL_SIZE / 2 + (x - dragStartX);
draggedCandy.y = GRID_START_Y + draggedCandy.gridY * CELL_SIZE + CELL_SIZE / 2 + (y - dragStartY);
}
};
game.up = function (x, y, obj) {
if (!draggedCandy) return;
if (isDragging) {
// Reset candy visual state
tween(draggedCandy, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 150,
easing: tween.easeOut
});
// Determine target grid position based on drag direction
var deltaX = x - dragStartX;
var deltaY = y - dragStartY;
var targetGridX = draggedCandy.gridX;
var targetGridY = draggedCandy.gridY;
// Check drag direction and distance
if (Math.abs(deltaX) > Math.abs(deltaY)) {
// Horizontal drag
if (Math.abs(deltaX) > 50) {
if (deltaX > 0 && draggedCandy.gridX < GRID_WIDTH - 1) {
targetGridX = draggedCandy.gridX + 1;
} else if (deltaX < 0 && draggedCandy.gridX > 0) {
targetGridX = draggedCandy.gridX - 1;
}
}
} else {
// Vertical drag
if (Math.abs(deltaY) > 50) {
if (deltaY > 0 && draggedCandy.gridY < GRID_HEIGHT - 1) {
targetGridY = draggedCandy.gridY + 1;
} else if (deltaY < 0 && draggedCandy.gridY > 0) {
targetGridY = draggedCandy.gridY - 1;
}
}
}
// Reset candy position
draggedCandy.x = GRID_START_X + draggedCandy.gridX * CELL_SIZE + CELL_SIZE / 2;
draggedCandy.y = GRID_START_Y + draggedCandy.gridY * CELL_SIZE + CELL_SIZE / 2;
// Perform swap if valid target
if ((targetGridX !== draggedCandy.gridX || targetGridY !== draggedCandy.gridY) && targetGridX >= 0 && targetGridX < GRID_WIDTH && targetGridY >= 0 && targetGridY < GRID_HEIGHT) {
var targetCandy = grid[targetGridY][targetGridX];
if (targetCandy && !targetCandy.isMoving) {
// Clear any previous selection
if (selectedCandy) {
selectedCandy.scaleX = 1.0;
selectedCandy.scaleY = 1.0;
}
// Perform swap - only if it will create matches
var swapSuccessful = swapCandies(draggedCandy, targetCandy);
if (swapSuccessful) {
if (soundEnabled) {
LK.getSound('swap').play();
}
LK.setTimeout(function () {
movesLeft--;
movesText.setText('Moves: ' + movesLeft);
processMatches();
}, 250);
}
}
}
}
// Reset drag state
draggedCandy = null;
isDragging = false;
selectedCandy = null;
};
}
// Add decorative candy elements floating in background
var decorations = [];
for (var i = 0; i < 8; i++) {
var decoration = LK.getAsset('candy_decoration', {
anchorX: 0.5,
anchorY: 0.5,
x: Math.random() * 2048,
y: Math.random() * 2732,
scaleX: 0.5 + Math.random() * 0.5,
scaleY: 0.5 + Math.random() * 0.5
});
decoration.alpha = 0.2 + Math.random() * 0.3;
game.addChild(decoration);
decorations.push(decoration);
// Animate floating motion
var animDuration = 3000 + Math.random() * 2000;
var targetY = decoration.y + (Math.random() - 0.5) * 400;
tween(decoration, {
y: targetY,
rotation: Math.random() * Math.PI * 2
}, {
duration: animDuration,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Restart animation
var newTargetY = decoration.y + (Math.random() - 0.5) * 400;
tween(decoration, {
y: newTargetY,
rotation: decoration.rotation + Math.PI * 2
}, {
duration: animDuration,
easing: tween.easeInOut
});
}
});
}
// Add sparkle effects
var sparkles = [];
for (var j = 0; j < 15; j++) {
var sparkle = LK.getAsset('sparkle', {
anchorX: 0.5,
anchorY: 0.5,
x: Math.random() * 2048,
y: Math.random() * 2732,
scaleX: 0.3 + Math.random() * 0.4,
scaleY: 0.3 + Math.random() * 0.4
});
sparkle.alpha = 0.4 + Math.random() * 0.6;
game.addChild(sparkle);
sparkles.push(sparkle);
// Twinkling animation
var twinkleDuration = 1000 + Math.random() * 1500;
tween(sparkle, {
alpha: 0.1,
scaleX: sparkle.scaleX * 0.5,
scaleY: sparkle.scaleY * 0.5
}, {
duration: twinkleDuration,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(sparkle, {
alpha: 0.4 + Math.random() * 0.6,
scaleX: 0.3 + Math.random() * 0.4,
scaleY: 0.3 + Math.random() * 0.4
}, {
duration: twinkleDuration,
easing: tween.easeInOut
});
}
});
}
// Initialize the game
loadProgress();
createMenu(); ===================================================================
--- original.js
+++ change.js
@@ -2186,8 +2186,12 @@
// Check if candies are valid before swapping
if (!candy1 || !candy2 || candy1.isMarkedForDestroy || candy2.isMarkedForDestroy) {
return false;
}
+ // Additional safety checks for candy properties
+ if (typeof candy1.gridX === 'undefined' || typeof candy1.gridY === 'undefined' || typeof candy2.gridX === 'undefined' || typeof candy2.gridY === 'undefined') {
+ return false;
+ }
// Temporarily swap in grid to test for matches
var tempGridX1 = candy1.gridX;
var tempGridY1 = candy1.gridY;
var tempGridX2 = candy2.gridX;
@@ -2212,10 +2216,14 @@
candy2.gridY = tempGridY2;
return false;
}
// If matches will be created, perform the actual visual swap for both candies
- candy1.moveTo(tempGridX2, tempGridY2, 200);
- candy2.moveTo(tempGridX1, tempGridY1, 200);
+ if (candy1 && candy1.moveTo) {
+ candy1.moveTo(tempGridX2, tempGridY2, 200);
+ }
+ if (candy2 && candy2.moveTo) {
+ candy2.moveTo(tempGridX1, tempGridY1, 200);
+ }
return true;
}
function processMatches() {
if (isProcessing) return;
Modern App Store icon, high definition, square with rounded corners, for a game titled "Candy Match Saga" and with the description "A match-3 puzzle game where players swap candies to create matching lines, clear objectives, and progress through challenging levels.". No text on icon!
Mavi şeker resmi. In-Game asset. 2d. High contrast. No shadows
Sarı şeker. In-Game asset. 2d. High contrast. No shadows
Kırmızı şeker. In-Game asset. 2d. High contrast. No shadows
Yeşil şeker. In-Game asset. 2d. High contrast. No shadows
Turuncu şeker. In-Game asset. 2d. High contrast. No shadows