User prompt
Add a counter in the middle saying how many total fruits you’ve merged ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Add more fruits to merge including lemon coconut and dragon fruits and any other cool ones
User prompt
Add more fruits like lemon coconut and dragon fruit
User prompt
Didn’t work
User prompt
Make taping and holding also start the music and sfx
User prompt
Make just simply dropping the fruit start the music and sfx
User prompt
Make staging also start the music and sfx
User prompt
Make the shake event move around the fruits randomly ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
During the shake event make the fruits jump around randomly
User prompt
Fix this ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Make the next fruit icon bob up and down slowly ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Make the the next fruit icon rotate from left to right to make it more alive ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Make randomize cost only 300
User prompt
Make randomize switch the position of your fruits randomly
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'previewFruit = LK.getAsset(fruitAssets[nextFruitType], {' Line Number: 221
User prompt
Make a another power up for 675 score that randomizes the fruit you have into another you currently have
User prompt
Make bg music
User prompt
Didn’t work
User prompt
Make the hitbox the asset instead of the circle
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
/**** * 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 = [120, 160, 200, 240, 280, 320, 360, 400, 440, 480]; 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) { // Stop any existing tweens before destroying tween.stop(nextFruitPreview); nextFruitPreview.destroy(); } var fruitAssets = ['cherry', 'strawberry', 'grape', 'orange', 'apple']; var fruitSizes = [120, 160, 200, 240, 280]; 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 // Add bobbing animation var originalY = nextFruitPreview.y; function bobUp() { tween(nextFruitPreview, { y: originalY - 15 }, { duration: 1000, easing: tween.easeInOut, onFinish: bobDown }); } function bobDown() { tween(nextFruitPreview, { y: originalY + 15 }, { duration: 1000, easing: tween.easeInOut, onFinish: bobUp }); } bobUp(); } 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', 'pear', 'peach', 'pineapple', 'melon', 'watermelon']; 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 = [120, 160, 200, 240, 280, 320, 360, 400, 440, 480]; 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); // Randomize fruit button var randomizeButton = new Text2('RANDOMIZE!', { size: 60, fill: 0x000000 }); randomizeButton.anchor.set(0.5, 0.5); // Place to the left of shake button randomizeButton.x = 2048 / 2 - 350; randomizeButton.y = 2732 - 150; game.addChild(randomizeButton); // Cost text under randomize button var randomizeCostText = new Text2('Cost: 300', { size: 40, fill: 0x000000 }); randomizeCostText.anchor.set(0.5, 0); // Position just below the randomize button randomizeCostText.x = randomizeButton.x; randomizeCostText.y = randomizeButton.y + 60; game.addChild(randomizeCostText); // Add randomize button click handler randomizeButton.down = function (x, y, obj) { if (LK.getScore() >= 300 && fruits.length > 1) { // Deduct score LK.setScore(LK.getScore() - 300); scoreTxt.setText('Score: ' + LK.getScore()); // Store all current fruit positions var positions = []; for (var i = 0; i < fruits.length; i++) { positions.push({ x: fruits[i].x, y: fruits[i].y }); } // Shuffle the positions array for (var i = positions.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); var temp = positions[i]; positions[i] = positions[j]; positions[j] = temp; } // Apply shuffled positions to fruits for (var i = 0; i < fruits.length; i++) { fruits[i].x = positions[i].x; fruits[i].y = positions[i].y; // Reset velocities to prevent physics issues fruits[i].velocityX = 0; fruits[i].velocityY = 0; fruits[i].angularVelocity = 0; } } }; // 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()); // Move all fruits to random positions within container bounds for (var i = 0; i < fruits.length; i++) { var fruit = fruits[i]; var radius = fruit.getRadius(); var containerLeft = containerX - containerWidth / 2; var containerRight = containerX + containerWidth / 2; var containerTop = containerY - containerHeight / 2; var containerBottom = containerY + containerHeight / 2; // Calculate valid random position within container bounds var randomX = containerLeft + radius + Math.random() * (containerRight - containerLeft - 2 * radius); var randomY = containerTop + radius + Math.random() * (containerBottom - containerTop - 2 * radius); // Animate fruit to new position with tween tween(fruit, { x: randomX, y: randomY }, { duration: 500 + Math.random() * 500, // Random duration between 500-1000ms easing: tween.easeOut }); // Reset velocities to prevent physics issues fruit.velocityX = 0; fruit.velocityY = 0; fruit.angularVelocity = 0; } } }; // Do not spawn a fruit at start; only spawn on click/hold createNextFruit(); // Start background music when staging starts LK.on('staging', function () { LK.playMusic('bgmusic'); }); // 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
@@ -436,10 +436,12 @@
}
};
// Do not spawn a fruit at start; only spawn on click/hold
createNextFruit();
-// Start background music
-LK.playMusic('bgmusic');
+// Start background music when staging starts
+LK.on('staging', function () {
+ LK.playMusic('bgmusic');
+});
// 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
Orange 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
Kiwi with cute face. In-Game asset. 2d. High contrast. No shadows
Coconut with cute face. In-Game asset. 2d. High contrast. No shadows