/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Fruit = Container.expand(function (type, x, y) {
var self = Container.call(this);
self.type = type;
self.settled = false;
self.mergeProcessed = false;
var fruitTypes = ['cherry', 'strawberry', 'grape', 'orange', 'apple', 'pear', 'peach', 'pineapple', 'melon', 'watermelon'];
var fruitSizes = [80, 100, 120, 140, 160, 180, 200, 220, 240, 280];
var fruitScores = [10, 20, 40, 80, 160, 320, 640, 1280, 2560, 5120];
self.typeIndex = fruitTypes.indexOf(type);
self.size = fruitSizes[self.typeIndex];
self.scoreValue = fruitScores[self.typeIndex];
var fruitGraphics = self.attachAsset(type, {
anchorX: 0.5,
anchorY: 0.5
});
self.x = x;
self.y = y;
self.vx = 0;
self.vy = 0;
self.radius = self.size / 2;
self.canMergeWith = function (otherFruit) {
return !self.mergeProcessed && !otherFruit.mergeProcessed && self.type === otherFruit.type && self.typeIndex < 9;
};
self.getNextType = function () {
if (self.typeIndex < 9) {
return fruitTypes[self.typeIndex + 1];
}
return null;
};
self.update = function () {
if (!self.settled) {
self.vy += gravity;
self.x += self.vx;
self.y += self.vy;
// Container bounds collision
if (self.x - self.radius <= containerLeft) {
self.x = containerLeft + self.radius;
self.vx = -self.vx * friction;
}
if (self.x + self.radius >= containerRight) {
self.x = containerRight - self.radius;
self.vx = -self.vx * friction;
}
// Bottom collision - account for bottom border thickness
var actualBottom = containerY + containerHeight - 20; // Top of bottom border
if (self.y + self.radius >= actualBottom) {
self.y = actualBottom - self.radius;
self.vy = 0;
self.vx *= groundFriction;
if (Math.abs(self.vx) < 0.5) {
self.vx = 0;
self.settled = true;
}
}
// Collision with other fruits
for (var i = 0; i < fruits.length; i++) {
var otherFruit = fruits[i];
if (otherFruit !== self) {
var dx = self.x - otherFruit.x;
var dy = self.y - otherFruit.y;
var distance = Math.sqrt(dx * dx + dy * dy);
var minDistance = self.radius + otherFruit.radius;
if (distance < minDistance) {
// Handle overlapping/intertwined fruits more gracefully
if (distance < 0.1) {
// Fruits are nearly on top of each other - gentle separation
distance = 0.1;
dx = Math.random() * 2 - 1; // Random direction
dy = Math.random() * 2 - 1;
var len = Math.sqrt(dx * dx + dy * dy);
dx /= len;
dy /= len;
}
var overlap = minDistance - distance;
var normalX = dx / distance;
var normalY = dy / distance;
// Very gentle position correction for intertwined fruits
var correctionFactor = Math.min(0.1, overlap * 0.05); // Even gentler correction
var selfCorrection = correctionFactor;
var otherCorrection = correctionFactor;
// If other fruit is settled, don't move it as much
if (otherFruit.settled) {
selfCorrection = correctionFactor * 1.5;
otherCorrection = correctionFactor * 0.3;
}
self.x += normalX * overlap * selfCorrection;
self.y += normalY * overlap * selfCorrection;
otherFruit.x -= normalX * overlap * otherCorrection;
otherFruit.y -= normalY * overlap * otherCorrection;
// Dampen velocities when fruits are intertwined
var relativeVx = self.vx - otherFruit.vx;
var relativeVy = self.vy - otherFruit.vy;
var speed = relativeVx * normalX + relativeVy * normalY;
if (speed < 0) continue;
// Much reduced velocity response for stability
speed *= restitution * 0.1; // Even less bounce
var impulseX = speed * normalX * 0.3;
var impulseY = speed * normalY * 0.3;
self.vx -= impulseX;
self.vy -= impulseY;
otherFruit.vx += impulseX * 0.5; // Less impact on other fruit
otherFruit.vy += impulseY * 0.5;
// Aggressive damping for intertwined fruits
if (overlap > 10) {
// Significantly overlapping
self.vx *= 0.7;
self.vy *= 0.7;
otherFruit.vx *= 0.7;
otherFruit.vy *= 0.7;
}
}
}
}
// Stronger damping for more stability
self.vx *= 0.95;
self.vy *= 0.95;
// More generous settling conditions
if (Math.abs(self.vx) < 0.5 && Math.abs(self.vy) < 0.5) {
// Check if touching ground or another settled fruit
var actualBottom = containerY + containerHeight - 20; // Top of bottom border
var touchingGround = self.y + self.radius >= actualBottom - 10;
var touchingSettledFruit = false;
for (var k = 0; k < fruits.length; k++) {
var otherFruit = fruits[k];
if (otherFruit !== self && otherFruit.settled) {
var dx = self.x - otherFruit.x;
var dy = self.y - otherFruit.y;
var distance = Math.sqrt(dx * dx + dy * dy);
var touchDistance = self.radius + otherFruit.radius + 5; // Small tolerance
if (distance <= touchDistance) {
touchingSettledFruit = true;
break;
}
}
}
if (touchingGround || touchingSettledFruit) {
self.settled = true;
self.vx = 0;
self.vy = 0;
}
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87ceeb
});
/****
* Game Code
****/
// Game constants - reduced for more stable physics
var gravity = 0.4; // Even more reduced gravity
var friction = 0.9; // Higher friction
var groundFriction = 0.98; // Even higher ground friction
var restitution = 0.15; // Much lower bounce for stability
// Container setup
var containerWidth = 1000;
var containerHeight = 800;
var containerX = (2048 - containerWidth) / 2;
var containerY = 1532 - containerHeight;
var containerLeft = containerX + 20;
var containerRight = containerX + containerWidth - 20;
var containerBottom = containerY + containerHeight - 20;
var overflowLine = containerY + 200;
// Game state
var fruits = [];
var nextFruitType = 'cherry';
var dropPosition = 1024;
var canDrop = true;
var gameActive = true;
// Fruit types for random generation
var initialFruitTypes = ['cherry', 'strawberry', 'grape', 'orange'];
// Create container
var container = game.addChild(LK.getAsset('container', {
anchorX: 0,
anchorY: 0,
x: containerX,
y: containerY
}));
// Create container borders
var leftBorder = game.addChild(LK.getAsset('containerBorder', {
anchorX: 0,
anchorY: 0,
x: containerX,
y: containerY
}));
var rightBorder = game.addChild(LK.getAsset('containerBorder', {
anchorX: 0,
anchorY: 0,
x: containerX + containerWidth - 20,
y: containerY
}));
var bottomBorder = game.addChild(LK.getAsset('containerBorder', {
anchorX: 0,
anchorY: 0,
x: containerX,
y: containerY + containerHeight - 20,
width: containerWidth,
height: 20
}));
// Create overflow line
var overflowLineGraphics = game.addChild(LK.getAsset('dropLine', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: overflowLine,
alpha: 0.5
}));
// UI elements
var scoreTxt = new Text2('Score: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var nextFruitTxt = new Text2('Next: Cherry', {
size: 60,
fill: 0xFFFFFF
});
nextFruitTxt.anchor.set(0, 0);
nextFruitTxt.x = 50;
nextFruitTxt.y = 150;
LK.gui.topLeft.addChild(nextFruitTxt);
// Preview fruit
var previewFruit = game.addChild(LK.getAsset(nextFruitType, {
anchorX: 0.5,
anchorY: 0.5,
x: dropPosition,
y: containerY - 100,
alpha: 0.7
}));
function getRandomInitialFruit() {
return initialFruitTypes[Math.floor(Math.random() * initialFruitTypes.length)];
}
function updatePreview() {
game.removeChild(previewFruit);
previewFruit = game.addChild(LK.getAsset(nextFruitType, {
anchorX: 0.5,
anchorY: 0.5,
x: dropPosition,
y: containerY - 100,
alpha: 0.7
}));
var capitalizedType = nextFruitType.charAt(0).toUpperCase() + nextFruitType.slice(1);
nextFruitTxt.setText('Next: ' + capitalizedType);
}
function dropFruit() {
if (!canDrop || !gameActive) return;
var newFruit = new Fruit(nextFruitType, dropPosition, containerY - 50);
fruits.push(newFruit);
game.addChild(newFruit);
LK.getSound('drop').play();
nextFruitType = getRandomInitialFruit();
updatePreview();
canDrop = false;
LK.setTimeout(function () {
canDrop = true;
}, 500);
}
function checkMerges() {
var fruitsToRemove = [];
var newFruitsToAdd = [];
for (var i = 0; i < fruits.length; i++) {
if (fruitsToRemove.indexOf(i) !== -1) continue;
for (var j = i + 1; j < fruits.length; j++) {
if (fruitsToRemove.indexOf(j) !== -1) continue;
var fruit1 = fruits[i];
var fruit2 = fruits[j];
if (fruit1.canMergeWith(fruit2)) {
var dx = fruit1.x - fruit2.x;
var dy = fruit1.y - fruit2.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// More generous merge distance for intertwined fruits
var mergeDistance = (fruit1.radius + fruit2.radius) * 1.1; // 10% more generous
// Also allow merge if fruits are heavily overlapping (intertwined)
var isOverlapping = distance < (fruit1.radius + fruit2.radius) * 0.8;
if (distance <= mergeDistance || isOverlapping) {
var newType = fruit1.getNextType();
if (newType) {
var mergeX = (fruit1.x + fruit2.x) / 2;
var mergeY = (fruit1.y + fruit2.y) / 2;
var newFruit = new Fruit(newType, mergeX, mergeY);
// Give merged fruit slight upward velocity to help separate from pile
newFruit.vy = -2;
newFruitsToAdd.push(newFruit);
var scoreIncrease = newFruit.scoreValue;
LK.setScore(LK.getScore() + scoreIncrease);
scoreTxt.setText('Score: ' + LK.getScore());
LK.getSound('merge').play();
LK.effects.flashObject(newFruit, 0xffff00, 500);
}
fruitsToRemove.push(i);
fruitsToRemove.push(j);
fruit1.mergeProcessed = true;
fruit2.mergeProcessed = true;
break;
}
}
}
}
// Remove merged fruits (in reverse order to maintain indices)
fruitsToRemove.sort(function (a, b) {
return b - a;
});
for (var k = 0; k < fruitsToRemove.length; k++) {
var index = fruitsToRemove[k];
var fruitToRemove = fruits[index];
game.removeChild(fruitToRemove);
fruits.splice(index, 1);
}
// Add new merged fruits
for (var m = 0; m < newFruitsToAdd.length; m++) {
fruits.push(newFruitsToAdd[m]);
game.addChild(newFruitsToAdd[m]);
}
}
function checkGameOver() {
for (var i = 0; i < fruits.length; i++) {
var fruit = fruits[i];
// Only trigger game over if fruit is settled/stable and clearly above overflow line
if (fruit.settled && fruit.y - fruit.radius < overflowLine - 20) {
gameActive = false;
LK.setTimeout(function () {
LK.showGameOver();
}, 1000);
break;
}
}
}
// Game controls
game.down = function (x, y, obj) {
if (!gameActive) return;
dropPosition = Math.max(containerLeft + 50, Math.min(containerRight - 50, x));
previewFruit.x = dropPosition;
};
game.move = function (x, y, obj) {
if (!gameActive) return;
dropPosition = Math.max(containerLeft + 50, Math.min(containerRight - 50, x));
previewFruit.x = dropPosition;
};
game.up = function (x, y, obj) {
if (!gameActive) return;
dropFruit();
};
// Create informational fruit sprites at bottom to show evolution order
var infoFruits = [];
var fruitTypes = ['cherry', 'strawberry', 'grape', 'orange', 'apple', 'pear', 'peach', 'pineapple', 'melon', 'watermelon'];
var infoFruitSize = 60; // Smaller size for info display
var infoStartX = containerX + 50;
var infoY = containerY + containerHeight + 40;
var infoSpacing = 90;
for (var i = 0; i < fruitTypes.length; i++) {
var infoFruit = game.addChild(LK.getAsset(fruitTypes[i], {
anchorX: 0.5,
anchorY: 0.5,
x: infoStartX + i * infoSpacing,
y: infoY,
scaleX: infoFruitSize / 160,
// Scale down from original size
scaleY: infoFruitSize / 160,
alpha: 0.8
}));
infoFruits.push(infoFruit);
}
// Add evolution arrows between fruits
for (var i = 0; i < fruitTypes.length - 1; i++) {
var arrow = new Text2('→', {
size: 40,
fill: 0x333333
});
arrow.anchor.set(0.5, 0.5);
arrow.x = infoStartX + i * infoSpacing + infoSpacing / 2;
arrow.y = infoY;
game.addChild(arrow);
}
// Main game loop
game.update = function () {
if (!gameActive) return;
// Update all fruits
for (var i = 0; i < fruits.length; i++) {
fruits[i].update();
}
// Check for merges every few frames
if (LK.ticks % 3 === 0) {
checkMerges();
}
// Check game over condition
if (LK.ticks % 30 === 0) {
checkGameOver();
}
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Fruit = Container.expand(function (type, x, y) {
var self = Container.call(this);
self.type = type;
self.settled = false;
self.mergeProcessed = false;
var fruitTypes = ['cherry', 'strawberry', 'grape', 'orange', 'apple', 'pear', 'peach', 'pineapple', 'melon', 'watermelon'];
var fruitSizes = [80, 100, 120, 140, 160, 180, 200, 220, 240, 280];
var fruitScores = [10, 20, 40, 80, 160, 320, 640, 1280, 2560, 5120];
self.typeIndex = fruitTypes.indexOf(type);
self.size = fruitSizes[self.typeIndex];
self.scoreValue = fruitScores[self.typeIndex];
var fruitGraphics = self.attachAsset(type, {
anchorX: 0.5,
anchorY: 0.5
});
self.x = x;
self.y = y;
self.vx = 0;
self.vy = 0;
self.radius = self.size / 2;
self.canMergeWith = function (otherFruit) {
return !self.mergeProcessed && !otherFruit.mergeProcessed && self.type === otherFruit.type && self.typeIndex < 9;
};
self.getNextType = function () {
if (self.typeIndex < 9) {
return fruitTypes[self.typeIndex + 1];
}
return null;
};
self.update = function () {
if (!self.settled) {
self.vy += gravity;
self.x += self.vx;
self.y += self.vy;
// Container bounds collision
if (self.x - self.radius <= containerLeft) {
self.x = containerLeft + self.radius;
self.vx = -self.vx * friction;
}
if (self.x + self.radius >= containerRight) {
self.x = containerRight - self.radius;
self.vx = -self.vx * friction;
}
// Bottom collision - account for bottom border thickness
var actualBottom = containerY + containerHeight - 20; // Top of bottom border
if (self.y + self.radius >= actualBottom) {
self.y = actualBottom - self.radius;
self.vy = 0;
self.vx *= groundFriction;
if (Math.abs(self.vx) < 0.5) {
self.vx = 0;
self.settled = true;
}
}
// Collision with other fruits
for (var i = 0; i < fruits.length; i++) {
var otherFruit = fruits[i];
if (otherFruit !== self) {
var dx = self.x - otherFruit.x;
var dy = self.y - otherFruit.y;
var distance = Math.sqrt(dx * dx + dy * dy);
var minDistance = self.radius + otherFruit.radius;
if (distance < minDistance) {
// Handle overlapping/intertwined fruits more gracefully
if (distance < 0.1) {
// Fruits are nearly on top of each other - gentle separation
distance = 0.1;
dx = Math.random() * 2 - 1; // Random direction
dy = Math.random() * 2 - 1;
var len = Math.sqrt(dx * dx + dy * dy);
dx /= len;
dy /= len;
}
var overlap = minDistance - distance;
var normalX = dx / distance;
var normalY = dy / distance;
// Very gentle position correction for intertwined fruits
var correctionFactor = Math.min(0.1, overlap * 0.05); // Even gentler correction
var selfCorrection = correctionFactor;
var otherCorrection = correctionFactor;
// If other fruit is settled, don't move it as much
if (otherFruit.settled) {
selfCorrection = correctionFactor * 1.5;
otherCorrection = correctionFactor * 0.3;
}
self.x += normalX * overlap * selfCorrection;
self.y += normalY * overlap * selfCorrection;
otherFruit.x -= normalX * overlap * otherCorrection;
otherFruit.y -= normalY * overlap * otherCorrection;
// Dampen velocities when fruits are intertwined
var relativeVx = self.vx - otherFruit.vx;
var relativeVy = self.vy - otherFruit.vy;
var speed = relativeVx * normalX + relativeVy * normalY;
if (speed < 0) continue;
// Much reduced velocity response for stability
speed *= restitution * 0.1; // Even less bounce
var impulseX = speed * normalX * 0.3;
var impulseY = speed * normalY * 0.3;
self.vx -= impulseX;
self.vy -= impulseY;
otherFruit.vx += impulseX * 0.5; // Less impact on other fruit
otherFruit.vy += impulseY * 0.5;
// Aggressive damping for intertwined fruits
if (overlap > 10) {
// Significantly overlapping
self.vx *= 0.7;
self.vy *= 0.7;
otherFruit.vx *= 0.7;
otherFruit.vy *= 0.7;
}
}
}
}
// Stronger damping for more stability
self.vx *= 0.95;
self.vy *= 0.95;
// More generous settling conditions
if (Math.abs(self.vx) < 0.5 && Math.abs(self.vy) < 0.5) {
// Check if touching ground or another settled fruit
var actualBottom = containerY + containerHeight - 20; // Top of bottom border
var touchingGround = self.y + self.radius >= actualBottom - 10;
var touchingSettledFruit = false;
for (var k = 0; k < fruits.length; k++) {
var otherFruit = fruits[k];
if (otherFruit !== self && otherFruit.settled) {
var dx = self.x - otherFruit.x;
var dy = self.y - otherFruit.y;
var distance = Math.sqrt(dx * dx + dy * dy);
var touchDistance = self.radius + otherFruit.radius + 5; // Small tolerance
if (distance <= touchDistance) {
touchingSettledFruit = true;
break;
}
}
}
if (touchingGround || touchingSettledFruit) {
self.settled = true;
self.vx = 0;
self.vy = 0;
}
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87ceeb
});
/****
* Game Code
****/
// Game constants - reduced for more stable physics
var gravity = 0.4; // Even more reduced gravity
var friction = 0.9; // Higher friction
var groundFriction = 0.98; // Even higher ground friction
var restitution = 0.15; // Much lower bounce for stability
// Container setup
var containerWidth = 1000;
var containerHeight = 800;
var containerX = (2048 - containerWidth) / 2;
var containerY = 1532 - containerHeight;
var containerLeft = containerX + 20;
var containerRight = containerX + containerWidth - 20;
var containerBottom = containerY + containerHeight - 20;
var overflowLine = containerY + 200;
// Game state
var fruits = [];
var nextFruitType = 'cherry';
var dropPosition = 1024;
var canDrop = true;
var gameActive = true;
// Fruit types for random generation
var initialFruitTypes = ['cherry', 'strawberry', 'grape', 'orange'];
// Create container
var container = game.addChild(LK.getAsset('container', {
anchorX: 0,
anchorY: 0,
x: containerX,
y: containerY
}));
// Create container borders
var leftBorder = game.addChild(LK.getAsset('containerBorder', {
anchorX: 0,
anchorY: 0,
x: containerX,
y: containerY
}));
var rightBorder = game.addChild(LK.getAsset('containerBorder', {
anchorX: 0,
anchorY: 0,
x: containerX + containerWidth - 20,
y: containerY
}));
var bottomBorder = game.addChild(LK.getAsset('containerBorder', {
anchorX: 0,
anchorY: 0,
x: containerX,
y: containerY + containerHeight - 20,
width: containerWidth,
height: 20
}));
// Create overflow line
var overflowLineGraphics = game.addChild(LK.getAsset('dropLine', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: overflowLine,
alpha: 0.5
}));
// UI elements
var scoreTxt = new Text2('Score: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var nextFruitTxt = new Text2('Next: Cherry', {
size: 60,
fill: 0xFFFFFF
});
nextFruitTxt.anchor.set(0, 0);
nextFruitTxt.x = 50;
nextFruitTxt.y = 150;
LK.gui.topLeft.addChild(nextFruitTxt);
// Preview fruit
var previewFruit = game.addChild(LK.getAsset(nextFruitType, {
anchorX: 0.5,
anchorY: 0.5,
x: dropPosition,
y: containerY - 100,
alpha: 0.7
}));
function getRandomInitialFruit() {
return initialFruitTypes[Math.floor(Math.random() * initialFruitTypes.length)];
}
function updatePreview() {
game.removeChild(previewFruit);
previewFruit = game.addChild(LK.getAsset(nextFruitType, {
anchorX: 0.5,
anchorY: 0.5,
x: dropPosition,
y: containerY - 100,
alpha: 0.7
}));
var capitalizedType = nextFruitType.charAt(0).toUpperCase() + nextFruitType.slice(1);
nextFruitTxt.setText('Next: ' + capitalizedType);
}
function dropFruit() {
if (!canDrop || !gameActive) return;
var newFruit = new Fruit(nextFruitType, dropPosition, containerY - 50);
fruits.push(newFruit);
game.addChild(newFruit);
LK.getSound('drop').play();
nextFruitType = getRandomInitialFruit();
updatePreview();
canDrop = false;
LK.setTimeout(function () {
canDrop = true;
}, 500);
}
function checkMerges() {
var fruitsToRemove = [];
var newFruitsToAdd = [];
for (var i = 0; i < fruits.length; i++) {
if (fruitsToRemove.indexOf(i) !== -1) continue;
for (var j = i + 1; j < fruits.length; j++) {
if (fruitsToRemove.indexOf(j) !== -1) continue;
var fruit1 = fruits[i];
var fruit2 = fruits[j];
if (fruit1.canMergeWith(fruit2)) {
var dx = fruit1.x - fruit2.x;
var dy = fruit1.y - fruit2.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// More generous merge distance for intertwined fruits
var mergeDistance = (fruit1.radius + fruit2.radius) * 1.1; // 10% more generous
// Also allow merge if fruits are heavily overlapping (intertwined)
var isOverlapping = distance < (fruit1.radius + fruit2.radius) * 0.8;
if (distance <= mergeDistance || isOverlapping) {
var newType = fruit1.getNextType();
if (newType) {
var mergeX = (fruit1.x + fruit2.x) / 2;
var mergeY = (fruit1.y + fruit2.y) / 2;
var newFruit = new Fruit(newType, mergeX, mergeY);
// Give merged fruit slight upward velocity to help separate from pile
newFruit.vy = -2;
newFruitsToAdd.push(newFruit);
var scoreIncrease = newFruit.scoreValue;
LK.setScore(LK.getScore() + scoreIncrease);
scoreTxt.setText('Score: ' + LK.getScore());
LK.getSound('merge').play();
LK.effects.flashObject(newFruit, 0xffff00, 500);
}
fruitsToRemove.push(i);
fruitsToRemove.push(j);
fruit1.mergeProcessed = true;
fruit2.mergeProcessed = true;
break;
}
}
}
}
// Remove merged fruits (in reverse order to maintain indices)
fruitsToRemove.sort(function (a, b) {
return b - a;
});
for (var k = 0; k < fruitsToRemove.length; k++) {
var index = fruitsToRemove[k];
var fruitToRemove = fruits[index];
game.removeChild(fruitToRemove);
fruits.splice(index, 1);
}
// Add new merged fruits
for (var m = 0; m < newFruitsToAdd.length; m++) {
fruits.push(newFruitsToAdd[m]);
game.addChild(newFruitsToAdd[m]);
}
}
function checkGameOver() {
for (var i = 0; i < fruits.length; i++) {
var fruit = fruits[i];
// Only trigger game over if fruit is settled/stable and clearly above overflow line
if (fruit.settled && fruit.y - fruit.radius < overflowLine - 20) {
gameActive = false;
LK.setTimeout(function () {
LK.showGameOver();
}, 1000);
break;
}
}
}
// Game controls
game.down = function (x, y, obj) {
if (!gameActive) return;
dropPosition = Math.max(containerLeft + 50, Math.min(containerRight - 50, x));
previewFruit.x = dropPosition;
};
game.move = function (x, y, obj) {
if (!gameActive) return;
dropPosition = Math.max(containerLeft + 50, Math.min(containerRight - 50, x));
previewFruit.x = dropPosition;
};
game.up = function (x, y, obj) {
if (!gameActive) return;
dropFruit();
};
// Create informational fruit sprites at bottom to show evolution order
var infoFruits = [];
var fruitTypes = ['cherry', 'strawberry', 'grape', 'orange', 'apple', 'pear', 'peach', 'pineapple', 'melon', 'watermelon'];
var infoFruitSize = 60; // Smaller size for info display
var infoStartX = containerX + 50;
var infoY = containerY + containerHeight + 40;
var infoSpacing = 90;
for (var i = 0; i < fruitTypes.length; i++) {
var infoFruit = game.addChild(LK.getAsset(fruitTypes[i], {
anchorX: 0.5,
anchorY: 0.5,
x: infoStartX + i * infoSpacing,
y: infoY,
scaleX: infoFruitSize / 160,
// Scale down from original size
scaleY: infoFruitSize / 160,
alpha: 0.8
}));
infoFruits.push(infoFruit);
}
// Add evolution arrows between fruits
for (var i = 0; i < fruitTypes.length - 1; i++) {
var arrow = new Text2('→', {
size: 40,
fill: 0x333333
});
arrow.anchor.set(0.5, 0.5);
arrow.x = infoStartX + i * infoSpacing + infoSpacing / 2;
arrow.y = infoY;
game.addChild(arrow);
}
// Main game loop
game.update = function () {
if (!gameActive) return;
// Update all fruits
for (var i = 0; i < fruits.length; i++) {
fruits[i].update();
}
// Check for merges every few frames
if (LK.ticks % 3 === 0) {
checkMerges();
}
// Check game over condition
if (LK.ticks % 30 === 0) {
checkGameOver();
}
};
Shiney Apple vecor. In-Game asset. 2d. High contrast. No shadows
Shiney Chery vector. In-Game asset. 2d. High contrast. No shadows
Shiney grape vector. In-Game asset. 2d. High contrast. No shadows
Shiney melon vector. In-Game asset. 2d. High contrast. No shadows
Shiney yellow melon vector. In-Game asset. 2d. High contrast. No shadows
Shiney orange fruit vector. In-Game asset. 2d. High contrast. No shadows
Shiney peach vector. In-Game asset. 2d. High contrast. No shadows
Shiney pear vector. In-Game asset. 2d. High contrast. No shadows
Shiney pineapple vector. In-Game asset. 2d. High contrast. No shadows
Shiney strawberry vector. In-Game asset. 2d. High contrast. No shadows
a background full of greenery and some flowers. In-Game asset. 3d. Realistic