/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Fruit = Container.expand(function (fruitType) {
var self = Container.call(this);
self.fruitType = fruitType;
self.gridX = 0;
self.gridY = 0;
self.isSelected = false;
self.isMatching = false;
var fruitGraphics = self.attachAsset(fruitType, {
anchorX: 0.5,
anchorY: 0.5
});
self.setGridPosition = function (gridX, gridY) {
self.gridX = gridX;
self.gridY = gridY;
self.x = GRID_START_X + gridX * CELL_SIZE + CELL_SIZE / 2;
self.y = GRID_START_Y + gridY * CELL_SIZE + CELL_SIZE / 2;
};
self.animateToPosition = function (x, y, duration) {
duration = duration || 300;
tween(self, {
x: x,
y: y
}, {
duration: duration
});
};
self.highlight = function () {
if (!self.isSelected) {
self.isSelected = true;
fruitGraphics.alpha = 0.7;
}
};
self.unhighlight = function () {
if (self.isSelected) {
self.isSelected = false;
fruitGraphics.alpha = 1.0;
}
};
self.explode = function () {
self.isMatching = true;
tween(self, {
scaleX: 1.5,
scaleY: 1.5,
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
self.destroy();
}
});
};
self.down = function (x, y, obj) {
if (!gameState.isProcessing && !self.isMatching) {
handleFruitClick(self);
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
var GRID_SIZE = 9;
var CELL_SIZE = 200;
var GRID_START_X = (2048 - GRID_SIZE * CELL_SIZE) / 2;
var GRID_START_Y = 400;
var FRUIT_TYPES = ['apple', 'orange', 'grape', 'strawberry', 'banana', 'kiwi'];
var FRUIT_POINTS = {
'apple': 15,
'orange': 20,
'grape': 25,
'strawberry': 30,
'banana': 35,
'kiwi': 40
};
var grid = [];
var selectedFruit = null;
var score = 0;
var gameState = {
isProcessing: false,
comboCount: 0
};
// Initialize score display
var scoreTxt = new Text2('💵 $0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Initialize grid array
for (var y = 0; y < GRID_SIZE; y++) {
grid[y] = [];
for (var x = 0; x < GRID_SIZE; x++) {
grid[y][x] = null;
}
}
// Draw grid background
for (var y = 0; y < GRID_SIZE; y++) {
for (var x = 0; x < GRID_SIZE; x++) {
var cell = LK.getAsset('gridCell', {
anchorX: 0,
anchorY: 0
});
cell.x = GRID_START_X + x * CELL_SIZE;
cell.y = GRID_START_Y + y * CELL_SIZE;
cell.alpha = 0.3;
game.addChild(cell);
}
}
function getRandomFruitType() {
return FRUIT_TYPES[Math.floor(Math.random() * FRUIT_TYPES.length)];
}
function createFruit(x, y, fruitType) {
if (!fruitType) {
fruitType = getRandomFruitType();
}
var fruit = new Fruit(fruitType);
fruit.setGridPosition(x, y);
grid[y][x] = fruit;
game.addChild(fruit);
return fruit;
}
function initializeGrid() {
for (var y = 0; y < GRID_SIZE; y++) {
for (var x = 0; x < GRID_SIZE; x++) {
if (!grid[y][x]) {
createFruit(x, y);
}
}
}
}
function isValidPosition(x, y) {
return x >= 0 && x < GRID_SIZE && y >= 0 && y < GRID_SIZE;
}
function areAdjacent(fruit1, fruit2) {
var dx = Math.abs(fruit1.gridX - fruit2.gridX);
var dy = Math.abs(fruit1.gridY - fruit2.gridY);
return dx === 1 && dy === 0 || dx === 0 && dy === 1;
}
function swapFruits(fruit1, fruit2) {
if (!fruit1 || !fruit2) return;
var tempX = fruit1.gridX;
var tempY = fruit1.gridY;
// Update grid references
grid[fruit1.gridY][fruit1.gridX] = fruit2;
grid[fruit2.gridY][fruit2.gridX] = fruit1;
// Update fruit grid positions
fruit1.gridX = fruit2.gridX;
fruit1.gridY = fruit2.gridY;
fruit2.gridX = tempX;
fruit2.gridY = tempY;
// Animate to new positions
var pos1X = GRID_START_X + fruit1.gridX * CELL_SIZE + CELL_SIZE / 2;
var pos1Y = GRID_START_Y + fruit1.gridY * CELL_SIZE + CELL_SIZE / 2;
var pos2X = GRID_START_X + fruit2.gridX * CELL_SIZE + CELL_SIZE / 2;
var pos2Y = GRID_START_Y + fruit2.gridY * CELL_SIZE + CELL_SIZE / 2;
fruit1.animateToPosition(pos1X, pos1Y);
fruit2.animateToPosition(pos2X, pos2Y);
LK.getSound('swap').play();
}
function findMatches() {
var matches = [];
// Check horizontal matches
for (var y = 0; y < GRID_SIZE; y++) {
var count = 1;
var currentType = grid[y][0] ? grid[y][0].fruitType : null;
for (var x = 1; x < GRID_SIZE; x++) {
var fruit = grid[y][x];
if (fruit && fruit.fruitType === currentType) {
count++;
} else {
if (count >= 3 && currentType) {
for (var i = x - count; i < x; i++) {
matches.push({
x: i,
y: y
});
}
}
count = 1;
currentType = fruit ? fruit.fruitType : null;
}
}
if (count >= 3 && currentType) {
for (var i = GRID_SIZE - count; i < GRID_SIZE; i++) {
matches.push({
x: i,
y: y
});
}
}
}
// Check vertical matches
for (var x = 0; x < GRID_SIZE; x++) {
var count = 1;
var currentType = grid[0][x] ? grid[0][x].fruitType : null;
for (var y = 1; y < GRID_SIZE; y++) {
var fruit = grid[y][x];
if (fruit && fruit.fruitType === currentType) {
count++;
} else {
if (count >= 3 && currentType) {
for (var i = y - count; i < y; i++) {
matches.push({
x: x,
y: i
});
}
}
count = 1;
currentType = fruit ? fruit.fruitType : null;
}
}
if (count >= 3 && currentType) {
for (var i = GRID_SIZE - count; i < GRID_SIZE; i++) {
matches.push({
x: x,
y: i
});
}
}
}
return matches;
}
function removeMatches(matches) {
if (matches.length === 0) return;
gameState.isProcessing = true;
// Mark fruits for removal and add score
for (var i = 0; i < matches.length; i++) {
var match = matches[i];
var fruit = grid[match.y][match.x];
if (fruit && !fruit.isMatching) {
var points = FRUIT_POINTS[fruit.fruitType];
fruit.explode();
grid[match.y][match.x] = null;
score += points;
// Create large floating dollar score text
var scoreText = new Text2('$' + points, {
size: 120,
fill: 0x00FF00
});
scoreText.anchor.set(0.5, 0.5);
scoreText.x = fruit.x;
scoreText.y = fruit.y;
scoreText.scaleX = 0.1;
scoreText.scaleY = 0.1;
game.addChild(scoreText);
// Animate the score text: scale up, move up, and fade out
tween(scoreText, {
scaleX: 1.5,
scaleY: 1.5,
y: scoreText.y - 150,
alpha: 0
}, {
duration: 1500,
easing: tween.easeOut,
onFinish: function onFinish() {
scoreText.destroy();
}
});
}
}
scoreTxt.setText('💵 $' + score);
LK.getSound('match').play();
// Wait for explosion animation to complete
LK.setTimeout(function () {
dropFruits();
}, 350);
}
function dropFruits() {
var moved = false;
// Drop existing fruits
for (var x = 0; x < GRID_SIZE; x++) {
var writePos = GRID_SIZE - 1;
for (var y = GRID_SIZE - 1; y >= 0; y--) {
if (grid[y][x] && !grid[y][x].isMatching) {
if (y !== writePos) {
grid[writePos][x] = grid[y][x];
grid[y][x] = null;
var fruit = grid[writePos][x];
fruit.gridY = writePos;
var newY = GRID_START_Y + writePos * CELL_SIZE + CELL_SIZE / 2;
fruit.animateToPosition(fruit.x, newY, 200);
moved = true;
}
writePos--;
}
}
}
// Fill empty spaces with new fruits
for (var x = 0; x < GRID_SIZE; x++) {
for (var y = 0; y < GRID_SIZE; y++) {
if (!grid[y][x]) {
createFruit(x, y);
var fruit = grid[y][x];
fruit.y = GRID_START_Y - CELL_SIZE;
fruit.animateToPosition(fruit.x, GRID_START_Y + y * CELL_SIZE + CELL_SIZE / 2, 300);
moved = true;
}
}
}
if (moved) {
LK.setTimeout(function () {
checkForMatches();
}, 350);
} else {
gameState.isProcessing = false;
}
}
function createFirework(x, y, color) {
// Create firework particles
for (var i = 0; i < 8; i++) {
var particle = new Text2("★", {
size: 60,
fill: color
});
particle.anchor.set(0.5, 0.5);
particle.x = x;
particle.y = y;
particle.alpha = 1;
game.addChild(particle);
// Calculate random direction and distance
var angle = i / 8 * Math.PI * 2;
var distance = 150 + Math.random() * 100;
var targetX = x + Math.cos(angle) * distance;
var targetY = y + Math.sin(angle) * distance;
// Animate particle explosion
tween(particle, {
x: targetX,
y: targetY,
alpha: 0,
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 800 + Math.random() * 400,
easing: tween.easeOut,
onFinish: function onFinish() {
particle.destroy();
}
});
}
}
function showComboText(comboCount) {
var comboText = "";
var textColor = 0xFFFFFF;
if (comboCount === 2) {
comboText = "AMAZING!";
textColor = 0xFF0066; // Pink
} else if (comboCount === 3) {
comboText = "WOW!";
textColor = 0x00FF00; // Green
} else if (comboCount === 4) {
comboText = "FANCY!";
textColor = 0xFF6600; // Orange
} else if (comboCount >= 5) {
comboText = "AMAZING!";
textColor = 0xFF0066; // Pink
}
if (comboText) {
// Add fireworks for 2-combo amazing effect
if (comboCount === 2) {
// Create multiple fireworks at different positions
LK.setTimeout(function () {
createFirework(2048 / 2 - 300, 1366 / 2 - 200, 0xFF6B35);
}, 300);
LK.setTimeout(function () {
createFirework(2048 / 2 + 300, 1366 / 2 - 200, 0x35FF6B);
}, 500);
LK.setTimeout(function () {
createFirework(2048 / 2, 1366 / 2 + 200, 0x6B35FF);
}, 700);
LK.setTimeout(function () {
createFirework(2048 / 2 - 200, 1366 / 2 + 100, 0xFF3535);
}, 900);
LK.setTimeout(function () {
createFirework(2048 / 2 + 200, 1366 / 2 + 100, 0x35A5FF);
}, 1100);
}
// Create shadow text for better readability
var shadowText = new Text2(comboText, {
size: 180,
fill: 0x000000
});
shadowText.anchor.set(0.5, 0.5);
shadowText.x = 2048 / 2 + 8;
shadowText.y = 1366 / 2 + 8;
shadowText.scaleX = 0.1;
shadowText.scaleY = 0.1;
shadowText.alpha = 0.7;
game.addChild(shadowText);
// Create main combo text
var comboDisplay = new Text2(comboText, {
size: 180,
fill: textColor
});
comboDisplay.anchor.set(0.5, 0.5);
comboDisplay.x = 2048 / 2;
comboDisplay.y = 1366 / 2;
comboDisplay.scaleX = 0.1;
comboDisplay.scaleY = 0.1;
game.addChild(comboDisplay);
// Sparkly entrance animation with scale and rotation
tween(comboDisplay, {
scaleX: 1.3,
scaleY: 1.3,
rotation: 0.2
}, {
duration: 200,
easing: tween.elasticOut
});
tween(shadowText, {
scaleX: 1.3,
scaleY: 1.3,
rotation: 0.2
}, {
duration: 200,
easing: tween.elasticOut
});
// Sparkle effect - quick tint changes
LK.setTimeout(function () {
tween(comboDisplay, {
tint: 0xFFFFFF
}, {
duration: 100,
easing: tween.linear
});
}, 250);
LK.setTimeout(function () {
tween(comboDisplay, {
tint: textColor
}, {
duration: 100,
easing: tween.linear
});
}, 400);
LK.setTimeout(function () {
tween(comboDisplay, {
tint: 0xFFFFFF
}, {
duration: 100,
easing: tween.linear
});
}, 550);
LK.setTimeout(function () {
tween(comboDisplay, {
tint: textColor
}, {
duration: 100,
easing: tween.linear
});
}, 700);
// Scale bounce effect
LK.setTimeout(function () {
tween(comboDisplay, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 150,
easing: tween.easeOut
});
tween(shadowText, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 150,
easing: tween.easeOut
});
}, 300);
LK.setTimeout(function () {
tween(comboDisplay, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 150,
easing: tween.easeIn
});
tween(shadowText, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 150,
easing: tween.easeIn
});
}, 450);
// Final fade out with upward movement
tween(comboDisplay, {
alpha: 0,
y: comboDisplay.y - 150,
rotation: -0.1
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
comboDisplay.destroy();
}
});
tween(shadowText, {
alpha: 0,
y: shadowText.y - 150,
rotation: -0.1
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
shadowText.destroy();
}
});
}
}
function showGameEndMessage() {
gameState.isProcessing = true;
// Create multiple celebration fireworks
for (var i = 0; i < 6; i++) {
LK.setTimeout(function () {
var x = 400 + Math.random() * 1200;
var y = 600 + Math.random() * 800;
createFirework(x, y, 0xFFD700);
}, i * 200);
}
// Create victory message background
var victoryBg = new Text2("YOU WIN THE UPIT PRICE", {
size: 180,
fill: 0x000000
});
victoryBg.anchor.set(0.5, 0.5);
victoryBg.x = 2048 / 2 + 10;
victoryBg.y = 1366 / 2 + 10;
victoryBg.alpha = 0.8;
game.addChild(victoryBg);
// Create main victory text
var victoryText = new Text2("YOU WIN THE UPIT PRICE", {
size: 180,
fill: 0xFFD700
});
victoryText.anchor.set(0.5, 0.5);
victoryText.x = 2048 / 2;
victoryText.y = 1366 / 2;
victoryText.scaleX = 0.1;
victoryText.scaleY = 0.1;
game.addChild(victoryText);
// Create final score text
var finalScoreText = new Text2("SKOR: $" + score, {
size: 150,
fill: 0x00FF00
});
finalScoreText.anchor.set(0.5, 0.5);
finalScoreText.x = 2048 / 2;
finalScoreText.y = 1366 / 2 + 200;
finalScoreText.alpha = 0;
game.addChild(finalScoreText);
// Animate victory text entrance
tween(victoryText, {
scaleX: 1.2,
scaleY: 1.2,
rotation: 0.1
}, {
duration: 500,
easing: tween.elasticOut
});
tween(victoryBg, {
scaleX: 1.2,
scaleY: 1.2,
rotation: 0.1
}, {
duration: 500,
easing: tween.elasticOut
});
// Show final score after victory text
LK.setTimeout(function () {
tween(finalScoreText, {
alpha: 1,
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 300,
easing: tween.easeOut
});
}, 800);
// Show "You Win" message after celebration
LK.setTimeout(function () {
LK.showYouWin();
}, 3000);
}
function checkForMatches() {
var matches = findMatches();
if (matches.length > 0) {
gameState.comboCount++;
if (gameState.comboCount >= 2) {
showComboText(gameState.comboCount);
}
removeMatches(matches);
} else {
gameState.comboCount = 0;
gameState.isProcessing = false;
// Check for game end condition
if (score >= 5000) {
showGameEndMessage();
}
}
}
function handleFruitClick(fruit) {
if (!selectedFruit) {
selectedFruit = fruit;
fruit.highlight();
} else if (selectedFruit === fruit) {
selectedFruit.unhighlight();
selectedFruit = null;
} else if (areAdjacent(selectedFruit, fruit)) {
gameState.isProcessing = true;
gameState.comboCount = 0; // Reset combo count for new player move
var oldSelected = selectedFruit;
selectedFruit.unhighlight();
selectedFruit = null;
swapFruits(oldSelected, fruit);
LK.setTimeout(function () {
var matches = findMatches();
if (matches.length > 0) {
removeMatches(matches);
} else {
// No matches, swap back
swapFruits(oldSelected, fruit);
LK.setTimeout(function () {
gameState.isProcessing = false;
}, 300);
}
}, 300);
} else {
selectedFruit.unhighlight();
selectedFruit = fruit;
fruit.highlight();
}
}
// Initialize the game
initializeGrid();
// Start background music
LK.playMusic('backround');
// Initial match check after a short delay
LK.setTimeout(function () {
checkForMatches();
}, 500);
game.update = function () {
// Game update logic if needed
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Fruit = Container.expand(function (fruitType) {
var self = Container.call(this);
self.fruitType = fruitType;
self.gridX = 0;
self.gridY = 0;
self.isSelected = false;
self.isMatching = false;
var fruitGraphics = self.attachAsset(fruitType, {
anchorX: 0.5,
anchorY: 0.5
});
self.setGridPosition = function (gridX, gridY) {
self.gridX = gridX;
self.gridY = gridY;
self.x = GRID_START_X + gridX * CELL_SIZE + CELL_SIZE / 2;
self.y = GRID_START_Y + gridY * CELL_SIZE + CELL_SIZE / 2;
};
self.animateToPosition = function (x, y, duration) {
duration = duration || 300;
tween(self, {
x: x,
y: y
}, {
duration: duration
});
};
self.highlight = function () {
if (!self.isSelected) {
self.isSelected = true;
fruitGraphics.alpha = 0.7;
}
};
self.unhighlight = function () {
if (self.isSelected) {
self.isSelected = false;
fruitGraphics.alpha = 1.0;
}
};
self.explode = function () {
self.isMatching = true;
tween(self, {
scaleX: 1.5,
scaleY: 1.5,
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
self.destroy();
}
});
};
self.down = function (x, y, obj) {
if (!gameState.isProcessing && !self.isMatching) {
handleFruitClick(self);
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
var GRID_SIZE = 9;
var CELL_SIZE = 200;
var GRID_START_X = (2048 - GRID_SIZE * CELL_SIZE) / 2;
var GRID_START_Y = 400;
var FRUIT_TYPES = ['apple', 'orange', 'grape', 'strawberry', 'banana', 'kiwi'];
var FRUIT_POINTS = {
'apple': 15,
'orange': 20,
'grape': 25,
'strawberry': 30,
'banana': 35,
'kiwi': 40
};
var grid = [];
var selectedFruit = null;
var score = 0;
var gameState = {
isProcessing: false,
comboCount: 0
};
// Initialize score display
var scoreTxt = new Text2('💵 $0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Initialize grid array
for (var y = 0; y < GRID_SIZE; y++) {
grid[y] = [];
for (var x = 0; x < GRID_SIZE; x++) {
grid[y][x] = null;
}
}
// Draw grid background
for (var y = 0; y < GRID_SIZE; y++) {
for (var x = 0; x < GRID_SIZE; x++) {
var cell = LK.getAsset('gridCell', {
anchorX: 0,
anchorY: 0
});
cell.x = GRID_START_X + x * CELL_SIZE;
cell.y = GRID_START_Y + y * CELL_SIZE;
cell.alpha = 0.3;
game.addChild(cell);
}
}
function getRandomFruitType() {
return FRUIT_TYPES[Math.floor(Math.random() * FRUIT_TYPES.length)];
}
function createFruit(x, y, fruitType) {
if (!fruitType) {
fruitType = getRandomFruitType();
}
var fruit = new Fruit(fruitType);
fruit.setGridPosition(x, y);
grid[y][x] = fruit;
game.addChild(fruit);
return fruit;
}
function initializeGrid() {
for (var y = 0; y < GRID_SIZE; y++) {
for (var x = 0; x < GRID_SIZE; x++) {
if (!grid[y][x]) {
createFruit(x, y);
}
}
}
}
function isValidPosition(x, y) {
return x >= 0 && x < GRID_SIZE && y >= 0 && y < GRID_SIZE;
}
function areAdjacent(fruit1, fruit2) {
var dx = Math.abs(fruit1.gridX - fruit2.gridX);
var dy = Math.abs(fruit1.gridY - fruit2.gridY);
return dx === 1 && dy === 0 || dx === 0 && dy === 1;
}
function swapFruits(fruit1, fruit2) {
if (!fruit1 || !fruit2) return;
var tempX = fruit1.gridX;
var tempY = fruit1.gridY;
// Update grid references
grid[fruit1.gridY][fruit1.gridX] = fruit2;
grid[fruit2.gridY][fruit2.gridX] = fruit1;
// Update fruit grid positions
fruit1.gridX = fruit2.gridX;
fruit1.gridY = fruit2.gridY;
fruit2.gridX = tempX;
fruit2.gridY = tempY;
// Animate to new positions
var pos1X = GRID_START_X + fruit1.gridX * CELL_SIZE + CELL_SIZE / 2;
var pos1Y = GRID_START_Y + fruit1.gridY * CELL_SIZE + CELL_SIZE / 2;
var pos2X = GRID_START_X + fruit2.gridX * CELL_SIZE + CELL_SIZE / 2;
var pos2Y = GRID_START_Y + fruit2.gridY * CELL_SIZE + CELL_SIZE / 2;
fruit1.animateToPosition(pos1X, pos1Y);
fruit2.animateToPosition(pos2X, pos2Y);
LK.getSound('swap').play();
}
function findMatches() {
var matches = [];
// Check horizontal matches
for (var y = 0; y < GRID_SIZE; y++) {
var count = 1;
var currentType = grid[y][0] ? grid[y][0].fruitType : null;
for (var x = 1; x < GRID_SIZE; x++) {
var fruit = grid[y][x];
if (fruit && fruit.fruitType === currentType) {
count++;
} else {
if (count >= 3 && currentType) {
for (var i = x - count; i < x; i++) {
matches.push({
x: i,
y: y
});
}
}
count = 1;
currentType = fruit ? fruit.fruitType : null;
}
}
if (count >= 3 && currentType) {
for (var i = GRID_SIZE - count; i < GRID_SIZE; i++) {
matches.push({
x: i,
y: y
});
}
}
}
// Check vertical matches
for (var x = 0; x < GRID_SIZE; x++) {
var count = 1;
var currentType = grid[0][x] ? grid[0][x].fruitType : null;
for (var y = 1; y < GRID_SIZE; y++) {
var fruit = grid[y][x];
if (fruit && fruit.fruitType === currentType) {
count++;
} else {
if (count >= 3 && currentType) {
for (var i = y - count; i < y; i++) {
matches.push({
x: x,
y: i
});
}
}
count = 1;
currentType = fruit ? fruit.fruitType : null;
}
}
if (count >= 3 && currentType) {
for (var i = GRID_SIZE - count; i < GRID_SIZE; i++) {
matches.push({
x: x,
y: i
});
}
}
}
return matches;
}
function removeMatches(matches) {
if (matches.length === 0) return;
gameState.isProcessing = true;
// Mark fruits for removal and add score
for (var i = 0; i < matches.length; i++) {
var match = matches[i];
var fruit = grid[match.y][match.x];
if (fruit && !fruit.isMatching) {
var points = FRUIT_POINTS[fruit.fruitType];
fruit.explode();
grid[match.y][match.x] = null;
score += points;
// Create large floating dollar score text
var scoreText = new Text2('$' + points, {
size: 120,
fill: 0x00FF00
});
scoreText.anchor.set(0.5, 0.5);
scoreText.x = fruit.x;
scoreText.y = fruit.y;
scoreText.scaleX = 0.1;
scoreText.scaleY = 0.1;
game.addChild(scoreText);
// Animate the score text: scale up, move up, and fade out
tween(scoreText, {
scaleX: 1.5,
scaleY: 1.5,
y: scoreText.y - 150,
alpha: 0
}, {
duration: 1500,
easing: tween.easeOut,
onFinish: function onFinish() {
scoreText.destroy();
}
});
}
}
scoreTxt.setText('💵 $' + score);
LK.getSound('match').play();
// Wait for explosion animation to complete
LK.setTimeout(function () {
dropFruits();
}, 350);
}
function dropFruits() {
var moved = false;
// Drop existing fruits
for (var x = 0; x < GRID_SIZE; x++) {
var writePos = GRID_SIZE - 1;
for (var y = GRID_SIZE - 1; y >= 0; y--) {
if (grid[y][x] && !grid[y][x].isMatching) {
if (y !== writePos) {
grid[writePos][x] = grid[y][x];
grid[y][x] = null;
var fruit = grid[writePos][x];
fruit.gridY = writePos;
var newY = GRID_START_Y + writePos * CELL_SIZE + CELL_SIZE / 2;
fruit.animateToPosition(fruit.x, newY, 200);
moved = true;
}
writePos--;
}
}
}
// Fill empty spaces with new fruits
for (var x = 0; x < GRID_SIZE; x++) {
for (var y = 0; y < GRID_SIZE; y++) {
if (!grid[y][x]) {
createFruit(x, y);
var fruit = grid[y][x];
fruit.y = GRID_START_Y - CELL_SIZE;
fruit.animateToPosition(fruit.x, GRID_START_Y + y * CELL_SIZE + CELL_SIZE / 2, 300);
moved = true;
}
}
}
if (moved) {
LK.setTimeout(function () {
checkForMatches();
}, 350);
} else {
gameState.isProcessing = false;
}
}
function createFirework(x, y, color) {
// Create firework particles
for (var i = 0; i < 8; i++) {
var particle = new Text2("★", {
size: 60,
fill: color
});
particle.anchor.set(0.5, 0.5);
particle.x = x;
particle.y = y;
particle.alpha = 1;
game.addChild(particle);
// Calculate random direction and distance
var angle = i / 8 * Math.PI * 2;
var distance = 150 + Math.random() * 100;
var targetX = x + Math.cos(angle) * distance;
var targetY = y + Math.sin(angle) * distance;
// Animate particle explosion
tween(particle, {
x: targetX,
y: targetY,
alpha: 0,
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 800 + Math.random() * 400,
easing: tween.easeOut,
onFinish: function onFinish() {
particle.destroy();
}
});
}
}
function showComboText(comboCount) {
var comboText = "";
var textColor = 0xFFFFFF;
if (comboCount === 2) {
comboText = "AMAZING!";
textColor = 0xFF0066; // Pink
} else if (comboCount === 3) {
comboText = "WOW!";
textColor = 0x00FF00; // Green
} else if (comboCount === 4) {
comboText = "FANCY!";
textColor = 0xFF6600; // Orange
} else if (comboCount >= 5) {
comboText = "AMAZING!";
textColor = 0xFF0066; // Pink
}
if (comboText) {
// Add fireworks for 2-combo amazing effect
if (comboCount === 2) {
// Create multiple fireworks at different positions
LK.setTimeout(function () {
createFirework(2048 / 2 - 300, 1366 / 2 - 200, 0xFF6B35);
}, 300);
LK.setTimeout(function () {
createFirework(2048 / 2 + 300, 1366 / 2 - 200, 0x35FF6B);
}, 500);
LK.setTimeout(function () {
createFirework(2048 / 2, 1366 / 2 + 200, 0x6B35FF);
}, 700);
LK.setTimeout(function () {
createFirework(2048 / 2 - 200, 1366 / 2 + 100, 0xFF3535);
}, 900);
LK.setTimeout(function () {
createFirework(2048 / 2 + 200, 1366 / 2 + 100, 0x35A5FF);
}, 1100);
}
// Create shadow text for better readability
var shadowText = new Text2(comboText, {
size: 180,
fill: 0x000000
});
shadowText.anchor.set(0.5, 0.5);
shadowText.x = 2048 / 2 + 8;
shadowText.y = 1366 / 2 + 8;
shadowText.scaleX = 0.1;
shadowText.scaleY = 0.1;
shadowText.alpha = 0.7;
game.addChild(shadowText);
// Create main combo text
var comboDisplay = new Text2(comboText, {
size: 180,
fill: textColor
});
comboDisplay.anchor.set(0.5, 0.5);
comboDisplay.x = 2048 / 2;
comboDisplay.y = 1366 / 2;
comboDisplay.scaleX = 0.1;
comboDisplay.scaleY = 0.1;
game.addChild(comboDisplay);
// Sparkly entrance animation with scale and rotation
tween(comboDisplay, {
scaleX: 1.3,
scaleY: 1.3,
rotation: 0.2
}, {
duration: 200,
easing: tween.elasticOut
});
tween(shadowText, {
scaleX: 1.3,
scaleY: 1.3,
rotation: 0.2
}, {
duration: 200,
easing: tween.elasticOut
});
// Sparkle effect - quick tint changes
LK.setTimeout(function () {
tween(comboDisplay, {
tint: 0xFFFFFF
}, {
duration: 100,
easing: tween.linear
});
}, 250);
LK.setTimeout(function () {
tween(comboDisplay, {
tint: textColor
}, {
duration: 100,
easing: tween.linear
});
}, 400);
LK.setTimeout(function () {
tween(comboDisplay, {
tint: 0xFFFFFF
}, {
duration: 100,
easing: tween.linear
});
}, 550);
LK.setTimeout(function () {
tween(comboDisplay, {
tint: textColor
}, {
duration: 100,
easing: tween.linear
});
}, 700);
// Scale bounce effect
LK.setTimeout(function () {
tween(comboDisplay, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 150,
easing: tween.easeOut
});
tween(shadowText, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 150,
easing: tween.easeOut
});
}, 300);
LK.setTimeout(function () {
tween(comboDisplay, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 150,
easing: tween.easeIn
});
tween(shadowText, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 150,
easing: tween.easeIn
});
}, 450);
// Final fade out with upward movement
tween(comboDisplay, {
alpha: 0,
y: comboDisplay.y - 150,
rotation: -0.1
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
comboDisplay.destroy();
}
});
tween(shadowText, {
alpha: 0,
y: shadowText.y - 150,
rotation: -0.1
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
shadowText.destroy();
}
});
}
}
function showGameEndMessage() {
gameState.isProcessing = true;
// Create multiple celebration fireworks
for (var i = 0; i < 6; i++) {
LK.setTimeout(function () {
var x = 400 + Math.random() * 1200;
var y = 600 + Math.random() * 800;
createFirework(x, y, 0xFFD700);
}, i * 200);
}
// Create victory message background
var victoryBg = new Text2("YOU WIN THE UPIT PRICE", {
size: 180,
fill: 0x000000
});
victoryBg.anchor.set(0.5, 0.5);
victoryBg.x = 2048 / 2 + 10;
victoryBg.y = 1366 / 2 + 10;
victoryBg.alpha = 0.8;
game.addChild(victoryBg);
// Create main victory text
var victoryText = new Text2("YOU WIN THE UPIT PRICE", {
size: 180,
fill: 0xFFD700
});
victoryText.anchor.set(0.5, 0.5);
victoryText.x = 2048 / 2;
victoryText.y = 1366 / 2;
victoryText.scaleX = 0.1;
victoryText.scaleY = 0.1;
game.addChild(victoryText);
// Create final score text
var finalScoreText = new Text2("SKOR: $" + score, {
size: 150,
fill: 0x00FF00
});
finalScoreText.anchor.set(0.5, 0.5);
finalScoreText.x = 2048 / 2;
finalScoreText.y = 1366 / 2 + 200;
finalScoreText.alpha = 0;
game.addChild(finalScoreText);
// Animate victory text entrance
tween(victoryText, {
scaleX: 1.2,
scaleY: 1.2,
rotation: 0.1
}, {
duration: 500,
easing: tween.elasticOut
});
tween(victoryBg, {
scaleX: 1.2,
scaleY: 1.2,
rotation: 0.1
}, {
duration: 500,
easing: tween.elasticOut
});
// Show final score after victory text
LK.setTimeout(function () {
tween(finalScoreText, {
alpha: 1,
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 300,
easing: tween.easeOut
});
}, 800);
// Show "You Win" message after celebration
LK.setTimeout(function () {
LK.showYouWin();
}, 3000);
}
function checkForMatches() {
var matches = findMatches();
if (matches.length > 0) {
gameState.comboCount++;
if (gameState.comboCount >= 2) {
showComboText(gameState.comboCount);
}
removeMatches(matches);
} else {
gameState.comboCount = 0;
gameState.isProcessing = false;
// Check for game end condition
if (score >= 5000) {
showGameEndMessage();
}
}
}
function handleFruitClick(fruit) {
if (!selectedFruit) {
selectedFruit = fruit;
fruit.highlight();
} else if (selectedFruit === fruit) {
selectedFruit.unhighlight();
selectedFruit = null;
} else if (areAdjacent(selectedFruit, fruit)) {
gameState.isProcessing = true;
gameState.comboCount = 0; // Reset combo count for new player move
var oldSelected = selectedFruit;
selectedFruit.unhighlight();
selectedFruit = null;
swapFruits(oldSelected, fruit);
LK.setTimeout(function () {
var matches = findMatches();
if (matches.length > 0) {
removeMatches(matches);
} else {
// No matches, swap back
swapFruits(oldSelected, fruit);
LK.setTimeout(function () {
gameState.isProcessing = false;
}, 300);
}
}, 300);
} else {
selectedFruit.unhighlight();
selectedFruit = fruit;
fruit.highlight();
}
}
// Initialize the game
initializeGrid();
// Start background music
LK.playMusic('backround');
// Initial match check after a short delay
LK.setTimeout(function () {
checkForMatches();
}, 500);
game.update = function () {
// Game update logic if needed
};
strawberry. In-Game asset. 2d. High contrast. No shadows
apple. In-Game asset. 2d. High contrast. No shadows
banana. In-Game asset. 2d. High contrast. No shadows
grape. In-Game asset. 2d. High contrast. No shadows
golden shiny very shiny apple. In-Game asset. 2d. High contrast. No shadows
watermelon slice juicy. In-Game asset. 2d. High contrast. No shadows
green leaf background. In-Game asset. 2d. High contrast. No shadows
bomb. In-Game asset. 2d. High contrast. No shadows