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
****/
// Create beautiful gradient background
// Beautiful gradient background layers
// Decorative elements
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 = ['orange', 'yellow', 'blue', 'green', '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;
// 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;
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);
}
}
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 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();
}
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 red and blue candies in corners
if (x < 3 && y < 3 || x > 6 && y > 6) {
return Math.random() < 0.6 ? Math.random() < 0.5 ? 'red' : '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 red and green
if (Math.abs(x - y) < 2 || Math.abs(x + y - 9) < 2) {
return Math.random() < 0.6 ? Math.random() < 0.5 ? 'red' : 'green' : 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 purple and red
if (x === 4 || x === 5 || y === 4 || y === 5) {
return Math.random() < 0.8 ? Math.random() < 0.5 ? 'purple' : 'red' : 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 purple
var spiralValue = (x * 3 + y * 2) % 7;
if (spiralValue < 3) {
return Math.random() < 0.7 ? Math.random() < 0.5 ? 'blue' : 'purple' : getRandomCandyType();
}
break;
case 9:
// Level 9: Scattered clusters with yellow and red
if (x % 3 === 0 && y % 3 === 0 || x % 3 === 2 && y % 3 === 2) {
return Math.random() < 0.8 ? Math.random() < 0.5 ? 'yellow' : 'red' : 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
var explosionSound = LK.getSound('explosion');
if (explosionSound) {
explosionSound.play();
}
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
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;
}
// 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
candy1.moveTo(candy2.gridX, candy2.gridY, 200);
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) {
LK.showGameOver();
return;
}
}
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) {
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) {
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();
initializeLevel(); ===================================================================
--- original.js
+++ change.js
@@ -6,30 +6,8 @@
/****
* Classes
****/
-var BlockedCell = Container.expand(function (gridX, gridY) {
- var self = Container.call(this);
- self.gridX = gridX;
- self.gridY = gridY;
- self.isBlocked = true;
- var blockedGraphics = self.attachAsset('frozen_overlay', {
- anchorX: 0.5,
- anchorY: 0.5
- });
- blockedGraphics.alpha = 0.8;
- // Add ice crystal effects
- for (var i = 0; i < 3; i++) {
- var crystal = LK.getAsset('ice_crystal', {
- anchorX: 0.5,
- anchorY: 0.5,
- x: (Math.random() - 0.5) * 60,
- y: (Math.random() - 0.5) * 60
- });
- self.addChild(crystal);
- }
- return self;
-});
var Candy = Container.expand(function (type, gridX, gridY) {
var self = Container.call(this);
self.candyType = type;
self.gridX = gridX;
@@ -121,84 +99,164 @@
});
cellGraphics.alpha = 0.3;
return self;
});
-var IcyBomb = Container.expand(function (gridX, gridY) {
+var HoneyCandy = Container.expand(function (type, gridX, gridY) {
var self = Container.call(this);
+ self.candyType = type;
self.gridX = gridX;
self.gridY = gridY;
- self.turnsLeft = 3 + Math.floor(Math.random() * 3); // 3-5 turns
- self.isIcyBomb = true;
- var bombGraphics = self.attachAsset('bomb_candy', {
+ self.isMoving = false;
+ self.isMarkedForDestroy = false;
+ self.isSticky = true;
+ self.movesSlowly = true;
+ var candyGraphics = self.attachAsset('candy_' + type, {
anchorX: 0.5,
anchorY: 0.5
});
- // Add countdown text
- self.countdownText = new Text2(self.turnsLeft.toString(), {
- size: 40,
- fill: 0xFFFFFF
+ var honeyOverlay = self.attachAsset('honey_overlay', {
+ anchorX: 0.5,
+ anchorY: 0.5
});
- self.countdownText.anchor.set(0.5, 0.5);
- self.addChild(self.countdownText);
- // Pulsing animation to show danger
- self.pulseAnimation = function () {
+ 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: 300,
- easing: tween.easeInOut,
+ duration: 100,
+ easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
scaleX: 1.0,
scaleY: 1.0
}, {
- duration: 300,
- easing: tween.easeInOut,
- onFinish: function onFinish() {
- if (self.parent) {
- self.pulseAnimation();
- }
- }
+ duration: 100,
+ easing: tween.easeIn
});
}
});
- };
- self.pulseAnimation();
- self.decrementTurn = function () {
- self.turnsLeft--;
- self.countdownText.setText(self.turnsLeft.toString());
- if (self.turnsLeft <= 0) {
- self.explode();
+ if (self.durability <= 0) {
+ self.destroy();
}
};
- self.explode = function () {
- // Create large explosion effect
- createEnhancedExplosionEffect(self.x, self.y);
- // Destroy surrounding candies in 3x3 area
- var bombGridX = self.gridX;
- var bombGridY = self.gridY;
- for (var dy = -1; dy <= 1; dy++) {
- for (var dx = -1; dx <= 1; dx++) {
- var checkX = bombGridX + dx;
- var checkY = bombGridY + dy;
- if (checkX >= 0 && checkX < GRID_WIDTH && checkY >= 0 && checkY < GRID_HEIGHT) {
- if (grid[checkY][checkX] && !grid[checkY][checkX].isIcyBomb) {
- grid[checkY][checkX].destroy();
- grid[checkY][checkX] = null;
- }
+ 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);
}
}
- }
- // Remove self from grid and arrays
- grid[self.gridY][self.gridX] = null;
- var index = icyBombs.indexOf(self);
- if (index > -1) {
- icyBombs.splice(index, 1);
- }
- self.destroy();
- // Trigger game over
- LK.showGameOver();
+ });
};
return self;
});
@@ -266,103 +324,109 @@
var targetScore = 1000;
var isProcessing = false;
var currentLevel = 1;
var maxLevel = 1;
-var timeLeft = 0;
-var levelTimer = null;
-var blockedCells = [];
-var icyBombs = [];
-// Level configurations with time limits and obstacles
+// Level configurations with challenging obstacles and requirements
var levelConfigs = [{
level: 1,
- targetScore: 1000,
- moves: 20,
+ targetScore: 1500,
+ moves: 18,
gridSize: 10,
- timeLimit: 120,
- // 2 minutes
- blockedCellsCount: 0,
- icyBombsCount: 0
+ obstacles: {
+ stoneBlocks: 2,
+ lockedCandies: 0,
+ honeyCandies: 0
+ }
}, {
level: 2,
- targetScore: 1500,
- moves: 18,
+ targetScore: 2200,
+ moves: 16,
gridSize: 10,
- timeLimit: 110,
- // 1:50
- blockedCellsCount: 2,
- icyBombsCount: 0
+ obstacles: {
+ stoneBlocks: 3,
+ lockedCandies: 2,
+ honeyCandies: 0
+ }
}, {
level: 3,
- targetScore: 2000,
- moves: 16,
+ targetScore: 3000,
+ moves: 15,
gridSize: 10,
- timeLimit: 100,
- // 1:40
- blockedCellsCount: 4,
- icyBombsCount: 1
+ obstacles: {
+ stoneBlocks: 4,
+ lockedCandies: 3,
+ honeyCandies: 2
+ }
}, {
level: 4,
- targetScore: 2500,
- moves: 15,
+ targetScore: 3800,
+ moves: 14,
gridSize: 10,
- timeLimit: 90,
- // 1:30
- blockedCellsCount: 6,
- icyBombsCount: 2
+ obstacles: {
+ stoneBlocks: 5,
+ lockedCandies: 4,
+ honeyCandies: 3
+ }
}, {
level: 5,
- targetScore: 3000,
- moves: 14,
+ targetScore: 4600,
+ moves: 13,
gridSize: 10,
- timeLimit: 80,
- // 1:20
- blockedCellsCount: 8,
- icyBombsCount: 3
+ obstacles: {
+ stoneBlocks: 6,
+ lockedCandies: 5,
+ honeyCandies: 4
+ }
}, {
level: 6,
- targetScore: 3500,
- moves: 13,
+ targetScore: 5500,
+ moves: 12,
gridSize: 10,
- timeLimit: 75,
- // 1:15
- blockedCellsCount: 10,
- icyBombsCount: 4
+ obstacles: {
+ stoneBlocks: 7,
+ lockedCandies: 6,
+ honeyCandies: 5
+ }
}, {
level: 7,
- targetScore: 4000,
- moves: 12,
+ targetScore: 6500,
+ moves: 11,
gridSize: 10,
- timeLimit: 70,
- // 1:10
- blockedCellsCount: 12,
- icyBombsCount: 5
+ obstacles: {
+ stoneBlocks: 8,
+ lockedCandies: 7,
+ honeyCandies: 6
+ }
}, {
level: 8,
- targetScore: 4500,
- moves: 11,
+ targetScore: 7600,
+ moves: 10,
gridSize: 10,
- timeLimit: 65,
- // 1:05
- blockedCellsCount: 14,
- icyBombsCount: 6
+ obstacles: {
+ stoneBlocks: 9,
+ lockedCandies: 8,
+ honeyCandies: 7
+ }
}, {
level: 9,
- targetScore: 5000,
- moves: 10,
+ targetScore: 8800,
+ moves: 9,
gridSize: 10,
- timeLimit: 60,
- // 1:00
- blockedCellsCount: 16,
- icyBombsCount: 7
+ obstacles: {
+ stoneBlocks: 10,
+ lockedCandies: 9,
+ honeyCandies: 8
+ }
}, {
level: 10,
- targetScore: 6000,
- moves: 10,
+ targetScore: 10000,
+ moves: 8,
gridSize: 10,
- timeLimit: 55,
- // 55 seconds
- blockedCellsCount: 18,
- icyBombsCount: 8
+ obstacles: {
+ stoneBlocks: 12,
+ lockedCandies: 10,
+ honeyCandies: 10
+ }
}];
// Initialize grid cells
for (var y = 0; y < GRID_HEIGHT; y++) {
grid[y] = [];
@@ -575,45 +639,8 @@
levelText.anchor.set(0.5, 0.5);
levelButtonContainer.addChild(levelText);
LK.gui.top.addChild(levelButtonContainer);
levelButtonContainer.y = 330;
-// UI Elements - Timer with button background
-var timerButtonBorder = LK.getAsset('score_button_border', {
- anchorX: 0.5,
- anchorY: 0.5,
- scaleX: 0.8,
- scaleY: 0.8
-});
-var timerButtonBg = LK.getAsset('score_button_bg', {
- anchorX: 0.5,
- anchorY: 0.5,
- scaleX: 0.8,
- scaleY: 0.8
-});
-var timerButtonHighlight = LK.getAsset('score_button_highlight', {
- anchorX: 0.5,
- anchorY: 0.5,
- scaleX: 0.8,
- scaleY: 0.8
-});
-// Create timer button container
-var timerButtonContainer = new Container();
-timerButtonContainer.addChild(timerButtonBorder);
-timerButtonContainer.addChild(timerButtonBg);
-timerButtonContainer.addChild(timerButtonHighlight);
-// Position button elements
-timerButtonBorder.y = 0;
-timerButtonBg.y = -2;
-timerButtonHighlight.y = -5;
-timerButtonHighlight.alpha = 0.6;
-var timerText = new Text2('Time: 0:00', {
- size: 50,
- fill: 0xFFFFFF
-});
-timerText.anchor.set(0.5, 0.5);
-timerButtonContainer.addChild(timerText);
-LK.gui.top.addChild(timerButtonContainer);
-timerButtonContainer.y = 400;
function getRandomCandyType() {
return CANDY_TYPES[Math.floor(Math.random() * CANDY_TYPES.length)];
}
function loadProgress() {
@@ -633,138 +660,48 @@
function getCurrentLevelConfig() {
if (currentLevel <= levelConfigs.length) {
return levelConfigs[currentLevel - 1];
}
- // For levels beyond predefined configs, generate dynamic difficulty
+ // For levels beyond predefined configs, generate dynamic difficulty with increasing obstacles
+ var obstacleCount = Math.min(15, currentLevel);
return {
level: currentLevel,
- targetScore: 1000 + (currentLevel - 1) * 750,
- moves: Math.max(8, 20 - Math.floor(currentLevel / 2)),
+ targetScore: 1000 + (currentLevel - 1) * 900,
+ moves: Math.max(6, 20 - Math.floor(currentLevel / 1.5)),
gridSize: 10,
- timeLimit: Math.max(45, 120 - currentLevel * 5),
- blockedCellsCount: Math.min(20, currentLevel * 2),
- icyBombsCount: Math.min(10, Math.floor(currentLevel / 2))
+ 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 startLevelTimer() {
- if (levelTimer) {
- LK.clearInterval(levelTimer);
- }
- levelTimer = LK.setInterval(function () {
- timeLeft--;
- updateTimerDisplay();
- // Change timer color when time is running out
- if (timeLeft <= 10) {
- timerText.style = {
- fill: 0xFF0000
- }; // Red
- } else if (timeLeft <= 30) {
- timerText.style = {
- fill: 0xFFFF00
- }; // Yellow
- } else {
- timerText.style = {
- fill: 0xFFFFFF
- }; // White
- }
- if (timeLeft <= 0) {
- LK.clearInterval(levelTimer);
- LK.showGameOver();
- }
- }, 1000);
-}
-function updateTimerDisplay() {
- var minutes = Math.floor(timeLeft / 60);
- var seconds = timeLeft % 60;
- var timeString = minutes + ':' + (seconds < 10 ? '0' : '') + seconds;
- timerText.setText('Time: ' + timeString);
-}
-function addObstacles(config) {
- // Add blocked cells
- var blockedPositions = [];
- for (var i = 0; i < config.blockedCellsCount; i++) {
- var attempts = 0;
- var x, y;
- do {
- x = Math.floor(Math.random() * GRID_WIDTH);
- y = Math.floor(Math.random() * GRID_HEIGHT);
- attempts++;
- } while (grid[y][x] !== null && attempts < 50);
- if (attempts < 50) {
- var blockedCell = new BlockedCell(x, y);
- blockedCell.x = GRID_START_X + x * CELL_SIZE + CELL_SIZE / 2;
- blockedCell.y = GRID_START_Y + y * CELL_SIZE + CELL_SIZE / 2;
- game.addChild(blockedCell);
- blockedCells.push(blockedCell);
- grid[y][x] = blockedCell;
- }
- }
- // Add icy bombs
- for (var j = 0; j < config.icyBombsCount; j++) {
- var attempts = 0;
- var x, y;
- do {
- x = Math.floor(Math.random() * GRID_WIDTH);
- y = Math.floor(Math.random() * GRID_HEIGHT);
- attempts++;
- } while (grid[y][x] !== null && attempts < 50);
- if (attempts < 50) {
- var icyBomb = new IcyBomb(x, y);
- icyBomb.x = GRID_START_X + x * CELL_SIZE + CELL_SIZE / 2;
- icyBomb.y = GRID_START_Y + y * CELL_SIZE + CELL_SIZE / 2;
- game.addChild(icyBomb);
- icyBombs.push(icyBomb);
- grid[y][x] = icyBomb;
- }
- }
-}
function initializeLevel() {
var config = getCurrentLevelConfig();
targetScore = config.targetScore;
movesLeft = config.moves;
- timeLeft = config.timeLimit;
currentScore = 0;
// Update UI
levelText.setText('Level: ' + currentLevel);
scoreText.setText('Score: 0');
movesText.setText('Moves: ' + movesLeft);
targetText.setText('Target: ' + targetScore);
- updateTimerDisplay();
- // Clear existing elements
+ // Clear existing candies
for (var i = candies.length - 1; i >= 0; i--) {
var candy = candies[i];
if (candy.parent) {
candy.parent.removeChild(candy);
}
}
candies = [];
- // Clear blocked cells
- for (var j = blockedCells.length - 1; j >= 0; j--) {
- var blockedCell = blockedCells[j];
- if (blockedCell.parent) {
- blockedCell.parent.removeChild(blockedCell);
- }
- }
- blockedCells = [];
- // Clear icy bombs
- for (var k = icyBombs.length - 1; k >= 0; k--) {
- var icyBomb = icyBombs[k];
- if (icyBomb.parent) {
- icyBomb.parent.removeChild(icyBomb);
- }
- }
- icyBombs = [];
// Reset grid
for (var y = 0; y < GRID_HEIGHT; y++) {
for (var x = 0; x < GRID_WIDTH; x++) {
grid[y][x] = null;
}
}
- // Start timer
- startLevelTimer();
- // Initialize new grid with obstacles
+ // Initialize new grid
initializeGrid();
- addObstacles(config);
}
function completeLevel() {
if (currentLevel >= maxLevel) {
maxLevel = currentLevel + 1;
@@ -818,8 +755,107 @@
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:
@@ -927,10 +963,8 @@
}
function initializeGrid() {
for (var y = 0; y < GRID_HEIGHT; y++) {
for (var x = 0; x < GRID_WIDTH; x++) {
- // Skip if already occupied by obstacle
- if (grid[y][x] !== null) continue;
var type;
var attempts = 0;
do {
// Use level-specific candy type generation
@@ -944,8 +978,11 @@
} 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;
@@ -1209,14 +1246,47 @@
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);
@@ -1438,12 +1508,8 @@
LK.getSound('swap').play();
LK.setTimeout(function () {
movesLeft--;
movesText.setText('Moves: ' + movesLeft);
- // Decrement icy bomb timers
- for (var i = 0; i < icyBombs.length; i++) {
- icyBombs[i].decrementTurn();
- }
processMatches();
selectedCandy = null;
}, 250);
} else {
@@ -1532,12 +1598,8 @@
LK.getSound('swap').play();
LK.setTimeout(function () {
movesLeft--;
movesText.setText('Moves: ' + movesLeft);
- // Decrement icy bomb timers
- for (var i = 0; i < icyBombs.length; i++) {
- icyBombs[i].decrementTurn();
- }
processMatches();
}, 250);
}
}
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