User prompt
Now it’s to small
User prompt
That’s way too much
User prompt
Make the fruits bigger
User prompt
Make the fruits huge
User prompt
Make a watermelon spawn automatically
User prompt
Make the text move according to the size of the fruit so you can always see the text
User prompt
Now move the next fruit text to the side of the fruit
User prompt
Higher
User prompt
Make the next fruit interface higher up
User prompt
Make the shake longer and a lot more violent ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Make score go down when the shake is bought ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Make text under the shake of how much it cost
User prompt
Make the fruits only spawn if you click or hold the container
User prompt
Make the shake at the bottom middle of the screen
User prompt
Make the shake more violent
User prompt
Make a button that shakes the container around for 450 score ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Add a cap to how fast the rotation speed can go
User prompt
Make the rotation parallel to the movement speed and direction
User prompt
Fix this
User prompt
Add friction to make the fruits rotate slower
User prompt
Make the fruits also rotate with physics
User prompt
Make them way less bouncy
User prompt
Fix it by making it more of a physics based system
User prompt
Make the gravity stronger
User prompt
Make all the fruits a lot bigger
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Fruit = Container.expand(function (type) {
var self = Container.call(this);
self.type = type;
self.velocityX = 0;
self.velocityY = 0;
self.angularVelocity = 0;
self.gravity = 1.2;
self.bounceX = 0.2;
self.bounceY = 0.1;
self.friction = 0.995;
self.rotationFriction = 0.85;
self.merged = false;
self.lastMergeCheck = false;
var fruitAssets = ['cherry', 'strawberry', 'grape', 'orange', 'apple', 'pear', 'peach', 'pineapple', 'melon', 'watermelon'];
var fruitSizes = [300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200];
var fruitScores = [1, 3, 6, 10, 15, 21, 28, 36, 45, 55];
self.assetName = fruitAssets[type];
self.size = fruitSizes[type];
self.scoreValue = fruitScores[type];
var fruitGraphics = self.attachAsset(self.assetName, {
anchorX: 0.5,
anchorY: 0.5
});
self.getRadius = function () {
return self.size / 2;
};
self.update = function () {
if (self.merged) return;
// Apply gravity
self.velocityY += self.gravity;
// Apply velocity
self.x += self.velocityX;
self.y += self.velocityY;
// Apply rotation
self.rotation += self.angularVelocity;
// Apply friction
self.velocityX *= self.friction;
self.velocityY *= self.friction;
self.angularVelocity *= self.rotationFriction;
// Cap maximum rotation speed
var maxAngularVelocity = 0.2;
if (self.angularVelocity > maxAngularVelocity) {
self.angularVelocity = maxAngularVelocity;
} else if (self.angularVelocity < -maxAngularVelocity) {
self.angularVelocity = -maxAngularVelocity;
}
// Prevent very small velocities that can cause sticking
if (Math.abs(self.velocityX) < 0.1) self.velocityX = 0;
if (Math.abs(self.velocityY) < 0.1) self.velocityY = 0;
if (Math.abs(self.angularVelocity) < 0.005) self.angularVelocity = 0;
var radius = self.getRadius();
var containerLeft = containerX - containerWidth / 2;
var containerRight = containerX + containerWidth / 2;
var containerBottom = containerY + containerHeight / 2;
// Collision with container walls
if (self.x - radius < containerLeft) {
self.x = containerLeft + radius;
self.velocityX = -self.velocityX * self.bounceX;
// Add rotational effect from wall collision
self.angularVelocity += self.velocityY * 0.01;
}
if (self.x + radius > containerRight) {
self.x = containerRight - radius;
self.velocityX = -self.velocityX * self.bounceX;
// Add rotational effect from wall collision
self.angularVelocity -= self.velocityY * 0.01;
}
// Collision with container bottom
if (self.y + radius > containerBottom) {
self.y = containerBottom - radius;
self.velocityY = -self.velocityY * self.bounceY;
// Add rotational effect from ground collision
self.angularVelocity += self.velocityX * 0.02;
if (Math.abs(self.velocityY) < 1) {
self.velocityY = 0;
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Game state
var fruits = [];
var currentFruit = null;
var nextFruitType = 0;
var gameRunning = true;
var dropLine = 400;
var gameOverLine = 300;
var isDragging = false;
var previewFruit = null;
// Container dimensions and position
var containerWidth = 1900;
var containerHeight = 2200;
var containerX = 2048 / 2;
var containerY = 1366;
// Create container
var container = game.attachAsset('container', {
anchorX: 0.5,
anchorY: 0.5,
x: containerX,
y: containerY
});
// Score display
var scoreTxt = new Text2('Score: 0', {
size: 80,
fill: 0x000000
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Next fruit preview
var nextFruitPreview = null;
var nextFruitLabel = new Text2('Next:', {
size: 60,
fill: 0x000000
});
nextFruitLabel.anchor.set(1, 0.5);
nextFruitLabel.x = 1580;
nextFruitLabel.y = 120;
game.addChild(nextFruitLabel);
// Drop line indicator
var dropLineIndicator = LK.getAsset('container', {
width: containerWidth,
height: 4,
anchorX: 0.5,
anchorY: 0.5
});
dropLineIndicator.x = containerX;
dropLineIndicator.y = dropLine;
dropLineIndicator.tint = 0x0000FF;
game.addChild(dropLineIndicator);
// Helper functions
function getRandomFruitType() {
return Math.floor(Math.random() * 5); // Only first 5 fruit types can be dropped
}
function createNextFruit() {
nextFruitType = getRandomFruitType();
if (nextFruitPreview) {
nextFruitPreview.destroy();
}
var fruitAssets = ['cherry', 'strawberry', 'grape', 'orange', 'apple'];
var fruitSizes = [300, 400, 500, 600, 700];
nextFruitPreview = LK.getAsset(fruitAssets[nextFruitType], {
anchorX: 0.5,
anchorY: 0.5
});
nextFruitPreview.x = 1700;
nextFruitPreview.y = 120;
game.addChild(nextFruitPreview);
// Position the label based on fruit size to ensure it's always visible
var fruitRadius = fruitSizes[nextFruitType] / 2;
nextFruitLabel.x = nextFruitPreview.x - fruitRadius - 20; // 20px padding from fruit edge
}
function dropFruit(x) {
if (!gameRunning || currentFruit) return;
currentFruit = new Fruit(nextFruitType);
currentFruit.x = Math.max(containerX - containerWidth / 2 + currentFruit.getRadius(), Math.min(x, containerX + containerWidth / 2 - currentFruit.getRadius()));
currentFruit.y = dropLine + currentFruit.getRadius() + 60; // Spawn lower below the line with more padding
// Add small random initial rotation
currentFruit.angularVelocity = (Math.random() - 0.5) * 0.05;
fruits.push(currentFruit);
game.addChild(currentFruit);
LK.getSound('drop').play();
// Reset current fruit after a delay
LK.setTimeout(function () {
currentFruit = null;
}, 100);
createNextFruit();
}
function createPreviewFruit(x) {
if (previewFruit) {
previewFruit.destroy();
}
var fruitAssets = ['cherry', 'strawberry', 'grape', 'orange', 'apple'];
previewFruit = LK.getAsset(fruitAssets[nextFruitType], {
anchorX: 0.5,
anchorY: 0.5
});
previewFruit.alpha = 0.7; // Make it semi-transparent
previewFruit.x = x;
previewFruit.y = dropLine;
game.addChild(previewFruit);
}
function updatePreviewFruit(x) {
if (!previewFruit) return;
var fruitSizes = [300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200];
var radius = fruitSizes[nextFruitType] / 2;
previewFruit.x = Math.max(containerX - containerWidth / 2 + radius, Math.min(x, containerX + containerWidth / 2 - radius));
}
function destroyPreviewFruit() {
if (previewFruit) {
previewFruit.destroy();
previewFruit = null;
}
}
function checkCollision(fruit1, fruit2) {
var dx = fruit1.x - fruit2.x;
var dy = fruit1.y - fruit2.y;
var distance = Math.sqrt(dx * dx + dy * dy);
var minDistance = fruit1.getRadius() + fruit2.getRadius();
return distance < minDistance;
}
function resolveFruitCollision(fruit1, fruit2) {
var dx = fruit1.x - fruit2.x;
var dy = fruit1.y - fruit2.y;
var distance = Math.sqrt(dx * dx + dy * dy);
var minDistance = fruit1.getRadius() + fruit2.getRadius();
if (distance < minDistance && distance > 0) {
var overlap = minDistance - distance;
// Stronger separation force to prevent sticking
var separationForce = 1.2;
var separationX = dx / distance * overlap * separationForce;
var separationY = dy / distance * overlap * separationForce;
fruit1.x += separationX;
fruit1.y += separationY;
fruit2.x -= separationX;
fruit2.y -= separationY;
// Realistic elastic collision response
var relativeVelX = fruit1.velocityX - fruit2.velocityX;
var relativeVelY = fruit1.velocityY - fruit2.velocityY;
var normalVelX = dx / distance;
var normalVelY = dy / distance;
var separatingVel = relativeVelX * normalVelX + relativeVelY * normalVelY;
// Only resolve if objects are moving toward each other
if (separatingVel < 0) {
var restitution = 0.1; // Bounciness factor
var impulse = -(1 + restitution) * separatingVel;
var impulseX = impulse * normalVelX;
var impulseY = impulse * normalVelY;
fruit1.velocityX += impulseX;
fruit1.velocityY += impulseY;
fruit2.velocityX -= impulseX;
fruit2.velocityY -= impulseY;
// Add rotational effects from collision
var rotationFactor = 0.015;
fruit1.angularVelocity += (impulseX + impulseY) * rotationFactor;
fruit2.angularVelocity -= (impulseX + impulseY) * rotationFactor;
}
}
}
function mergeFruits(fruit1, fruit2) {
if (fruit1.type !== fruit2.type || fruit1.merged || fruit2.merged) return false;
if (fruit1.type >= 9) return false; // Can't merge watermelon
// Create new fruit
var newFruit = new Fruit(fruit1.type + 1);
newFruit.x = (fruit1.x + fruit2.x) / 2;
newFruit.y = (fruit1.y + fruit2.y) / 2;
// Add score
LK.setScore(LK.getScore() + newFruit.scoreValue);
scoreTxt.setText('Score: ' + LK.getScore());
// Mark old fruits as merged
fruit1.merged = true;
fruit2.merged = true;
// Remove old fruits
for (var i = fruits.length - 1; i >= 0; i--) {
if (fruits[i] === fruit1 || fruits[i] === fruit2) {
fruits[i].destroy();
fruits.splice(i, 1);
}
}
// Add new fruit
fruits.push(newFruit);
game.addChild(newFruit);
LK.getSound('merge').play();
// Flash effect
tween(newFruit, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(newFruit, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 200,
easing: tween.easeIn
});
}
});
return true;
}
function checkGameOver() {
for (var i = 0; i < fruits.length; i++) {
var fruit = fruits[i];
if (fruit.y - fruit.getRadius() < gameOverLine) {
return true;
}
}
return false;
}
// Shake button
var shakeButton = new Text2('SHAKE!', {
size: 60,
fill: 0x000000
});
shakeButton.anchor.set(0.5, 0.5);
// Place at bottom middle, above the very bottom edge (e.g. 150px up)
shakeButton.x = 2048 / 2;
shakeButton.y = 2732 - 150;
game.addChild(shakeButton);
// Cost text under shake button
var shakeCostText = new Text2('Cost: 450', {
size: 40,
fill: 0x000000
});
shakeCostText.anchor.set(0.5, 0);
// Position just below the shake button (e.g. 20px below)
shakeCostText.x = shakeButton.x;
shakeCostText.y = shakeButton.y + 60;
game.addChild(shakeCostText);
// Add shake button click handler
shakeButton.down = function (x, y, obj) {
if (LK.getScore() >= 450) {
// Deduct score
LK.setScore(LK.getScore() - 450);
scoreTxt.setText('Score: ' + LK.getScore());
// Create shake animation - much more violent and longer
var originalX = container.x;
var originalY = container.y;
var shakeIntensity = 150; // Much more violent shake
var shakeDuration = 2500; // Much longer duration
var shakeFrequency = 16; // Much faster frequency for violent effect
var shakeCount = 0;
var maxShakes = Math.floor(shakeDuration / shakeFrequency);
var shakeTimer = LK.setInterval(function () {
if (shakeCount >= maxShakes) {
// Return to original position with smooth tween
tween(container, {
x: originalX,
y: originalY
}, {
duration: 200,
easing: tween.easeOut
});
LK.clearInterval(shakeTimer);
return;
}
// Much more violent random shake offset with varying intensity
var currentIntensity = shakeIntensity * (1 - shakeCount / maxShakes * 0.3); // Slightly decrease over time
var offsetX = (Math.random() - 0.5) * currentIntensity;
var offsetY = (Math.random() - 0.5) * currentIntensity;
container.x = originalX + offsetX;
container.y = originalY + offsetY;
shakeCount++;
}, shakeFrequency);
}
};
// Do not spawn a fruit at start; only spawn on click/hold
createNextFruit();
// Event handlers
game.down = function (x, y, obj) {
if (!gameRunning || currentFruit) return;
// Only allow spawning if the press is inside the container bounds
var radius = 0;
if (x >= containerX - containerWidth / 2 + radius && x <= containerX + containerWidth / 2 - radius && y >= containerY - containerHeight / 2 + radius && y <= containerY + containerHeight / 2 - radius) {
isDragging = true;
createPreviewFruit(x);
}
};
game.move = function (x, y, obj) {
if (!gameRunning || !isDragging) return;
updatePreviewFruit(x);
};
game.up = function (x, y, obj) {
if (!gameRunning || !isDragging) return;
isDragging = false;
var dropX = previewFruit ? previewFruit.x : x;
destroyPreviewFruit();
dropFruit(dropX);
};
// Main game loop
game.update = function () {
if (!gameRunning) return;
// Update all fruits
for (var i = 0; i < fruits.length; i++) {
fruits[i].update();
}
// Check collisions and merges
for (var i = 0; i < fruits.length; i++) {
for (var j = i + 1; j < fruits.length; j++) {
var fruit1 = fruits[i];
var fruit2 = fruits[j];
if (fruit1.merged || fruit2.merged) continue;
if (checkCollision(fruit1, fruit2)) {
// Always apply physics first to prevent sticking
resolveFruitCollision(fruit1, fruit2);
// Then check for merge
var currentMerging = fruit1.type === fruit2.type;
if (!fruit1.lastMergeCheck && currentMerging) {
if (mergeFruits(fruit1, fruit2)) {
break; // Break out of inner loop as fruits array changed
}
}
fruit1.lastMergeCheck = currentMerging;
fruit2.lastMergeCheck = currentMerging;
} else {
fruit1.lastMergeCheck = false;
fruit2.lastMergeCheck = false;
}
}
}
// Check game over condition
if (checkGameOver() && LK.ticks % 60 === 0) {
// Check every second
gameRunning = false;
LK.showGameOver();
}
}; ===================================================================
--- original.js
+++ change.js
@@ -19,9 +19,9 @@
self.rotationFriction = 0.85;
self.merged = false;
self.lastMergeCheck = false;
var fruitAssets = ['cherry', 'strawberry', 'grape', 'orange', 'apple', 'pear', 'peach', 'pineapple', 'melon', 'watermelon'];
- var fruitSizes = [120, 160, 200, 240, 280, 320, 360, 400, 440, 480];
+ var fruitSizes = [300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200];
var fruitScores = [1, 3, 6, 10, 15, 21, 28, 36, 45, 55];
self.assetName = fruitAssets[type];
self.size = fruitSizes[type];
self.scoreValue = fruitScores[type];
@@ -155,9 +155,9 @@
if (nextFruitPreview) {
nextFruitPreview.destroy();
}
var fruitAssets = ['cherry', 'strawberry', 'grape', 'orange', 'apple'];
- var fruitSizes = [120, 160, 200, 240, 280];
+ var fruitSizes = [300, 400, 500, 600, 700];
nextFruitPreview = LK.getAsset(fruitAssets[nextFruitType], {
anchorX: 0.5,
anchorY: 0.5
});
@@ -199,9 +199,9 @@
game.addChild(previewFruit);
}
function updatePreviewFruit(x) {
if (!previewFruit) return;
- var fruitSizes = [120, 160, 200, 240, 280, 320, 360, 400, 440, 480];
+ var fruitSizes = [300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200];
var radius = fruitSizes[nextFruitType] / 2;
previewFruit.x = Math.max(containerX - containerWidth / 2 + radius, Math.min(x, containerX + containerWidth / 2 - radius));
}
function destroyPreviewFruit() {
@@ -365,22 +365,8 @@
}
};
// Do not spawn a fruit at start; only spawn on click/hold
createNextFruit();
-// Automatic watermelon spawning timer - every 10 seconds
-var watermelonTimer = LK.setInterval(function () {
- if (!gameRunning) return;
- // Create a watermelon at random position
- var watermelon = new Fruit(9); // Watermelon is type 9
- var randomX = containerX - containerWidth / 2 + watermelon.getRadius() + Math.random() * (containerWidth - watermelon.getRadius() * 2);
- watermelon.x = randomX;
- watermelon.y = dropLine + watermelon.getRadius() + 60;
- // Add small random initial rotation
- watermelon.angularVelocity = (Math.random() - 0.5) * 0.05;
- fruits.push(watermelon);
- game.addChild(watermelon);
- LK.getSound('drop').play();
-}, 10000); // 10 seconds interval
// Event handlers
game.down = function (x, y, obj) {
if (!gameRunning || currentFruit) return;
// Only allow spawning if the press is inside the container bounds
Apple with cute face. In-Game asset. 2d. High contrast. No shadows
Cherry with cute face. In-Game asset. 2d. High contrast. No shadows
Greyish blue square. In-Game asset. 2d. High contrast. No shadows
Grapes with a cute face. In-Game asset. 2d. High contrast. No shadows
Circle water melon with cute face. In-Game asset. 2d. High contrast. No shadows
Circle cantaloupe with cute face. In-Game asset. 2d. High contrast. No shadows
Pear with cute face. In-Game asset. 2d. High contrast. No shadows
Strawberry with cute face. In-Game asset. 2d. High contrast. No shadows
Peach with cute face. In-Game asset. 2d. High contrast. No shadows
Pineapple with cute face. In-Game asset. 2d. High contrast. No shadows
Dragon fruit with cute face. In-Game asset. 2d. High contrast. No shadows
Lemon with cute face. In-Game asset. 2d. High contrast. No shadows
Coconut with cute face. In-Game asset. 2d. High contrast. No shadows
Kiwi with cute face. In-Game asset. 2d. High contrast. No shadows
Durian with cute face. In-Game asset. 2d. High contrast. No shadows
Mango with cute face. In-Game asset. 2d. High contrast. No shadows
Papaya with cute face. In-Game asset. 2d. High contrast. No shadows
Arrow pointing down. In-Game asset. 2d. High contrast. No shadows
Shine. In-Game asset. 2d. High contrast. No shadows
Purple galaxy. In-Game asset. 2d. High contrast. No shadows
Blueberry with cute face. In-Game asset. 2d. High contrast. No shadows
Open pomegranate with cute face. In-Game asset. 2d. High contrast. No shadows
A cut in half avocado with cute face. In-Game asset. 2d. High contrast. No shadows
Cranberry’s with cute face. In-Game asset. 2d. High contrast. No shadows