/****
* 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);
};