/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Basket = Container.expand(function () { var self = Container.call(this); var basketGraphics = self.attachAsset('basket', { anchorX: 0.5, anchorY: 0.5 }); self.isFrozen = false; self.freeze = function () { if (!self.isFrozen) { self.isFrozen = true; self.removeChild(basketGraphics); basketGraphics = self.attachAsset('F-bucket', { anchorX: 0.5, anchorY: 0.5 }); } }; self.unfreeze = function () { if (self.isFrozen) { self.isFrozen = false; self.removeChild(basketGraphics); basketGraphics = self.attachAsset('basket', { anchorX: 0.5, anchorY: 0.5 }); } }; self.down = function (x, y, obj) { // Logic for basket interaction is handled in game event handlers }; self.up = function (x, y, obj) { // Logic for basket interaction is handled in game event handlers }; return self; }); var Bomb = Container.expand(function () { var self = Container.call(this); var bombGraphics = self.attachAsset('Bomb', { anchorX: 0.5, anchorY: 0.5 }); self.speed = Math.random() * 4 + 6; // Slightly faster than fruits self.update = function () { self.y += self.speed; bombGraphics.rotation += 0.03; // Constant rotation for visual effect }; return self; }); var Fruit = Container.expand(function (type) { var self = Container.call(this); self.type = type || 'apple'; self.speed = Math.random() * 3 + 5; self.value = 0; switch (self.type) { case 'apple': case 'F-Apple': self.value = 1; break; case 'banana': case 'F-banana': self.value = 2; break; case 'orange': case 'F-orange': self.value = 3; break; case 'pear': case 'F-pear': self.value = 5; break; case 'Kiwi': case 'F-kiwi': self.value = 10; break; case 'Strawberry': case 'F-strawberry': self.value = 7; break; case 'Coconut': case 'F-Coconut': self.value = 8; break; case 'Blueberry': case 'F-Blueberry': self.value = 6; break; } // Check if we need to create a frozen fruit variant self.isFrozen = self.type.startsWith('F-'); var fruitGraphics = self.attachAsset(self.type, { anchorX: 0.5, anchorY: 0.5 }); // Add rotation to make it more dynamic self.rotationSpeed = (Math.random() - 0.5) * 0.05; self.update = function () { self.y += self.speed; fruitGraphics.rotation += self.rotationSpeed; // Logic for missed fruits is handled in the game update function }; return self; }); var Nuke = Container.expand(function () { var self = Container.call(this); var nukeGraphics = self.attachAsset('Nuke', { anchorX: 0.5, anchorY: 0.5 }); self.speed = Math.random() * 4 + 6; // Same speed as regular bombs self.update = function () { self.y += self.speed; nukeGraphics.rotation += 0.03; // Constant rotation for visual effect }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87CEEB }); /**** * Game Code ****/ // Game constants var GAME_WIDTH = 2048; var GAME_HEIGHT = 2732; var GAME_DURATION = 60; // seconds var SPAWN_INTERVAL = 60; // frames (60 = 1 second at 60fps) var SPAWN_INCREASE_RATE = 0.98; // Rate at which spawn interval decreases var MIN_SPAWN_INTERVAL = 15; // Minimum spawn interval // Game variables var fruits = []; var bombs = []; var nukes = []; var gameOver = false; var spawnCounter = 0; var currentSpawnInterval = SPAWN_INTERVAL; var fruitTypes = ['apple', 'banana', 'orange', 'pear', 'Kiwi', 'Strawberry', 'Coconut', 'Blueberry']; var frozenFruitTypes = ['F-Apple', 'F-banana', 'F-orange', 'F-pear', 'F-kiwi', 'F-strawberry', 'F-Coconut', 'F-Blueberry']; var allFruitTypes = fruitTypes.concat(frozenFruitTypes); var timeLeft = GAME_DURATION; var lastTime = Date.now(); var bombSpawnChance = 0.15; // 15% chance to spawn a bomb instead of fruit var nukeSpawnChance = 0.05; // 5% chance to spawn a nuke // Create background var background = LK.getAsset('background', { anchorX: 0, anchorY: 0, x: 0, y: 0 }); game.addChild(background); // Create basket var basket = new Basket(); basket.x = GAME_WIDTH / 2; basket.y = GAME_HEIGHT - 150; game.addChild(basket); // Create score text var scoreTxt = new Text2('0', { size: 100, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); scoreTxt.y = 20; // Create timer text var timerTxt = new Text2('Time: ' + timeLeft, { size: 80, fill: 0xFFFFFF }); timerTxt.anchor.set(0, 0); LK.gui.topRight.addChild(timerTxt); timerTxt.x = -250; timerTxt.y = 20; // Set initial score display scoreTxt.setText("Score: " + LK.getScore()); // Start playing background music LK.playMusic('gameMusic', { fade: { start: 0, end: 1, duration: 1000 } }); // Create timer for the game duration var gameTimer = LK.setInterval(function () { timeLeft -= 1; timerTxt.setText("Time: " + timeLeft); if (timeLeft <= 0) { LK.clearInterval(gameTimer); LK.showGameOver(); } }, 1000); // Drag handling var isDragging = false; game.down = function (x, y, obj) { if (!basket.isFrozen) { isDragging = true; basket.x = x; } }; game.up = function (x, y, obj) { isDragging = false; }; game.move = function (x, y, obj) { if (isDragging && !basket.isFrozen) { basket.x = x; // Keep basket within screen bounds if (basket.x < 150) { basket.x = 150; } if (basket.x > GAME_WIDTH - 150) { basket.x = GAME_WIDTH - 150; } } }; // Spawn a new fruit function spawnFruit() { // Get a random number to decide what to spawn var spawnRoll = Math.random(); // Decide whether to spawn a nuke, bomb, or regular fruit if (spawnRoll < nukeSpawnChance) { // Spawn a nuke var nuke = new Nuke(); // Position nuke randomly at the top nuke.x = Math.random() * (GAME_WIDTH - 200) + 100; nuke.y = -100; nukes.push(nuke); game.addChild(nuke); } else if (spawnRoll < nukeSpawnChance + bombSpawnChance) { // Spawn a bomb var bomb = new Bomb(); // Position bomb randomly at the top bomb.x = Math.random() * (GAME_WIDTH - 200) + 100; bomb.y = -100; bombs.push(bomb); game.addChild(bomb); } else { // Spawn a fruit // Determine if it should be a regular or frozen fruit (20% chance for frozen fruit) var fruitArray = Math.random() < 0.2 ? frozenFruitTypes : fruitTypes; var type = fruitArray[Math.floor(Math.random() * fruitArray.length)]; var fruit = new Fruit(type); // Position fruit randomly at the top fruit.x = Math.random() * (GAME_WIDTH - 200) + 100; fruit.y = -100; fruits.push(fruit); game.addChild(fruit); } // Make spawn interval shorter over time for increased difficulty currentSpawnInterval *= SPAWN_INCREASE_RATE; if (currentSpawnInterval < MIN_SPAWN_INTERVAL) { currentSpawnInterval = MIN_SPAWN_INTERVAL; } } // Main game update loop game.update = function () { // Spawn new fruits at intervals spawnCounter++; if (spawnCounter >= currentSpawnInterval) { spawnFruit(); spawnCounter = 0; } // Update and check all fruits for (var i = fruits.length - 1; i >= 0; i--) { var fruit = fruits[i]; // Check if fruit has fallen off the screen if (fruit.y > GAME_HEIGHT + 100) { LK.getSound('miss').play(); fruit.destroy(); fruits.splice(i, 1); continue; } // Check for collision with basket if (!fruit.collected && Math.abs(fruit.x - basket.x) < 150 && Math.abs(fruit.y - basket.y) < 100 && fruit.y > basket.y - 150) { // Collect the fruit fruit.collected = true; LK.setScore(LK.getScore() + fruit.value); scoreTxt.setText("Score: " + LK.getScore()); // Play catch sound LK.getSound('catch').play(); // Animate fruit disappearing tween(fruit, { alpha: 0, scaleX: 0.2, scaleY: 0.2 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { var fruitIndex = fruits.indexOf(fruit); if (fruitIndex !== -1) { fruit.destroy(); fruits.splice(fruitIndex, 1); } } }); // If it's a F-fruit, freeze the basket and change to F-bucket // Otherwise, just check if already frozen if (fruit.isFrozen || fruit.type.startsWith('F-')) { basket.freeze(); // Flash basket to give visual feedback LK.effects.flashObject(basket, 0xFFFFFF, 300); } } } // Update and check all bombs for (var j = bombs.length - 1; j >= 0; j--) { var bomb = bombs[j]; // Check if bomb has fallen off the screen if (bomb.y > GAME_HEIGHT + 100) { bomb.destroy(); bombs.splice(j, 1); continue; } // Check for collision with basket if (Math.abs(bomb.x - basket.x) < 150 && Math.abs(bomb.y - basket.y) < 100 && bomb.y > basket.y - 150) { // If basket is frozen, unfreeze it and don't end the game if (basket.isFrozen) { basket.unfreeze(); // Clean up the bomb bomb.destroy(); bombs.splice(j, 1); // Flash the basket red to indicate the state change LK.effects.flashObject(basket, 0xFF0000, 300); } else { // Game over if player catches a bomb with normal basket LK.effects.flashScreen(0xFF0000, 500); // Flash screen red LK.clearInterval(gameTimer); // Clear game timer LK.showGameOver(); // Show game over screen // Clean up the bomb bomb.destroy(); bombs.splice(j, 1); } } } // Update and check all nukes for (var k = nukes.length - 1; k >= 0; k--) { var nuke = nukes[k]; // Check if nuke has fallen off the screen if (nuke.y > GAME_HEIGHT + 100) { nuke.destroy(); nukes.splice(k, 1); continue; } // Check for collision with basket if (Math.abs(nuke.x - basket.x) < 150 && Math.abs(nuke.y - basket.y) < 100 && nuke.y > basket.y - 150) { // If basket is frozen or the nuke hits F-bucket, game over if (basket.isFrozen) { // Game over LK.effects.flashScreen(0xFF0000, 500); // Flash screen red LK.clearInterval(gameTimer); // Clear game timer LK.showGameOver(); // Show game over screen } else { // Treat like a normal bomb if basket is not frozen LK.effects.flashScreen(0xFF0000, 500); // Flash screen red LK.clearInterval(gameTimer); // Clear game timer LK.showGameOver(); // Show game over screen } // Clean up the nuke nuke.destroy(); nukes.splice(k, 1); } } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Basket = Container.expand(function () {
var self = Container.call(this);
var basketGraphics = self.attachAsset('basket', {
anchorX: 0.5,
anchorY: 0.5
});
self.isFrozen = false;
self.freeze = function () {
if (!self.isFrozen) {
self.isFrozen = true;
self.removeChild(basketGraphics);
basketGraphics = self.attachAsset('F-bucket', {
anchorX: 0.5,
anchorY: 0.5
});
}
};
self.unfreeze = function () {
if (self.isFrozen) {
self.isFrozen = false;
self.removeChild(basketGraphics);
basketGraphics = self.attachAsset('basket', {
anchorX: 0.5,
anchorY: 0.5
});
}
};
self.down = function (x, y, obj) {
// Logic for basket interaction is handled in game event handlers
};
self.up = function (x, y, obj) {
// Logic for basket interaction is handled in game event handlers
};
return self;
});
var Bomb = Container.expand(function () {
var self = Container.call(this);
var bombGraphics = self.attachAsset('Bomb', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = Math.random() * 4 + 6; // Slightly faster than fruits
self.update = function () {
self.y += self.speed;
bombGraphics.rotation += 0.03; // Constant rotation for visual effect
};
return self;
});
var Fruit = Container.expand(function (type) {
var self = Container.call(this);
self.type = type || 'apple';
self.speed = Math.random() * 3 + 5;
self.value = 0;
switch (self.type) {
case 'apple':
case 'F-Apple':
self.value = 1;
break;
case 'banana':
case 'F-banana':
self.value = 2;
break;
case 'orange':
case 'F-orange':
self.value = 3;
break;
case 'pear':
case 'F-pear':
self.value = 5;
break;
case 'Kiwi':
case 'F-kiwi':
self.value = 10;
break;
case 'Strawberry':
case 'F-strawberry':
self.value = 7;
break;
case 'Coconut':
case 'F-Coconut':
self.value = 8;
break;
case 'Blueberry':
case 'F-Blueberry':
self.value = 6;
break;
}
// Check if we need to create a frozen fruit variant
self.isFrozen = self.type.startsWith('F-');
var fruitGraphics = self.attachAsset(self.type, {
anchorX: 0.5,
anchorY: 0.5
});
// Add rotation to make it more dynamic
self.rotationSpeed = (Math.random() - 0.5) * 0.05;
self.update = function () {
self.y += self.speed;
fruitGraphics.rotation += self.rotationSpeed;
// Logic for missed fruits is handled in the game update function
};
return self;
});
var Nuke = Container.expand(function () {
var self = Container.call(this);
var nukeGraphics = self.attachAsset('Nuke', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = Math.random() * 4 + 6; // Same speed as regular bombs
self.update = function () {
self.y += self.speed;
nukeGraphics.rotation += 0.03; // Constant rotation for visual effect
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Game constants
var GAME_WIDTH = 2048;
var GAME_HEIGHT = 2732;
var GAME_DURATION = 60; // seconds
var SPAWN_INTERVAL = 60; // frames (60 = 1 second at 60fps)
var SPAWN_INCREASE_RATE = 0.98; // Rate at which spawn interval decreases
var MIN_SPAWN_INTERVAL = 15; // Minimum spawn interval
// Game variables
var fruits = [];
var bombs = [];
var nukes = [];
var gameOver = false;
var spawnCounter = 0;
var currentSpawnInterval = SPAWN_INTERVAL;
var fruitTypes = ['apple', 'banana', 'orange', 'pear', 'Kiwi', 'Strawberry', 'Coconut', 'Blueberry'];
var frozenFruitTypes = ['F-Apple', 'F-banana', 'F-orange', 'F-pear', 'F-kiwi', 'F-strawberry', 'F-Coconut', 'F-Blueberry'];
var allFruitTypes = fruitTypes.concat(frozenFruitTypes);
var timeLeft = GAME_DURATION;
var lastTime = Date.now();
var bombSpawnChance = 0.15; // 15% chance to spawn a bomb instead of fruit
var nukeSpawnChance = 0.05; // 5% chance to spawn a nuke
// Create background
var background = LK.getAsset('background', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
});
game.addChild(background);
// Create basket
var basket = new Basket();
basket.x = GAME_WIDTH / 2;
basket.y = GAME_HEIGHT - 150;
game.addChild(basket);
// Create score text
var scoreTxt = new Text2('0', {
size: 100,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
scoreTxt.y = 20;
// Create timer text
var timerTxt = new Text2('Time: ' + timeLeft, {
size: 80,
fill: 0xFFFFFF
});
timerTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(timerTxt);
timerTxt.x = -250;
timerTxt.y = 20;
// Set initial score display
scoreTxt.setText("Score: " + LK.getScore());
// Start playing background music
LK.playMusic('gameMusic', {
fade: {
start: 0,
end: 1,
duration: 1000
}
});
// Create timer for the game duration
var gameTimer = LK.setInterval(function () {
timeLeft -= 1;
timerTxt.setText("Time: " + timeLeft);
if (timeLeft <= 0) {
LK.clearInterval(gameTimer);
LK.showGameOver();
}
}, 1000);
// Drag handling
var isDragging = false;
game.down = function (x, y, obj) {
if (!basket.isFrozen) {
isDragging = true;
basket.x = x;
}
};
game.up = function (x, y, obj) {
isDragging = false;
};
game.move = function (x, y, obj) {
if (isDragging && !basket.isFrozen) {
basket.x = x;
// Keep basket within screen bounds
if (basket.x < 150) {
basket.x = 150;
}
if (basket.x > GAME_WIDTH - 150) {
basket.x = GAME_WIDTH - 150;
}
}
};
// Spawn a new fruit
function spawnFruit() {
// Get a random number to decide what to spawn
var spawnRoll = Math.random();
// Decide whether to spawn a nuke, bomb, or regular fruit
if (spawnRoll < nukeSpawnChance) {
// Spawn a nuke
var nuke = new Nuke();
// Position nuke randomly at the top
nuke.x = Math.random() * (GAME_WIDTH - 200) + 100;
nuke.y = -100;
nukes.push(nuke);
game.addChild(nuke);
} else if (spawnRoll < nukeSpawnChance + bombSpawnChance) {
// Spawn a bomb
var bomb = new Bomb();
// Position bomb randomly at the top
bomb.x = Math.random() * (GAME_WIDTH - 200) + 100;
bomb.y = -100;
bombs.push(bomb);
game.addChild(bomb);
} else {
// Spawn a fruit
// Determine if it should be a regular or frozen fruit (20% chance for frozen fruit)
var fruitArray = Math.random() < 0.2 ? frozenFruitTypes : fruitTypes;
var type = fruitArray[Math.floor(Math.random() * fruitArray.length)];
var fruit = new Fruit(type);
// Position fruit randomly at the top
fruit.x = Math.random() * (GAME_WIDTH - 200) + 100;
fruit.y = -100;
fruits.push(fruit);
game.addChild(fruit);
}
// Make spawn interval shorter over time for increased difficulty
currentSpawnInterval *= SPAWN_INCREASE_RATE;
if (currentSpawnInterval < MIN_SPAWN_INTERVAL) {
currentSpawnInterval = MIN_SPAWN_INTERVAL;
}
}
// Main game update loop
game.update = function () {
// Spawn new fruits at intervals
spawnCounter++;
if (spawnCounter >= currentSpawnInterval) {
spawnFruit();
spawnCounter = 0;
}
// Update and check all fruits
for (var i = fruits.length - 1; i >= 0; i--) {
var fruit = fruits[i];
// Check if fruit has fallen off the screen
if (fruit.y > GAME_HEIGHT + 100) {
LK.getSound('miss').play();
fruit.destroy();
fruits.splice(i, 1);
continue;
}
// Check for collision with basket
if (!fruit.collected && Math.abs(fruit.x - basket.x) < 150 && Math.abs(fruit.y - basket.y) < 100 && fruit.y > basket.y - 150) {
// Collect the fruit
fruit.collected = true;
LK.setScore(LK.getScore() + fruit.value);
scoreTxt.setText("Score: " + LK.getScore());
// Play catch sound
LK.getSound('catch').play();
// Animate fruit disappearing
tween(fruit, {
alpha: 0,
scaleX: 0.2,
scaleY: 0.2
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
var fruitIndex = fruits.indexOf(fruit);
if (fruitIndex !== -1) {
fruit.destroy();
fruits.splice(fruitIndex, 1);
}
}
});
// If it's a F-fruit, freeze the basket and change to F-bucket
// Otherwise, just check if already frozen
if (fruit.isFrozen || fruit.type.startsWith('F-')) {
basket.freeze();
// Flash basket to give visual feedback
LK.effects.flashObject(basket, 0xFFFFFF, 300);
}
}
}
// Update and check all bombs
for (var j = bombs.length - 1; j >= 0; j--) {
var bomb = bombs[j];
// Check if bomb has fallen off the screen
if (bomb.y > GAME_HEIGHT + 100) {
bomb.destroy();
bombs.splice(j, 1);
continue;
}
// Check for collision with basket
if (Math.abs(bomb.x - basket.x) < 150 && Math.abs(bomb.y - basket.y) < 100 && bomb.y > basket.y - 150) {
// If basket is frozen, unfreeze it and don't end the game
if (basket.isFrozen) {
basket.unfreeze();
// Clean up the bomb
bomb.destroy();
bombs.splice(j, 1);
// Flash the basket red to indicate the state change
LK.effects.flashObject(basket, 0xFF0000, 300);
} else {
// Game over if player catches a bomb with normal basket
LK.effects.flashScreen(0xFF0000, 500); // Flash screen red
LK.clearInterval(gameTimer); // Clear game timer
LK.showGameOver(); // Show game over screen
// Clean up the bomb
bomb.destroy();
bombs.splice(j, 1);
}
}
}
// Update and check all nukes
for (var k = nukes.length - 1; k >= 0; k--) {
var nuke = nukes[k];
// Check if nuke has fallen off the screen
if (nuke.y > GAME_HEIGHT + 100) {
nuke.destroy();
nukes.splice(k, 1);
continue;
}
// Check for collision with basket
if (Math.abs(nuke.x - basket.x) < 150 && Math.abs(nuke.y - basket.y) < 100 && nuke.y > basket.y - 150) {
// If basket is frozen or the nuke hits F-bucket, game over
if (basket.isFrozen) {
// Game over
LK.effects.flashScreen(0xFF0000, 500); // Flash screen red
LK.clearInterval(gameTimer); // Clear game timer
LK.showGameOver(); // Show game over screen
} else {
// Treat like a normal bomb if basket is not frozen
LK.effects.flashScreen(0xFF0000, 500); // Flash screen red
LK.clearInterval(gameTimer); // Clear game timer
LK.showGameOver(); // Show game over screen
}
// Clean up the nuke
nuke.destroy();
nukes.splice(k, 1);
}
}
};
Bomb. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Apple. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A sunset on a beach for a background. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Orange the juice fruit. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Banana peeled. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Pear with a bit. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A basket. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Kiwi fruit. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Strawberry. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Frozen apple. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Frozen orange. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Frozen banana. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Frozen pear. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Frozen kiwi. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Frozen strawberry. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Frozen straw buckets. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Nuke without any explosions. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Coconut. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Blueberry. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Frozen blueberry. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Frozen coconut. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows