/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Basket class: player-controlled basket var Basket = Container.expand(function () { var self = Container.call(this); // Attach basket asset (ellipse, brown) var basketAsset = self.attachAsset('basket', { anchorX: 0.5, anchorY: 0.5 }); // Set basket size basketAsset.width = 350; basketAsset.height = 120; basketAsset.color = 0x8B5C2A; // brown // For collision, use the container's bounds // Down event for basket (not used, handled globally) self.down = function (x, y, obj) {}; return self; }); // Kiwi class: falling good fruit var Kiwi = Container.expand(function () { var self = Container.call(this); // Attach kiwi asset (ellipse, green) var kiwiAsset = self.attachAsset('kiwi', { anchorX: 0.5, anchorY: 0.5 }); kiwiAsset.width = 100; kiwiAsset.height = 100; kiwiAsset.color = 0x7ED957; // green // Falling speed (will be set on spawn) self.speed = 8; // For collision, use the container's bounds // Update method: move down self.update = function () { self.y += self.speed; }; return self; }); // RottenFruit class: falling bad fruit var RottenFruit = Container.expand(function () { var self = Container.call(this); // Attach rotten fruit asset (ellipse, purple) var rottenAsset = self.attachAsset('rotten', { anchorX: 0.5, anchorY: 0.5 }); rottenAsset.width = 100; rottenAsset.height = 100; rottenAsset.color = 0x7B2F7B; // purple // Falling speed (will be set on spawn) self.speed = 8; // Update method: move down self.update = function () { self.y += self.speed; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0xE3F6FF // light blue }); /**** * Game Code ****/ // Game area dimensions var GAME_WIDTH = 2048; var GAME_HEIGHT = 2732; // Start music at game start LK.playMusic('music'); // Score and timer var score = 0; var timeLeft = 60; // seconds // Game speed var baseSpeed = 8; var speedIncrease = 0.5; // per 10 seconds var maxSpeed = 28; // Arrays for fruits var kiwis = []; var rottenFruits = []; // Basket var basket = new Basket(); game.addChild(basket); // Position basket at bottom center basket.x = GAME_WIDTH / 2; basket.y = GAME_HEIGHT - 200; // Score text var scoreTxt = new Text2('0', { size: 120, fill: "#222" }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Timer text var timerTxt = new Text2('30', { size: 90, fill: "#222" }); timerTxt.anchor.set(1, 0); LK.gui.topRight.addChild(timerTxt); // Dragging var dragNode = null; var dragOffsetX = 0; // Helper: clamp basket within screen function clampBasketX(x) { var halfWidth = basket.width / 2; if (x < halfWidth) return halfWidth; if (x > GAME_WIDTH - halfWidth) return GAME_WIDTH - halfWidth; return x; } // Move handler: drag basket horizontally function handleMove(x, y, obj) { if (dragNode === basket) { // Only move horizontally var newX = clampBasketX(x - dragOffsetX); basket.x = newX; } } // Down: start dragging if touch is on basket game.down = function (x, y, obj) { // Only allow drag if touch is on basket var local = basket.toLocal(game.toGlobal({ x: x, y: y })); if (local.x >= -basket.width / 2 && local.x <= basket.width / 2 && local.y >= -basket.height / 2 && local.y <= basket.height / 2) { dragNode = basket; dragOffsetX = x - basket.x; } }; // Up: stop dragging game.up = function (x, y, obj) { dragNode = null; }; // Move: handle dragging game.move = handleMove; // Fruit spawn timers var kiwiSpawnInterval = 40; // frames var rottenSpawnInterval = 90; // frames var lastKiwiSpawn = 0; var lastRottenSpawn = 0; // Timer for game countdown var timerInterval = LK.setInterval(function () { timeLeft -= 1; if (timeLeft < 0) timeLeft = 0; timerTxt.setText(timeLeft + ''); if (timeLeft <= 0) { LK.showGameOver(); } }, 1000); // Main game update game.update = function () { // Increase speed as time passes var elapsed = 30 - timeLeft; var currentSpeed = Math.min(baseSpeed + Math.floor(elapsed / 10) * speedIncrease, maxSpeed); // Spawn kiwis if (LK.ticks - lastKiwiSpawn >= kiwiSpawnInterval) { var kiwi = new Kiwi(); kiwi.x = 150 + Math.random() * (GAME_WIDTH - 300); kiwi.y = -60; kiwi.speed = currentSpeed; kiwis.push(kiwi); game.addChild(kiwi); lastKiwiSpawn = LK.ticks; } // Spawn rotten fruit if (LK.ticks - lastRottenSpawn >= rottenSpawnInterval) { var rotten = new RottenFruit(); rotten.x = 150 + Math.random() * (GAME_WIDTH - 300); rotten.y = -60; rotten.speed = currentSpeed + 1.5; rottenFruits.push(rotten); game.addChild(rotten); lastRottenSpawn = LK.ticks; } // Update kiwis for (var i = kiwis.length - 1; i >= 0; i--) { var kiwi = kiwis[i]; kiwi.update(); // Off screen if (kiwi.y > GAME_HEIGHT + 80) { kiwi.destroy(); kiwis.splice(i, 1); continue; } // Collision with basket if (kiwi.intersects(basket)) { // Play yummy sound LK.getSound('yummy').play(); // Score up score += 1; scoreTxt.setText(score + ''); LK.setScore(score); // Win condition: if score reaches 60, show win if (score >= 60) { LK.showYouWin(); return; } // Flash basket green LK.effects.flashObject(basket, 0x7ED957, 300); kiwi.destroy(); kiwis.splice(i, 1); continue; } } // Update rotten fruits for (var j = rottenFruits.length - 1; j >= 0; j--) { var rotten = rottenFruits[j]; rotten.update(); // Off screen if (rotten.y > GAME_HEIGHT + 80) { rotten.destroy(); rottenFruits.splice(j, 1); continue; } // Collision with basket if (rotten.intersects(basket)) { // Play vomiting sound LK.getSound('vomiting').play(); // Score down (min 0) score = Math.max(0, score - 2); scoreTxt.setText(score + ''); LK.setScore(score); // Flash basket red LK.effects.flashObject(basket, 0xB22222, 400); rotten.destroy(); rottenFruits.splice(j, 1); continue; } } }; // Clean up timer on game over (handled by LK, but for completeness) game.onDestroy = function () { LK.clearInterval(timerInterval); };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Basket class: player-controlled basket
var Basket = Container.expand(function () {
var self = Container.call(this);
// Attach basket asset (ellipse, brown)
var basketAsset = self.attachAsset('basket', {
anchorX: 0.5,
anchorY: 0.5
});
// Set basket size
basketAsset.width = 350;
basketAsset.height = 120;
basketAsset.color = 0x8B5C2A; // brown
// For collision, use the container's bounds
// Down event for basket (not used, handled globally)
self.down = function (x, y, obj) {};
return self;
});
// Kiwi class: falling good fruit
var Kiwi = Container.expand(function () {
var self = Container.call(this);
// Attach kiwi asset (ellipse, green)
var kiwiAsset = self.attachAsset('kiwi', {
anchorX: 0.5,
anchorY: 0.5
});
kiwiAsset.width = 100;
kiwiAsset.height = 100;
kiwiAsset.color = 0x7ED957; // green
// Falling speed (will be set on spawn)
self.speed = 8;
// For collision, use the container's bounds
// Update method: move down
self.update = function () {
self.y += self.speed;
};
return self;
});
// RottenFruit class: falling bad fruit
var RottenFruit = Container.expand(function () {
var self = Container.call(this);
// Attach rotten fruit asset (ellipse, purple)
var rottenAsset = self.attachAsset('rotten', {
anchorX: 0.5,
anchorY: 0.5
});
rottenAsset.width = 100;
rottenAsset.height = 100;
rottenAsset.color = 0x7B2F7B; // purple
// Falling speed (will be set on spawn)
self.speed = 8;
// Update method: move down
self.update = function () {
self.y += self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xE3F6FF // light blue
});
/****
* Game Code
****/
// Game area dimensions
var GAME_WIDTH = 2048;
var GAME_HEIGHT = 2732;
// Start music at game start
LK.playMusic('music');
// Score and timer
var score = 0;
var timeLeft = 60; // seconds
// Game speed
var baseSpeed = 8;
var speedIncrease = 0.5; // per 10 seconds
var maxSpeed = 28;
// Arrays for fruits
var kiwis = [];
var rottenFruits = [];
// Basket
var basket = new Basket();
game.addChild(basket);
// Position basket at bottom center
basket.x = GAME_WIDTH / 2;
basket.y = GAME_HEIGHT - 200;
// Score text
var scoreTxt = new Text2('0', {
size: 120,
fill: "#222"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Timer text
var timerTxt = new Text2('30', {
size: 90,
fill: "#222"
});
timerTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(timerTxt);
// Dragging
var dragNode = null;
var dragOffsetX = 0;
// Helper: clamp basket within screen
function clampBasketX(x) {
var halfWidth = basket.width / 2;
if (x < halfWidth) return halfWidth;
if (x > GAME_WIDTH - halfWidth) return GAME_WIDTH - halfWidth;
return x;
}
// Move handler: drag basket horizontally
function handleMove(x, y, obj) {
if (dragNode === basket) {
// Only move horizontally
var newX = clampBasketX(x - dragOffsetX);
basket.x = newX;
}
}
// Down: start dragging if touch is on basket
game.down = function (x, y, obj) {
// Only allow drag if touch is on basket
var local = basket.toLocal(game.toGlobal({
x: x,
y: y
}));
if (local.x >= -basket.width / 2 && local.x <= basket.width / 2 && local.y >= -basket.height / 2 && local.y <= basket.height / 2) {
dragNode = basket;
dragOffsetX = x - basket.x;
}
};
// Up: stop dragging
game.up = function (x, y, obj) {
dragNode = null;
};
// Move: handle dragging
game.move = handleMove;
// Fruit spawn timers
var kiwiSpawnInterval = 40; // frames
var rottenSpawnInterval = 90; // frames
var lastKiwiSpawn = 0;
var lastRottenSpawn = 0;
// Timer for game countdown
var timerInterval = LK.setInterval(function () {
timeLeft -= 1;
if (timeLeft < 0) timeLeft = 0;
timerTxt.setText(timeLeft + '');
if (timeLeft <= 0) {
LK.showGameOver();
}
}, 1000);
// Main game update
game.update = function () {
// Increase speed as time passes
var elapsed = 30 - timeLeft;
var currentSpeed = Math.min(baseSpeed + Math.floor(elapsed / 10) * speedIncrease, maxSpeed);
// Spawn kiwis
if (LK.ticks - lastKiwiSpawn >= kiwiSpawnInterval) {
var kiwi = new Kiwi();
kiwi.x = 150 + Math.random() * (GAME_WIDTH - 300);
kiwi.y = -60;
kiwi.speed = currentSpeed;
kiwis.push(kiwi);
game.addChild(kiwi);
lastKiwiSpawn = LK.ticks;
}
// Spawn rotten fruit
if (LK.ticks - lastRottenSpawn >= rottenSpawnInterval) {
var rotten = new RottenFruit();
rotten.x = 150 + Math.random() * (GAME_WIDTH - 300);
rotten.y = -60;
rotten.speed = currentSpeed + 1.5;
rottenFruits.push(rotten);
game.addChild(rotten);
lastRottenSpawn = LK.ticks;
}
// Update kiwis
for (var i = kiwis.length - 1; i >= 0; i--) {
var kiwi = kiwis[i];
kiwi.update();
// Off screen
if (kiwi.y > GAME_HEIGHT + 80) {
kiwi.destroy();
kiwis.splice(i, 1);
continue;
}
// Collision with basket
if (kiwi.intersects(basket)) {
// Play yummy sound
LK.getSound('yummy').play();
// Score up
score += 1;
scoreTxt.setText(score + '');
LK.setScore(score);
// Win condition: if score reaches 60, show win
if (score >= 60) {
LK.showYouWin();
return;
}
// Flash basket green
LK.effects.flashObject(basket, 0x7ED957, 300);
kiwi.destroy();
kiwis.splice(i, 1);
continue;
}
}
// Update rotten fruits
for (var j = rottenFruits.length - 1; j >= 0; j--) {
var rotten = rottenFruits[j];
rotten.update();
// Off screen
if (rotten.y > GAME_HEIGHT + 80) {
rotten.destroy();
rottenFruits.splice(j, 1);
continue;
}
// Collision with basket
if (rotten.intersects(basket)) {
// Play vomiting sound
LK.getSound('vomiting').play();
// Score down (min 0)
score = Math.max(0, score - 2);
scoreTxt.setText(score + '');
LK.setScore(score);
// Flash basket red
LK.effects.flashObject(basket, 0xB22222, 400);
rotten.destroy();
rottenFruits.splice(j, 1);
continue;
}
}
};
// Clean up timer on game over (handled by LK, but for completeness)
game.onDestroy = function () {
LK.clearInterval(timerInterval);
};