/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Fruit = Container.expand(function (type) {
var self = Container.call(this);
self.type = type || 'fruit_red';
self.isBomb = self.type === 'bomb';
self.isSpecial = self.type === 'fruit_special';
var fruitGraphics = self.attachAsset(self.type, {
anchorX: 0.5,
anchorY: 0.5
});
self.sliced = false;
self.speed = {
x: Math.random() * 10 - 5,
y: -(Math.random() * 15) - 10
};
self.gravity = 0.3;
self.rotationSpeed = Math.random() * 0.1 - 0.05;
self.update = function () {
// Store last position for tracking
self.lastX = self.x;
self.lastY = self.y;
if (self.sliced) return;
// Apply gravity
self.speed.y += self.gravity;
// Update position
self.x += self.speed.x;
self.y += self.speed.y;
// Rotate the fruit
self.rotation += self.rotationSpeed;
// Check if out of bounds
if (self.y > 2732 + 100 || self.x < -100 || self.x > 2048 + 100) {
self.outOfBounds = true;
}
};
self.slice = function () {
if (self.sliced) return false;
self.sliced = true;
// Visual effect for slicing
fruitGraphics.alpha = 0.5;
fruitGraphics.scaleX = 1.2;
fruitGraphics.scaleY = 0.8;
// Create split effect with two halves
if (!self.isBomb) {
// Create two halves of the fruit
var leftHalf = self.attachAsset(self.type, {
anchorX: 0.5,
anchorY: 0.5,
x: -20,
scaleX: 0.8
});
var rightHalf = self.attachAsset(self.type, {
anchorX: 0.5,
anchorY: 0.5,
x: 20,
scaleX: 0.8
});
// Animate the halves falling apart
tween(leftHalf, {
x: -50,
y: 50,
rotation: -0.3
}, {
duration: 500
});
tween(rightHalf, {
x: 50,
y: 50,
rotation: 0.3
}, {
duration: 500
});
// Hide the original fruit
fruitGraphics.alpha = 0;
// Add juice particles
var fruitColor;
switch (self.type) {
case 'fruit_red':
fruitColor = 0xFF0000;
break;
case 'fruit_green':
fruitColor = 0x00FF00;
break;
case 'fruit_yellow':
fruitColor = 0xFFFF00;
break;
case 'fruit_purple':
fruitColor = 0x8A2BE2;
break;
case 'fruit_special':
fruitColor = 0xFFD700;
break;
default:
fruitColor = 0xFF0000;
}
// Create 8-10 particles
var particleCount = 8 + Math.floor(Math.random() * 3);
for (var i = 0; i < particleCount; i++) {
var particle = new Particle(fruitColor);
particle.x = self.x;
particle.y = self.y;
game.addChild(particle);
}
}
// Play sound
if (self.isBomb) {
LK.getSound('bomb').play();
} else if (self.isSpecial) {
LK.getSound('special').play();
} else {
LK.getSound('slice').play();
}
// Start tween to fade out
tween(self, {
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
self.destroy();
}
});
return true;
};
return self;
});
var Particle = Container.expand(function (color) {
var self = Container.call(this);
// Create particle based on color
var particleGraphics = self.attachAsset('fruit_red', {
// Using fruit asset for juice
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.2,
scaleY: 0.2
});
// Set the color tint of the particle
particleGraphics.tint = color || 0xFF0000;
// Set random movement properties
self.speed = {
x: (Math.random() - 0.5) * 8,
y: (Math.random() - 0.5) * 8
};
self.gravity = 0.2;
self.life = 400 + Math.random() * 300;
self.update = function () {
// Apply gravity
self.speed.y += self.gravity;
// Update position
self.x += self.speed.x;
self.y += self.speed.y;
// Reduce life
self.life -= 16.67;
// Fade out as life decreases
self.alpha = self.life / 700;
// Remove when life is over
if (self.life <= 0) {
self.destroy();
}
};
return self;
});
var Slash = Container.expand(function () {
var self = Container.call(this);
var slashGraphics = self.attachAsset('slash', {
anchorX: 0.5,
anchorY: 0.5
});
self.life = 300; // Slash display time in ms
self.setup = function (startX, startY, endX, endY) {
// Position at start point
self.x = startX;
self.y = startY;
// Calculate angle for rotation
var angle = Math.atan2(endY - startY, endX - startX);
self.rotation = angle;
// Calculate length based on start and end points
var length = Math.sqrt(Math.pow(endX - startX, 2) + Math.pow(endY - startY, 2));
slashGraphics.width = Math.max(50, length);
};
self.update = function () {
self.life -= 16.67; // Approximately 16.67ms per frame at 60fps
if (self.life <= 0) {
self.alpha = 0;
self.destroy();
} else {
self.alpha = self.life / 300;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Game variables
var fruits = [];
var slashes = [];
var swipeStart = null;
var score = 0;
var comboCount = 0;
var comboTimer = 0;
var lastSpawnTime = 0;
var spawnInterval = 1000; // Time in ms between fruit spawns
var level = 1;
var gameActive = true;
var missedFruits = 0;
var maxMissedFruits = 3;
// Set game background to a nice sky blue
game.setBackgroundColor(0x3366CC);
// Create score text
var scoreTxt = new Text2('0', {
size: 120,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
scoreTxt.y = 50;
// Create combo text
var comboTxt = new Text2('', {
size: 80,
fill: 0xFFFF00
});
comboTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(comboTxt);
comboTxt.y = 180;
comboTxt.alpha = 0;
// Level indicator
var levelTxt = new Text2('Level: 1', {
size: 60,
fill: 0xFFFFFF
});
levelTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(levelTxt);
levelTxt.x = -200;
levelTxt.y = 50;
// Missed fruits counter
var missedTxt = new Text2('❌ 0/' + maxMissedFruits, {
size: 60,
fill: 0xFF0000
});
missedTxt.anchor.set(0, 0);
LK.gui.topLeft.addChild(missedTxt);
missedTxt.x = 120; // Keep away from top-left menu icon
missedTxt.y = 50;
// Game swipe handlers
game.down = function (x, y) {
swipeStart = {
x: x,
y: y
};
};
game.move = function (x, y) {
if (swipeStart && gameActive) {
// Calculate distance between current position and start
var dx = x - swipeStart.x;
var dy = y - swipeStart.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Only create a slash if the swipe is long enough
if (distance > 50) {
var slash = new Slash();
slash.setup(swipeStart.x, swipeStart.y, x, y);
slashes.push(slash);
game.addChild(slash);
// Check for fruit collisions along the swipe path
var slicedFruits = 0;
var bombSliced = false;
// Simple line-circle collision for each fruit
fruits.forEach(function (fruit) {
if (fruit.sliced) return;
// Check if fruit is near the line segment of the swipe
var fruitHit = lineCircleCollision(swipeStart.x, swipeStart.y, x, y, fruit.x, fruit.y, fruit.children[0].width / 2);
if (fruitHit) {
if (fruit.slice()) {
if (fruit.isBomb) {
bombSliced = true;
} else {
slicedFruits++;
// Award points
var pointsAwarded = fruit.isSpecial ? 25 : 10;
// Apply combo bonus
if (comboTimer > 0) {
comboCount++;
pointsAwarded = Math.floor(pointsAwarded * (1 + comboCount * 0.1));
} else {
comboCount = 1;
}
// Reset combo timer
comboTimer = 1000;
// Update score
score += pointsAwarded;
scoreTxt.setText(score);
// Show combo text
if (comboCount > 1) {
comboTxt.setText(comboCount + "x COMBO!");
comboTxt.alpha = 1;
tween(comboTxt, {
alpha: 0
}, {
duration: 800
});
}
// Check for level up
var newLevel = Math.floor(score / 100) + 1;
if (newLevel > level) {
level = newLevel;
levelTxt.setText("Level: " + level);
// Increase spawn rate with level
spawnInterval = Math.max(400, 1000 - (level - 1) * 100);
}
}
}
}
});
// Game over if bomb sliced
if (bombSliced) {
gameActive = false;
// Flash screen red
LK.effects.flashScreen(0xff0000, 1000);
// Show game over
LK.setTimeout(function () {
LK.showGameOver();
}, 1000);
}
// Update swipe start for continuous swiping
swipeStart = {
x: x,
y: y
};
}
}
};
game.up = function () {
swipeStart = null;
};
// Collision detection between line (swipe) and circle (fruit)
function lineCircleCollision(x1, y1, x2, y2, cx, cy, r) {
// Calculate vector from start to end of swipe
var lineVecX = x2 - x1;
var lineVecY = y2 - y1;
// Calculate vector from start to circle center
var startToCenterX = cx - x1;
var startToCenterY = cy - y1;
// Calculate dot product
var dotProduct = (startToCenterX * lineVecX + startToCenterY * lineVecY) / (lineVecX * lineVecX + lineVecY * lineVecY);
// Clamp dot product to [0,1] to get point on line segment
dotProduct = Math.max(0, Math.min(1, dotProduct));
// Find nearest point on line to circle center
var nearestX = x1 + dotProduct * lineVecX;
var nearestY = y1 + dotProduct * lineVecY;
// Calculate distance from nearest point to circle center
var distance = Math.sqrt(Math.pow(nearestX - cx, 2) + Math.pow(nearestY - cy, 2));
// Check if distance is less than circle radius
return distance <= r;
}
// Random fruit generator
function spawnFruit() {
// Determine the fruit type to spawn
var types = ['fruit_red', 'fruit_green', 'fruit_yellow', 'fruit_purple'];
// Add special fruit with lower probability
if (Math.random() < 0.1) {
types.push('fruit_special');
}
// Add bombs with increasing probability based on level
var bombChance = Math.min(0.3, 0.05 + (level - 1) * 0.02);
if (Math.random() < bombChance) {
types.push('bomb');
}
// Randomly select a type
var type = types[Math.floor(Math.random() * types.length)];
// Create and position the fruit
var fruit = new Fruit(type);
// Set random starting position at bottom of screen
fruit.x = Math.random() * 1848 + 100; // Keep away from edges
fruit.y = 2732 + 50; // Start below screen
// Add to game
fruits.push(fruit);
game.addChild(fruit);
// For higher levels, spawn multiple fruits sometimes
if (level > 2 && Math.random() < 0.3) {
LK.setTimeout(function () {
spawnFruit();
}, 200);
}
}
// Game update loop
game.update = function () {
if (!gameActive) return;
// Update combo timer
if (comboTimer > 0) {
comboTimer -= 16.67; // Approximate ms per frame at 60fps
if (comboTimer <= 0) {
comboCount = 0;
}
}
// Spawn fruits
var currentTime = Date.now();
if (currentTime - lastSpawnTime > spawnInterval) {
spawnFruit();
lastSpawnTime = currentTime;
}
// Update fruits
for (var i = fruits.length - 1; i >= 0; i--) {
var fruit = fruits[i];
// Remove fruits that are out of bounds or destroyed
if (fruit.outOfBounds || fruit.destroyed) {
// Count missed fruits (only if not sliced and not a bomb)
if (!fruit.sliced && !fruit.isBomb && fruit.outOfBounds && fruit.y > 2732) {
missedFruits++;
missedTxt.setText('❌ ' + missedFruits + '/' + maxMissedFruits);
// Game over if too many fruits missed
if (missedFruits >= maxMissedFruits && gameActive) {
gameActive = false;
LK.effects.flashScreen(0xFF0000, 1000);
LK.setTimeout(function () {
LK.showGameOver();
}, 1000);
}
}
fruits.splice(i, 1);
continue;
}
}
// Update slashes
for (var j = slashes.length - 1; j >= 0; j--) {
var slash = slashes[j];
// Remove destroyed slashes
if (slash.destroyed) {
slashes.splice(j, 1);
}
}
};
// Start game
LK.playMusic('gameMusic'); ===================================================================
--- original.js
+++ change.js
@@ -23,8 +23,11 @@
};
self.gravity = 0.3;
self.rotationSpeed = Math.random() * 0.1 - 0.05;
self.update = function () {
+ // Store last position for tracking
+ self.lastX = self.x;
+ self.lastY = self.y;
if (self.sliced) return;
// Apply gravity
self.speed.y += self.gravity;
// Update position
@@ -43,8 +46,70 @@
// Visual effect for slicing
fruitGraphics.alpha = 0.5;
fruitGraphics.scaleX = 1.2;
fruitGraphics.scaleY = 0.8;
+ // Create split effect with two halves
+ if (!self.isBomb) {
+ // Create two halves of the fruit
+ var leftHalf = self.attachAsset(self.type, {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: -20,
+ scaleX: 0.8
+ });
+ var rightHalf = self.attachAsset(self.type, {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 20,
+ scaleX: 0.8
+ });
+ // Animate the halves falling apart
+ tween(leftHalf, {
+ x: -50,
+ y: 50,
+ rotation: -0.3
+ }, {
+ duration: 500
+ });
+ tween(rightHalf, {
+ x: 50,
+ y: 50,
+ rotation: 0.3
+ }, {
+ duration: 500
+ });
+ // Hide the original fruit
+ fruitGraphics.alpha = 0;
+ // Add juice particles
+ var fruitColor;
+ switch (self.type) {
+ case 'fruit_red':
+ fruitColor = 0xFF0000;
+ break;
+ case 'fruit_green':
+ fruitColor = 0x00FF00;
+ break;
+ case 'fruit_yellow':
+ fruitColor = 0xFFFF00;
+ break;
+ case 'fruit_purple':
+ fruitColor = 0x8A2BE2;
+ break;
+ case 'fruit_special':
+ fruitColor = 0xFFD700;
+ break;
+ default:
+ fruitColor = 0xFF0000;
+ }
+ // Create 8-10 particles
+ var particleCount = 8 + Math.floor(Math.random() * 3);
+ for (var i = 0; i < particleCount; i++) {
+ var particle = new Particle(fruitColor);
+ particle.x = self.x;
+ particle.y = self.y;
+ game.addChild(particle);
+ }
+ }
// Play sound
if (self.isBomb) {
LK.getSound('bomb').play();
} else if (self.isSpecial) {
@@ -64,8 +129,44 @@
return true;
};
return self;
});
+var Particle = Container.expand(function (color) {
+ var self = Container.call(this);
+ // Create particle based on color
+ var particleGraphics = self.attachAsset('fruit_red', {
+ // Using fruit asset for juice
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 0.2,
+ scaleY: 0.2
+ });
+ // Set the color tint of the particle
+ particleGraphics.tint = color || 0xFF0000;
+ // Set random movement properties
+ self.speed = {
+ x: (Math.random() - 0.5) * 8,
+ y: (Math.random() - 0.5) * 8
+ };
+ self.gravity = 0.2;
+ self.life = 400 + Math.random() * 300;
+ self.update = function () {
+ // Apply gravity
+ self.speed.y += self.gravity;
+ // Update position
+ self.x += self.speed.x;
+ self.y += self.speed.y;
+ // Reduce life
+ self.life -= 16.67;
+ // Fade out as life decreases
+ self.alpha = self.life / 700;
+ // Remove when life is over
+ if (self.life <= 0) {
+ self.destroy();
+ }
+ };
+ return self;
+});
var Slash = Container.expand(function () {
var self = Container.call(this);
var slashGraphics = self.attachAsset('slash', {
anchorX: 0.5,
@@ -98,9 +199,9 @@
/****
* Initialize Game
****/
var game = new LK.Game({
- backgroundColor: 0x3366CC
+ backgroundColor: 0x000000
});
/****
* Game Code
@@ -115,8 +216,12 @@
var lastSpawnTime = 0;
var spawnInterval = 1000; // Time in ms between fruit spawns
var level = 1;
var gameActive = true;
+var missedFruits = 0;
+var maxMissedFruits = 3;
+// Set game background to a nice sky blue
+game.setBackgroundColor(0x3366CC);
// Create score text
var scoreTxt = new Text2('0', {
size: 120,
fill: 0xFFFFFF
@@ -141,8 +246,17 @@
levelTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(levelTxt);
levelTxt.x = -200;
levelTxt.y = 50;
+// Missed fruits counter
+var missedTxt = new Text2('❌ 0/' + maxMissedFruits, {
+ size: 60,
+ fill: 0xFF0000
+});
+missedTxt.anchor.set(0, 0);
+LK.gui.topLeft.addChild(missedTxt);
+missedTxt.x = 120; // Keep away from top-left menu icon
+missedTxt.y = 50;
// Game swipe handlers
game.down = function (x, y) {
swipeStart = {
x: x,
@@ -302,8 +416,21 @@
for (var i = fruits.length - 1; i >= 0; i--) {
var fruit = fruits[i];
// Remove fruits that are out of bounds or destroyed
if (fruit.outOfBounds || fruit.destroyed) {
+ // Count missed fruits (only if not sliced and not a bomb)
+ if (!fruit.sliced && !fruit.isBomb && fruit.outOfBounds && fruit.y > 2732) {
+ missedFruits++;
+ missedTxt.setText('❌ ' + missedFruits + '/' + maxMissedFruits);
+ // Game over if too many fruits missed
+ if (missedFruits >= maxMissedFruits && gameActive) {
+ gameActive = false;
+ LK.effects.flashScreen(0xFF0000, 1000);
+ LK.setTimeout(function () {
+ LK.showGameOver();
+ }, 1000);
+ }
+ }
fruits.splice(i, 1);
continue;
}
}
Bomb . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
watermelon . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Grape. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Tomato. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Apple Green. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Blade Power . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Peach. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat