User prompt
You should also write the scores of other players on the end-game screen.
User prompt
game hangs
User prompt
add this to the game
User prompt
Don't burn the character when hitting the edges
User prompt
the game lags a lot
User prompt
The character gives an error after a certain point, please fix it
User prompt
Health bar decreases when bomb hits
User prompt
add health bar
User prompt
add user-friendly gameplay elements
User prompt
add sound to game
User prompt
Add different fruits that give beautiful features
User prompt
try again
User prompt
fixed
User prompt
fix please
User prompt
Adjust the falling of stones according to human reflexes
User prompt
Basket does not work after a certain point
User prompt
Let the background be a nice 2d background
User prompt
add a lot of features add at least 10 features
User prompt
add different features
User prompt
diğer kullanıcıların puanlarınında olduğu bir tablo olmalı
User prompt
liderlik tablosunu oyunun sonunda göster
User prompt
add leaderboard
User prompt
Please fix the bug: 'Timeout.tick error: LK.showLeaderBoard is not a function' in or related to this line: 'LK.showLeaderBoard();' Line Number: 423
User prompt
Please fix the bug: 'Timeout.tick error: LK.showLeaderboard is not a function' in or related to this line: 'LK.showLeaderboard();' Line Number: 372
User prompt
add something for competition
/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
/**** 
* Classes
****/ 
// Fruit: Apple (extra points)
var Apple = Container.expand(function () {
	var self = Container.call(this);
	var appleAsset = self.attachAsset('ball', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	appleAsset.tint = 0xff2222; // Red
	appleAsset.scaleX = 1.1;
	appleAsset.scaleY = 1.1;
	tween(appleAsset, {
		alpha: 0.85
	}, {
		duration: 350,
		yoyo: true,
		repeat: Infinity,
		easing: tween.easeInOut
	});
	var baseSpeed = 10 + Math.random() * 3;
	if (typeof LK !== "undefined" && typeof LK.getScore === "function") {
		baseSpeed += Math.min(8, Math.floor(LK.getScore() / 12));
	}
	self.speed = baseSpeed;
	self.type = "apple";
	self.update = function () {
		self.y += self.speed;
	};
	return self;
});
// Ball class
var Ball = Container.expand(function () {
	var self = Container.call(this);
	var ballAsset = self.attachAsset('ball', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Neon color palette for balls
	var colors = [0x00ffff, 0xff00ff, 0xffff00, 0x00ff00, 0xff8800, 0x00ffea, 0xff0088];
	ballAsset.color = colors[Math.floor(Math.random() * colors.length)];
	ballAsset.tint = ballAsset.color;
	// Neon glow effect: animate alpha for a pulsing glow
	tween(ballAsset, {
		alpha: 0.7
	}, {
		duration: 400,
		yoyo: true,
		repeat: Infinity,
		easing: tween.easeInOut
	});
	// Adjusted for human reflexes: start slower, increase with score, cap max speed
	var baseSpeed = 10 + Math.random() * 4;
	if (typeof LK !== "undefined" && typeof LK.getScore === "function") {
		baseSpeed += Math.min(10, Math.floor(LK.getScore() / 8)); // increase 1 per 8 points, max +10
	}
	self.speed = baseSpeed;
	self.vx = (Math.random() - 0.5) * 10; // random horizontal speed
	self.update = function () {
		self.y += self.speed;
		self.x += self.vx;
		// Bounce off left/right walls
		if (self.x < 60 && self.vx < 0) {
			self.x = 60;
			self.vx *= -1;
		}
		if (self.x > 2048 - 60 && self.vx > 0) {
			self.x = 2048 - 60;
			self.vx *= -1;
		}
	};
	return self;
});
// Fruit: Banana (wider catch area)
var Banana = Container.expand(function () {
	var self = Container.call(this);
	var bananaAsset = self.attachAsset('ball', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	bananaAsset.tint = 0xfff700; // Yellow
	bananaAsset.scaleX = 1.5;
	bananaAsset.scaleY = 0.8;
	tween(bananaAsset, {
		alpha: 0.8
	}, {
		duration: 400,
		yoyo: true,
		repeat: Infinity,
		easing: tween.easeInOut
	});
	var baseSpeed = 9 + Math.random() * 2;
	if (typeof LK !== "undefined" && typeof LK.getScore === "function") {
		baseSpeed += Math.min(7, Math.floor(LK.getScore() / 14));
	}
	self.speed = baseSpeed;
	self.type = "banana";
	self.update = function () {
		self.y += self.speed;
	};
	return self;
});
// Basket class
var Basket = Container.expand(function () {
	var self = Container.call(this);
	var basketAsset = self.attachAsset('basket', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Neon basket: random neon color and glow
	var basketColors = [0x00ffff, 0xff00ff, 0xffff00, 0x00ff00, 0xff8800, 0x00ffea, 0xff0088];
	basketAsset.tint = basketColors[Math.floor(Math.random() * basketColors.length)];
	tween(basketAsset, {
		alpha: 0.7
	}, {
		duration: 600,
		yoyo: true,
		repeat: Infinity,
		easing: tween.easeInOut
	});
	return self;
});
// Bomb class
var Bomb = Container.expand(function () {
	var self = Container.call(this);
	var bombAsset = self.attachAsset('bomb', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Neon bomb: magenta or cyan
	var bombColors = [0xff00ff, 0x00ffff, 0xffff00];
	bombAsset.tint = bombColors[Math.floor(Math.random() * bombColors.length)];
	tween(bombAsset, {
		alpha: 0.6
	}, {
		duration: 400,
		yoyo: true,
		repeat: Infinity,
		easing: tween.easeInOut
	});
	// Adjusted for human reflexes: start slower, increase with score, cap max speed
	var baseBombSpeed = 12 + Math.random() * 5;
	if (typeof LK !== "undefined" && typeof LK.getScore === "function") {
		baseBombSpeed += Math.min(12, Math.floor(LK.getScore() / 7)); // increase 1 per 7 points, max +12
	}
	self.speed = baseBombSpeed;
	self.update = function () {
		self.y += self.speed;
	};
	return self;
});
// Fruit: Grape (slows bombs for a short time)
var Grape = Container.expand(function () {
	var self = Container.call(this);
	var grapeAsset = self.attachAsset('ball', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	grapeAsset.tint = 0x9900ff; // Purple
	grapeAsset.scaleX = 1.0;
	grapeAsset.scaleY = 1.0;
	tween(grapeAsset, {
		alpha: 0.7
	}, {
		duration: 300,
		yoyo: true,
		repeat: Infinity,
		easing: tween.easeInOut
	});
	var baseSpeed = 11 + Math.random() * 2;
	if (typeof LK !== "undefined" && typeof LK.getScore === "function") {
		baseSpeed += Math.min(7, Math.floor(LK.getScore() / 13));
	}
	self.speed = baseSpeed;
	self.type = "grape";
	self.update = function () {
		self.y += self.speed;
	};
	return self;
});
// PowerUp class (neon star)
var PowerUp = Container.expand(function () {
	var self = Container.call(this);
	// Use a ball asset for now, but tint and scale to look like a power-up
	var starAsset = self.attachAsset('ball', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Neon star color
	var starColors = [0xFFD700, 0x00ffea, 0xff00ff, 0x00ff00];
	starAsset.tint = starColors[Math.floor(Math.random() * starColors.length)];
	starAsset.scaleX = 1.3;
	starAsset.scaleY = 1.3;
	// Animate alpha for a pulsing glow
	tween(starAsset, {
		alpha: 0.8
	}, {
		duration: 300,
		yoyo: true,
		repeat: Infinity,
		easing: tween.easeInOut
	});
	// Adjusted for human reflexes: start slower, increase with score, cap max speed
	var basePowerSpeed = 9 + Math.random() * 3;
	if (typeof LK !== "undefined" && typeof LK.getScore === "function") {
		basePowerSpeed += Math.min(8, Math.floor(LK.getScore() / 10)); // increase 1 per 10 points, max +8
	}
	self.speed = basePowerSpeed;
	self.type = "score"; // default type
	self.update = function () {
		self.y += self.speed;
	};
	return self;
});
// ShieldPowerUp class (neon blue ring)
var ShieldPowerUp = Container.expand(function () {
	var self = Container.call(this);
	var shieldAsset = self.attachAsset('ball', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	shieldAsset.tint = 0x00ffff;
	shieldAsset.scaleX = 1.5;
	shieldAsset.scaleY = 1.5;
	tween(shieldAsset, {
		alpha: 0.6
	}, {
		duration: 200,
		yoyo: true,
		repeat: Infinity,
		easing: tween.easeInOut
	});
	// Adjusted for human reflexes: start slower, increase with score, cap max speed
	var baseShieldSpeed = 8 + Math.random() * 2;
	if (typeof LK !== "undefined" && typeof LK.getScore === "function") {
		baseShieldSpeed += Math.min(7, Math.floor(LK.getScore() / 12)); // increase 1 per 12 points, max +7
	}
	self.speed = baseShieldSpeed;
	self.type = "shield";
	self.update = function () {
		self.y += self.speed;
	};
	return self;
});
// Fruit: Watermelon (big, gives shield)
var Watermelon = Container.expand(function () {
	var self = Container.call(this);
	var melonAsset = self.attachAsset('ball', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	melonAsset.tint = 0x22ff44; // Green
	melonAsset.scaleX = 1.7;
	melonAsset.scaleY = 1.3;
	tween(melonAsset, {
		alpha: 0.8
	}, {
		duration: 500,
		yoyo: true,
		repeat: Infinity,
		easing: tween.easeInOut
	});
	var baseSpeed = 8 + Math.random() * 2;
	if (typeof LK !== "undefined" && typeof LK.getScore === "function") {
		baseSpeed += Math.min(6, Math.floor(LK.getScore() / 15));
	}
	self.speed = baseSpeed;
	self.type = "watermelon";
	self.update = function () {
		self.y += self.speed;
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x000000
});
/**** 
* Game Code
****/ 
// No background image, only black background
// No background image, only black background
// Game area: 2048x2732
// Basket: wide rectangle
// Ball: colored ellipse
// Bomb: black ellipse
// Sound for catching a ball
// Sound for catching a bomb
// Sound for missing a ball
game.setBackgroundColor(0x000000);
// Neon-style game objective text at the start (small, English, subtle neon)
var objectiveTxt = new Text2('Goal: Catch the balls, avoid the bombs!', {
	size: 54,
	// smaller text
	fill: 0x00ffff,
	stroke: 0x222222,
	strokeThickness: 8,
	dropShadow: true,
	dropShadowColor: 0x00ffff,
	dropShadowBlur: 12,
	dropShadowDistance: 0,
	align: "center"
});
objectiveTxt.anchor.set(0.5, 0);
objectiveTxt.y = 90;
LK.gui.top.addChild(objectiveTxt);
// Add leaderboard button for competition
var leaderboardBtn = new Text2('🏆 Leaderboard', {
	size: 60,
	fill: 0xFFD700,
	stroke: 0x00ffff,
	strokeThickness: 8,
	dropShadow: true,
	dropShadowColor: 0xFFD700,
	dropShadowBlur: 10,
	dropShadowDistance: 0,
	align: "center"
});
leaderboardBtn.anchor.set(0.5, 0);
leaderboardBtn.x = 2048 - 250;
leaderboardBtn.y = 90;
leaderboardBtn.interactive = true;
leaderboardBtn.buttonMode = true;
leaderboardBtn.down = function () {
	if (typeof LK.showLeaderboard === "function") {
		LK.showLeaderboard();
	}
};
LK.gui.top.addChild(leaderboardBtn);
// Hide objective after 2.5 seconds
LK.setTimeout(function () {
	objectiveTxt.visible = false;
}, 2500);
// Score text
var scoreTxt = new Text2('0', {
	size: 120,
	fill: 0x00FFEA,
	stroke: 0xFF00FF,
	strokeThickness: 18,
	dropShadow: true,
	dropShadowColor: 0x00FFFF,
	dropShadowBlur: 24,
	dropShadowDistance: 0,
	align: "center"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Misses text (shows "Missed!" when a ball is missed)
var missTxt = new Text2('', {
	size: 90,
	fill: 0x00FFFF,
	stroke: 0xFF00FF,
	strokeThickness: 14,
	dropShadow: true,
	dropShadowColor: 0x00FFFF,
	dropShadowBlur: 18,
	dropShadowDistance: 0,
	align: "center"
});
missTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(missTxt);
missTxt.visible = false;
// Basket
var basket = new Basket();
game.addChild(basket);
basket.y = 2732 - 180;
basket.x = 2048 / 2;
// Ball, bomb, and power-up arrays
var balls = [];
var bombs = [];
var powerups = [];
// Dragging
var dragNode = null;
// Spawning control
var spawnTimer = 0;
var spawnInterval = 55; // frames between spawns, will decrease as score increases
// State
var lastScore = 0;
var gameOver = false;
// Combo scoring
var comboCount = 0;
var comboTimeout = null;
var comboTxt = new Text2('', {
	size: 80,
	fill: 0xFFD700,
	stroke: 0x00ffff,
	strokeThickness: 10,
	dropShadow: true,
	dropShadowColor: 0xFFD700,
	dropShadowBlur: 12,
	dropShadowDistance: 0,
	align: "center"
});
comboTxt.anchor.set(0.5, 0);
comboTxt.y = 200;
comboTxt.visible = false;
LK.gui.top.addChild(comboTxt);
// Helper: spawn a ball, bomb, or power-up
function spawnFallingObject() {
	// 80% ball, 20% bomb, 5% power-up, 3% shield power-up, plus fruits
	var rand = Math.random();
	var x = 150 + Math.random() * (2048 - 300);
	if (rand < 0.10) {
		var bomb = new Bomb();
		bomb.x = x;
		bomb.y = -60;
		bomb.lastIntersecting = false;
		bombs.push(bomb);
		game.addChild(bomb);
	} else if (rand < 0.13) {
		// 3% chance for super bomb
		var superBomb = new Bomb();
		superBomb.x = x;
		superBomb.y = -60;
		superBomb.lastIntersecting = false;
		superBomb.isSuper = true;
		if (superBomb.children && superBomb.children.length > 0) {
			superBomb.children[0].tint = 0xffffff;
		}
		bombs.push(superBomb);
		game.addChild(superBomb);
	} else if (rand > 0.98) {
		// 2% chance for slow motion power-up
		var slowPower = new PowerUp();
		slowPower.x = x;
		slowPower.y = -60;
		slowPower.lastIntersecting = false;
		slowPower.type = "slow";
		if (slowPower.children && slowPower.children.length > 0) {
			slowPower.children[0].tint = 0x3b6eea;
		}
		powerups.push(slowPower);
		game.addChild(slowPower);
	} else if (rand > 0.96) {
		// 4% chance for shield power-up
		var shield = new ShieldPowerUp();
		shield.x = x;
		shield.y = -60;
		shield.lastIntersecting = false;
		powerups.push(shield);
		game.addChild(shield);
	} else if (rand > 0.94) {
		// 2% chance for score power-up
		var powerup = new PowerUp();
		powerup.x = x;
		powerup.y = -60;
		powerup.lastIntersecting = false;
		powerups.push(powerup);
		game.addChild(powerup);
	} else if (rand > 0.92) {
		// 2% chance for Watermelon (shield fruit)
		var watermelon = new Watermelon();
		watermelon.x = x;
		watermelon.y = -60;
		watermelon.lastIntersecting = false;
		powerups.push(watermelon);
		game.addChild(watermelon);
	} else if (rand > 0.89) {
		// 3% chance for Grape (slows bombs)
		var grape = new Grape();
		grape.x = x;
		grape.y = -60;
		grape.lastIntersecting = false;
		powerups.push(grape);
		game.addChild(grape);
	} else if (rand > 0.86) {
		// 3% chance for Banana (wider catch area)
		var banana = new Banana();
		banana.x = x;
		banana.y = -60;
		banana.lastIntersecting = false;
		powerups.push(banana);
		game.addChild(banana);
	} else if (rand > 0.83) {
		// 3% chance for Apple (extra points)
		var apple = new Apple();
		apple.x = x;
		apple.y = -60;
		apple.lastIntersecting = false;
		powerups.push(apple);
		game.addChild(apple);
	} else {
		var ball = new Ball();
		ball.x = x;
		ball.y = -60;
		ball.lastIntersecting = false;
		balls.push(ball);
		game.addChild(ball);
	}
}
// Move handler for dragging basket
function handleMove(x, y, obj) {
	if (dragNode) {
		// Clamp basket within screen
		var halfWidth = dragNode.width / 2;
		var minX = halfWidth;
		var maxX = 2048 - halfWidth;
		dragNode.x = Math.max(minX, Math.min(maxX, x));
	}
}
// Touch/mouse events
game.down = function (x, y, obj) {
	// Allow drag from anywhere in lower 1/3 of screen for easier control
	if (y > 2732 * 2 / 3) {
		dragNode = basket;
		handleMove(x, y, obj);
	}
};
game.move = handleMove;
game.up = function (x, y, obj) {
	dragNode = null;
};
// Main update loop
game.update = function () {
	if (gameOver) return;
	// Change background color at each 5 points (neon palette)
	var neonBgColors = [0x000000, 0x0ff0fc, 0x1a0033, 0x3b6eea, 0x00ffea, 0xff00ff, 0x00ff00, 0xf75e5e, 0xf7c325];
	var score = LK.getScore();
	var bgIndex = Math.floor(score / 5) % neonBgColors.length;
	game.setBackgroundColor(neonBgColors[bgIndex]);
	// Challenge mode: basket moves left/right automatically every 20 points
	if (score > 0 && score % 20 === 0 && !basket.challengeActive) {
		basket.challengeActive = true;
		basket.challengeDir = Math.random() > 0.5 ? 1 : -1;
		basket.challengeTween = tween(basket, {
			x: basket.challengeDir > 0 ? 2048 - basket.width / 2 : basket.width / 2
		}, {
			duration: 2200,
			yoyo: true,
			repeat: 2,
			easing: tween.easeInOut,
			onFinish: function onFinish() {
				basket.challengeActive = false;
			}
		});
	}
	// Spawn balls/bombs
	spawnTimer++;
	// Decrease interval as score increases (min 35 for human reflexes)
	var interval = Math.max(35, spawnInterval - Math.floor(LK.getScore() / 10) * 3);
	if (spawnTimer >= interval) {
		spawnFallingObject();
		spawnTimer = 0;
	}
	// Speed up all balls every 10 points
	if (score > 0 && score % 10 === 0 && !game.lastSpeedupScore) {
		for (var si = 0; si < balls.length; si++) {
			balls[si].speed *= 1.08; // less aggressive speedup for human reflexes
			balls[si].vx *= 1.05;
		}
		game.lastSpeedupScore = score;
	}
	if (score % 10 !== 0) {
		game.lastSpeedupScore = null;
	}
	// Update balls
	for (var i = balls.length - 1; i >= 0; i--) {
		var ball = balls[i];
		if (ball.lastY === undefined) ball.lastY = ball.y;
		if (ball.lastIntersecting === undefined) ball.lastIntersecting = false;
		ball.update();
		// Check for catch
		var intersecting = ball.intersects(basket);
		if (!ball.lastIntersecting && intersecting) {
			// Caught!
			// Combo logic
			comboCount++;
			if (comboTimeout) {
				LK.clearTimeout(comboTimeout);
				comboTimeout = null;
			}
			if (comboCount > 1) {
				comboTxt.setText('Combo x' + comboCount + '!');
				comboTxt.visible = true;
				// Animate combo text
				comboTxt.alpha = 1;
				tween(comboTxt, {
					alpha: 0
				}, {
					duration: 900,
					onFinish: function onFinish() {
						comboTxt.visible = false;
					}
				});
			}
			// Combo bonus: +1 for first, +2 for 2nd, +3 for 3rd, etc.
			var comboBonus = comboCount > 1 ? comboCount : 1;
			LK.setScore(LK.getScore() + comboBonus);
			// Streak bonus: every 5 consecutive catches, +10 bonus
			if (comboCount > 0 && comboCount % 5 === 0) {
				LK.setScore(LK.getScore() + 10);
				// Show streak bonus text
				comboTxt.setText('Streak! +10');
				comboTxt.visible = true;
				comboTxt.alpha = 1;
				tween(comboTxt, {
					alpha: 0
				}, {
					duration: 900,
					onFinish: function onFinish() {
						comboTxt.visible = false;
					}
				});
			}
			// Edge catch bonus: if ball is caught at the left/right 20% of basket
			var basketLeft = basket.x - basket.width / 2;
			var basketRight = basket.x + basket.width / 2;
			if (ball.x < basketLeft + basket.width * 0.2 || ball.x > basketRight - basket.width * 0.2) {
				LK.setScore(LK.getScore() + 3);
				comboTxt.setText('Edge Catch! +3');
				comboTxt.visible = true;
				comboTxt.alpha = 1;
				tween(comboTxt, {
					alpha: 0
				}, {
					duration: 900,
					onFinish: function onFinish() {
						comboTxt.visible = false;
					}
				});
			}
			scoreTxt.setText(LK.getScore());
			LK.getSound('catch').play();
			// Flash screen with a random color for fun
			var flashColors = [0x4ad991, 0xf75e5e, 0x3b6eea, 0xf7a325, 0xFFD700];
			LK.effects.flashScreen(flashColors[Math.floor(Math.random() * flashColors.length)], 200);
			// Animate ball to basket and fade out
			LK.effects.flashObject(basket, 0x4ad991, 200); // Flash basket green
			tween(ball, {
				y: basket.y,
				alpha: 0
			}, {
				duration: 200,
				easing: tween.easeIn,
				onFinish: function onFinish() {
					ball.destroy();
				}
			});
			balls.splice(i, 1);
			// Reset combo if no catch in 1.2s
			comboTimeout = LK.setTimeout(function () {
				comboCount = 0;
				comboTxt.visible = false;
				comboTimeout = null;
			}, 1200);
			continue;
		}
		// Missed (goes below basket)
		if (ball.lastY < 2732 && ball.y >= 2732 - 80) {
			// Missed!
			LK.getSound('miss').play();
			missTxt.setText('Missed!');
			missTxt.visible = true;
			// Reset combo
			comboCount = 0;
			if (comboTimeout) {
				LK.clearTimeout(comboTimeout);
				comboTimeout = null;
			}
			comboTxt.visible = false;
			// Flash screen
			LK.effects.flashScreen(0xff0000, 600);
			// Miss forgiveness: first miss does not end game
			if (!game.missForgiven) {
				game.missForgiven = true;
				missTxt.setText('Forgiven! Next miss ends game.');
				missTxt.visible = true;
				if (missTxt.hideTimeout) {
					LK.clearTimeout(missTxt.hideTimeout);
					missTxt.hideTimeout = null;
				}
				missTxt.hideTimeout = LK.setTimeout(function () {
					missTxt.visible = false;
					missTxt.hideTimeout = null;
				}, 1200);
				// Remove ball and continue
				ball.destroy();
				balls.splice(i, 1);
				continue;
			}
			// End game after short delay
			LK.setTimeout(function () {
				LK.showGameOver();
				if (typeof LK.showLeaderboard === "function") {
					LK.showLeaderboard({
						showOthers: true
					}); // Show leaderboard with other users' scores
				}
			}, 600);
			gameOver = true;
			return;
		}
		// Off screen (cleanup)
		if (ball.y > 2800) {
			ball.destroy();
			balls.splice(i, 1);
			continue;
		}
		ball.lastY = ball.y;
		ball.lastIntersecting = intersecting;
	}
	// Update bombs
	for (var j = bombs.length - 1; j >= 0; j--) {
		var bomb = bombs[j];
		if (bomb.lastY === undefined) bomb.lastY = bomb.y;
		if (bomb.lastIntersecting === undefined) bomb.lastIntersecting = false;
		bomb.update();
		// Check for catch
		var intersecting = bomb.intersects(basket);
		if (!bomb.lastIntersecting && intersecting) {
			if (basket.hasShield) {
				// Consume shield, no game over
				basket.hasShield = false;
				// Remove shield visual effect if present
				if (basket.shieldTween) {
					basket.shieldTween.stop();
					basket.shieldTween = null;
				}
				LK.effects.flashObject(basket, 0x00ffff, 400);
				LK.effects.flashScreen(0x00ffff, 200);
				// Super bomb: clear all balls and give bonus
				if (bomb.isSuper) {
					for (var bi = balls.length - 1; bi >= 0; bi--) {
						balls[bi].destroy();
						balls.splice(bi, 1);
					}
					LK.setScore(LK.getScore() + 15);
					scoreTxt.setText(LK.getScore());
					missTxt.setText('Super Bomb! Cleared!');
					missTxt.visible = true;
					if (missTxt.hideTimeout) {
						LK.clearTimeout(missTxt.hideTimeout);
						missTxt.hideTimeout = null;
					}
					missTxt.hideTimeout = LK.setTimeout(function () {
						missTxt.visible = false;
						missTxt.hideTimeout = null;
					}, 1200);
				}
				// Destroy bomb
				bomb.destroy();
				bombs.splice(j, 1);
				continue;
			}
			// Caught bomb: game over
			LK.getSound('boom').play();
			// Flash basket red
			LK.effects.flashObject(basket, 0xff0000, 600);
			// Reset combo
			comboCount = 0;
			if (comboTimeout) {
				LK.clearTimeout(comboTimeout);
				comboTimeout = null;
			}
			comboTxt.visible = false;
			// Flash screen
			LK.effects.flashScreen(0x000000, 600);
			// End game after short delay
			LK.setTimeout(function () {
				LK.showGameOver();
				if (typeof LK.showLeaderboard === "function") {
					LK.showLeaderboard({
						showOthers: true
					}); // Show leaderboard with other users' scores
				}
			}, 600);
			gameOver = true;
			return;
		}
		// Off screen (cleanup)
		if (bomb.y > 2800) {
			bomb.destroy();
			bombs.splice(j, 1);
			continue;
		}
		bomb.lastY = bomb.y;
		bomb.lastIntersecting = intersecting;
	}
	// Update power-ups
	for (var k = powerups.length - 1; k >= 0; k--) {
		var powerup = powerups[k];
		if (powerup.lastY === undefined) powerup.lastY = powerup.y;
		if (powerup.lastIntersecting === undefined) powerup.lastIntersecting = false;
		powerup.update();
		// Check for catch
		var intersecting = powerup.intersects(basket);
		if (!powerup.lastIntersecting && intersecting) {
			if (powerup.type === "shield" || powerup instanceof ShieldPowerUp || powerup instanceof Watermelon) {
				// Caught shield or watermelon: activate shield
				basket.hasShield = true;
				LK.effects.flashObject(basket, 0x00ffff, 400);
				LK.effects.flashScreen(0x00ffff, 200);
				if (!basket.shieldTween) {
					basket.shieldTween = tween(basket, {
						alpha: 1
					}, {
						duration: 200,
						yoyo: true,
						repeat: Infinity,
						easing: tween.easeInOut
					});
				}
				// Animate power-up to basket and fade out
				tween(powerup, {
					y: basket.y,
					alpha: 0
				}, {
					duration: 200,
					easing: tween.easeIn,
					onFinish: function onFinish() {
						powerup.destroy();
					}
				});
				powerups.splice(k, 1);
				continue;
			} else if (powerup.type === "slow" || powerup instanceof Grape) {
				// Slow motion: slow all falling objects for 3 seconds
				for (var bi = 0; bi < balls.length; bi++) {
					balls[bi].speed *= 0.4;
					balls[bi].vx *= 0.4;
				}
				for (var bj = 0; bj < bombs.length; bj++) {
					bombs[bj].speed *= 0.4;
				}
				for (var bp = 0; bp < powerups.length; bp++) {
					powerups[bp].speed *= 0.4;
				}
				missTxt.setText('Slow Motion!');
				missTxt.visible = true;
				if (missTxt.hideTimeout) {
					LK.clearTimeout(missTxt.hideTimeout);
					missTxt.hideTimeout = null;
				}
				missTxt.hideTimeout = LK.setTimeout(function () {
					missTxt.visible = false;
					missTxt.hideTimeout = null;
				}, 1200);
				// Restore speed after 3 seconds
				LK.setTimeout(function () {
					for (var bi = 0; bi < balls.length; bi++) {
						balls[bi].speed /= 0.4;
						balls[bi].vx /= 0.4;
					}
					for (var bj = 0; bj < bombs.length; bj++) {
						bombs[bj].speed /= 0.4;
					}
					for (var bp = 0; bp < powerups.length; bp++) {
						powerups[bp].speed /= 0.4;
					}
				}, 3000);
				// Animate power-up to basket and fade out
				tween(powerup, {
					y: basket.y,
					alpha: 0
				}, {
					duration: 200,
					easing: tween.easeIn,
					onFinish: function onFinish() {
						powerup.destroy();
					}
				});
				powerups.splice(k, 1);
				continue;
			} else if (powerup.type === "banana" || powerup instanceof Banana) {
				// Banana: temporarily widen basket for 4 seconds
				var originalScale = basket.scaleX || 1;
				basket.scaleX = originalScale * 1.5;
				basket.scaleY = (basket.scaleY || 1) * 1.1;
				LK.effects.flashObject(basket, 0xfff700, 300);
				missTxt.setText('Wide Basket!');
				missTxt.visible = true;
				if (missTxt.hideTimeout) {
					LK.clearTimeout(missTxt.hideTimeout);
					missTxt.hideTimeout = null;
				}
				missTxt.hideTimeout = LK.setTimeout(function () {
					missTxt.visible = false;
					missTxt.hideTimeout = null;
				}, 1200);
				LK.setTimeout(function () {
					basket.scaleX = originalScale;
					basket.scaleY = 1;
				}, 4000);
				tween(powerup, {
					y: basket.y,
					alpha: 0
				}, {
					duration: 200,
					easing: tween.easeIn,
					onFinish: function onFinish() {
						powerup.destroy();
					}
				});
				powerups.splice(k, 1);
				continue;
			} else if (powerup.type === "apple" || powerup instanceof Apple) {
				// Apple: +5 points, flash red
				LK.setScore(LK.getScore() + 5);
				scoreTxt.setText(LK.getScore());
				LK.getSound('catch').play();
				LK.effects.flashScreen(0xff2222, 350);
				LK.effects.flashObject(basket, 0xff2222, 300);
				missTxt.setText('Apple! +5');
				missTxt.visible = true;
				if (missTxt.hideTimeout) {
					LK.clearTimeout(missTxt.hideTimeout);
					missTxt.hideTimeout = null;
				}
				missTxt.hideTimeout = LK.setTimeout(function () {
					missTxt.visible = false;
					missTxt.hideTimeout = null;
				}, 1200);
				tween(powerup, {
					y: basket.y,
					alpha: 0
				}, {
					duration: 200,
					easing: tween.easeIn,
					onFinish: function onFinish() {
						powerup.destroy();
					}
				});
				powerups.splice(k, 1);
				continue;
			} else {
				// Caught score power-up: double points!
				LK.setScore(LK.getScore() + 2);
				scoreTxt.setText(LK.getScore());
				LK.getSound('catch').play();
				LK.effects.flashScreen(0xFFD700, 350);
				LK.effects.flashObject(basket, 0xFFD700, 300);
				tween(powerup, {
					y: basket.y,
					alpha: 0
				}, {
					duration: 200,
					easing: tween.easeIn,
					onFinish: function onFinish() {
						powerup.destroy();
					}
				});
				powerups.splice(k, 1);
				continue;
			}
		}
		// Off screen (cleanup)
		if (powerup.y > 2800) {
			powerup.destroy();
			powerups.splice(k, 1);
			continue;
		}
		powerup.lastY = powerup.y;
		powerup.lastIntersecting = intersecting;
	}
	// Hide miss text after a short time
	if (missTxt.visible) {
		if (!missTxt.hideTimeout) {
			missTxt.hideTimeout = LK.setTimeout(function () {
				missTxt.visible = false;
				missTxt.hideTimeout = null;
			}, 900);
		}
	}
	// Draw shield icon above basket if shield is active
	if (basket.hasShield) {
		if (!basket.shieldIcon) {
			basket.shieldIcon = LK.getAsset('ball', {
				anchorX: 0.5,
				anchorY: 0.5
			});
			basket.shieldIcon.tint = 0x00ffff;
			basket.shieldIcon.scaleX = 0.5;
			basket.shieldIcon.scaleY = 0.5;
			game.addChild(basket.shieldIcon);
		}
		basket.shieldIcon.x = basket.x;
		basket.shieldIcon.y = basket.y - 70;
		basket.shieldIcon.visible = true;
	} else if (basket.shieldIcon) {
		basket.shieldIcon.visible = false;
	}
	// Rainbow basket after 40 points
	if (LK.getScore() >= 40 && basket.children && basket.children.length > 0) {
		var t = LK.ticks % 60 / 60;
		var r = Math.floor(127 * Math.sin(2 * Math.PI * t) + 128);
		var g = Math.floor(127 * Math.sin(2 * Math.PI * t + 2) + 128);
		var b = Math.floor(127 * Math.sin(2 * Math.PI * t + 4) + 128);
		basket.children[0].tint = r << 16 | g << 8 | b;
	}
};
// Reset state on new game
LK.on('gameStart', function () {
	// Remove all balls, bombs, and powerups
	for (var i = 0; i < balls.length; i++) balls[i].destroy();
	for (var j = 0; j < bombs.length; j++) bombs[j].destroy();
	for (var k = 0; k < powerups.length; k++) powerups[k].destroy();
	balls = [];
	bombs = [];
	powerups = [];
	basket.x = 2048 / 2;
	basket.y = 2732 - 180;
	// Reset challenge mode state
	basket.challengeActive = false;
	basket.challengeDir = null;
	if (basket.challengeTween) {
		basket.challengeTween.stop();
		basket.challengeTween = null;
	}
	// Reset shield state
	basket.hasShield = false;
	if (basket.shieldTween) {
		basket.shieldTween.stop();
		basket.shieldTween = null;
	}
	// Randomize basket color on new game
	var basketColors = [0x3b6eea, 0x4ad991, 0xf75e5e, 0xf7a325, 0xFFD700];
	if (basket.children && basket.children.length > 0) {
		basket.children[0].tint = basketColors[Math.floor(Math.random() * basketColors.length)];
	}
	LK.setScore(0);
	scoreTxt.setText('0');
	missTxt.setText('');
	missTxt.visible = false;
	if (missTxt.hideTimeout) {
		LK.clearTimeout(missTxt.hideTimeout);
		missTxt.hideTimeout = null;
	}
	spawnTimer = 0;
	gameOver = false;
	game.missForgiven = false;
	// Reset combo
	comboCount = 0;
	if (comboTimeout) {
		LK.clearTimeout(comboTimeout);
		comboTimeout = null;
	}
	comboTxt.visible = false;
}); ===================================================================
--- original.js
+++ change.js
@@ -5,8 +5,37 @@
 
 /**** 
 * Classes
 ****/ 
+// Fruit: Apple (extra points)
+var Apple = Container.expand(function () {
+	var self = Container.call(this);
+	var appleAsset = self.attachAsset('ball', {
+		anchorX: 0.5,
+		anchorY: 0.5
+	});
+	appleAsset.tint = 0xff2222; // Red
+	appleAsset.scaleX = 1.1;
+	appleAsset.scaleY = 1.1;
+	tween(appleAsset, {
+		alpha: 0.85
+	}, {
+		duration: 350,
+		yoyo: true,
+		repeat: Infinity,
+		easing: tween.easeInOut
+	});
+	var baseSpeed = 10 + Math.random() * 3;
+	if (typeof LK !== "undefined" && typeof LK.getScore === "function") {
+		baseSpeed += Math.min(8, Math.floor(LK.getScore() / 12));
+	}
+	self.speed = baseSpeed;
+	self.type = "apple";
+	self.update = function () {
+		self.y += self.speed;
+	};
+	return self;
+});
 // Ball class
 var Ball = Container.expand(function () {
 	var self = Container.call(this);
 	var ballAsset = self.attachAsset('ball', {
@@ -47,8 +76,37 @@
 		}
 	};
 	return self;
 });
+// Fruit: Banana (wider catch area)
+var Banana = Container.expand(function () {
+	var self = Container.call(this);
+	var bananaAsset = self.attachAsset('ball', {
+		anchorX: 0.5,
+		anchorY: 0.5
+	});
+	bananaAsset.tint = 0xfff700; // Yellow
+	bananaAsset.scaleX = 1.5;
+	bananaAsset.scaleY = 0.8;
+	tween(bananaAsset, {
+		alpha: 0.8
+	}, {
+		duration: 400,
+		yoyo: true,
+		repeat: Infinity,
+		easing: tween.easeInOut
+	});
+	var baseSpeed = 9 + Math.random() * 2;
+	if (typeof LK !== "undefined" && typeof LK.getScore === "function") {
+		baseSpeed += Math.min(7, Math.floor(LK.getScore() / 14));
+	}
+	self.speed = baseSpeed;
+	self.type = "banana";
+	self.update = function () {
+		self.y += self.speed;
+	};
+	return self;
+});
 // Basket class
 var Basket = Container.expand(function () {
 	var self = Container.call(this);
 	var basketAsset = self.attachAsset('basket', {
@@ -96,8 +154,37 @@
 		self.y += self.speed;
 	};
 	return self;
 });
+// Fruit: Grape (slows bombs for a short time)
+var Grape = Container.expand(function () {
+	var self = Container.call(this);
+	var grapeAsset = self.attachAsset('ball', {
+		anchorX: 0.5,
+		anchorY: 0.5
+	});
+	grapeAsset.tint = 0x9900ff; // Purple
+	grapeAsset.scaleX = 1.0;
+	grapeAsset.scaleY = 1.0;
+	tween(grapeAsset, {
+		alpha: 0.7
+	}, {
+		duration: 300,
+		yoyo: true,
+		repeat: Infinity,
+		easing: tween.easeInOut
+	});
+	var baseSpeed = 11 + Math.random() * 2;
+	if (typeof LK !== "undefined" && typeof LK.getScore === "function") {
+		baseSpeed += Math.min(7, Math.floor(LK.getScore() / 13));
+	}
+	self.speed = baseSpeed;
+	self.type = "grape";
+	self.update = function () {
+		self.y += self.speed;
+	};
+	return self;
+});
 // PowerUp class (neon star)
 var PowerUp = Container.expand(function () {
 	var self = Container.call(this);
 	// Use a ball asset for now, but tint and scale to look like a power-up
@@ -160,8 +247,37 @@
 		self.y += self.speed;
 	};
 	return self;
 });
+// Fruit: Watermelon (big, gives shield)
+var Watermelon = Container.expand(function () {
+	var self = Container.call(this);
+	var melonAsset = self.attachAsset('ball', {
+		anchorX: 0.5,
+		anchorY: 0.5
+	});
+	melonAsset.tint = 0x22ff44; // Green
+	melonAsset.scaleX = 1.7;
+	melonAsset.scaleY = 1.3;
+	tween(melonAsset, {
+		alpha: 0.8
+	}, {
+		duration: 500,
+		yoyo: true,
+		repeat: Infinity,
+		easing: tween.easeInOut
+	});
+	var baseSpeed = 8 + Math.random() * 2;
+	if (typeof LK !== "undefined" && typeof LK.getScore === "function") {
+		baseSpeed += Math.min(6, Math.floor(LK.getScore() / 15));
+	}
+	self.speed = baseSpeed;
+	self.type = "watermelon";
+	self.update = function () {
+		self.y += self.speed;
+	};
+	return self;
+});
 
 /**** 
 * Initialize Game
 ****/ 
@@ -290,60 +406,90 @@
 comboTxt.visible = false;
 LK.gui.top.addChild(comboTxt);
 // Helper: spawn a ball, bomb, or power-up
 function spawnFallingObject() {
-	// 80% ball, 20% bomb, 5% power-up, 3% shield power-up
+	// 80% ball, 20% bomb, 5% power-up, 3% shield power-up, plus fruits
 	var rand = Math.random();
 	var x = 150 + Math.random() * (2048 - 300);
-	if (rand < 0.15) {
+	if (rand < 0.10) {
 		var bomb = new Bomb();
 		bomb.x = x;
 		bomb.y = -60;
 		bomb.lastIntersecting = false;
 		bombs.push(bomb);
 		game.addChild(bomb);
-	} else if (rand < 0.2) {
-		// 5% chance for super bomb
+	} else if (rand < 0.13) {
+		// 3% chance for super bomb
 		var superBomb = new Bomb();
 		superBomb.x = x;
 		superBomb.y = -60;
 		superBomb.lastIntersecting = false;
 		superBomb.isSuper = true;
-		// Tint super bomb white
 		if (superBomb.children && superBomb.children.length > 0) {
 			superBomb.children[0].tint = 0xffffff;
 		}
 		bombs.push(superBomb);
 		game.addChild(superBomb);
-	} else if (rand > 0.97) {
-		// 1.5% chance for slow motion power-up
+	} else if (rand > 0.98) {
+		// 2% chance for slow motion power-up
 		var slowPower = new PowerUp();
 		slowPower.x = x;
 		slowPower.y = -60;
 		slowPower.lastIntersecting = false;
 		slowPower.type = "slow";
-		// Tint blue
 		if (slowPower.children && slowPower.children.length > 0) {
 			slowPower.children[0].tint = 0x3b6eea;
 		}
 		powerups.push(slowPower);
 		game.addChild(slowPower);
-	} else if (rand > 0.95) {
-		// 3% chance for shield power-up
+	} else if (rand > 0.96) {
+		// 4% chance for shield power-up
 		var shield = new ShieldPowerUp();
 		shield.x = x;
 		shield.y = -60;
 		shield.lastIntersecting = false;
 		powerups.push(shield);
 		game.addChild(shield);
-	} else if (rand > 0.92) {
-		// 5% chance for score power-up
+	} else if (rand > 0.94) {
+		// 2% chance for score power-up
 		var powerup = new PowerUp();
 		powerup.x = x;
 		powerup.y = -60;
 		powerup.lastIntersecting = false;
 		powerups.push(powerup);
 		game.addChild(powerup);
+	} else if (rand > 0.92) {
+		// 2% chance for Watermelon (shield fruit)
+		var watermelon = new Watermelon();
+		watermelon.x = x;
+		watermelon.y = -60;
+		watermelon.lastIntersecting = false;
+		powerups.push(watermelon);
+		game.addChild(watermelon);
+	} else if (rand > 0.89) {
+		// 3% chance for Grape (slows bombs)
+		var grape = new Grape();
+		grape.x = x;
+		grape.y = -60;
+		grape.lastIntersecting = false;
+		powerups.push(grape);
+		game.addChild(grape);
+	} else if (rand > 0.86) {
+		// 3% chance for Banana (wider catch area)
+		var banana = new Banana();
+		banana.x = x;
+		banana.y = -60;
+		banana.lastIntersecting = false;
+		powerups.push(banana);
+		game.addChild(banana);
+	} else if (rand > 0.83) {
+		// 3% chance for Apple (extra points)
+		var apple = new Apple();
+		apple.x = x;
+		apple.y = -60;
+		apple.lastIntersecting = false;
+		powerups.push(apple);
+		game.addChild(apple);
 	} else {
 		var ball = new Ball();
 		ball.x = x;
 		ball.y = -60;
@@ -648,15 +794,13 @@
 		powerup.update();
 		// Check for catch
 		var intersecting = powerup.intersects(basket);
 		if (!powerup.lastIntersecting && intersecting) {
-			if (powerup.type === "shield" || powerup instanceof ShieldPowerUp) {
-				// Caught shield: activate shield
+			if (powerup.type === "shield" || powerup instanceof ShieldPowerUp || powerup instanceof Watermelon) {
+				// Caught shield or watermelon: activate shield
 				basket.hasShield = true;
-				// Visual feedback: blue flash and basket glow
 				LK.effects.flashObject(basket, 0x00ffff, 400);
 				LK.effects.flashScreen(0x00ffff, 200);
-				// Add a neon blue outline to basket (simulate with a pulsing alpha tween)
 				if (!basket.shieldTween) {
 					basket.shieldTween = tween(basket, {
 						alpha: 1
 					}, {
@@ -665,9 +809,8 @@
 						repeat: Infinity,
 						easing: tween.easeInOut
 					});
 				}
-				// Show shield icon (optional: could add a small blue ball above basket)
 				// Animate power-up to basket and fade out
 				tween(powerup, {
 					y: basket.y,
 					alpha: 0
@@ -679,9 +822,9 @@
 					}
 				});
 				powerups.splice(k, 1);
 				continue;
-			} else if (powerup.type === "slow") {
+			} else if (powerup.type === "slow" || powerup instanceof Grape) {
 				// Slow motion: slow all falling objects for 3 seconds
 				for (var bi = 0; bi < balls.length; bi++) {
 					balls[bi].speed *= 0.4;
 					balls[bi].vx *= 0.4;
@@ -727,16 +870,75 @@
 					}
 				});
 				powerups.splice(k, 1);
 				continue;
+			} else if (powerup.type === "banana" || powerup instanceof Banana) {
+				// Banana: temporarily widen basket for 4 seconds
+				var originalScale = basket.scaleX || 1;
+				basket.scaleX = originalScale * 1.5;
+				basket.scaleY = (basket.scaleY || 1) * 1.1;
+				LK.effects.flashObject(basket, 0xfff700, 300);
+				missTxt.setText('Wide Basket!');
+				missTxt.visible = true;
+				if (missTxt.hideTimeout) {
+					LK.clearTimeout(missTxt.hideTimeout);
+					missTxt.hideTimeout = null;
+				}
+				missTxt.hideTimeout = LK.setTimeout(function () {
+					missTxt.visible = false;
+					missTxt.hideTimeout = null;
+				}, 1200);
+				LK.setTimeout(function () {
+					basket.scaleX = originalScale;
+					basket.scaleY = 1;
+				}, 4000);
+				tween(powerup, {
+					y: basket.y,
+					alpha: 0
+				}, {
+					duration: 200,
+					easing: tween.easeIn,
+					onFinish: function onFinish() {
+						powerup.destroy();
+					}
+				});
+				powerups.splice(k, 1);
+				continue;
+			} else if (powerup.type === "apple" || powerup instanceof Apple) {
+				// Apple: +5 points, flash red
+				LK.setScore(LK.getScore() + 5);
+				scoreTxt.setText(LK.getScore());
+				LK.getSound('catch').play();
+				LK.effects.flashScreen(0xff2222, 350);
+				LK.effects.flashObject(basket, 0xff2222, 300);
+				missTxt.setText('Apple! +5');
+				missTxt.visible = true;
+				if (missTxt.hideTimeout) {
+					LK.clearTimeout(missTxt.hideTimeout);
+					missTxt.hideTimeout = null;
+				}
+				missTxt.hideTimeout = LK.setTimeout(function () {
+					missTxt.visible = false;
+					missTxt.hideTimeout = null;
+				}, 1200);
+				tween(powerup, {
+					y: basket.y,
+					alpha: 0
+				}, {
+					duration: 200,
+					easing: tween.easeIn,
+					onFinish: function onFinish() {
+						powerup.destroy();
+					}
+				});
+				powerups.splice(k, 1);
+				continue;
 			} else {
 				// Caught score power-up: double points!
 				LK.setScore(LK.getScore() + 2);
 				scoreTxt.setText(LK.getScore());
 				LK.getSound('catch').play();
-				// Flash screen with a bright gold
 				LK.effects.flashScreen(0xFFD700, 350);
-				// Animate power-up to basket and fade out
 				LK.effects.flashObject(basket, 0xFFD700, 300);
 				tween(powerup, {
 					y: basket.y,
 					alpha: 0