User prompt
Please arrange the fruits so that they are not crushed and cannot pass under the container border below.
User prompt
No, it's not like that. There should be fruits under the container for informational purposes to tell who will transform into whom in order, but these have nothing to do with the game, they are for visual purposes. Please bring the game back to its old state.
User prompt
I think the fruit pictures should be side by side at the bottom of the container.
User prompt
Awesome But container should be lower
User prompt
It would be better if the container was thinner, since we can add more fruits when the space is large. And game be so easy
User prompt
great but can you add a container border to the floor so it doesn't overflow from the bottom
User prompt
The fruits are intertwined, can you please adjust the collapse event well?
User prompt
It is very difficult to go up because the fruits on top of each other crush each other, so the game does not end, it would be better if they did not crush each other
User prompt
sometimes it gives game over error at wrong times, I think you should write the game over part again
User prompt
There is a bug in the game. When the fruits hit each other, they do not move to the next fruit.
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'toGlobal')' in or related to this line: 'var gamePos = game.toLocal(obj.parent.toGlobal(obj.position));' Line Number: 309
Code edit (1 edits merged)
Please save this source code
User prompt
Merge Fruits
Initial prompt
Hi, please make me a suika game
/****
* 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
if (self.y + self.radius >= containerBottom) {
self.y = containerBottom - 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 && distance > 0) {
// Collision response
var overlap = minDistance - distance;
var normalX = dx / distance;
var normalY = dy / distance;
self.x += normalX * overlap * 0.5;
self.y += normalY * overlap * 0.5;
otherFruit.x -= normalX * overlap * 0.5;
otherFruit.y -= normalY * overlap * 0.5;
// Velocity response
var relativeVx = self.vx - otherFruit.vx;
var relativeVy = self.vy - otherFruit.vy;
var speed = relativeVx * normalX + relativeVy * normalY;
if (speed < 0) continue;
speed *= restitution;
var impulseX = speed * normalX;
var impulseY = speed * normalY;
self.vx -= impulseX;
self.vy -= impulseY;
otherFruit.vx += impulseX;
otherFruit.vy += impulseY;
}
}
}
// Damping
self.vx *= 0.99;
self.vy *= 0.99;
if (Math.abs(self.vx) < 0.1 && Math.abs(self.vy) < 0.1 && self.y + self.radius >= containerBottom - 5) {
self.settled = true;
self.vx = 0;
self.vy = 0;
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87ceeb
});
/****
* Game Code
****/
// Game constants
var gravity = 0.8;
var friction = 0.7;
var groundFriction = 0.9;
var restitution = 0.6;
// Container setup
var containerWidth = 1600;
var containerHeight = 1200;
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
}));
// 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);
var touchDistance = fruit1.radius + fruit2.radius;
if (distance <= touchDistance) {
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);
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++) {
if (fruits[i].y - fruits[i].radius < overflowLine) {
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();
};
// 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();
}
}; ===================================================================
--- original.js
+++ change.js
@@ -215,54 +215,58 @@
canDrop = true;
}, 500);
}
function checkMerges() {
- var mergedPairs = [];
+ 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);
- var touchDistance = fruit1.radius + fruit2.radius - 5;
+ var touchDistance = fruit1.radius + fruit2.radius;
if (distance <= touchDistance) {
- mergedPairs.push([i, j]);
+ 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);
+ 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;
}
}
}
}
- for (var k = mergedPairs.length - 1; k >= 0; k--) {
- var pair = mergedPairs[k];
- var index1 = pair[0];
- var index2 = pair[1];
- if (index1 >= fruits.length || index2 >= fruits.length) continue;
- var fruit1 = fruits[index1];
- var fruit2 = fruits[index2];
- if (!fruit1 || !fruit2) continue;
- 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);
- fruits.push(newFruit);
- game.addChild(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);
- }
- game.removeChild(fruit1);
- game.removeChild(fruit2);
- var higherIndex = Math.max(index1, index2);
- var lowerIndex = Math.min(index1, index2);
- fruits.splice(higherIndex, 1);
- fruits.splice(lowerIndex, 1);
+ // 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++) {
if (fruits[i].y - fruits[i].radius < overflowLine) {
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