/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Bomb = Container.expand(function () { var self = Container.call(this); var bombGraphics = self.attachAsset('bomb', { anchorX: 0.5, anchorY: 0.5 }); self.velocityX = 0; self.velocityY = 0; self.gravity = 0.5; self.exploded = false; self.lastX = 0; self.lastY = 0; self.update = function () { if (!self.exploded) { self.lastX = self.x; self.lastY = self.y; self.x += self.velocityX; self.y += self.velocityY; self.velocityY += self.gravity; self.rotation += 0.03; } }; self.explode = function () { if (self.exploded) return; self.exploded = true; var bombSound = LK.getSound('bomb'); bombSound.volume = soundVolume; bombSound.play(); // Flash screen red LK.effects.flashScreen(0xff0000, 1000); // Game over LK.showGameOver(); }; return self; }); var Fruit = Container.expand(function (fruitType) { var self = Container.call(this); var colors = { apple: 0xff4444, orange: 0xff8844, banana: 0xffff44, grape: 0x8844ff }; var fruitGraphics = self.attachAsset(fruitType, { anchorX: 0.5, anchorY: 0.5 }); self.fruitType = fruitType; self.velocityX = 0; self.velocityY = 0; self.gravity = 0.5; self.sliced = false; self.lastX = 0; self.lastY = 0; self.update = function () { if (!self.sliced) { self.lastX = self.x; self.lastY = self.y; self.x += self.velocityX; self.y += self.velocityY; self.velocityY += self.gravity; self.rotation += 0.05; } }; self.slice = function () { if (self.sliced) return; self.sliced = true; var sliceSound = LK.getSound('slice'); sliceSound.volume = soundVolume; sliceSound.play(); // Create fruit pieces for (var i = 0; i < 4; i++) { var piece = new FruitPiece(colors[self.fruitType]); piece.x = self.x + (Math.random() - 0.5) * 40; piece.y = self.y + (Math.random() - 0.5) * 40; piece.velocityX = (Math.random() - 0.5) * 10; piece.velocityY = Math.random() * -8 - 5; game.addChild(piece); fruitPieces.push(piece); } // Award points LK.setScore(LK.getScore() + 10); scoreTxt.setText(LK.getScore()); // Remove from game var index = fruits.indexOf(self); if (index !== -1) { fruits.splice(index, 1); } self.destroy(); }; return self; }); var FruitPiece = Container.expand(function (color) { var self = Container.call(this); var pieceGraphics = self.attachAsset('fruitPiece', { anchorX: 0.5, anchorY: 0.5, tint: color }); self.velocityX = 0; self.velocityY = 0; self.gravity = 0.3; self.lifeTime = 0; self.update = function () { self.x += self.velocityX; self.y += self.velocityY; self.velocityY += self.gravity; self.rotation += 0.1; self.lifeTime++; // Fade out over time self.alpha = Math.max(0, 1 - self.lifeTime / 120); }; return self; }); var MainMenu = Container.expand(function () { var self = Container.call(this); // Title var titleTxt = new Text2('FRUIT SLICE FRENZY', { size: 120, fill: 0xFFFFFF }); titleTxt.anchor.set(0.5, 0.5); titleTxt.x = 1024; titleTxt.y = 600; self.addChild(titleTxt); // Play button var playButton = new Text2('JUGAR', { size: 150, fill: 0x44ff44 }); playButton.anchor.set(0.5, 0.5); playButton.x = 1024; playButton.y = 1200; self.addChild(playButton); // Settings button var settingsButton = new Text2('AJUSTES', { size: 150, fill: 0x4444ff }); settingsButton.anchor.set(0.5, 0.5); settingsButton.x = 1024; settingsButton.y = 1400; self.addChild(settingsButton); // Button handlers playButton.down = function (x, y, obj) { startGame(); }; settingsButton.down = function (x, y, obj) { showSettingsMenu(); }; // Add decorative fruits to main menu background var decorativeFruits = []; var fruitTypes = ['apple', 'orange', 'banana', 'grape']; // Create static decorative fruits for (var i = 0; i < 15; i++) { var randomType = fruitTypes[Math.floor(Math.random() * fruitTypes.length)]; var decorativeFruit = self.attachAsset(randomType, { anchorX: 0.5, anchorY: 0.5 }); // Position fruits randomly around the screen decorativeFruit.x = Math.random() * 1800 + 124; // Keep away from edges decorativeFruit.y = Math.random() * 2000 + 200; decorativeFruit.alpha = Math.random() * 0.3 + 0.2; // Vary transparency decorativeFruit.scaleX = Math.random() * 0.6 + 0.4; // Vary size decorativeFruit.scaleY = decorativeFruit.scaleX; // Keep aspect ratio decorativeFruit.rotation = Math.random() * Math.PI * 2; // Add some fruits with tween animations if (i % 3 === 0) { // Gentle bobbing animation tween(decorativeFruit, { y: decorativeFruit.y + 30 }, { duration: 2000 + Math.random() * 1000, easing: tween.easeInOut, onFinish: function onFinish() { tween(decorativeFruit, { y: decorativeFruit.y - 30 }, { duration: 2000 + Math.random() * 1000, easing: tween.easeInOut }); } }); } decorativeFruits.push(decorativeFruit); } self.decorativeFruits = decorativeFruits; // Add update method for gentle floating animation self.update = function () { // Animate decorative fruits with gentle floating motion for (var i = 0; i < self.decorativeFruits.length; i++) { var fruit = self.decorativeFruits[i]; fruit.y += Math.sin(LK.ticks * 0.01 + i) * 0.5; fruit.rotation += 0.002; // Add subtle scale pulsing for some fruits if (i % 4 === 0) { var scaleOffset = Math.sin(LK.ticks * 0.008 + i) * 0.05; fruit.scaleX += scaleOffset; fruit.scaleY += scaleOffset; } } }; return self; }); var MenuFruit = Container.expand(function (fruitType) { var self = Container.call(this); var fruitGraphics = self.attachAsset(fruitType, { anchorX: 0.5, anchorY: 0.5 }); self.fruitType = fruitType; self.velocityX = 2; self.startX = -100; self.update = function () { self.x += self.velocityX; self.rotation += 0.02; // Reset position when off screen if (self.x > 2148) { self.x = self.startX; self.y = Math.random() * 400 + 800; } }; return self; }); var SettingsMenu = Container.expand(function () { var self = Container.call(this); // Title var titleTxt = new Text2('AJUSTES', { size: 120, fill: 0xFFFFFF }); titleTxt.anchor.set(0.5, 0.5); titleTxt.x = 1024; titleTxt.y = 600; self.addChild(titleTxt); // Sound volume label var soundLabelTxt = new Text2('VOLUMEN SONIDO: ' + Math.round(soundVolume * 100) + '%', { size: 80, fill: 0xFFFFFF }); soundLabelTxt.anchor.set(0.5, 0.5); soundLabelTxt.x = 1024; soundLabelTxt.y = 1000; self.addChild(soundLabelTxt); // Sound volume buttons var soundMinusBtn = new Text2('-', { size: 100, fill: 0xff4444 }); soundMinusBtn.anchor.set(0.5, 0.5); soundMinusBtn.x = 800; soundMinusBtn.y = 1100; self.addChild(soundMinusBtn); var soundPlusBtn = new Text2('+', { size: 100, fill: 0x44ff44 }); soundPlusBtn.anchor.set(0.5, 0.5); soundPlusBtn.x = 1248; soundPlusBtn.y = 1100; self.addChild(soundPlusBtn); // Music volume label var musicLabelTxt = new Text2('VOLUMEN MÚSICA: ' + Math.round(musicVolume * 100) + '%', { size: 80, fill: 0xFFFFFF }); musicLabelTxt.anchor.set(0.5, 0.5); musicLabelTxt.x = 1024; musicLabelTxt.y = 1300; self.addChild(musicLabelTxt); // Music volume buttons var musicMinusBtn = new Text2('-', { size: 100, fill: 0xff4444 }); musicMinusBtn.anchor.set(0.5, 0.5); musicMinusBtn.x = 800; musicMinusBtn.y = 1400; self.addChild(musicMinusBtn); var musicPlusBtn = new Text2('+', { size: 100, fill: 0x44ff44 }); musicPlusBtn.anchor.set(0.5, 0.5); musicPlusBtn.x = 1248; musicPlusBtn.y = 1400; self.addChild(musicPlusBtn); // Back button var backButton = new Text2('VOLVER', { size: 100, fill: 0xffff44 }); backButton.anchor.set(0.5, 0.5); backButton.x = 1024; backButton.y = 1800; self.addChild(backButton); // Button handlers soundMinusBtn.down = function (x, y, obj) { soundVolume = Math.max(0, soundVolume - 0.1); soundLabelTxt.setText('VOLUMEN SONIDO: ' + Math.round(soundVolume * 100) + '%'); storage.soundVolume = soundVolume; }; soundPlusBtn.down = function (x, y, obj) { soundVolume = Math.min(1, soundVolume + 0.1); soundLabelTxt.setText('VOLUMEN SONIDO: ' + Math.round(soundVolume * 100) + '%'); storage.soundVolume = soundVolume; }; musicMinusBtn.down = function (x, y, obj) { musicVolume = Math.max(0, musicVolume - 0.1); musicLabelTxt.setText('VOLUMEN MÚSICA: ' + Math.round(musicVolume * 100) + '%'); storage.musicVolume = musicVolume; LK.stopMusic(); if (musicVolume > 0) { LK.playMusic('bgmusic', { fade: { start: 0, end: musicVolume, duration: 200 } }); } }; musicPlusBtn.down = function (x, y, obj) { musicVolume = Math.min(1, musicVolume + 0.1); musicLabelTxt.setText('VOLUMEN MÚSICA: ' + Math.round(musicVolume * 100) + '%'); storage.musicVolume = musicVolume; LK.stopMusic(); if (musicVolume > 0) { LK.playMusic('bgmusic', { fade: { start: 0, end: musicVolume, duration: 200 } }); } }; backButton.down = function (x, y, obj) { showMainMenu(); }; return self; // Add animated fruits var menuFruits = []; var fruitTypes = ['apple', 'orange', 'banana', 'grape']; for (var i = 0; i < 3; i++) { var randomType = fruitTypes[Math.floor(Math.random() * fruitTypes.length)]; var menuFruit = new MenuFruit(randomType); menuFruit.x = -100 - i * 300; menuFruit.y = Math.random() * 400 + 800; menuFruit.scaleX = 0.6; menuFruit.scaleY = 0.6; self.addChild(menuFruit); menuFruits.push(menuFruit); } self.menuFruits = menuFruits; }); var SliceTrail = Container.expand(function () { var self = Container.call(this); var trailGraphics = self.attachAsset('sliceTrail', { anchorX: 0.5, anchorY: 0.5 }); self.lifeTime = 0; self.update = function () { self.lifeTime++; self.alpha = Math.max(0, 1 - self.lifeTime / 20); if (self.alpha <= 0) { var index = sliceTrails.indexOf(self); if (index !== -1) { sliceTrails.splice(index, 1); } self.destroy(); } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87CEEB }); /**** * Game Code ****/ // Game state var gameState = 'menu'; // 'menu', 'settings', 'playing' var mainMenu = null; var settingsMenu = null; // Settings variables var soundVolume = storage.soundVolume || 1.0; var musicVolume = storage.musicVolume || 1.0; // Game variables var fruits = []; var bombs = []; var fruitPieces = []; var sliceTrails = []; var spawnTimer = 0; var spawnRate = 120; // frames between spawns var difficultyTimer = 0; var isSlicing = false; var lastSliceX = 0; var lastSliceY = 0; var missedFruits = 0; var maxMissedFruits = 5; // UI elements (will be created when game starts) var scoreTxt = null; var missedTxt = null; // Menu functions function showMainMenu() { gameState = 'menu'; clearGame(); if (settingsMenu) { settingsMenu.destroy(); settingsMenu = null; } if (!mainMenu) { mainMenu = new MainMenu(); game.addChild(mainMenu); } } function showSettingsMenu() { gameState = 'settings'; if (mainMenu) { mainMenu.destroy(); mainMenu = null; } if (!settingsMenu) { settingsMenu = new SettingsMenu(); game.addChild(settingsMenu); } } function startGame() { gameState = 'playing'; if (mainMenu) { mainMenu.destroy(); mainMenu = null; } if (settingsMenu) { settingsMenu.destroy(); settingsMenu = null; } // Reset game variables clearGame(); LK.setScore(0); missedFruits = 0; spawnTimer = 0; spawnRate = 120; difficultyTimer = 0; // Create UI elements scoreTxt = new Text2('0', { size: 80, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); missedTxt = new Text2('Missed: 0/5', { size: 50, fill: 0xFFFFFF }); missedTxt.anchor.set(1, 0); LK.gui.topRight.addChild(missedTxt); missedTxt.x -= 120; missedTxt.y += 20; // Initialize score display scoreTxt.setText(LK.getScore()); // Start background music if (musicVolume > 0) { LK.playMusic('bgmusic', { fade: { start: 0, end: musicVolume, duration: 1000 } }); } } function clearGame() { // Clear all game objects for (var i = 0; i < fruits.length; i++) { fruits[i].destroy(); } for (var i = 0; i < bombs.length; i++) { bombs[i].destroy(); } for (var i = 0; i < fruitPieces.length; i++) { fruitPieces[i].destroy(); } for (var i = 0; i < sliceTrails.length; i++) { sliceTrails[i].destroy(); } fruits = []; bombs = []; fruitPieces = []; sliceTrails = []; // Clear UI if (scoreTxt) { scoreTxt.destroy(); scoreTxt = null; } if (missedTxt) { missedTxt.destroy(); missedTxt = null; } } // Initialize main menu showMainMenu(); // Spawn fruit function function spawnFruit() { var fruitTypes = ['apple', 'orange', 'banana', 'grape']; var randomType = fruitTypes[Math.floor(Math.random() * fruitTypes.length)]; var fruit = new Fruit(randomType); // Random spawn from sides var side = Math.floor(Math.random() * 4); if (side === 0) { // Left side fruit.x = -100; fruit.y = Math.random() * 1000 + 1000; fruit.velocityX = Math.random() * 8 + 6; fruit.velocityY = Math.random() * -15 - 10; } else if (side === 1) { // Right side fruit.x = 2148; fruit.y = Math.random() * 1000 + 1000; fruit.velocityX = -(Math.random() * 8 + 6); fruit.velocityY = Math.random() * -15 - 10; } else if (side === 2) { // Bottom left fruit.x = Math.random() * 500; fruit.y = 2800; fruit.velocityX = Math.random() * 12 + 8; fruit.velocityY = Math.random() * -20 - 15; } else { // Bottom right fruit.x = Math.random() * 500 + 1548; fruit.y = 2800; fruit.velocityX = -(Math.random() * 12 + 8); fruit.velocityY = Math.random() * -20 - 15; } fruits.push(fruit); game.addChild(fruit); } function spawnBomb() { var bomb = new Bomb(); // Random spawn from sides (same logic as fruits) var side = Math.floor(Math.random() * 4); if (side === 0) { bomb.x = -100; bomb.y = Math.random() * 1000 + 1000; bomb.velocityX = Math.random() * 8 + 6; bomb.velocityY = Math.random() * -15 - 10; } else if (side === 1) { bomb.x = 2148; bomb.y = Math.random() * 1000 + 1000; bomb.velocityX = -(Math.random() * 8 + 6); bomb.velocityY = Math.random() * -15 - 10; } else if (side === 2) { bomb.x = Math.random() * 500; bomb.y = 2800; bomb.velocityX = Math.random() * 12 + 8; bomb.velocityY = Math.random() * -20 - 15; } else { bomb.x = Math.random() * 500 + 1548; bomb.y = 2800; bomb.velocityX = -(Math.random() * 12 + 8); bomb.velocityY = Math.random() * -20 - 15; } bombs.push(bomb); game.addChild(bomb); } // Event handlers game.down = function (x, y, obj) { if (gameState === 'playing') { isSlicing = true; lastSliceX = x; lastSliceY = y; } }; game.up = function (x, y, obj) { if (gameState === 'playing') { isSlicing = false; } }; game.move = function (x, y, obj) { if (gameState === 'playing' && isSlicing) { // Create slice trail var trail = new SliceTrail(); trail.x = x; trail.y = y; sliceTrails.push(trail); game.addChild(trail); // Check for fruit slicing for (var i = 0; i < fruits.length; i++) { var fruit = fruits[i]; var distance = Math.sqrt(Math.pow(fruit.x - x, 2) + Math.pow(fruit.y - y, 2)); if (distance < 150 && !fruit.sliced) { fruit.slice(); break; } } // Check for bomb slicing for (var i = 0; i < bombs.length; i++) { var bomb = bombs[i]; var distance = Math.sqrt(Math.pow(bomb.x - x, 2) + Math.pow(bomb.y - y, 2)); if (distance < 100 && !bomb.exploded) { bomb.explode(); break; } } lastSliceX = x; lastSliceY = y; } }; // Main game update loop game.update = function () { if (gameState === 'playing') { // Timer-based spawning spawnTimer++; if (spawnTimer >= spawnRate) { spawnTimer = 0; // 80% chance for fruit, 20% chance for bomb if (Math.random() < 0.8) { spawnFruit(); } else { spawnBomb(); } } // Increase difficulty over time difficultyTimer++; if (difficultyTimer >= 1800) { // Every 30 seconds difficultyTimer = 0; spawnRate = Math.max(60, spawnRate - 10); // Minimum spawn rate of 60 frames } // Clean up off-screen fruits for (var i = fruits.length - 1; i >= 0; i--) { var fruit = fruits[i]; // Check if fruit went off screen (fell down or went too far to sides) if (fruit.y > 2800 || fruit.x < -200 || fruit.x > 2248) { if (!fruit.sliced) { missedFruits++; if (missedTxt) { missedTxt.setText('Missed: ' + missedFruits + '/' + maxMissedFruits); } if (missedFruits >= maxMissedFruits) { LK.showGameOver(); } } fruits.splice(i, 1); fruit.destroy(); } } // Clean up off-screen bombs for (var i = bombs.length - 1; i >= 0; i--) { var bomb = bombs[i]; if (bomb.y > 2800 || bomb.x < -200 || bomb.x > 2248) { bombs.splice(i, 1); bomb.destroy(); } } // Clean up fruit pieces for (var i = fruitPieces.length - 1; i >= 0; i--) { var piece = fruitPieces[i]; if (piece.alpha <= 0 || piece.y > 2800) { fruitPieces.splice(i, 1); piece.destroy(); } } } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Bomb = Container.expand(function () {
var self = Container.call(this);
var bombGraphics = self.attachAsset('bomb', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = 0;
self.velocityY = 0;
self.gravity = 0.5;
self.exploded = false;
self.lastX = 0;
self.lastY = 0;
self.update = function () {
if (!self.exploded) {
self.lastX = self.x;
self.lastY = self.y;
self.x += self.velocityX;
self.y += self.velocityY;
self.velocityY += self.gravity;
self.rotation += 0.03;
}
};
self.explode = function () {
if (self.exploded) return;
self.exploded = true;
var bombSound = LK.getSound('bomb');
bombSound.volume = soundVolume;
bombSound.play();
// Flash screen red
LK.effects.flashScreen(0xff0000, 1000);
// Game over
LK.showGameOver();
};
return self;
});
var Fruit = Container.expand(function (fruitType) {
var self = Container.call(this);
var colors = {
apple: 0xff4444,
orange: 0xff8844,
banana: 0xffff44,
grape: 0x8844ff
};
var fruitGraphics = self.attachAsset(fruitType, {
anchorX: 0.5,
anchorY: 0.5
});
self.fruitType = fruitType;
self.velocityX = 0;
self.velocityY = 0;
self.gravity = 0.5;
self.sliced = false;
self.lastX = 0;
self.lastY = 0;
self.update = function () {
if (!self.sliced) {
self.lastX = self.x;
self.lastY = self.y;
self.x += self.velocityX;
self.y += self.velocityY;
self.velocityY += self.gravity;
self.rotation += 0.05;
}
};
self.slice = function () {
if (self.sliced) return;
self.sliced = true;
var sliceSound = LK.getSound('slice');
sliceSound.volume = soundVolume;
sliceSound.play();
// Create fruit pieces
for (var i = 0; i < 4; i++) {
var piece = new FruitPiece(colors[self.fruitType]);
piece.x = self.x + (Math.random() - 0.5) * 40;
piece.y = self.y + (Math.random() - 0.5) * 40;
piece.velocityX = (Math.random() - 0.5) * 10;
piece.velocityY = Math.random() * -8 - 5;
game.addChild(piece);
fruitPieces.push(piece);
}
// Award points
LK.setScore(LK.getScore() + 10);
scoreTxt.setText(LK.getScore());
// Remove from game
var index = fruits.indexOf(self);
if (index !== -1) {
fruits.splice(index, 1);
}
self.destroy();
};
return self;
});
var FruitPiece = Container.expand(function (color) {
var self = Container.call(this);
var pieceGraphics = self.attachAsset('fruitPiece', {
anchorX: 0.5,
anchorY: 0.5,
tint: color
});
self.velocityX = 0;
self.velocityY = 0;
self.gravity = 0.3;
self.lifeTime = 0;
self.update = function () {
self.x += self.velocityX;
self.y += self.velocityY;
self.velocityY += self.gravity;
self.rotation += 0.1;
self.lifeTime++;
// Fade out over time
self.alpha = Math.max(0, 1 - self.lifeTime / 120);
};
return self;
});
var MainMenu = Container.expand(function () {
var self = Container.call(this);
// Title
var titleTxt = new Text2('FRUIT SLICE FRENZY', {
size: 120,
fill: 0xFFFFFF
});
titleTxt.anchor.set(0.5, 0.5);
titleTxt.x = 1024;
titleTxt.y = 600;
self.addChild(titleTxt);
// Play button
var playButton = new Text2('JUGAR', {
size: 150,
fill: 0x44ff44
});
playButton.anchor.set(0.5, 0.5);
playButton.x = 1024;
playButton.y = 1200;
self.addChild(playButton);
// Settings button
var settingsButton = new Text2('AJUSTES', {
size: 150,
fill: 0x4444ff
});
settingsButton.anchor.set(0.5, 0.5);
settingsButton.x = 1024;
settingsButton.y = 1400;
self.addChild(settingsButton);
// Button handlers
playButton.down = function (x, y, obj) {
startGame();
};
settingsButton.down = function (x, y, obj) {
showSettingsMenu();
};
// Add decorative fruits to main menu background
var decorativeFruits = [];
var fruitTypes = ['apple', 'orange', 'banana', 'grape'];
// Create static decorative fruits
for (var i = 0; i < 15; i++) {
var randomType = fruitTypes[Math.floor(Math.random() * fruitTypes.length)];
var decorativeFruit = self.attachAsset(randomType, {
anchorX: 0.5,
anchorY: 0.5
});
// Position fruits randomly around the screen
decorativeFruit.x = Math.random() * 1800 + 124; // Keep away from edges
decorativeFruit.y = Math.random() * 2000 + 200;
decorativeFruit.alpha = Math.random() * 0.3 + 0.2; // Vary transparency
decorativeFruit.scaleX = Math.random() * 0.6 + 0.4; // Vary size
decorativeFruit.scaleY = decorativeFruit.scaleX; // Keep aspect ratio
decorativeFruit.rotation = Math.random() * Math.PI * 2;
// Add some fruits with tween animations
if (i % 3 === 0) {
// Gentle bobbing animation
tween(decorativeFruit, {
y: decorativeFruit.y + 30
}, {
duration: 2000 + Math.random() * 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(decorativeFruit, {
y: decorativeFruit.y - 30
}, {
duration: 2000 + Math.random() * 1000,
easing: tween.easeInOut
});
}
});
}
decorativeFruits.push(decorativeFruit);
}
self.decorativeFruits = decorativeFruits;
// Add update method for gentle floating animation
self.update = function () {
// Animate decorative fruits with gentle floating motion
for (var i = 0; i < self.decorativeFruits.length; i++) {
var fruit = self.decorativeFruits[i];
fruit.y += Math.sin(LK.ticks * 0.01 + i) * 0.5;
fruit.rotation += 0.002;
// Add subtle scale pulsing for some fruits
if (i % 4 === 0) {
var scaleOffset = Math.sin(LK.ticks * 0.008 + i) * 0.05;
fruit.scaleX += scaleOffset;
fruit.scaleY += scaleOffset;
}
}
};
return self;
});
var MenuFruit = Container.expand(function (fruitType) {
var self = Container.call(this);
var fruitGraphics = self.attachAsset(fruitType, {
anchorX: 0.5,
anchorY: 0.5
});
self.fruitType = fruitType;
self.velocityX = 2;
self.startX = -100;
self.update = function () {
self.x += self.velocityX;
self.rotation += 0.02;
// Reset position when off screen
if (self.x > 2148) {
self.x = self.startX;
self.y = Math.random() * 400 + 800;
}
};
return self;
});
var SettingsMenu = Container.expand(function () {
var self = Container.call(this);
// Title
var titleTxt = new Text2('AJUSTES', {
size: 120,
fill: 0xFFFFFF
});
titleTxt.anchor.set(0.5, 0.5);
titleTxt.x = 1024;
titleTxt.y = 600;
self.addChild(titleTxt);
// Sound volume label
var soundLabelTxt = new Text2('VOLUMEN SONIDO: ' + Math.round(soundVolume * 100) + '%', {
size: 80,
fill: 0xFFFFFF
});
soundLabelTxt.anchor.set(0.5, 0.5);
soundLabelTxt.x = 1024;
soundLabelTxt.y = 1000;
self.addChild(soundLabelTxt);
// Sound volume buttons
var soundMinusBtn = new Text2('-', {
size: 100,
fill: 0xff4444
});
soundMinusBtn.anchor.set(0.5, 0.5);
soundMinusBtn.x = 800;
soundMinusBtn.y = 1100;
self.addChild(soundMinusBtn);
var soundPlusBtn = new Text2('+', {
size: 100,
fill: 0x44ff44
});
soundPlusBtn.anchor.set(0.5, 0.5);
soundPlusBtn.x = 1248;
soundPlusBtn.y = 1100;
self.addChild(soundPlusBtn);
// Music volume label
var musicLabelTxt = new Text2('VOLUMEN MÚSICA: ' + Math.round(musicVolume * 100) + '%', {
size: 80,
fill: 0xFFFFFF
});
musicLabelTxt.anchor.set(0.5, 0.5);
musicLabelTxt.x = 1024;
musicLabelTxt.y = 1300;
self.addChild(musicLabelTxt);
// Music volume buttons
var musicMinusBtn = new Text2('-', {
size: 100,
fill: 0xff4444
});
musicMinusBtn.anchor.set(0.5, 0.5);
musicMinusBtn.x = 800;
musicMinusBtn.y = 1400;
self.addChild(musicMinusBtn);
var musicPlusBtn = new Text2('+', {
size: 100,
fill: 0x44ff44
});
musicPlusBtn.anchor.set(0.5, 0.5);
musicPlusBtn.x = 1248;
musicPlusBtn.y = 1400;
self.addChild(musicPlusBtn);
// Back button
var backButton = new Text2('VOLVER', {
size: 100,
fill: 0xffff44
});
backButton.anchor.set(0.5, 0.5);
backButton.x = 1024;
backButton.y = 1800;
self.addChild(backButton);
// Button handlers
soundMinusBtn.down = function (x, y, obj) {
soundVolume = Math.max(0, soundVolume - 0.1);
soundLabelTxt.setText('VOLUMEN SONIDO: ' + Math.round(soundVolume * 100) + '%');
storage.soundVolume = soundVolume;
};
soundPlusBtn.down = function (x, y, obj) {
soundVolume = Math.min(1, soundVolume + 0.1);
soundLabelTxt.setText('VOLUMEN SONIDO: ' + Math.round(soundVolume * 100) + '%');
storage.soundVolume = soundVolume;
};
musicMinusBtn.down = function (x, y, obj) {
musicVolume = Math.max(0, musicVolume - 0.1);
musicLabelTxt.setText('VOLUMEN MÚSICA: ' + Math.round(musicVolume * 100) + '%');
storage.musicVolume = musicVolume;
LK.stopMusic();
if (musicVolume > 0) {
LK.playMusic('bgmusic', {
fade: {
start: 0,
end: musicVolume,
duration: 200
}
});
}
};
musicPlusBtn.down = function (x, y, obj) {
musicVolume = Math.min(1, musicVolume + 0.1);
musicLabelTxt.setText('VOLUMEN MÚSICA: ' + Math.round(musicVolume * 100) + '%');
storage.musicVolume = musicVolume;
LK.stopMusic();
if (musicVolume > 0) {
LK.playMusic('bgmusic', {
fade: {
start: 0,
end: musicVolume,
duration: 200
}
});
}
};
backButton.down = function (x, y, obj) {
showMainMenu();
};
return self;
// Add animated fruits
var menuFruits = [];
var fruitTypes = ['apple', 'orange', 'banana', 'grape'];
for (var i = 0; i < 3; i++) {
var randomType = fruitTypes[Math.floor(Math.random() * fruitTypes.length)];
var menuFruit = new MenuFruit(randomType);
menuFruit.x = -100 - i * 300;
menuFruit.y = Math.random() * 400 + 800;
menuFruit.scaleX = 0.6;
menuFruit.scaleY = 0.6;
self.addChild(menuFruit);
menuFruits.push(menuFruit);
}
self.menuFruits = menuFruits;
});
var SliceTrail = Container.expand(function () {
var self = Container.call(this);
var trailGraphics = self.attachAsset('sliceTrail', {
anchorX: 0.5,
anchorY: 0.5
});
self.lifeTime = 0;
self.update = function () {
self.lifeTime++;
self.alpha = Math.max(0, 1 - self.lifeTime / 20);
if (self.alpha <= 0) {
var index = sliceTrails.indexOf(self);
if (index !== -1) {
sliceTrails.splice(index, 1);
}
self.destroy();
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Game state
var gameState = 'menu'; // 'menu', 'settings', 'playing'
var mainMenu = null;
var settingsMenu = null;
// Settings variables
var soundVolume = storage.soundVolume || 1.0;
var musicVolume = storage.musicVolume || 1.0;
// Game variables
var fruits = [];
var bombs = [];
var fruitPieces = [];
var sliceTrails = [];
var spawnTimer = 0;
var spawnRate = 120; // frames between spawns
var difficultyTimer = 0;
var isSlicing = false;
var lastSliceX = 0;
var lastSliceY = 0;
var missedFruits = 0;
var maxMissedFruits = 5;
// UI elements (will be created when game starts)
var scoreTxt = null;
var missedTxt = null;
// Menu functions
function showMainMenu() {
gameState = 'menu';
clearGame();
if (settingsMenu) {
settingsMenu.destroy();
settingsMenu = null;
}
if (!mainMenu) {
mainMenu = new MainMenu();
game.addChild(mainMenu);
}
}
function showSettingsMenu() {
gameState = 'settings';
if (mainMenu) {
mainMenu.destroy();
mainMenu = null;
}
if (!settingsMenu) {
settingsMenu = new SettingsMenu();
game.addChild(settingsMenu);
}
}
function startGame() {
gameState = 'playing';
if (mainMenu) {
mainMenu.destroy();
mainMenu = null;
}
if (settingsMenu) {
settingsMenu.destroy();
settingsMenu = null;
}
// Reset game variables
clearGame();
LK.setScore(0);
missedFruits = 0;
spawnTimer = 0;
spawnRate = 120;
difficultyTimer = 0;
// Create UI elements
scoreTxt = new Text2('0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
missedTxt = new Text2('Missed: 0/5', {
size: 50,
fill: 0xFFFFFF
});
missedTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(missedTxt);
missedTxt.x -= 120;
missedTxt.y += 20;
// Initialize score display
scoreTxt.setText(LK.getScore());
// Start background music
if (musicVolume > 0) {
LK.playMusic('bgmusic', {
fade: {
start: 0,
end: musicVolume,
duration: 1000
}
});
}
}
function clearGame() {
// Clear all game objects
for (var i = 0; i < fruits.length; i++) {
fruits[i].destroy();
}
for (var i = 0; i < bombs.length; i++) {
bombs[i].destroy();
}
for (var i = 0; i < fruitPieces.length; i++) {
fruitPieces[i].destroy();
}
for (var i = 0; i < sliceTrails.length; i++) {
sliceTrails[i].destroy();
}
fruits = [];
bombs = [];
fruitPieces = [];
sliceTrails = [];
// Clear UI
if (scoreTxt) {
scoreTxt.destroy();
scoreTxt = null;
}
if (missedTxt) {
missedTxt.destroy();
missedTxt = null;
}
}
// Initialize main menu
showMainMenu();
// Spawn fruit function
function spawnFruit() {
var fruitTypes = ['apple', 'orange', 'banana', 'grape'];
var randomType = fruitTypes[Math.floor(Math.random() * fruitTypes.length)];
var fruit = new Fruit(randomType);
// Random spawn from sides
var side = Math.floor(Math.random() * 4);
if (side === 0) {
// Left side
fruit.x = -100;
fruit.y = Math.random() * 1000 + 1000;
fruit.velocityX = Math.random() * 8 + 6;
fruit.velocityY = Math.random() * -15 - 10;
} else if (side === 1) {
// Right side
fruit.x = 2148;
fruit.y = Math.random() * 1000 + 1000;
fruit.velocityX = -(Math.random() * 8 + 6);
fruit.velocityY = Math.random() * -15 - 10;
} else if (side === 2) {
// Bottom left
fruit.x = Math.random() * 500;
fruit.y = 2800;
fruit.velocityX = Math.random() * 12 + 8;
fruit.velocityY = Math.random() * -20 - 15;
} else {
// Bottom right
fruit.x = Math.random() * 500 + 1548;
fruit.y = 2800;
fruit.velocityX = -(Math.random() * 12 + 8);
fruit.velocityY = Math.random() * -20 - 15;
}
fruits.push(fruit);
game.addChild(fruit);
}
function spawnBomb() {
var bomb = new Bomb();
// Random spawn from sides (same logic as fruits)
var side = Math.floor(Math.random() * 4);
if (side === 0) {
bomb.x = -100;
bomb.y = Math.random() * 1000 + 1000;
bomb.velocityX = Math.random() * 8 + 6;
bomb.velocityY = Math.random() * -15 - 10;
} else if (side === 1) {
bomb.x = 2148;
bomb.y = Math.random() * 1000 + 1000;
bomb.velocityX = -(Math.random() * 8 + 6);
bomb.velocityY = Math.random() * -15 - 10;
} else if (side === 2) {
bomb.x = Math.random() * 500;
bomb.y = 2800;
bomb.velocityX = Math.random() * 12 + 8;
bomb.velocityY = Math.random() * -20 - 15;
} else {
bomb.x = Math.random() * 500 + 1548;
bomb.y = 2800;
bomb.velocityX = -(Math.random() * 12 + 8);
bomb.velocityY = Math.random() * -20 - 15;
}
bombs.push(bomb);
game.addChild(bomb);
}
// Event handlers
game.down = function (x, y, obj) {
if (gameState === 'playing') {
isSlicing = true;
lastSliceX = x;
lastSliceY = y;
}
};
game.up = function (x, y, obj) {
if (gameState === 'playing') {
isSlicing = false;
}
};
game.move = function (x, y, obj) {
if (gameState === 'playing' && isSlicing) {
// Create slice trail
var trail = new SliceTrail();
trail.x = x;
trail.y = y;
sliceTrails.push(trail);
game.addChild(trail);
// Check for fruit slicing
for (var i = 0; i < fruits.length; i++) {
var fruit = fruits[i];
var distance = Math.sqrt(Math.pow(fruit.x - x, 2) + Math.pow(fruit.y - y, 2));
if (distance < 150 && !fruit.sliced) {
fruit.slice();
break;
}
}
// Check for bomb slicing
for (var i = 0; i < bombs.length; i++) {
var bomb = bombs[i];
var distance = Math.sqrt(Math.pow(bomb.x - x, 2) + Math.pow(bomb.y - y, 2));
if (distance < 100 && !bomb.exploded) {
bomb.explode();
break;
}
}
lastSliceX = x;
lastSliceY = y;
}
};
// Main game update loop
game.update = function () {
if (gameState === 'playing') {
// Timer-based spawning
spawnTimer++;
if (spawnTimer >= spawnRate) {
spawnTimer = 0;
// 80% chance for fruit, 20% chance for bomb
if (Math.random() < 0.8) {
spawnFruit();
} else {
spawnBomb();
}
}
// Increase difficulty over time
difficultyTimer++;
if (difficultyTimer >= 1800) {
// Every 30 seconds
difficultyTimer = 0;
spawnRate = Math.max(60, spawnRate - 10); // Minimum spawn rate of 60 frames
}
// Clean up off-screen fruits
for (var i = fruits.length - 1; i >= 0; i--) {
var fruit = fruits[i];
// Check if fruit went off screen (fell down or went too far to sides)
if (fruit.y > 2800 || fruit.x < -200 || fruit.x > 2248) {
if (!fruit.sliced) {
missedFruits++;
if (missedTxt) {
missedTxt.setText('Missed: ' + missedFruits + '/' + maxMissedFruits);
}
if (missedFruits >= maxMissedFruits) {
LK.showGameOver();
}
}
fruits.splice(i, 1);
fruit.destroy();
}
}
// Clean up off-screen bombs
for (var i = bombs.length - 1; i >= 0; i--) {
var bomb = bombs[i];
if (bomb.y > 2800 || bomb.x < -200 || bomb.x > 2248) {
bombs.splice(i, 1);
bomb.destroy();
}
}
// Clean up fruit pieces
for (var i = fruitPieces.length - 1; i >= 0; i--) {
var piece = fruitPieces[i];
if (piece.alpha <= 0 || piece.y > 2800) {
fruitPieces.splice(i, 1);
piece.destroy();
}
}
}
};