User prompt
bu seferde çok az olduğu matchlenecek şeker yok
User prompt
çok sık aynı şekerden olmasın oyunu kolaylaştırıyor
User prompt
hala matchleme sorununu yaşıyorum bazen şekerler aynı olmasına rağmen matchlenmiyor
User prompt
eğer yanlış matchlersem scorem 300 eksilsin ve bi ses çıkarsın
User prompt
bazı şekerler aynı tür olmasına rağmen matchlenmiyorlar
User prompt
eğer şekerler kendiliğinden matchlencek pozisyondaysa otomatik matchlensinler
User prompt
dedect the bugs like a pro dev and fix it
User prompt
add mute music section
User prompt
candies cant match
User prompt
Sometimes the candies do not matchs even after being tripled and there may be a bug.
User prompt
make game harder
User prompt
When the bomb explodes it affects a 3x3 area.
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading '0')' in or related to this line: 'if (grid[row][col] && grid[row][col].candyType) {' Line Number: 96
User prompt
Set a limit on the types of candy, there can be a maximum of 6 of each candy block
User prompt
bombs explode 3x3 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
make game harder
User prompt
Generate a balanced initial game board for a match-3 puzzle with the following strict constraints: No immediate matches: There must be no 3 or more identical blocks consecutively aligned horizontally or vertically at the start. Limited quantity per block type: Each block type must appear no more than a specified maximum count on the board, distributed as evenly as possible. Placement validation: When placing a block, check neighbors to prevent forming 3-in-a-row or 3-in-a-column matches. Random but controlled: Use randomization within these constraints to keep the board fresh and fair. Re-generation if needed: If no suitable block can be placed in a cell without breaking constraints, backtrack or reshuffle the board to ensure validity. Implement a robust board generation algorithm that respects these rules to avoid starting boards with clusters or imbalanced block counts.
User prompt
When generating the game board (seed) for the match-3 game, ensure the following constraints to avoid large clusters of identical blocks: No initial matches: The board should never start with 3 or more identical blocks aligned horizontally or vertically. Diverse distribution: Implement a placement algorithm that places blocks one by one, checking the neighbors of each placed block to avoid creating immediate matches. Controlled randomness: Use a shuffled pool of block types and place them iteratively, validating after each placement that no match occurs. Board validation: After filling the board, scan for any accidental matches and reshuffle or adjust if any are found. Seed reproducibility: Use a seeded random number generator for consistency but ensure enough variation. The goal is to produce a fair, playable board at the start of each seed with no immediate matches or overly repetitive patterns.
User prompt
When generating a new seed (board layout) for the match-3 game, ensure the following: The blocks are randomly distributed but balanced — avoid long runs or clusters of only one block type. Each seed must include a diverse mix of block types, with no single block type dominating more than 25-30% of the board. Guarantee that at least one valid match is possible at the start of the seed. The randomization should be seeded to allow reproducibility but also varied enough to keep gameplay fresh. Implement logic to prevent impossible boards or those that break game mechanics (e.g., full rows or columns of the same block). This will ensure the game remains fair, challenging, and fun as the player progresses through multiple seeds.
User prompt
Create a loop system where the player progresses through consecutive seeds (board setups) by reaching a target score. Each new seed should increase difficulty slightly, making the game progressively harder. The game continues indefinitely until the player fails to meet the score goal. ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Fix the bug where matched blocks don’t mix or clear properly. Ensure reliable match detection and grid updates. Also, make the mixing effects extremely satisfying — with juicy particles, sound, and smooth animations that enhance the player experience without causing lag or delays. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
add background music
User prompt
add image to background too
Code edit (1 edits merged)
Please save this source code
User prompt
Sweet Swap Match
/****
* Plugins
****/
var tween = LK.import("@upit/tween.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.isSpecial = false;
self.specialType = null; // 'lineH', 'lineV', 'explosive'
self.falling = false;
var assetId = 'candy' + type;
if (self.specialType === 'lineH') assetId = 'lineCandyH';else if (self.specialType === 'lineV') assetId = 'lineCandyV';else if (self.specialType === 'explosive') assetId = 'explosiveCandy';
var candyGraphics = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
self.setSpecialType = function (specialType) {
self.isSpecial = true;
self.specialType = specialType;
self.removeChild(candyGraphics);
var newAssetId = 'candy' + type;
if (specialType === 'lineH') newAssetId = 'lineCandyH';else if (specialType === 'lineV') newAssetId = 'lineCandyV';else if (specialType === 'explosive') newAssetId = 'explosiveCandy';
candyGraphics = self.attachAsset(newAssetId, {
anchorX: 0.5,
anchorY: 0.5
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2a1810
});
/****
* Game Code
****/
var GRID_SIZE = 8;
var CELL_SIZE = 200;
var CANDY_TYPES = 7;
var TARGET_SCORE = 8000;
var MAX_MOVES = 20;
var grid = [];
var score = 0;
var moves = 0;
var selectedCandy = null;
var isProcessing = false;
var gridOffsetX = (2048 - GRID_SIZE * CELL_SIZE) / 2;
var gridOffsetY = 400;
// UI Elements
var scoreTxt = new Text2('Score: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var movesTxt = new Text2('Moves: ' + MAX_MOVES, {
size: 80,
fill: 0xFFFFFF
});
movesTxt.anchor.set(0.5, 0);
movesTxt.y = 100;
LK.gui.top.addChild(movesTxt);
var targetTxt = new Text2('Target: ' + TARGET_SCORE, {
size: 60,
fill: 0xFFFF00
});
targetTxt.anchor.set(0.5, 0);
targetTxt.y = 200;
LK.gui.top.addChild(targetTxt);
// Create grid background
for (var row = 0; row < GRID_SIZE; row++) {
for (var col = 0; col < GRID_SIZE; col++) {
var bgTile = game.addChild(LK.getAsset('gridBackground', {
anchorX: 0.5,
anchorY: 0.5,
x: gridOffsetX + col * CELL_SIZE + CELL_SIZE / 2,
y: gridOffsetY + row * CELL_SIZE + CELL_SIZE / 2,
alpha: 0.3
}));
}
}
function initializeGrid() {
grid = [];
for (var row = 0; row < GRID_SIZE; row++) {
grid[row] = [];
for (var col = 0; col < GRID_SIZE; col++) {
var candyType = Math.floor(Math.random() * CANDY_TYPES) + 1;
var candy = new Candy(candyType, col, row);
candy.x = gridOffsetX + col * CELL_SIZE + CELL_SIZE / 2;
candy.y = gridOffsetY + row * CELL_SIZE + CELL_SIZE / 2;
grid[row][col] = candy;
game.addChild(candy);
}
}
// Remove initial matches
var hasMatches = true;
while (hasMatches) {
hasMatches = false;
for (var row = 0; row < GRID_SIZE; row++) {
for (var col = 0; col < GRID_SIZE; col++) {
if (checkMatch(row, col).length >= 3) {
grid[row][col].candyType = Math.floor(Math.random() * CANDY_TYPES) + 1;
hasMatches = true;
}
}
}
}
}
function getGridPosition(x, y) {
var col = Math.floor((x - gridOffsetX) / CELL_SIZE);
var row = Math.floor((y - gridOffsetY) / CELL_SIZE);
if (col >= 0 && col < GRID_SIZE && row >= 0 && row < GRID_SIZE) {
return {
row: row,
col: col
};
}
return null;
}
function checkMatch(row, col) {
var candy = grid[row][col];
if (!candy || candy.falling) return [];
var type = candy.candyType;
var horizontalMatches = [candy];
var verticalMatches = [candy];
// Check horizontal matches
var left = col - 1;
while (left >= 0 && grid[row][left] && !grid[row][left].falling && grid[row][left].candyType === type) {
horizontalMatches.push(grid[row][left]);
left--;
}
var right = col + 1;
while (right < GRID_SIZE && grid[row][right] && !grid[row][right].falling && grid[row][right].candyType === type) {
horizontalMatches.push(grid[row][right]);
right++;
}
// Check vertical matches
var up = row - 1;
while (up >= 0 && grid[up][col] && !grid[up][col].falling && grid[up][col].candyType === type) {
verticalMatches.push(grid[up][col]);
up--;
}
var down = row + 1;
while (down < GRID_SIZE && grid[down][col] && !grid[down][col].falling && grid[down][col].candyType === type) {
verticalMatches.push(grid[down][col]);
down++;
}
// Return the larger match group if either is 3 or more
if (horizontalMatches.length >= 3 && verticalMatches.length >= 3) {
// Return combined matches for cross patterns
var allMatches = [];
for (var i = 0; i < horizontalMatches.length; i++) {
if (allMatches.indexOf(horizontalMatches[i]) === -1) {
allMatches.push(horizontalMatches[i]);
}
}
for (var i = 0; i < verticalMatches.length; i++) {
if (allMatches.indexOf(verticalMatches[i]) === -1) {
allMatches.push(verticalMatches[i]);
}
}
return allMatches;
} else if (horizontalMatches.length >= 3) {
return horizontalMatches;
} else if (verticalMatches.length >= 3) {
return verticalMatches;
}
return [];
}
function findAllMatches() {
var allMatches = [];
var processed = [];
for (var row = 0; row < GRID_SIZE; row++) {
processed[row] = [];
for (var col = 0; col < GRID_SIZE; col++) {
processed[row][col] = false;
}
}
for (var row = 0; row < GRID_SIZE; row++) {
for (var col = 0; col < GRID_SIZE; col++) {
if (!processed[row][col] && grid[row][col] && !grid[row][col].falling) {
var matches = checkMatch(row, col);
if (matches.length >= 3) {
allMatches.push(matches);
for (var i = 0; i < matches.length; i++) {
if (matches[i] && matches[i].gridY !== undefined && matches[i].gridX !== undefined) {
processed[matches[i].gridY][matches[i].gridX] = true;
}
}
}
}
}
}
return allMatches;
}
function removeMatches(matchGroups) {
var totalScore = 0;
for (var g = 0; g < matchGroups.length; g++) {
var matches = matchGroups[g];
var matchScore = 0;
if (matches.length === 3) matchScore = 50;else if (matches.length === 4) matchScore = 120;else if (matches.length >= 5) matchScore = 300;
totalScore += matchScore;
// Create special candy for 4+ matches
var specialCandy = null;
if (matches.length >= 4) {
var centerCandy = matches[Math.floor(matches.length / 2)];
if (matches.length === 4) {
// Create line candy based on match direction
var isHorizontal = matches[0].gridY === matches[1].gridY;
centerCandy.setSpecialType(isHorizontal ? 'lineH' : 'lineV');
} else if (matches.length >= 5) {
centerCandy.setSpecialType('explosive');
}
specialCandy = centerCandy;
}
// Mark candies for removal first
var candiesToRemove = [];
for (var i = 0; i < matches.length; i++) {
var candy = matches[i];
if (matches.length < 4 || candy !== specialCandy) {
candiesToRemove.push(candy);
}
}
// Remove candies from grid immediately to prevent double processing
for (var i = 0; i < candiesToRemove.length; i++) {
var candy = candiesToRemove[i];
if (candy && grid[candy.gridY] && grid[candy.gridY][candy.gridX] === candy) {
grid[candy.gridY][candy.gridX] = null;
}
}
// Animate candy destruction with satisfying effects
for (var i = 0; i < candiesToRemove.length; i++) {
var candy = candiesToRemove[i];
if (candy) {
// Create particle effect before destroying
createParticleEffect(candy.x, candy.y, candy.candyType);
// Animate candy scaling down with bounce
tween(candy, {
scaleX: 0,
scaleY: 0,
rotation: Math.PI * 2,
alpha: 0
}, {
duration: 300,
easing: tween.bounceIn,
onFinish: function onFinish() {
if (candy.parent) {
candy.destroy();
}
}
});
}
}
// Handle special candy creation effect
if (specialCandy) {
// Special candy creation effect
tween(specialCandy, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 200,
easing: tween.bounceOut,
onFinish: function onFinish() {
tween(specialCandy, {
scaleX: 1,
scaleY: 1
}, {
duration: 150,
easing: tween.easeOut
});
}
});
LK.effects.flashObject(specialCandy, 0xFFD700, 500);
}
}
if (totalScore > 0) {
LK.getSound('match').play();
LK.effects.flashScreen(0xFFFFFF, 200);
}
return totalScore;
}
function applyGravity() {
var moved = false;
var animationDelay = 0;
for (var col = 0; col < GRID_SIZE; col++) {
var writePos = GRID_SIZE - 1;
var colDelay = col * 30; // Stagger columns slightly
for (var row = GRID_SIZE - 1; row >= 0; row--) {
if (grid[row][col] !== null) {
if (row !== writePos) {
grid[writePos][col] = grid[row][col];
grid[row][col] = null;
var candy = grid[writePos][col];
candy.gridY = writePos;
candy.falling = true;
var fallDistance = writePos - row;
var fallDuration = 200 + fallDistance * 50; // Longer falls take more time
LK.setTimeout(function (candy, writePos, fallDuration) {
return function () {
tween(candy, {
y: gridOffsetY + writePos * CELL_SIZE + CELL_SIZE / 2
}, {
duration: fallDuration,
easing: tween.bounceOut,
onFinish: function onFinish() {
candy.falling = false;
}
});
};
}(candy, writePos, fallDuration), colDelay);
moved = true;
}
writePos--;
}
}
// Fill empty spaces with new candies
for (var emptyRow = writePos; emptyRow >= 0; emptyRow--) {
var candyType = Math.floor(Math.random() * CANDY_TYPES) + 1;
var newCandy = new Candy(candyType, col, emptyRow);
newCandy.x = gridOffsetX + col * CELL_SIZE + CELL_SIZE / 2;
newCandy.y = gridOffsetY + (emptyRow - GRID_SIZE) * CELL_SIZE + CELL_SIZE / 2;
newCandy.falling = true;
grid[emptyRow][col] = newCandy;
game.addChild(newCandy);
var dropDelay = colDelay + (GRID_SIZE - emptyRow) * 50;
LK.setTimeout(function (newCandy, emptyRow) {
return function () {
tween(newCandy, {
y: gridOffsetY + emptyRow * CELL_SIZE + CELL_SIZE / 2
}, {
duration: 300,
easing: tween.bounceOut,
onFinish: function onFinish() {
newCandy.falling = false;
}
});
};
}(newCandy, emptyRow), dropDelay);
moved = true;
}
}
return moved;
}
function swapCandies(candy1, candy2) {
if (isProcessing) return false;
var tempGridX = candy1.gridX;
var tempGridY = candy1.gridY;
candy1.gridX = candy2.gridX;
candy1.gridY = candy2.gridY;
candy2.gridX = tempGridX;
candy2.gridY = tempGridY;
grid[candy1.gridY][candy1.gridX] = candy1;
grid[candy2.gridY][candy2.gridX] = candy2;
var pos1 = {
x: gridOffsetX + candy1.gridX * CELL_SIZE + CELL_SIZE / 2,
y: gridOffsetY + candy1.gridY * CELL_SIZE + CELL_SIZE / 2
};
var pos2 = {
x: gridOffsetX + candy2.gridX * CELL_SIZE + CELL_SIZE / 2,
y: gridOffsetY + candy2.gridY * CELL_SIZE + CELL_SIZE / 2
};
isProcessing = true;
tween(candy1, pos1, {
duration: 200,
easing: tween.easeInOut
});
tween(candy2, pos2, {
duration: 200,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Check for matches in all directions from both swapped positions
var hasValidMatch = false;
var allMatches = findAllMatches();
for (var m = 0; m < allMatches.length; m++) {
for (var c = 0; c < allMatches[m].length; c++) {
if (allMatches[m][c] === candy1 || allMatches[m][c] === candy2) {
hasValidMatch = true;
break;
}
}
if (hasValidMatch) break;
}
if (hasValidMatch) {
LK.getSound('swap').play();
moves++;
movesTxt.setText('Moves: ' + (MAX_MOVES - moves));
processMatches();
} else {
// Swap back
var tempGridX = candy1.gridX;
var tempGridY = candy1.gridY;
candy1.gridX = candy2.gridX;
candy1.gridY = candy2.gridY;
candy2.gridX = tempGridX;
candy2.gridY = tempGridY;
grid[candy1.gridY][candy1.gridX] = candy1;
grid[candy2.gridY][candy2.gridX] = candy2;
tween(candy1, pos2, {
duration: 200
});
tween(candy2, pos1, {
duration: 200,
onFinish: function onFinish() {
isProcessing = false;
}
});
}
}
});
return true;
}
function processMatches() {
LK.setTimeout(function () {
var matchGroups = findAllMatches();
if (matchGroups.length > 0) {
var matchScore = removeMatches(matchGroups);
score += matchScore;
scoreTxt.setText('Score: ' + score);
LK.setTimeout(function () {
var moved = applyGravity();
if (moved) {
LK.setTimeout(function () {
processMatches();
}, 400);
} else {
isProcessing = false;
checkGameEnd();
}
}, 100);
} else {
isProcessing = false;
checkGameEnd();
}
}, 100);
}
function createParticleEffect(x, y, candyType) {
// Create multiple particle sprites for a juicy effect
var colors = [0xFF6B6B, 0x4ECDC4, 0x45B7D1, 0x96CEB4, 0xFECE2F, 0xFF8A80];
var particleColor = colors[candyType - 1] || 0xFFFFFF;
for (var i = 0; i < 8; i++) {
var particle = game.addChild(LK.getAsset('candy' + candyType, {
anchorX: 0.5,
anchorY: 0.5,
x: x,
y: y,
scaleX: 0.3,
scaleY: 0.3,
alpha: 0.8
}));
// Random direction and distance for particles
var angle = Math.PI * 2 * i / 8;
var distance = 50 + Math.random() * 100;
var targetX = x + Math.cos(angle) * distance;
var targetY = y + Math.sin(angle) * distance;
// Animate particles flying out and fading
tween(particle, {
x: targetX,
y: targetY,
scaleX: 0,
scaleY: 0,
alpha: 0,
rotation: Math.random() * Math.PI * 4
}, {
duration: 400 + Math.random() * 200,
easing: tween.easeOut,
onFinish: function onFinish() {
if (particle.parent) {
particle.destroy();
}
}
});
}
}
function checkGameEnd() {
if (score >= TARGET_SCORE) {
LK.showYouWin();
} else if (moves >= MAX_MOVES) {
LK.showGameOver();
}
}
function isAdjacent(candy1, candy2) {
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;
}
game.down = function (x, y, obj) {
if (isProcessing) return;
var gridPos = getGridPosition(x, y);
if (!gridPos) return;
var candy = grid[gridPos.row][gridPos.col];
if (!candy || candy.falling) return;
if (selectedCandy === null) {
selectedCandy = candy;
tween(candy, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 150,
easing: tween.bounceOut
});
LK.effects.flashObject(candy, 0xFFFFFF, 300);
} else if (selectedCandy === candy) {
tween(candy, {
scaleX: 1,
scaleY: 1
}, {
duration: 150,
easing: tween.easeOut
});
selectedCandy = null;
} else if (isAdjacent(selectedCandy, candy)) {
tween(selectedCandy, {
scaleX: 1,
scaleY: 1
}, {
duration: 150,
easing: tween.easeOut
});
swapCandies(selectedCandy, candy);
selectedCandy = null;
} else {
tween(selectedCandy, {
scaleX: 1,
scaleY: 1
}, {
duration: 150,
easing: tween.easeOut
});
selectedCandy = candy;
tween(candy, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 150,
easing: tween.bounceOut
});
LK.effects.flashObject(candy, 0xFFFFFF, 300);
}
};
// Add background image
var backgroundImage = game.addChild(LK.getAsset('gameBackground', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
alpha: 0.8
}));
// Initialize the game
initializeGrid();
// Start background music
LK.playMusic('backgroundMusic');
; ===================================================================
--- original.js
+++ change.js
@@ -128,31 +128,31 @@
return null;
}
function checkMatch(row, col) {
var candy = grid[row][col];
- if (!candy) return [];
+ if (!candy || candy.falling) return [];
var type = candy.candyType;
var horizontalMatches = [candy];
var verticalMatches = [candy];
// Check horizontal matches
var left = col - 1;
- while (left >= 0 && grid[row][left] && grid[row][left].candyType === type) {
+ while (left >= 0 && grid[row][left] && !grid[row][left].falling && grid[row][left].candyType === type) {
horizontalMatches.push(grid[row][left]);
left--;
}
var right = col + 1;
- while (right < GRID_SIZE && grid[row][right] && grid[row][right].candyType === type) {
+ while (right < GRID_SIZE && grid[row][right] && !grid[row][right].falling && grid[row][right].candyType === type) {
horizontalMatches.push(grid[row][right]);
right++;
}
// Check vertical matches
var up = row - 1;
- while (up >= 0 && grid[up][col] && grid[up][col].candyType === type) {
+ while (up >= 0 && grid[up][col] && !grid[up][col].falling && grid[up][col].candyType === type) {
verticalMatches.push(grid[up][col]);
up--;
}
var down = row + 1;
- while (down < GRID_SIZE && grid[down][col] && grid[down][col].candyType === type) {
+ while (down < GRID_SIZE && grid[down][col] && !grid[down][col].falling && grid[down][col].candyType === type) {
verticalMatches.push(grid[down][col]);
down++;
}
// Return the larger match group if either is 3 or more
@@ -187,14 +187,16 @@
}
}
for (var row = 0; row < GRID_SIZE; row++) {
for (var col = 0; col < GRID_SIZE; col++) {
- if (!processed[row][col] && grid[row][col]) {
+ if (!processed[row][col] && grid[row][col] && !grid[row][col].falling) {
var matches = checkMatch(row, col);
if (matches.length >= 3) {
allMatches.push(matches);
for (var i = 0; i < matches.length; i++) {
- processed[matches[i].gridY][matches[i].gridX] = true;
+ if (matches[i] && matches[i].gridY !== undefined && matches[i].gridX !== undefined) {
+ processed[matches[i].gridY][matches[i].gridX] = true;
+ }
}
}
}
}
green gummy bear candy shiny and cute (sitting). No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
blue foot candy looks funny and shiny. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
yellow appetite enhancer candy looks shiny and delicous. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
pink cotton candy looks shiny and delicous. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
blue shiny and delicous lollipop, no stick. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
bomb and lollipop mix candy . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
blurry beautiful snow view background image. In-Game asset. 2d. High contrast. No shadows
blurry ice block texture. In-Game asset. 2d. High contrast. No shadows
stick candy. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
stick candy with green lines . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
bean candy red and shiny . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat