User prompt
Clear the screen atthe end of a level
User prompt
Increase the number of fruits spawned by level 4 boss
User prompt
Increase the number of fruits spawned by level 4 boss
User prompt
Make level 4 boss spawn fruit 1, 2, 3 and 4 at random
User prompt
Make level 5 boss spawn level 5 fruits
User prompt
Make level 3 boss spawn level 3 fruits
User prompt
Let level 4 boss spawn level 4 fruits
User prompt
Make fruits bounce agains each other and not overlap βͺπ‘ Consider importing and using the following plugins: @upit/tween.v1
User prompt
Increase number of level 4 fruit types spawned by level 4 boss
User prompt
Increase number of level 3 fruit types spawned by level 3 boss
User prompt
Let level 4 boss spawn level 4 fruit types
User prompt
Let level 3 boss spawn level 3 fruit types
User prompt
Let level 5 boss spawn level 5 fruit types
User prompt
Let level 4 boss spawn level 4 fruit types
User prompt
Increase blitz, life and bullet time powerups spawned in level 5
User prompt
Increase blitz, life and bullet time powerups spawned in level 4
User prompt
Increase lifefruit spawn chances in all levels
User prompt
Increase powerup spawn chances in level 4 and 5
User prompt
Increase blitz, life and bullet time powerups spawned in level 3
User prompt
Increase blitz, life and bullet time powerups spawned in level 4
User prompt
Increase blitz, life and bullet time powerups spawned in level 3
User prompt
Add more blitz, life and bullet time powerups to levels 3, 4 and 5
User prompt
Let level 3 boss spawn level 3 fruit types
User prompt
Reduce delay between fruit spawns in level 1 by 20%
User prompt
Reduce delay between fruit spawns in level 1, 2 and 3 by 30%
/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/**** 
* Classes
****/ 
var Blade = Container.expand(function () {
	var self = Container.call(this);
	self.active = false;
	self.points = [];
	self.maxPoints = 20; // Increased from 10 to 20 to track more points for smoother detection
	self.trail = [];
	for (var i = 0; i < self.maxPoints; i++) {
		var trailPart = self.attachAsset('blade', {
			anchorX: 0.5,
			anchorY: 0.5,
			alpha: 0
		});
		self.trail.push(trailPart);
	}
	self.update = function () {
		// Update trail visuals
		for (var i = 0; i < self.trail.length; i++) {
			if (i < self.points.length) {
				var point = self.points[i];
				var trailPart = self.trail[i];
				trailPart.x = point.x;
				trailPart.y = point.y;
				trailPart.alpha = 0; // Keep blade invisible
				if (i > 0) {
					var prevPoint = self.points[i - 1];
					var angle = Math.atan2(point.y - prevPoint.y, point.x - prevPoint.x);
					trailPart.rotation = angle;
				}
			} else {
				self.trail[i].alpha = 0;
			}
		}
	};
	self.addPoint = function (x, y) {
		self.points.unshift({
			x: x,
			y: y
		});
		if (self.points.length > self.maxPoints) {
			self.points.pop();
		}
	};
	self.reset = function () {
		self.points = [];
		self.active = false;
		for (var i = 0; i < self.trail.length; i++) {
			self.trail[i].alpha = 0;
		}
	};
	return self;
});
var BlitzPowerup = Container.expand(function () {
	var self = Container.call(this);
	self.type = 'blitz';
	self.sliced = false;
	self.width = 300;
	self.height = 300;
	self.points = 0;
	self.baseSpeed = 1.5;
	// Create a red lightning bolt-shaped fruit for blitz
	var blitzGraphics = self.attachAsset('kiwi', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	blitzGraphics.tint = 0xFF0000; // Red color for blitz power
	// Create lightning bolt symbol
	var boltTop = self.attachAsset('blade', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 20,
		height: 100
	});
	boltTop.tint = 0xFFFFFF;
	boltTop.rotation = Math.PI / 4;
	boltTop.y = -30;
	var boltBottom = self.attachAsset('blade', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 20,
		height: 100
	});
	boltBottom.tint = 0xFFFFFF;
	boltBottom.rotation = -Math.PI / 4;
	boltBottom.y = 30;
	self.vx = 0;
	self.vy = 0;
	self.gravity = 0.01;
	self.rotationSpeed = (Math.random() - 0.5) * 0.015;
	self.init = function (x, y, direction) {
		self.x = x;
		self.y = y;
		var angle = direction * (Math.PI / 4) + Math.random() * Math.PI / 8 - Math.PI / 16;
		var speed = self.baseSpeed + Math.random() * 0.8;
		self.vx = Math.cos(angle) * speed * 1.15;
		self.vy = -Math.sin(angle) * speed - 8;
	};
	self.slice = function () {
		if (self.sliced) {
			return;
		}
		self.sliced = true;
		// Flash effect
		blitzGraphics.tint = 0xFFFFFF;
		boltTop.tint = 0xFF0000;
		boltBottom.tint = 0xFF0000;
		tween(blitzGraphics, {
			alpha: 0,
			scaleX: 1.5,
			scaleY: 1.5
		}, {
			duration: 300,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				blitzGraphics.tint = 0xFF0000;
			}
		});
		// Display "Blitzkrieg!" text in the middle of screen
		var blitzText = new Text2('Blitzkrieg!', {
			size: 120,
			fill: 0xFF0000,
			weight: 'bold'
		});
		blitzText.anchor.set(0.5, 0.5);
		blitzText.x = GAME_WIDTH / 2;
		blitzText.y = GAME_HEIGHT / 2;
		game.addChild(blitzText);
		// Animate the text
		tween(blitzText, {
			scaleX: 1.5,
			scaleY: 1.5,
			alpha: 0
		}, {
			duration: 1500,
			easing: tween.elasticOut,
			onFinish: function onFinish() {
				blitzText.destroy();
			}
		});
		// Shake the screen effect
		var originalX = game.x;
		var originalY = game.y;
		var shakeCount = 0;
		var maxShakes = 10;
		var shakeIntensity = 20;
		var shakeInterval = LK.setInterval(function () {
			if (shakeCount >= maxShakes) {
				LK.clearInterval(shakeInterval);
				game.x = originalX;
				game.y = originalY;
				// After shake is done, destroy all fruits
				LK.getSound('explosion').play();
				// Destroy all fruits on screen (including bombs)
				for (var i = fruits.length - 1; i >= 0; i--) {
					var fruit = fruits[i];
					if (fruit.type !== 'lifefruit' && fruit.type !== 'bullettime' && fruit.type !== 'blitz') {
						// Add points for each destroyed fruit
						if (fruit.type !== 'bomb') {
							LK.setScore(LK.getScore() + fruit.points);
						}
						// Create explosive effect for each fruit
						var fruitGraphics = fruit.children[0];
						fruitGraphics.tint = 0xFFFFFF;
						tween(fruitGraphics, {
							alpha: 0,
							scaleX: 1.5,
							scaleY: 1.5
						}, {
							duration: 200,
							easing: tween.easeOut
						});
						// Play squash sound for each fruit
						LK.getSound('squash').play();
						// Remove fruit
						fruit.destroy();
						fruits.splice(i, 1);
					}
				}
				// Update score display
				scoreTxt.setText(LK.getScore());
				return;
			}
			// Apply random shake offset
			game.x = originalX + (Math.random() - 0.5) * shakeIntensity;
			game.y = originalY + (Math.random() - 0.5) * shakeIntensity;
			shakeCount++;
		}, 50);
		// Play slice sound
		LK.getSound('slice').play();
		LK.getSound('squash').play();
	};
	self.down = function (x, y, obj) {
		if (!self.sliced) {
			self.slice();
			// Update combo
			comboCount++;
			comboTimer = Date.now() + comboTimeout;
		}
	};
	self.update = function () {
		// Don't update movement if gameActive is false (leaderboard is visible)
		if (!gameActive) {
			return;
		}
		if (!self.sliced) {
			// Update whole fruit
			self.vy += self.gravity;
			self.x += self.vx;
			self.y += self.vy;
			self.rotation += self.rotationSpeed;
			// Bounce off walls if not sliced
			if (self.x < self.width / 2 && self.vx < 0) {
				self.vx = -self.vx * 0.8;
				self.x = self.width / 2;
			}
			if (self.x > GAME_WIDTH - self.width / 2 && self.vx > 0) {
				self.vx = -self.vx * 0.8;
				self.x = GAME_WIDTH - self.width / 2;
			}
		}
	};
	self.isOffScreen = function () {
		return self.y > 2732 + self.height || self.x > GAME_WIDTH + self.width;
	};
	return self;
});
var Boss = Container.expand(function (level) {
	var self = Container.call(this);
	// Boss properties
	self.level = level || 1;
	self.health = 5 + self.level; // Health increases with level
	self.maxHealth = self.health;
	self.width = 800;
	self.height = 800;
	self.active = false;
	self.attackTimer = 0;
	self.attackInterval = self.level === 5 ? 833 : 3000 - self.level * 250; // Level 5 boss spawn speed reduced by 25% (increased from 667ms to 833ms)
	// Ensure level is within valid range (1-5)
	if (self.level < 1) {
		self.level = 1;
	}
	if (self.level > 5) {
		self.level = 5;
	}
	// Determine boss type based on level
	var bossType = BOSS_FRUIT_TYPES[self.level - 1] || 'strawberry';
	// Create boss visual
	var bossGraphic = self.attachAsset(bossType, {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: self.level === 1 ? 1.95 : self.level === 2 ? 2.8 : self.level === 5 ? 3.5 : 4,
		// Make level 1 boss smaller by 35%, level 2 boss smaller by 30%, level 5 boss 30% smaller (from 5 to 3.5)
		scaleY: self.level === 1 ? 1.95 : self.level === 2 ? 2.8 : self.level === 5 ? 3.5 : 4 // Make level 1 boss smaller by 35%, level 2 boss smaller by 30%, level 5 boss 30% smaller (from 5 to 3.5)
	});
	// Health bar background
	var healthBarBg = new Container();
	healthBarBg.x = -200;
	healthBarBg.y = -450;
	var healthBarBack = LK.getAsset('blade', {
		anchorX: 0,
		anchorY: 0.5,
		width: 400,
		height: 30
	});
	healthBarBack.tint = 0x333333;
	// Health bar fill
	var healthBarFill = LK.getAsset('blade', {
		anchorX: 0,
		anchorY: 0.5,
		width: 400,
		height: 30
	});
	healthBarFill.tint = 0xFF0000;
	healthBarBg.addChild(healthBarBack);
	healthBarBg.addChild(healthBarFill);
	self.addChild(healthBarBg);
	self.healthBar = healthBarFill;
	// Boss movement
	self.vx = self.level === 5 ? 8 : 2 + self.level * 0.5; // Level 5 boss moves much faster
	self.targetX = GAME_WIDTH / 2;
	self.activate = function () {
		self.active = true;
		self.health = self.maxHealth;
		self.x = GAME_WIDTH / 2;
		// Position boss below the top boundary (320px) with enough space to not overlap
		// Boss dimensions depend on the asset scale (4x) and boss type
		// Account for boss height and health bar to ensure it appears fully below the boundary
		// Position bosses at different heights based on level to avoid overlapping the top boundary
		if (self.level === 2) {
			self.y = 320 + 570; // Level 2 boss: 60px lower
		} else if (self.level === 3) {
			self.y = 320 + 690; // Level 3 boss: 170px lower (moved additional 30px lower)
		} else if (self.level === 4) {
			self.y = 320 + 750; // Level 4 boss: 200px lower
		} else if (self.level === 5) {
			self.y = 320 + 900; // Level 5 boss: 300px lower (moved from 600 to 900)
		} else {
			self.y = 320 + 570; // Default position for level 1 boss
		}
		self.updateHealthBar();
	};
	self.updateHealthBar = function () {
		self.healthBar.width = self.health / self.maxHealth * 400;
	};
	self.hit = function () {
		if (!self.active) {
			return;
		}
		self.health--;
		self.updateHealthBar();
		// Flash the boss red
		bossGraphic.tint = 0xFF0000;
		LK.setTimeout(function () {
			bossGraphic.tint = 0xFFFFFF;
		}, 200);
		// Check if boss is defeated
		if (self.health <= 0) {
			self.defeat();
			return true;
		}
		return false;
	};
	self.defeat = function () {
		self.active = false;
		// Make the health bar transparent
		healthBarBg.alpha = 0;
		// Create explosion effect
		bossGraphic.tint = 0xFFFFFF;
		tween(bossGraphic, {
			alpha: 0,
			scaleX: 3,
			scaleY: 3,
			rotation: Math.PI * 2
		}, {
			duration: 1000,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				// Add bonus points (increased for higher level bosses)
				var bonus = 25 * self.level;
				LK.setScore(LK.getScore() + bonus);
				scoreTxt.setText(LK.getScore());
				LK.effects.flashScreen(0x00FF00, 500);
			}
		});
		// Play explosion sound
		LK.getSound('explosion').play();
	};
	self.throwFruit = function () {
		if (!self.active) {
			return;
		}
		// Launch multiple bombs at the player
		var bombCount = self.level === 5 ? Math.floor(Math.random() * 3) + 2 :
		// Level 5: 2-4 bombs (reduced from 3-6)
		Math.floor(Math.random() * self.level) + 1; // Other levels: 1-level bombs
		// For level 5, also spawn random fruits alongside bombs
		// Also spawn random fruits with level 1 and level 2 bosses
		var fruitCount = self.level === 5 || self.level === 1 || self.level === 2 ? Math.floor(Math.random() * 2) : 0; // Reduced from 1-2 to 0-1
		// Spawn bombs
		for (var i = 0; i < bombCount; i++) {
			var fruit = new Fruit('bomb');
			// Generate random position on the boss perimeter
			var spawnAngle = Math.random() * Math.PI * 2; // Full 360 degrees
			var spawnRadius = self.width / 3; // Radius to spawn from (edge of boss)
			// Position the bomb on the perimeter
			fruit.x = self.x + Math.cos(spawnAngle) * spawnRadius;
			fruit.y = self.y + Math.sin(spawnAngle) * spawnRadius;
			// Aim outward from the spawn point with spread
			var angle = spawnAngle + Math.PI + (Math.random() - 0.5); // Outward direction with randomness
			var speed = self.level === 5 ? 5 + Math.random() * 3 :
			// Level 5: Much faster bombs
			3 + Math.random() * 2 + self.level * 0.5; // Other levels: Normal speed
			fruit.vx = Math.cos(angle) * speed;
			fruit.vy = Math.sin(angle) * speed;
			game.addChild(fruit);
			fruits.push(fruit);
		}
		// For level 5, level 1, or level 2, also spawn random fruits
		if (self.level === 5 || self.level === 1 || self.level === 2) {
			// Level 2 boss spawns fewer fruits (1-2 instead of 2-3)
			var fruitCount = self.level === 2 ? Math.floor(Math.random() * 2) + 1 : self.level === 5 || self.level === 1 ? Math.floor(Math.random() * 2) : 0;
			for (var j = 0; j < fruitCount; j++) {
				// Select a random fruit type
				// For level 1, only use level 1 fruits (strawberry)
				// For level 2, use level 2 fruits (strawberry, kiwi)
				var availableFruits;
				if (self.level === 1) {
					availableFruits = ['strawberry']; // Level 1 fruits
				} else if (self.level === 2) {
					availableFruits = ['strawberry', 'kiwi']; // Level 2 fruits
				} else {
					availableFruits = FRUIT_TYPES; // All fruits for level 5
				}
				var fruitType = availableFruits[Math.floor(Math.random() * availableFruits.length)];
				var randomFruit = new Fruit(fruitType);
				// Generate random position on the boss perimeter
				var fruitAngle = Math.random() * Math.PI * 2;
				var fruitRadius = self.width / 3;
				// Position the fruit on the perimeter
				randomFruit.x = self.x + Math.cos(fruitAngle) * fruitRadius;
				randomFruit.y = self.y + Math.sin(fruitAngle) * fruitRadius;
				// Aim outward with different trajectory
				var fruitDirection = fruitAngle + Math.PI + (Math.random() - 0.5) * 0.5;
				var fruitSpeed = 4 + Math.random() * 2;
				randomFruit.vx = Math.cos(fruitDirection) * fruitSpeed;
				randomFruit.vy = Math.sin(fruitDirection) * fruitSpeed;
				game.addChild(randomFruit);
				fruits.push(randomFruit);
			}
		}
	};
	self.update = function (delta) {
		if (!self.active) {
			return;
		}
		// Apply bullet time effect if active (slow down by 75%)
		var speedMultiplier = bulletTimeActive ? 0.25 : 1;
		// Move boss back and forth
		if (Math.abs(self.x - self.targetX) < 10) {
			self.targetX = Math.random() * (GAME_WIDTH - 400) + 200;
		}
		var dirX = self.targetX - self.x;
		self.x += dirX / Math.abs(dirX) * self.vx * speedMultiplier;
		// Attack on timer
		var currentTime = Date.now();
		if (currentTime >= self.attackTimer) {
			self.throwFruit();
			// Extend attack interval during bullet time
			self.attackTimer = currentTime + self.attackInterval * (bulletTimeActive ? 4 : 1);
		}
	};
	self.down = function (x, y, obj) {
		// Allow clicking on boss to damage it
		if (self.active) {
			self.hit();
		}
	};
	return self;
});
var BulletTimePowerup = Container.expand(function () {
	var self = Container.call(this);
	self.type = 'bullettime';
	self.sliced = false;
	self.width = 300;
	self.height = 300;
	self.points = 0;
	self.baseSpeed = 1.5;
	// Create a blue hourglass-shaped fruit for bullet time
	var bulletTimeGraphics = self.attachAsset('kiwi', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	bulletTimeGraphics.tint = 0x00BFFF; // Deep sky blue color
	// Create hourglass symbol
	var hourglassTop = self.attachAsset('blade', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 140,
		height: 20
	});
	hourglassTop.tint = 0xFFFFFF;
	hourglassTop.y = -50;
	var hourglassBottom = self.attachAsset('blade', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 140,
		height: 20
	});
	hourglassBottom.tint = 0xFFFFFF;
	hourglassBottom.y = 50;
	var hourglassLeft = self.attachAsset('blade', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 20,
		height: 100
	});
	hourglassLeft.tint = 0xFFFFFF;
	hourglassLeft.x = -60;
	var hourglassRight = self.attachAsset('blade', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 20,
		height: 100
	});
	hourglassRight.tint = 0xFFFFFF;
	hourglassRight.x = 60;
	self.vx = 0;
	self.vy = 0;
	self.gravity = 0.01;
	self.rotationSpeed = (Math.random() - 0.5) * 0.015;
	self.init = function (x, y, direction) {
		self.x = x;
		self.y = y;
		var angle = direction * (Math.PI / 4) + Math.random() * Math.PI / 8 - Math.PI / 16;
		var speed = self.baseSpeed + Math.random() * 0.8;
		self.vx = Math.cos(angle) * speed * 1.15;
		self.vy = -Math.sin(angle) * speed - 8;
	};
	self.slice = function () {
		if (self.sliced) {
			return;
		}
		self.sliced = true;
		// Flash effect
		bulletTimeGraphics.tint = 0xFFFFFF;
		hourglassTop.tint = 0x00BFFF;
		hourglassBottom.tint = 0x00BFFF;
		hourglassLeft.tint = 0x00BFFF;
		hourglassRight.tint = 0x00BFFF;
		tween(bulletTimeGraphics, {
			alpha: 0,
			scaleX: 1.5,
			scaleY: 1.5
		}, {
			duration: 300,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				bulletTimeGraphics.tint = 0x00BFFF;
			}
		});
		// Activate bullet time effect
		activateBulletTime();
		// Play slice and bullet sounds only (no squash)
		LK.getSound('slice').play();
		LK.getSound('bullet').play();
	};
	self.down = function (x, y, obj) {
		if (!self.sliced) {
			self.slice();
			// Update combo
			comboCount++;
			comboTimer = Date.now() + comboTimeout;
		}
	};
	self.update = function () {
		// Don't update movement if gameActive is false (leaderboard is visible)
		if (!gameActive) {
			return;
		}
		if (!self.sliced) {
			// Update whole fruit
			self.vy += self.gravity;
			self.x += self.vx;
			self.y += self.vy;
			self.rotation += self.rotationSpeed;
			// Bounce off walls if not sliced
			if (self.x < self.width / 2 && self.vx < 0) {
				self.vx = -self.vx * 0.8;
				self.x = self.width / 2;
			}
			if (self.x > GAME_WIDTH - self.width / 2 && self.vx > 0) {
				self.vx = -self.vx * 0.8;
				self.x = GAME_WIDTH - self.width / 2;
			}
		}
	};
	self.isOffScreen = function () {
		return self.y > 2732 + self.height || self.x > GAME_WIDTH + self.width;
	};
	return self;
});
var Fruit = Container.expand(function (type) {
	var self = Container.call(this);
	self.type = type || 'apple';
	self.sliced = false;
	self.width = 0;
	self.height = 0;
	self.points = 0;
	self.baseSpeed = 0;
	var fruitGraphics;
	switch (self.type) {
		case 'watermelon':
			self.width = 200;
			self.height = 200;
			self.points = 5;
			self.baseSpeed = 1.6; // Faster base speed
			break;
		case 'apple':
			self.width = 240;
			self.height = 240;
			self.points = 4;
			self.baseSpeed = 1.7; // Faster base speed
			break;
		case 'orange':
			self.width = 280;
			self.height = 280;
			self.points = 3;
			self.baseSpeed = 1.8; // Faster base speed
			break;
		case 'kiwi':
			self.width = 320;
			self.height = 320;
			self.points = 2;
			self.baseSpeed = 2.0; // Faster base speed
			break;
		case 'passion_fruit':
			self.width = 360;
			self.height = 360;
			self.points = 6;
			self.baseSpeed = 2.3; // Even faster base speed
			break;
		case 'strawberry':
			self.width = 480;
			self.height = 480;
			self.points = 1;
			self.baseSpeed = 2.2; // Faster base speed
			break;
		case 'bomb':
			self.width = 320;
			self.height = 320;
			self.points = -10;
			self.baseSpeed = 1.7; // Faster base speed
			break;
	}
	fruitGraphics = self.attachAsset(self.type, {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.vx = 0;
	self.vy = 0;
	self.gravity = 0.01; // Reduced gravity to make fruits go higher
	self.rotationSpeed = (Math.random() - 0.5) * 0.018; // Slightly faster rotation
	self.init = function (x, y, direction) {
		self.x = x;
		self.y = y;
		var angle = direction * (Math.PI / 4) + Math.random() * Math.PI / 8 - Math.PI / 16;
		var currentLevel = Math.floor(LK.getScore() / 50) + 1;
		var levelMultiplier = 1 + (currentLevel - 1) * 0.1; // 10% increase per level
		// Use constant base speed without random factor to keep speed consistent within level
		var speed = self.baseSpeed * levelMultiplier;
		// Apply 30% speed reduction for level 1
		if (currentLevel === 1) {
			speed *= 0.7; // 30% slower for level 1
		}
		self.vx = Math.cos(angle) * speed * 1.15; // Slightly faster horizontal movement
		self.vy = -Math.sin(angle) * speed - 8; // Higher initial upward velocity
	};
	self.slice = function () {
		if (self.sliced) {
			return;
		}
		self.sliced = true;
		// Create explosive flash effect
		fruitGraphics.tint = 0xFFFFFF;
		fruitGraphics.alpha = 1;
		// Animate explosive flash effect with scaling
		tween(fruitGraphics, {
			alpha: 0,
			scaleX: 1.5,
			scaleY: 1.5
		}, {
			duration: 300,
			easing: tween.easeOut,
			onUpdate: function onUpdate(progress) {
				// Create a pulsing effect with rotation during explosion
				fruitGraphics.rotation += 0.1;
			},
			onFinish: function onFinish() {
				// Clean up after animation
				fruitGraphics.tint = 0xFFFFFF;
				fruitGraphics.scaleX = 1;
				fruitGraphics.scaleY = 1;
			}
		});
		// Play slice and squash sounds
		LK.getSound('slice').play();
		LK.getSound('squash').play();
		return self.points;
	};
	self.down = function (x, y, obj) {
		if (!self.sliced) {
			// Slice the fruit when clicked
			var points = self.slice();
			// Check if it's a bomb
			if (self.type === 'bomb') {
				// Lose a life when clicking a bomb
				LK.getSound('explosion').play();
				LK.effects.flashScreen(0xFF0000, 500);
				playerLives--; // Reduce lives by 1
				updateLivesDisplay(); // Update hearts display
				// Make bomb disappear
				self.sliced = true;
				// Create explosive flash effect for bomb
				fruitGraphics.tint = 0xFFFFFF;
				// Animate bomb disappearing
				tween(fruitGraphics, {
					alpha: 0,
					scaleX: 1.5,
					scaleY: 1.5
				}, {
					duration: 300,
					easing: tween.easeOut,
					onFinish: function onFinish() {
						// Remove bomb from game
						self.destroy();
						// Find and remove from fruits array
						var index = fruits.indexOf(self);
						if (index > -1) {
							fruits.splice(index, 1);
						}
					}
				});
				// If no lives left, game over
				if (playerLives <= 0) {
					// Update high score if current score is higher
					if (LK.getScore() > highScore) {
						highScore = LK.getScore();
						storage.highScore = highScore;
					}
					// Add score to global leaderboard
					addScoreToLeaderboard(LK.getScore());
					// Pass the current score and high score to game over display
					LK.showGameOver({
						score: LK.getScore(),
						highScore: highScore
					});
				}
				return;
			}
			// Add points to score
			LK.setScore(LK.getScore() + points);
			scoreTxt.setText(LK.getScore());
			// Increment sliced fruits counter for current level
			slicedFruitsInLevel++;
			// Update combo
			comboCount++;
			comboTimer = Date.now() + comboTimeout;
		}
	};
	self.update = function () {
		// Don't update movement if gameActive is false (leaderboard is visible)
		if (!gameActive) {
			return;
		}
		if (!self.sliced) {
			// Update whole fruit
			// Apply bullet time effect if active (slow down by 75%)
			var speedMultiplier = bulletTimeActive ? 0.25 : 1;
			self.vy += self.gravity * speedMultiplier;
			self.x += self.vx * speedMultiplier;
			self.y += self.vy * speedMultiplier;
			self.rotation += self.rotationSpeed * speedMultiplier;
			// Bounce off walls if not sliced
			if (self.x < self.width / 2 && self.vx < 0) {
				self.vx = -self.vx * 0.8; // Bounce with some energy loss
				self.x = self.width / 2;
			}
			if (self.x > GAME_WIDTH - self.width / 2 && self.vx > 0) {
				self.vx = -self.vx * 0.8; // Bounce with some energy loss
				self.x = GAME_WIDTH - self.width / 2;
			}
		} else {
			// No update for sliced fruit since we're just flashing and fading them
		}
	};
	self.isOffScreen = function () {
		return self.y > 2732 + self.height || self.x > GAME_WIDTH + self.width;
	};
	return self;
});
var Heart = Container.expand(function () {
	var self = Container.call(this);
	// Create a red heart shape (using blade asset tinted red)
	var heartShape = self.attachAsset('blade', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 60,
		height: 60
	});
	heartShape.tint = 0xFF0000;
	return self;
});
var Leaderboard = Container.expand(function () {
	var self = Container.call(this);
	self.visible = false;
	// Background panel
	var panel = self.attachAsset('blade', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 1500,
		height: 1800
	});
	panel.tint = 0x111111; // Very dark color (almost black) for better contrast
	panel.alpha = 0.9; // Slightly transparent for better visibility
	// Title
	var title = new Text2('GLOBAL LEADERBOARD', {
		size: 100,
		fill: 0xFFFFFF
	});
	title.anchor.set(0.5, 0);
	title.y = -800;
	self.addChild(title);
	// Scores container
	var scoresContainer = new Container();
	scoresContainer.y = -650;
	self.addChild(scoresContainer);
	self.scoresContainer = scoresContainer;
	// Close button
	var closeBtn = self.attachAsset('blade', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 80,
		height: 80
	});
	closeBtn.tint = 0xFF0000;
	closeBtn.x = 700;
	closeBtn.y = -800;
	// X symbol on close button
	var closeX1 = self.attachAsset('blade', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 40,
		height: 8
	});
	closeX1.tint = 0xFFFFFF;
	closeX1.rotation = Math.PI / 4;
	closeX1.x = 700;
	closeX1.y = -800;
	var closeX2 = self.attachAsset('blade', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 40,
		height: 8
	});
	closeX2.tint = 0xFFFFFF;
	closeX2.rotation = -Math.PI / 4;
	closeX2.x = 700;
	closeX2.y = -800;
	// Close button interaction
	closeBtn.interactive = true;
	closeBtn.down = function (x, y, obj) {
		self.hide();
	};
	// Show leaderboard
	self.show = function (scores) {
		self.visible = true;
		self.updateScores(scores);
		// Pause the game when leaderboard is visible
		gameActive = false;
		// Make game area 50% transparent
		game.alpha = 0.5;
		// Make leaderboard panel fully opaque (0% transparent)
		panel.alpha = 1.0;
		// Bring leaderboard to front layer
		if (self.parent) {
			var parent = self.parent;
			parent.removeChild(self);
			parent.addChild(self);
		}
	};
	// Hide leaderboard
	self.hide = function () {
		self.visible = false;
		// Resume the game when leaderboard is hidden
		gameActive = true;
		// Restore game area opacity
		game.alpha = 1.0;
	};
	// Update scores display
	self.updateScores = function (scores) {
		// Clear existing score entries
		while (scoresContainer.children.length > 0) {
			scoresContainer.removeChildAt(0);
		}
		// Add score entries
		for (var i = 0; i < scores.length; i++) {
			var entry = scores[i];
			var yPos = i * 120;
			// Rank
			var rank = new Text2(i + 1 + '.', {
				size: 80,
				fill: 0xFFFFFF
			});
			rank.anchor.set(1, 0);
			rank.x = -600;
			rank.y = yPos;
			scoresContainer.addChild(rank);
			// Username
			var username = entry.username || "Player";
			var usernameText = new Text2(username, {
				size: 60,
				fill: 0xFFFFFF
			});
			usernameText.anchor.set(0, 0);
			usernameText.x = -500;
			usernameText.y = yPos;
			scoresContainer.addChild(usernameText);
			// Score value
			var scoreText = new Text2(entry.score.toString(), {
				size: 80,
				fill: 0xFFF200 // Brighter yellow color for better visibility
			});
			scoreText.anchor.set(0, 0);
			scoreText.x = 0;
			scoreText.y = yPos;
			scoresContainer.addChild(scoreText);
		}
		// Add message if no scores
		if (scores.length === 0) {
			var noScores = new Text2("No scores yet!", {
				size: 80,
				fill: 0x00FFFF //{3Y} // Bright cyan color for better visibility
			});
			noScores.anchor.set(0.5, 0);
			noScores.y = 100;
			scoresContainer.addChild(noScores);
		}
	};
	return self;
});
var LeaderboardButton = Container.expand(function () {
	var self = Container.call(this);
	// Create button background
	var buttonBg = self.attachAsset('blade', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 400,
		height: 120
	});
	buttonBg.tint = 0x3498db;
	// Create button text that says LEADERBOARD
	var buttonText = new Text2('LEADERBOARD', {
		size: 60,
		fill: 0xFFFFFF
	});
	buttonText.anchor.set(0.5, 0.5);
	self.addChild(buttonText);
	// Button interaction
	self.down = function (x, y, obj) {
		// Scale down effect on press
		tween(self, {
			scaleX: 0.9,
			scaleY: 0.9
		}, {
			duration: 100
		});
		// Toggle leaderboard visibility
		if (leaderboard && leaderboard.visible) {
			leaderboard.hide();
		} else {
			showLeaderboard();
		}
	};
	self.up = function (x, y, obj) {
		// Scale back to normal on release
		tween(self, {
			scaleX: 1,
			scaleY: 1
		}, {
			duration: 100
		});
	};
	return self;
});
var LifeFruit = Container.expand(function () {
	var self = Container.call(this);
	self.type = 'lifefruit';
	self.sliced = false;
	self.width = 320;
	self.height = 320;
	self.points = 0;
	self.baseSpeed = 1.5;
	// Create a white fruit with heart shape for extra life
	var lifeGraphics = self.attachAsset('kiwi', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	lifeGraphics.tint = 0xFFFFFF; // White color for life fruit
	var heartShape = self.attachAsset('blade', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 120,
		height: 120
	});
	heartShape.tint = 0xFF0000;
	self.vx = 0;
	self.vy = 0;
	self.gravity = 0.01;
	self.rotationSpeed = (Math.random() - 0.5) * 0.015;
	self.init = function (x, y, direction) {
		self.x = x;
		self.y = y;
		var angle = direction * (Math.PI / 4) + Math.random() * Math.PI / 8 - Math.PI / 16;
		var speed = self.baseSpeed + Math.random() * 0.8;
		self.vx = Math.cos(angle) * speed * 1.15;
		self.vy = -Math.sin(angle) * speed - 8;
	};
	self.slice = function () {
		if (self.sliced) {
			return;
		}
		self.sliced = true;
		// Add an extra life
		playerLives = Math.min(playerLives + 1, 5); // Cap at maximum 5 lives
		updateLivesDisplay();
		// Flash effect
		lifeGraphics.tint = 0xFFFFFF;
		heartShape.tint = 0xFFFFFF;
		tween(lifeGraphics, {
			alpha: 0,
			scaleX: 1.5,
			scaleY: 1.5
		}, {
			duration: 300,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				lifeGraphics.tint = 0xFFFFFF;
				heartShape.tint = 0xFF0000;
			}
		});
		// Play slice and squash sounds
		LK.getSound('slice').play();
		LK.getSound('squash').play();
	};
	self.down = function (x, y, obj) {
		if (!self.sliced) {
			self.slice();
			// Update combo
			comboCount++;
			comboTimer = Date.now() + comboTimeout;
		}
	};
	self.update = function () {
		// Don't update movement if gameActive is false (leaderboard is visible)
		if (!gameActive) {
			return;
		}
		if (!self.sliced) {
			// Update whole fruit
			// Apply bullet time effect if active (slow down by 75%)
			var speedMultiplier = bulletTimeActive ? 0.25 : 1;
			self.vy += self.gravity * speedMultiplier;
			self.x += self.vx * speedMultiplier;
			self.y += self.vy * speedMultiplier;
			self.rotation += self.rotationSpeed * speedMultiplier;
			// Bounce off walls if not sliced
			if (self.x < self.width / 2 && self.vx < 0) {
				self.vx = -self.vx * 0.8;
				self.x = self.width / 2;
			}
			if (self.x > GAME_WIDTH - self.width / 2 && self.vx > 0) {
				self.vx = -self.vx * 0.8;
				self.x = GAME_WIDTH - self.width / 2;
			}
		}
	};
	self.isOffScreen = function () {
		return self.y > 2732 + self.height || self.x > GAME_WIDTH + self.width;
	};
	return self;
});
var PlayAreaBoundary = Container.expand(function (isTop) {
	var self = Container.call(this);
	var line = self.attachAsset('blade', {
		anchorX: 0,
		anchorY: 0.5,
		width: GAME_WIDTH,
		height: 10
	});
	line.tint = 0xFFFFFF;
	line.alpha = 0.7;
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x3498DB
});
/**** 
* Game Code
****/ 
// Game constants
var GAME_WIDTH = 2048;
var GAME_HEIGHT = 2732;
var SPAWN_INTERVAL_MIN = 1000; // Decreased spawn interval minimum for more frequent spawning
var SPAWN_INTERVAL_MAX = 2000; // Decreased spawn interval maximum for more frequent spawning
var SPAWN_COUNT_MIN = 1;
var SPAWN_COUNT_MAX = 2; // Increased to spawn more fruits at once
var FRUIT_TYPES = ['watermelon', 'apple', 'orange', 'kiwi', 'strawberry', 'passion_fruit'];
var BOSS_FRUIT_TYPES = ['strawberry', 'kiwi', 'orange', 'apple', 'passion_fruit']; // Boss type matches newest fruit type introduced in each level
var LEVEL_THRESHOLDS = [5, 50, 150, 300, 450]; // Score thresholds for each level boss
var LEVEL_FRUITS = [['strawberry'],
// Level 1 fruits
['strawberry', 'kiwi'],
// Level 2 fruits
['strawberry', 'kiwi', 'orange'],
// Level 3 fruits
['strawberry', 'kiwi', 'orange', 'apple'],
// Level 4 fruits
['strawberry', 'kiwi', 'orange', 'apple', 'watermelon'] // Level 5 fruits
];
var BOMB_PROBABILITY = 0.2; // Increased bomb probability
// Game variables
var fruits = [];
var blade = null;
// Boss-related variables
var boss = null;
var bossActivated = false;
var slicedFruitsInLevel = 0; // Track how many fruits sliced in current level for boss activation
var bossFlashed = false; // Track if boss has been flashed in current level
// Bullet time variables
var bulletTimeActive = false;
var bulletTimeEndTime = 0;
var bulletTimeBar; // Progress bar for bullet time
var bulletTimeDuration = 10000; // 10 seconds
// Level tracking
var currentLevel = 1;
var nextLevelNotified = false;
var showingLevelText = false;
var levelTextTimer = 0;
var levelText; // Level notification text
var levelDisplay; // Text to display current level
// Spawn timers
var lastSpawnTime = 0;
var nextSpawnTime = 0;
// Combo system
var comboCount = 0;
var comboTimer = 0;
var comboTimeout = 1000; // ms to reset combo
var comboTxt; // Text to display combo
// Player state
var gameActive = true;
var playerLives = 3; // Player starts with 3 lives
var heartsDisplay; // Container for heart icons
var missedFruits = 0; // Counter for missed fruits
var missedText; // Text to display missed count
var lifeFruitSpawned = 0; // Track how many life fruits we've spawned
// Score-related
var scoreTxt; // Text to display score
var highScore = storage.highScore || 0; // Get high score from storage or default to 0
var highScoreText; // Text to display high score
// Leaderboard
var leaderboardButton; // Button to open leaderboard
var leaderboard; // Leaderboard UI component
// Parse leaderboard scores from storage or use empty array if none exists
var leaderboardScores = [];
if (storage.leaderboardScores) {
	var scoresArray = storage.leaderboardScores.split(';');
	for (var i = 0; i < scoresArray.length; i++) {
		if (scoresArray[i]) {
			var parts = scoresArray[i].split(',');
			var scoreObj = {
				score: parseInt(parts[0])
			};
			if (parts.length > 1) {
				scoreObj.username = parts[1];
			}
			leaderboardScores.push(scoreObj);
		}
	}
} // Global leaderboard data
var playerName = storage.playerName || "Player"; // Get saved player name or use default
// UI elements
var scoreTxt;
var comboTxt;
function setupGame() {
	// Prompt for player name if not already stored
	if (!storage.playerName) {
		var defaultName = "Player";
		// Skip popup for now and just use default name
		// LK.showPopup is not available in the current version
		storage.playerName = defaultName;
		playerName = defaultName;
	}
	// Create blade
	blade = game.addChild(new Blade());
	// Create boss reference but don't create the actual boss instance yet
	// We'll create it only when needed for the boss fight
	boss = null;
	// Set up score display
	scoreTxt = new Text2('0', {
		size: 100,
		fill: 0xFFFFFF,
		weight: 'bold' // Make text bold
	});
	scoreTxt.anchor.set(0.5, 0);
	scoreTxt.y = 30;
	LK.gui.top.addChild(scoreTxt);
	// Set up combo display
	comboTxt = new Text2('', {
		size: 60,
		fill: 0xFFFF00
	});
	comboTxt.anchor.set(0.5, 0);
	comboTxt.y = 140;
	comboTxt.alpha = 0;
	LK.gui.top.addChild(comboTxt);
	// Set up level text display
	levelText = new Text2('Level 1', {
		size: 120,
		fill: 0xFFFFFF
	});
	levelText.anchor.set(0.5, 0.5);
	levelText.x = GAME_WIDTH / 2;
	levelText.y = GAME_HEIGHT / 2;
	levelText.alpha = 0;
	game.addChild(levelText);
	// Add level display to top right
	levelDisplay = new Text2('Level: 1', {
		size: 100,
		fill: 0xFFFFFF,
		weight: 'bold' // Make text bold
	});
	levelDisplay.anchor.set(1, 0);
	levelDisplay.x = GAME_WIDTH - 50; // Right justified 50px from right wall
	levelDisplay.y = 100;
	game.addChild(levelDisplay);
	// Initialize missed counter
	missedFruits = 0;
	// Initialize the missed counter display through the dedicated function
	updateMissedCounter();
	// Set up high score display
	highScoreText = new Text2('Your High Score: ' + highScore, {
		size: 60,
		fill: 0xFFFFFF
	});
	highScoreText.anchor.set(0, 1);
	highScoreText.x = 50;
	highScoreText.y = -30; // Position at the bottom, moved 20 pixels below
	LK.gui.bottomLeft.addChild(highScoreText);
	// Create bullet time bar (initially hidden)
	bulletTimeBar = new Container();
	bulletTimeBar.x = GAME_WIDTH / 2;
	bulletTimeBar.y = 280; // Moved 80px down from the top
	bulletTimeBar.visible = false;
	game.addChild(bulletTimeBar);
	// Bullet time bar background
	var bulletTimeBarBg = LK.getAsset('blade', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 1000,
		height: 30
	});
	bulletTimeBarBg.tint = 0x333333;
	// Bullet time bar fill
	var bulletTimeBarFill = LK.getAsset('blade', {
		anchorX: 0,
		anchorY: 0.5,
		width: 1000,
		height: 30
	});
	bulletTimeBarFill.tint = 0x00BFFF; // Match bullet time powerup color
	bulletTimeBarFill.x = -500; // Center the bar
	// Bullet time text
	var bulletTimeText = new Text2('BULLET TIME', {
		size: 60,
		fill: 0xFFFFFF
	});
	bulletTimeText.anchor.set(0.5, 0.5);
	bulletTimeText.y = -60;
	// Add elements to bullet time bar
	bulletTimeBar.addChild(bulletTimeBarBg);
	bulletTimeBar.addChild(bulletTimeBarFill);
	bulletTimeBar.addChild(bulletTimeText);
	bulletTimeBar.barFill = bulletTimeBarFill; // Store reference to the fill for updates
	// Create hearts display for lives
	heartsDisplay = new Container();
	heartsDisplay.x = GAME_WIDTH - 100; // Right justified 100px from right wall
	heartsDisplay.y = 250; // 250px from top
	game.addChild(heartsDisplay);
	// Add initial hearts (3 lives)
	updateLivesDisplay();
	// Set up leaderboard button
	leaderboardButton = new LeaderboardButton();
	leaderboardButton.x = GAME_WIDTH - 250; // Moved 30px to the left (from 220 to 250)
	leaderboardButton.y = GAME_HEIGHT - 100;
	game.addChild(leaderboardButton);
	// Create and position leaderboard UI
	leaderboard = new Leaderboard();
	leaderboard.x = GAME_WIDTH / 2;
	leaderboard.y = GAME_HEIGHT / 2;
	leaderboard.visible = false;
	game.addChild(leaderboard);
	// Set initial spawn time
	nextSpawnTime = Date.now() + Math.random() * (SPAWN_INTERVAL_MAX - SPAWN_INTERVAL_MIN) + SPAWN_INTERVAL_MIN;
	// Special level 1 powerup spawning removed
	// Play background music
	LK.playMusic('gameMusic');
	// Reset all game state
	currentLevel = 1;
	bossActivated = false;
	nextLevelNotified = false;
	LK.setScore(0);
	missedFruits = 0;
	playerLives = 3; // Reset lives to 3
	lifeFruitSpawned = 0; // Reset life fruit spawn counter
	slicedFruitsInLevel = 0; // Reset sliced fruits counter
	comboCount = 0; // Reset combo counter
	comboTimer = 0; // Reset combo timer
	// Add play area boundary lines
	var topBoundary = new PlayAreaBoundary(true);
	topBoundary.y = 320; // Position 320px from the top
	game.addChild(topBoundary);
	var bottomBoundary = new PlayAreaBoundary(false);
	bottomBoundary.y = GAME_HEIGHT - 200; // Position 200px from the bottom
	game.addChild(bottomBoundary);
	// Show level 1 text at start
	showLevelText(1);
}
// Function to display level text and reset level-specific state
function showLevelText(level) {
	// Set level text content
	levelText.setText('Level ' + level);
	levelText.alpha = 0;
	showingLevelText = true;
	// Reset level-specific counters
	missedFruits = 0;
	updateMissedCounter();
	slicedFruitsInLevel = 0;
	// Reset boss state for new level
	bossActivated = false;
	bossFlashed = false; // Reset boss flash state for new level
	// Reset bullet time
	bulletTimeActive = false;
	bulletTimeBar.visible = false;
	// Update level display in top right
	levelDisplay.setText('Level: ' + level);
	// Animate the level text
	tween(levelText, {
		alpha: 1
	}, {
		duration: 500,
		easing: tween.easeOut,
		onFinish: function onFinish() {
			// Hold the text visible for a moment
			levelTextTimer = Date.now() + 2000;
		}
	});
}
function spawnFruits() {
	var count = currentLevel === 1 ? Math.ceil((Math.floor(Math.random() * (SPAWN_COUNT_MAX - SPAWN_COUNT_MIN + 1)) + SPAWN_COUNT_MIN) / 2) :
	// 50% reduction for level 1
	Math.floor(Math.random() * (SPAWN_COUNT_MAX - SPAWN_COUNT_MIN + 1)) + SPAWN_COUNT_MIN;
	// Get appropriate fruit types for current level
	var availableFruits = LEVEL_FRUITS[currentLevel - 1] || ['strawberry'];
	// Check if we should spawn a life fruit based on the current level
	var spawnLifeFruit = false;
	var spawnBulletTime = false;
	var spawnBlitz = false;
	var maxLifeFruits = currentLevel;
	if (currentLevel === 4) {
		maxLifeFruits = 3;
	} // Level 4 gets 3 life fruits
	if (currentLevel === 1) {
		maxLifeFruits = 3; // Level 1 gets 3 life fruits
	}
	if (lifeFruitSpawned < maxLifeFruits && Math.random() < 0.1) {
		// 10% chance to spawn a life fruit
		spawnLifeFruit = true;
		lifeFruitSpawned++;
	} else if (!bulletTimeActive && Math.random() < 0.05) {
		// 5% chance to spawn bullet time powerup if not already active
		spawnBulletTime = true;
	} else if (Math.random() < (currentLevel === 1 ? 0.12 : 0.05)) {
		// 12% chance to spawn blitz powerup in level 1, 5% in other levels
		spawnBlitz = true;
	}
	// Loop through and create fruits
	for (var i = 0; i < count; i++) {
		var fruit;
		// Create life fruit if it's time
		if (i === 0 && spawnLifeFruit) {
			fruit = new LifeFruit();
		} else if (i === 0 && spawnBulletTime) {
			fruit = new BulletTimePowerup();
		} else if (i === 0 && spawnBlitz) {
			fruit = new BlitzPowerup();
		} else {
			var isBomb = Math.random() < BOMB_PROBABILITY;
			var type = isBomb ? 'bomb' : availableFruits[Math.floor(Math.random() * availableFruits.length)];
			fruit = new Fruit(type);
		}
		// Determine flight pattern
		var pattern = Math.random();
		if (pattern < 0.5) {
			// Horizontal flight from left to right
			var x = -fruit.width;
			var y = Math.random() * (GAME_HEIGHT / 3) + 300; // Higher position range
			fruit.x = x;
			fruit.y = y;
			fruit.vx = fruit.baseSpeed + Math.random() * 2.5; // Slightly faster
			fruit.vy = -Math.random() * 2; // Add slight upward movement
		} else {
			// Vertical drop
			var x = Math.random() * (GAME_WIDTH - 200) + 100;
			var direction = Math.random(); // Random direction between 0 and 1
			fruit.init(x, GAME_HEIGHT, direction);
		}
		game.addChild(fruit);
		fruits.push(fruit);
	}
	// Schedule next spawn with appropriate delay based on level
	// Level 1, 2, & 3: 30% shorter delay
	// Level 4+: normal delay
	var delayMultiplier = 1;
	if (currentLevel === 1) {
		delayMultiplier = 0.7; // 30% shorter delay for level 1
	} else if (currentLevel === 2 || currentLevel === 3) {
		delayMultiplier = 0.7; // 30% shorter delay for level 2 and 3
	}
	nextSpawnTime = Date.now() + delayMultiplier * (Math.random() * (SPAWN_INTERVAL_MAX - SPAWN_INTERVAL_MIN) + SPAWN_INTERVAL_MIN);
}
function updateCombo() {
	if (comboCount > 1) {
		comboTxt.setText('COMBO x' + comboCount + '!');
		comboTxt.alpha = 1;
		// Add combo bonus points
		LK.setScore(LK.getScore() + comboCount * 2);
		// Play combo sound
		LK.getSound('combo').play();
		// Animate combo text
		tween(comboTxt, {
			alpha: 0
		}, {
			duration: 1000,
			easing: tween.easeOut
		});
	}
	comboCount = 0;
}
function handleBladeCollisions() {
	// Return early if the blade isn't active or doesn't have enough points to form a line
	if (!blade.active || blade.points.length < 2) {
		return;
	}
	// Process multiple segments for more accurate detection
	var segmentsToCheck = Math.min(5, blade.points.length - 1);
	// Check multiple segments of the blade for better sensitivity
	var hitFruits = {};
	var hitBoss = false;
	for (var j = 0; j < segmentsToCheck; j++) {
		var startPoint = blade.points[j];
		var endPoint = blade.points[j + 1];
		// Check boss collision if active
		if (boss && boss.active && !hitBoss && lineIntersectsCircle(startPoint.x, startPoint.y, endPoint.x, endPoint.y, boss.x, boss.y, boss.width / 3)) {
			// Hit the boss
			var defeated = boss.hit();
			// Play slice and squash sounds
			LK.getSound('slice').play();
			LK.getSound('squash').play();
			// Update combo
			comboCount++;
			comboTimer = Date.now() + comboTimeout;
			hitBoss = true;
		}
		// Check collisions with fruits
		for (var i = 0; i < fruits.length; i++) {
			var fruit = fruits[i];
			if (!fruit.sliced && !hitFruits[i] && lineIntersectsCircle(startPoint.x, startPoint.y, endPoint.x, endPoint.y, fruit.x, fruit.y, fruit.width / 2)) {
				hitFruits[i] = true;
				if (fruit.type === 'bomb') {
					// Lose a life when hitting a bomb
					LK.getSound('explosion').play();
					LK.effects.flashScreen(0xFF0000, 500);
					playerLives--; // Reduce lives by 1
					updateLivesDisplay(); // Update hearts display
					// If no lives left, game over
					if (playerLives <= 0) {
						// Update high score if current score is higher
						if (LK.getScore() > highScore) {
							highScore = LK.getScore();
							storage.highScore = highScore;
						}
						// Add score to global leaderboard
						addScoreToLeaderboard(LK.getScore());
						// Pass the current score and high score to game over display
						LK.showGameOver({
							score: LK.getScore(),
							highScore: highScore
						});
					}
					break; // Exit the inner loop since we hit a bomb
				}
			}
			// Handle life fruit
			else if (fruit.type === 'lifefruit') {
				// Slice the life fruit and gain an extra life
				fruit.slice();
				// Play a special sound
				LK.getSound('combo').play();
				// Flash green for the extra life
				LK.effects.flashScreen(0x00FF00, 300);
				// Update combo
				comboCount++;
				comboTimer = Date.now() + comboTimeout;
			} else {
				// Slice regular fruit
				var points = fruit.slice();
				LK.setScore(LK.getScore() + points);
				scoreTxt.setText(LK.getScore());
				// Increment sliced fruits counter for current level
				slicedFruitsInLevel++;
				// Play slice sound
				LK.getSound('slice').play();
				// Update combo
				comboCount++;
				comboTimer = Date.now() + comboTimeout;
			}
		}
	}
}
function lineIntersectsCircle(x1, y1, x2, y2, cx, cy, r) {
	// Increase detection radius by 30% to make blade more sensitive
	r = r * 1.3;
	// Find the closest point on the line segment to the circle center
	var dx = x2 - x1;
	var dy = y2 - y1;
	var len = Math.sqrt(dx * dx + dy * dy);
	// Normalize direction vector
	dx /= len;
	dy /= len;
	// Vector from line start to circle center
	var vx = cx - x1;
	var vy = cy - y1;
	// Project this vector onto the line direction
	var projection = vx * dx + vy * dy;
	// Clamp projection to line segment
	projection = Math.max(0, Math.min(len, projection));
	// Find the closest point on the line segment
	var closestX = x1 + projection * dx;
	var closestY = y1 + projection * dy;
	// Check if this point is within the circle
	var distanceSquared = (cx - closestX) * (cx - closestX) + (cy - closestY) * (cy - closestY);
	return distanceSquared <= r * r;
}
// Show the leaderboard UI
function showLeaderboard() {
	if (leaderboard) {
		leaderboard.show(leaderboardScores);
	}
}
// Update the hearts display based on current lives
function updateLivesDisplay() {
	// Clear existing hearts
	while (heartsDisplay.children.length > 0) {
		heartsDisplay.removeChildAt(0);
	}
	// Add new hearts based on current lives
	for (var i = 0; i < playerLives; i++) {
		var heart = new Heart();
		heart.x = -i * 80; // Space hearts horizontally from right to left
		heartsDisplay.addChild(heart);
	}
	// Update the missed counter
	updateMissedCounter();
}
// Dedicated function to update missed fruits counter and its color
function updateMissedCounter() {
	// Determine color based on missed count
	var missedColor;
	if (missedFruits <= 3) {
		missedColor = 0x00FF00; // Green for 0-3 misses
	} else if (missedFruits <= 6) {
		missedColor = 0xFFA500; // Orange for 4-6 misses
	} else {
		missedColor = 0xFF0000; // Red for 7-10 misses
	}
	// Remove old text from parent if it exists
	if (missedText && missedText.parent) {
		missedText.parent.removeChild(missedText);
	}
	// Create new Text2 with the appropriate color
	missedText = new Text2('Missed: ' + missedFruits + '/10', {
		size: 100,
		fill: missedColor,
		// Apply the color based on missed count
		weight: 'bold' // Make text bold
	});
	missedText.anchor.set(1, 0);
	missedText.x = GAME_WIDTH - 50;
	missedText.y = 10;
	game.addChild(missedText);
}
// Activate bullet time effect
function activateBulletTime() {
	bulletTimeActive = true;
	bulletTimeEndTime = Date.now() + bulletTimeDuration;
	bulletTimeBar.visible = true;
	// Flash screen blue to indicate bullet time activation
	LK.effects.flashScreen(0x00BFFF, 500);
	// Play a sound
	LK.getSound('combo').play();
}
// Update bullet time progress bar
function updateBulletTime() {
	if (!bulletTimeActive) {
		return;
	}
	var currentTime = Date.now();
	var remaining = bulletTimeEndTime - currentTime;
	if (remaining <= 0) {
		// Bullet time has ended
		bulletTimeActive = false;
		bulletTimeBar.visible = false;
		return;
	}
	// Update progress bar
	var progress = remaining / bulletTimeDuration;
	bulletTimeBar.barFill.width = 1000 * progress;
}
// Add a score to the leaderboard
function addScoreToLeaderboard(score) {
	// Only add score if it's greater than 0
	if (score <= 0) {
		return;
	}
	// Add new score to leaderboard with Upit username or 'Anon'
	var username = LK.getUptUsername ? LK.getUptUsername() : 'Anon';
	leaderboardScores.push({
		score: score,
		username: username
	});
	// Sort leaderboard by score (highest first)
	leaderboardScores.sort(function (a, b) {
		return b.score - a.score;
	});
	// Limit to top 10 scores
	if (leaderboardScores.length > 10) {
		leaderboardScores = leaderboardScores.slice(0, 10);
	}
	// Save to storage - convert to simple string format to avoid undefined JSON error
	var scoresString = '';
	for (var i = 0; i < leaderboardScores.length; i++) {
		scoresString += leaderboardScores[i].score + "," + (leaderboardScores[i].username || "Player");
		if (i < leaderboardScores.length - 1) {
			scoresString += ';';
		}
	}
	storage.leaderboardScores = scoresString;
}
;
// Game update function
game.update = function () {
	// Don't update game state if game is paused (leaderboard is shown)
	if (!gameActive) {
		return;
	}
	var currentTime = Date.now();
	// Handle level text animation
	if (showingLevelText && currentTime > levelTextTimer && levelText.alpha > 0) {
		tween(levelText, {
			alpha: 0
		}, {
			duration: 500,
			easing: tween.easeIn,
			onFinish: function onFinish() {
				showingLevelText = false;
			}
		});
	}
	// Check if we should flash the boss at 80% into the level (4 fruits sliced out of 5)
	if (currentLevel >= 1 && currentLevel <= 5 && slicedFruitsInLevel >= 4 && !bossFlashed && !bossActivated) {
		var _doMultipleFlashes = function doMultipleFlashes(flashCount) {
			if (flashCount <= 0) {
				tempBoss.destroy();
				return;
			}
			// Flash in
			tween(tempBoss, {
				alpha: 1
			}, {
				duration: 250,
				// Half second total per flash (250ms in, 250ms out)
				easing: tween.easeOut,
				onFinish: function onFinish() {
					// Flash out
					tween(tempBoss, {
						alpha: 0
					}, {
						duration: 250,
						// Half second total per flash (250ms in, 250ms out)
						easing: tween.easeIn,
						onFinish: function onFinish() {
							// Continue with next flash
							_doMultipleFlashes(flashCount - 1);
						}
					});
				}
			});
		}; // Start the sequence with 3 flashes
		bossFlashed = true;
		// Create a temporary boss image for flashing
		var tempBoss = new Boss(currentLevel);
		tempBoss.x = GAME_WIDTH / 2;
		tempBoss.y = GAME_HEIGHT / 2;
		tempBoss.alpha = 0;
		game.addChild(tempBoss);
		// Function to perform multiple boss flashes
		_doMultipleFlashes(3);
	}
	// Check if we should activate the boss fight based on fruit count
	// All levels: After 5 sliced fruits consistently
	var shouldActivateBoss = false;
	if (currentLevel >= 1 && currentLevel <= 5) {
		shouldActivateBoss = slicedFruitsInLevel >= 5 && !bossActivated && !nextLevelNotified;
	} else {
		// Fallback for any future levels beyond 5
		shouldActivateBoss = LK.getScore() >= LEVEL_THRESHOLDS[currentLevel - 1] && !bossActivated && !nextLevelNotified;
	}
	if (currentLevel <= 5 && shouldActivateBoss) {
		bossActivated = true;
		// Create a new boss for the current level
		if (boss) {
			boss.destroy();
		}
		boss = game.addChild(new Boss(currentLevel));
		boss.activate();
		// Clear existing fruits during boss transition
		for (var i = fruits.length - 1; i >= 0; i--) {
			fruits[i].destroy();
			fruits.splice(i, 1);
		}
	}
	// Only spawn normal fruits if we're not in a boss fight
	if (currentTime >= nextSpawnTime && (!bossActivated || !boss.active)) {
		spawnFruits();
	}
	// Update all fruits
	for (var i = fruits.length - 1; i >= 0; i--) {
		var fruit = fruits[i];
		fruit.update();
		// Remove fruits that are off-screen
		if (fruit.isOffScreen()) {
			// Only count missed fruits that aren't bombs or already sliced
			if (!fruit.sliced && fruit.type !== 'bomb') {
				missedFruits++;
				// Update the missed counter with new value and color
				updateMissedCounter();
				// If 10 fruits are missed, lose a life and reset miss counter
				if (missedFruits >= 10) {
					LK.effects.flashScreen(0xFF0000, 500);
					playerLives--; // Reduce lives by 1
					updateLivesDisplay(); // Update hearts display
					missedFruits = 0; // Reset missed fruits counter
					updateMissedCounter(); // Update missed counter display
					// Only show game over if no lives left
					if (playerLives <= 0) {
						// Update high score if current score is higher
						if (LK.getScore() > highScore) {
							highScore = LK.getScore();
							storage.highScore = highScore;
						}
						// Add score to global leaderboard
						addScoreToLeaderboard(LK.getScore());
						// Pass the current score and high score to game over display
						LK.showGameOver({
							score: LK.getScore(),
							highScore: highScore
						});
					}
				}
			}
			fruit.destroy();
			fruits.splice(i, 1);
		}
	}
	// Check for blade collisions
	handleBladeCollisions();
	// Update blade
	blade.update();
	// Update boss if active
	if (boss && boss.active) {
		boss.update(1 / 60); // Pass approximate delta time
	}
	// If boss was defeated, move to next level
	if (bossActivated && boss && !boss.active) {
		bossActivated = false;
		nextLevelNotified = false;
		// Move to next level if we haven't reached level 5 yet
		if (currentLevel < 5) {
			currentLevel++;
			// Show level notification
			showLevelText(currentLevel);
		} else if (currentLevel === 5) {
			// Player has beaten all levels
			LK.effects.flashScreen(0x00FF00, 800);
			// Show "You Win" screen after completing all levels
			if (LK.getScore() > highScore) {
				highScore = LK.getScore();
				storage.highScore = highScore;
			}
			// Add score to global leaderboard
			addScoreToLeaderboard(LK.getScore());
			// Show you win screen
			LK.showYouWin({
				score: LK.getScore(),
				highScore: highScore
			});
		}
	}
	// Check combo timer
	if (comboCount > 0 && Date.now() > comboTimer) {
		updateCombo();
	}
	// Update bullet time effect
	if (bulletTimeActive) {
		updateBulletTime();
	}
};
// Handle touch/mouse events
game.down = function (x, y, obj) {
	blade.active = true;
	blade.reset();
	blade.addPoint(x, y);
};
game.move = function (x, y, obj) {
	if (blade.active) {
		blade.addPoint(x, y);
		handleBladeCollisions();
	}
};
game.up = function (x, y, obj) {
	blade.active = false;
};
// Start the game
setupGame(); /**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/**** 
* Classes
****/ 
var Blade = Container.expand(function () {
	var self = Container.call(this);
	self.active = false;
	self.points = [];
	self.maxPoints = 20; // Increased from 10 to 20 to track more points for smoother detection
	self.trail = [];
	for (var i = 0; i < self.maxPoints; i++) {
		var trailPart = self.attachAsset('blade', {
			anchorX: 0.5,
			anchorY: 0.5,
			alpha: 0
		});
		self.trail.push(trailPart);
	}
	self.update = function () {
		// Update trail visuals
		for (var i = 0; i < self.trail.length; i++) {
			if (i < self.points.length) {
				var point = self.points[i];
				var trailPart = self.trail[i];
				trailPart.x = point.x;
				trailPart.y = point.y;
				trailPart.alpha = 0; // Keep blade invisible
				if (i > 0) {
					var prevPoint = self.points[i - 1];
					var angle = Math.atan2(point.y - prevPoint.y, point.x - prevPoint.x);
					trailPart.rotation = angle;
				}
			} else {
				self.trail[i].alpha = 0;
			}
		}
	};
	self.addPoint = function (x, y) {
		self.points.unshift({
			x: x,
			y: y
		});
		if (self.points.length > self.maxPoints) {
			self.points.pop();
		}
	};
	self.reset = function () {
		self.points = [];
		self.active = false;
		for (var i = 0; i < self.trail.length; i++) {
			self.trail[i].alpha = 0;
		}
	};
	return self;
});
var BlitzPowerup = Container.expand(function () {
	var self = Container.call(this);
	self.type = 'blitz';
	self.sliced = false;
	self.width = 300;
	self.height = 300;
	self.points = 0;
	self.baseSpeed = 1.5;
	// Create a red lightning bolt-shaped fruit for blitz
	var blitzGraphics = self.attachAsset('kiwi', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	blitzGraphics.tint = 0xFF0000; // Red color for blitz power
	// Create lightning bolt symbol
	var boltTop = self.attachAsset('blade', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 20,
		height: 100
	});
	boltTop.tint = 0xFFFFFF;
	boltTop.rotation = Math.PI / 4;
	boltTop.y = -30;
	var boltBottom = self.attachAsset('blade', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 20,
		height: 100
	});
	boltBottom.tint = 0xFFFFFF;
	boltBottom.rotation = -Math.PI / 4;
	boltBottom.y = 30;
	self.vx = 0;
	self.vy = 0;
	self.gravity = 0.01;
	self.rotationSpeed = (Math.random() - 0.5) * 0.015;
	self.init = function (x, y, direction) {
		self.x = x;
		self.y = y;
		var angle = direction * (Math.PI / 4) + Math.random() * Math.PI / 8 - Math.PI / 16;
		var speed = self.baseSpeed + Math.random() * 0.8;
		self.vx = Math.cos(angle) * speed * 1.15;
		self.vy = -Math.sin(angle) * speed - 8;
	};
	self.slice = function () {
		if (self.sliced) {
			return;
		}
		self.sliced = true;
		// Flash effect
		blitzGraphics.tint = 0xFFFFFF;
		boltTop.tint = 0xFF0000;
		boltBottom.tint = 0xFF0000;
		tween(blitzGraphics, {
			alpha: 0,
			scaleX: 1.5,
			scaleY: 1.5
		}, {
			duration: 300,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				blitzGraphics.tint = 0xFF0000;
			}
		});
		// Display "Blitzkrieg!" text in the middle of screen
		var blitzText = new Text2('Blitzkrieg!', {
			size: 120,
			fill: 0xFF0000,
			weight: 'bold'
		});
		blitzText.anchor.set(0.5, 0.5);
		blitzText.x = GAME_WIDTH / 2;
		blitzText.y = GAME_HEIGHT / 2;
		game.addChild(blitzText);
		// Animate the text
		tween(blitzText, {
			scaleX: 1.5,
			scaleY: 1.5,
			alpha: 0
		}, {
			duration: 1500,
			easing: tween.elasticOut,
			onFinish: function onFinish() {
				blitzText.destroy();
			}
		});
		// Shake the screen effect
		var originalX = game.x;
		var originalY = game.y;
		var shakeCount = 0;
		var maxShakes = 10;
		var shakeIntensity = 20;
		var shakeInterval = LK.setInterval(function () {
			if (shakeCount >= maxShakes) {
				LK.clearInterval(shakeInterval);
				game.x = originalX;
				game.y = originalY;
				// After shake is done, destroy all fruits
				LK.getSound('explosion').play();
				// Destroy all fruits on screen (including bombs)
				for (var i = fruits.length - 1; i >= 0; i--) {
					var fruit = fruits[i];
					if (fruit.type !== 'lifefruit' && fruit.type !== 'bullettime' && fruit.type !== 'blitz') {
						// Add points for each destroyed fruit
						if (fruit.type !== 'bomb') {
							LK.setScore(LK.getScore() + fruit.points);
						}
						// Create explosive effect for each fruit
						var fruitGraphics = fruit.children[0];
						fruitGraphics.tint = 0xFFFFFF;
						tween(fruitGraphics, {
							alpha: 0,
							scaleX: 1.5,
							scaleY: 1.5
						}, {
							duration: 200,
							easing: tween.easeOut
						});
						// Play squash sound for each fruit
						LK.getSound('squash').play();
						// Remove fruit
						fruit.destroy();
						fruits.splice(i, 1);
					}
				}
				// Update score display
				scoreTxt.setText(LK.getScore());
				return;
			}
			// Apply random shake offset
			game.x = originalX + (Math.random() - 0.5) * shakeIntensity;
			game.y = originalY + (Math.random() - 0.5) * shakeIntensity;
			shakeCount++;
		}, 50);
		// Play slice sound
		LK.getSound('slice').play();
		LK.getSound('squash').play();
	};
	self.down = function (x, y, obj) {
		if (!self.sliced) {
			self.slice();
			// Update combo
			comboCount++;
			comboTimer = Date.now() + comboTimeout;
		}
	};
	self.update = function () {
		// Don't update movement if gameActive is false (leaderboard is visible)
		if (!gameActive) {
			return;
		}
		if (!self.sliced) {
			// Update whole fruit
			self.vy += self.gravity;
			self.x += self.vx;
			self.y += self.vy;
			self.rotation += self.rotationSpeed;
			// Bounce off walls if not sliced
			if (self.x < self.width / 2 && self.vx < 0) {
				self.vx = -self.vx * 0.8;
				self.x = self.width / 2;
			}
			if (self.x > GAME_WIDTH - self.width / 2 && self.vx > 0) {
				self.vx = -self.vx * 0.8;
				self.x = GAME_WIDTH - self.width / 2;
			}
		}
	};
	self.isOffScreen = function () {
		return self.y > 2732 + self.height || self.x > GAME_WIDTH + self.width;
	};
	return self;
});
var Boss = Container.expand(function (level) {
	var self = Container.call(this);
	// Boss properties
	self.level = level || 1;
	self.health = 5 + self.level; // Health increases with level
	self.maxHealth = self.health;
	self.width = 800;
	self.height = 800;
	self.active = false;
	self.attackTimer = 0;
	self.attackInterval = self.level === 5 ? 833 : 3000 - self.level * 250; // Level 5 boss spawn speed reduced by 25% (increased from 667ms to 833ms)
	// Ensure level is within valid range (1-5)
	if (self.level < 1) {
		self.level = 1;
	}
	if (self.level > 5) {
		self.level = 5;
	}
	// Determine boss type based on level
	var bossType = BOSS_FRUIT_TYPES[self.level - 1] || 'strawberry';
	// Create boss visual
	var bossGraphic = self.attachAsset(bossType, {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: self.level === 1 ? 1.95 : self.level === 2 ? 2.8 : self.level === 5 ? 3.5 : 4,
		// Make level 1 boss smaller by 35%, level 2 boss smaller by 30%, level 5 boss 30% smaller (from 5 to 3.5)
		scaleY: self.level === 1 ? 1.95 : self.level === 2 ? 2.8 : self.level === 5 ? 3.5 : 4 // Make level 1 boss smaller by 35%, level 2 boss smaller by 30%, level 5 boss 30% smaller (from 5 to 3.5)
	});
	// Health bar background
	var healthBarBg = new Container();
	healthBarBg.x = -200;
	healthBarBg.y = -450;
	var healthBarBack = LK.getAsset('blade', {
		anchorX: 0,
		anchorY: 0.5,
		width: 400,
		height: 30
	});
	healthBarBack.tint = 0x333333;
	// Health bar fill
	var healthBarFill = LK.getAsset('blade', {
		anchorX: 0,
		anchorY: 0.5,
		width: 400,
		height: 30
	});
	healthBarFill.tint = 0xFF0000;
	healthBarBg.addChild(healthBarBack);
	healthBarBg.addChild(healthBarFill);
	self.addChild(healthBarBg);
	self.healthBar = healthBarFill;
	// Boss movement
	self.vx = self.level === 5 ? 8 : 2 + self.level * 0.5; // Level 5 boss moves much faster
	self.targetX = GAME_WIDTH / 2;
	self.activate = function () {
		self.active = true;
		self.health = self.maxHealth;
		self.x = GAME_WIDTH / 2;
		// Position boss below the top boundary (320px) with enough space to not overlap
		// Boss dimensions depend on the asset scale (4x) and boss type
		// Account for boss height and health bar to ensure it appears fully below the boundary
		// Position bosses at different heights based on level to avoid overlapping the top boundary
		if (self.level === 2) {
			self.y = 320 + 570; // Level 2 boss: 60px lower
		} else if (self.level === 3) {
			self.y = 320 + 690; // Level 3 boss: 170px lower (moved additional 30px lower)
		} else if (self.level === 4) {
			self.y = 320 + 750; // Level 4 boss: 200px lower
		} else if (self.level === 5) {
			self.y = 320 + 900; // Level 5 boss: 300px lower (moved from 600 to 900)
		} else {
			self.y = 320 + 570; // Default position for level 1 boss
		}
		self.updateHealthBar();
	};
	self.updateHealthBar = function () {
		self.healthBar.width = self.health / self.maxHealth * 400;
	};
	self.hit = function () {
		if (!self.active) {
			return;
		}
		self.health--;
		self.updateHealthBar();
		// Flash the boss red
		bossGraphic.tint = 0xFF0000;
		LK.setTimeout(function () {
			bossGraphic.tint = 0xFFFFFF;
		}, 200);
		// Check if boss is defeated
		if (self.health <= 0) {
			self.defeat();
			return true;
		}
		return false;
	};
	self.defeat = function () {
		self.active = false;
		// Make the health bar transparent
		healthBarBg.alpha = 0;
		// Create explosion effect
		bossGraphic.tint = 0xFFFFFF;
		tween(bossGraphic, {
			alpha: 0,
			scaleX: 3,
			scaleY: 3,
			rotation: Math.PI * 2
		}, {
			duration: 1000,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				// Add bonus points (increased for higher level bosses)
				var bonus = 25 * self.level;
				LK.setScore(LK.getScore() + bonus);
				scoreTxt.setText(LK.getScore());
				LK.effects.flashScreen(0x00FF00, 500);
			}
		});
		// Play explosion sound
		LK.getSound('explosion').play();
	};
	self.throwFruit = function () {
		if (!self.active) {
			return;
		}
		// Launch multiple bombs at the player
		var bombCount = self.level === 5 ? Math.floor(Math.random() * 3) + 2 :
		// Level 5: 2-4 bombs (reduced from 3-6)
		Math.floor(Math.random() * self.level) + 1; // Other levels: 1-level bombs
		// For level 5, also spawn random fruits alongside bombs
		// Also spawn random fruits with level 1 and level 2 bosses
		var fruitCount = self.level === 5 || self.level === 1 || self.level === 2 ? Math.floor(Math.random() * 2) : 0; // Reduced from 1-2 to 0-1
		// Spawn bombs
		for (var i = 0; i < bombCount; i++) {
			var fruit = new Fruit('bomb');
			// Generate random position on the boss perimeter
			var spawnAngle = Math.random() * Math.PI * 2; // Full 360 degrees
			var spawnRadius = self.width / 3; // Radius to spawn from (edge of boss)
			// Position the bomb on the perimeter
			fruit.x = self.x + Math.cos(spawnAngle) * spawnRadius;
			fruit.y = self.y + Math.sin(spawnAngle) * spawnRadius;
			// Aim outward from the spawn point with spread
			var angle = spawnAngle + Math.PI + (Math.random() - 0.5); // Outward direction with randomness
			var speed = self.level === 5 ? 5 + Math.random() * 3 :
			// Level 5: Much faster bombs
			3 + Math.random() * 2 + self.level * 0.5; // Other levels: Normal speed
			fruit.vx = Math.cos(angle) * speed;
			fruit.vy = Math.sin(angle) * speed;
			game.addChild(fruit);
			fruits.push(fruit);
		}
		// For level 5, level 1, or level 2, also spawn random fruits
		if (self.level === 5 || self.level === 1 || self.level === 2) {
			// Level 2 boss spawns fewer fruits (1-2 instead of 2-3)
			var fruitCount = self.level === 2 ? Math.floor(Math.random() * 2) + 1 : self.level === 5 || self.level === 1 ? Math.floor(Math.random() * 2) : 0;
			for (var j = 0; j < fruitCount; j++) {
				// Select a random fruit type
				// For level 1, only use level 1 fruits (strawberry)
				// For level 2, use level 2 fruits (strawberry, kiwi)
				var availableFruits;
				if (self.level === 1) {
					availableFruits = ['strawberry']; // Level 1 fruits
				} else if (self.level === 2) {
					availableFruits = ['strawberry', 'kiwi']; // Level 2 fruits
				} else {
					availableFruits = FRUIT_TYPES; // All fruits for level 5
				}
				var fruitType = availableFruits[Math.floor(Math.random() * availableFruits.length)];
				var randomFruit = new Fruit(fruitType);
				// Generate random position on the boss perimeter
				var fruitAngle = Math.random() * Math.PI * 2;
				var fruitRadius = self.width / 3;
				// Position the fruit on the perimeter
				randomFruit.x = self.x + Math.cos(fruitAngle) * fruitRadius;
				randomFruit.y = self.y + Math.sin(fruitAngle) * fruitRadius;
				// Aim outward with different trajectory
				var fruitDirection = fruitAngle + Math.PI + (Math.random() - 0.5) * 0.5;
				var fruitSpeed = 4 + Math.random() * 2;
				randomFruit.vx = Math.cos(fruitDirection) * fruitSpeed;
				randomFruit.vy = Math.sin(fruitDirection) * fruitSpeed;
				game.addChild(randomFruit);
				fruits.push(randomFruit);
			}
		}
	};
	self.update = function (delta) {
		if (!self.active) {
			return;
		}
		// Apply bullet time effect if active (slow down by 75%)
		var speedMultiplier = bulletTimeActive ? 0.25 : 1;
		// Move boss back and forth
		if (Math.abs(self.x - self.targetX) < 10) {
			self.targetX = Math.random() * (GAME_WIDTH - 400) + 200;
		}
		var dirX = self.targetX - self.x;
		self.x += dirX / Math.abs(dirX) * self.vx * speedMultiplier;
		// Attack on timer
		var currentTime = Date.now();
		if (currentTime >= self.attackTimer) {
			self.throwFruit();
			// Extend attack interval during bullet time
			self.attackTimer = currentTime + self.attackInterval * (bulletTimeActive ? 4 : 1);
		}
	};
	self.down = function (x, y, obj) {
		// Allow clicking on boss to damage it
		if (self.active) {
			self.hit();
		}
	};
	return self;
});
var BulletTimePowerup = Container.expand(function () {
	var self = Container.call(this);
	self.type = 'bullettime';
	self.sliced = false;
	self.width = 300;
	self.height = 300;
	self.points = 0;
	self.baseSpeed = 1.5;
	// Create a blue hourglass-shaped fruit for bullet time
	var bulletTimeGraphics = self.attachAsset('kiwi', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	bulletTimeGraphics.tint = 0x00BFFF; // Deep sky blue color
	// Create hourglass symbol
	var hourglassTop = self.attachAsset('blade', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 140,
		height: 20
	});
	hourglassTop.tint = 0xFFFFFF;
	hourglassTop.y = -50;
	var hourglassBottom = self.attachAsset('blade', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 140,
		height: 20
	});
	hourglassBottom.tint = 0xFFFFFF;
	hourglassBottom.y = 50;
	var hourglassLeft = self.attachAsset('blade', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 20,
		height: 100
	});
	hourglassLeft.tint = 0xFFFFFF;
	hourglassLeft.x = -60;
	var hourglassRight = self.attachAsset('blade', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 20,
		height: 100
	});
	hourglassRight.tint = 0xFFFFFF;
	hourglassRight.x = 60;
	self.vx = 0;
	self.vy = 0;
	self.gravity = 0.01;
	self.rotationSpeed = (Math.random() - 0.5) * 0.015;
	self.init = function (x, y, direction) {
		self.x = x;
		self.y = y;
		var angle = direction * (Math.PI / 4) + Math.random() * Math.PI / 8 - Math.PI / 16;
		var speed = self.baseSpeed + Math.random() * 0.8;
		self.vx = Math.cos(angle) * speed * 1.15;
		self.vy = -Math.sin(angle) * speed - 8;
	};
	self.slice = function () {
		if (self.sliced) {
			return;
		}
		self.sliced = true;
		// Flash effect
		bulletTimeGraphics.tint = 0xFFFFFF;
		hourglassTop.tint = 0x00BFFF;
		hourglassBottom.tint = 0x00BFFF;
		hourglassLeft.tint = 0x00BFFF;
		hourglassRight.tint = 0x00BFFF;
		tween(bulletTimeGraphics, {
			alpha: 0,
			scaleX: 1.5,
			scaleY: 1.5
		}, {
			duration: 300,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				bulletTimeGraphics.tint = 0x00BFFF;
			}
		});
		// Activate bullet time effect
		activateBulletTime();
		// Play slice and bullet sounds only (no squash)
		LK.getSound('slice').play();
		LK.getSound('bullet').play();
	};
	self.down = function (x, y, obj) {
		if (!self.sliced) {
			self.slice();
			// Update combo
			comboCount++;
			comboTimer = Date.now() + comboTimeout;
		}
	};
	self.update = function () {
		// Don't update movement if gameActive is false (leaderboard is visible)
		if (!gameActive) {
			return;
		}
		if (!self.sliced) {
			// Update whole fruit
			self.vy += self.gravity;
			self.x += self.vx;
			self.y += self.vy;
			self.rotation += self.rotationSpeed;
			// Bounce off walls if not sliced
			if (self.x < self.width / 2 && self.vx < 0) {
				self.vx = -self.vx * 0.8;
				self.x = self.width / 2;
			}
			if (self.x > GAME_WIDTH - self.width / 2 && self.vx > 0) {
				self.vx = -self.vx * 0.8;
				self.x = GAME_WIDTH - self.width / 2;
			}
		}
	};
	self.isOffScreen = function () {
		return self.y > 2732 + self.height || self.x > GAME_WIDTH + self.width;
	};
	return self;
});
var Fruit = Container.expand(function (type) {
	var self = Container.call(this);
	self.type = type || 'apple';
	self.sliced = false;
	self.width = 0;
	self.height = 0;
	self.points = 0;
	self.baseSpeed = 0;
	var fruitGraphics;
	switch (self.type) {
		case 'watermelon':
			self.width = 200;
			self.height = 200;
			self.points = 5;
			self.baseSpeed = 1.6; // Faster base speed
			break;
		case 'apple':
			self.width = 240;
			self.height = 240;
			self.points = 4;
			self.baseSpeed = 1.7; // Faster base speed
			break;
		case 'orange':
			self.width = 280;
			self.height = 280;
			self.points = 3;
			self.baseSpeed = 1.8; // Faster base speed
			break;
		case 'kiwi':
			self.width = 320;
			self.height = 320;
			self.points = 2;
			self.baseSpeed = 2.0; // Faster base speed
			break;
		case 'passion_fruit':
			self.width = 360;
			self.height = 360;
			self.points = 6;
			self.baseSpeed = 2.3; // Even faster base speed
			break;
		case 'strawberry':
			self.width = 480;
			self.height = 480;
			self.points = 1;
			self.baseSpeed = 2.2; // Faster base speed
			break;
		case 'bomb':
			self.width = 320;
			self.height = 320;
			self.points = -10;
			self.baseSpeed = 1.7; // Faster base speed
			break;
	}
	fruitGraphics = self.attachAsset(self.type, {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.vx = 0;
	self.vy = 0;
	self.gravity = 0.01; // Reduced gravity to make fruits go higher
	self.rotationSpeed = (Math.random() - 0.5) * 0.018; // Slightly faster rotation
	self.init = function (x, y, direction) {
		self.x = x;
		self.y = y;
		var angle = direction * (Math.PI / 4) + Math.random() * Math.PI / 8 - Math.PI / 16;
		var currentLevel = Math.floor(LK.getScore() / 50) + 1;
		var levelMultiplier = 1 + (currentLevel - 1) * 0.1; // 10% increase per level
		// Use constant base speed without random factor to keep speed consistent within level
		var speed = self.baseSpeed * levelMultiplier;
		// Apply 30% speed reduction for level 1
		if (currentLevel === 1) {
			speed *= 0.7; // 30% slower for level 1
		}
		self.vx = Math.cos(angle) * speed * 1.15; // Slightly faster horizontal movement
		self.vy = -Math.sin(angle) * speed - 8; // Higher initial upward velocity
	};
	self.slice = function () {
		if (self.sliced) {
			return;
		}
		self.sliced = true;
		// Create explosive flash effect
		fruitGraphics.tint = 0xFFFFFF;
		fruitGraphics.alpha = 1;
		// Animate explosive flash effect with scaling
		tween(fruitGraphics, {
			alpha: 0,
			scaleX: 1.5,
			scaleY: 1.5
		}, {
			duration: 300,
			easing: tween.easeOut,
			onUpdate: function onUpdate(progress) {
				// Create a pulsing effect with rotation during explosion
				fruitGraphics.rotation += 0.1;
			},
			onFinish: function onFinish() {
				// Clean up after animation
				fruitGraphics.tint = 0xFFFFFF;
				fruitGraphics.scaleX = 1;
				fruitGraphics.scaleY = 1;
			}
		});
		// Play slice and squash sounds
		LK.getSound('slice').play();
		LK.getSound('squash').play();
		return self.points;
	};
	self.down = function (x, y, obj) {
		if (!self.sliced) {
			// Slice the fruit when clicked
			var points = self.slice();
			// Check if it's a bomb
			if (self.type === 'bomb') {
				// Lose a life when clicking a bomb
				LK.getSound('explosion').play();
				LK.effects.flashScreen(0xFF0000, 500);
				playerLives--; // Reduce lives by 1
				updateLivesDisplay(); // Update hearts display
				// Make bomb disappear
				self.sliced = true;
				// Create explosive flash effect for bomb
				fruitGraphics.tint = 0xFFFFFF;
				// Animate bomb disappearing
				tween(fruitGraphics, {
					alpha: 0,
					scaleX: 1.5,
					scaleY: 1.5
				}, {
					duration: 300,
					easing: tween.easeOut,
					onFinish: function onFinish() {
						// Remove bomb from game
						self.destroy();
						// Find and remove from fruits array
						var index = fruits.indexOf(self);
						if (index > -1) {
							fruits.splice(index, 1);
						}
					}
				});
				// If no lives left, game over
				if (playerLives <= 0) {
					// Update high score if current score is higher
					if (LK.getScore() > highScore) {
						highScore = LK.getScore();
						storage.highScore = highScore;
					}
					// Add score to global leaderboard
					addScoreToLeaderboard(LK.getScore());
					// Pass the current score and high score to game over display
					LK.showGameOver({
						score: LK.getScore(),
						highScore: highScore
					});
				}
				return;
			}
			// Add points to score
			LK.setScore(LK.getScore() + points);
			scoreTxt.setText(LK.getScore());
			// Increment sliced fruits counter for current level
			slicedFruitsInLevel++;
			// Update combo
			comboCount++;
			comboTimer = Date.now() + comboTimeout;
		}
	};
	self.update = function () {
		// Don't update movement if gameActive is false (leaderboard is visible)
		if (!gameActive) {
			return;
		}
		if (!self.sliced) {
			// Update whole fruit
			// Apply bullet time effect if active (slow down by 75%)
			var speedMultiplier = bulletTimeActive ? 0.25 : 1;
			self.vy += self.gravity * speedMultiplier;
			self.x += self.vx * speedMultiplier;
			self.y += self.vy * speedMultiplier;
			self.rotation += self.rotationSpeed * speedMultiplier;
			// Bounce off walls if not sliced
			if (self.x < self.width / 2 && self.vx < 0) {
				self.vx = -self.vx * 0.8; // Bounce with some energy loss
				self.x = self.width / 2;
			}
			if (self.x > GAME_WIDTH - self.width / 2 && self.vx > 0) {
				self.vx = -self.vx * 0.8; // Bounce with some energy loss
				self.x = GAME_WIDTH - self.width / 2;
			}
		} else {
			// No update for sliced fruit since we're just flashing and fading them
		}
	};
	self.isOffScreen = function () {
		return self.y > 2732 + self.height || self.x > GAME_WIDTH + self.width;
	};
	return self;
});
var Heart = Container.expand(function () {
	var self = Container.call(this);
	// Create a red heart shape (using blade asset tinted red)
	var heartShape = self.attachAsset('blade', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 60,
		height: 60
	});
	heartShape.tint = 0xFF0000;
	return self;
});
var Leaderboard = Container.expand(function () {
	var self = Container.call(this);
	self.visible = false;
	// Background panel
	var panel = self.attachAsset('blade', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 1500,
		height: 1800
	});
	panel.tint = 0x111111; // Very dark color (almost black) for better contrast
	panel.alpha = 0.9; // Slightly transparent for better visibility
	// Title
	var title = new Text2('GLOBAL LEADERBOARD', {
		size: 100,
		fill: 0xFFFFFF
	});
	title.anchor.set(0.5, 0);
	title.y = -800;
	self.addChild(title);
	// Scores container
	var scoresContainer = new Container();
	scoresContainer.y = -650;
	self.addChild(scoresContainer);
	self.scoresContainer = scoresContainer;
	// Close button
	var closeBtn = self.attachAsset('blade', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 80,
		height: 80
	});
	closeBtn.tint = 0xFF0000;
	closeBtn.x = 700;
	closeBtn.y = -800;
	// X symbol on close button
	var closeX1 = self.attachAsset('blade', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 40,
		height: 8
	});
	closeX1.tint = 0xFFFFFF;
	closeX1.rotation = Math.PI / 4;
	closeX1.x = 700;
	closeX1.y = -800;
	var closeX2 = self.attachAsset('blade', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 40,
		height: 8
	});
	closeX2.tint = 0xFFFFFF;
	closeX2.rotation = -Math.PI / 4;
	closeX2.x = 700;
	closeX2.y = -800;
	// Close button interaction
	closeBtn.interactive = true;
	closeBtn.down = function (x, y, obj) {
		self.hide();
	};
	// Show leaderboard
	self.show = function (scores) {
		self.visible = true;
		self.updateScores(scores);
		// Pause the game when leaderboard is visible
		gameActive = false;
		// Make game area 50% transparent
		game.alpha = 0.5;
		// Make leaderboard panel fully opaque (0% transparent)
		panel.alpha = 1.0;
		// Bring leaderboard to front layer
		if (self.parent) {
			var parent = self.parent;
			parent.removeChild(self);
			parent.addChild(self);
		}
	};
	// Hide leaderboard
	self.hide = function () {
		self.visible = false;
		// Resume the game when leaderboard is hidden
		gameActive = true;
		// Restore game area opacity
		game.alpha = 1.0;
	};
	// Update scores display
	self.updateScores = function (scores) {
		// Clear existing score entries
		while (scoresContainer.children.length > 0) {
			scoresContainer.removeChildAt(0);
		}
		// Add score entries
		for (var i = 0; i < scores.length; i++) {
			var entry = scores[i];
			var yPos = i * 120;
			// Rank
			var rank = new Text2(i + 1 + '.', {
				size: 80,
				fill: 0xFFFFFF
			});
			rank.anchor.set(1, 0);
			rank.x = -600;
			rank.y = yPos;
			scoresContainer.addChild(rank);
			// Username
			var username = entry.username || "Player";
			var usernameText = new Text2(username, {
				size: 60,
				fill: 0xFFFFFF
			});
			usernameText.anchor.set(0, 0);
			usernameText.x = -500;
			usernameText.y = yPos;
			scoresContainer.addChild(usernameText);
			// Score value
			var scoreText = new Text2(entry.score.toString(), {
				size: 80,
				fill: 0xFFF200 // Brighter yellow color for better visibility
			});
			scoreText.anchor.set(0, 0);
			scoreText.x = 0;
			scoreText.y = yPos;
			scoresContainer.addChild(scoreText);
		}
		// Add message if no scores
		if (scores.length === 0) {
			var noScores = new Text2("No scores yet!", {
				size: 80,
				fill: 0x00FFFF //{3Y} // Bright cyan color for better visibility
			});
			noScores.anchor.set(0.5, 0);
			noScores.y = 100;
			scoresContainer.addChild(noScores);
		}
	};
	return self;
});
var LeaderboardButton = Container.expand(function () {
	var self = Container.call(this);
	// Create button background
	var buttonBg = self.attachAsset('blade', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 400,
		height: 120
	});
	buttonBg.tint = 0x3498db;
	// Create button text that says LEADERBOARD
	var buttonText = new Text2('LEADERBOARD', {
		size: 60,
		fill: 0xFFFFFF
	});
	buttonText.anchor.set(0.5, 0.5);
	self.addChild(buttonText);
	// Button interaction
	self.down = function (x, y, obj) {
		// Scale down effect on press
		tween(self, {
			scaleX: 0.9,
			scaleY: 0.9
		}, {
			duration: 100
		});
		// Toggle leaderboard visibility
		if (leaderboard && leaderboard.visible) {
			leaderboard.hide();
		} else {
			showLeaderboard();
		}
	};
	self.up = function (x, y, obj) {
		// Scale back to normal on release
		tween(self, {
			scaleX: 1,
			scaleY: 1
		}, {
			duration: 100
		});
	};
	return self;
});
var LifeFruit = Container.expand(function () {
	var self = Container.call(this);
	self.type = 'lifefruit';
	self.sliced = false;
	self.width = 320;
	self.height = 320;
	self.points = 0;
	self.baseSpeed = 1.5;
	// Create a white fruit with heart shape for extra life
	var lifeGraphics = self.attachAsset('kiwi', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	lifeGraphics.tint = 0xFFFFFF; // White color for life fruit
	var heartShape = self.attachAsset('blade', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 120,
		height: 120
	});
	heartShape.tint = 0xFF0000;
	self.vx = 0;
	self.vy = 0;
	self.gravity = 0.01;
	self.rotationSpeed = (Math.random() - 0.5) * 0.015;
	self.init = function (x, y, direction) {
		self.x = x;
		self.y = y;
		var angle = direction * (Math.PI / 4) + Math.random() * Math.PI / 8 - Math.PI / 16;
		var speed = self.baseSpeed + Math.random() * 0.8;
		self.vx = Math.cos(angle) * speed * 1.15;
		self.vy = -Math.sin(angle) * speed - 8;
	};
	self.slice = function () {
		if (self.sliced) {
			return;
		}
		self.sliced = true;
		// Add an extra life
		playerLives = Math.min(playerLives + 1, 5); // Cap at maximum 5 lives
		updateLivesDisplay();
		// Flash effect
		lifeGraphics.tint = 0xFFFFFF;
		heartShape.tint = 0xFFFFFF;
		tween(lifeGraphics, {
			alpha: 0,
			scaleX: 1.5,
			scaleY: 1.5
		}, {
			duration: 300,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				lifeGraphics.tint = 0xFFFFFF;
				heartShape.tint = 0xFF0000;
			}
		});
		// Play slice and squash sounds
		LK.getSound('slice').play();
		LK.getSound('squash').play();
	};
	self.down = function (x, y, obj) {
		if (!self.sliced) {
			self.slice();
			// Update combo
			comboCount++;
			comboTimer = Date.now() + comboTimeout;
		}
	};
	self.update = function () {
		// Don't update movement if gameActive is false (leaderboard is visible)
		if (!gameActive) {
			return;
		}
		if (!self.sliced) {
			// Update whole fruit
			// Apply bullet time effect if active (slow down by 75%)
			var speedMultiplier = bulletTimeActive ? 0.25 : 1;
			self.vy += self.gravity * speedMultiplier;
			self.x += self.vx * speedMultiplier;
			self.y += self.vy * speedMultiplier;
			self.rotation += self.rotationSpeed * speedMultiplier;
			// Bounce off walls if not sliced
			if (self.x < self.width / 2 && self.vx < 0) {
				self.vx = -self.vx * 0.8;
				self.x = self.width / 2;
			}
			if (self.x > GAME_WIDTH - self.width / 2 && self.vx > 0) {
				self.vx = -self.vx * 0.8;
				self.x = GAME_WIDTH - self.width / 2;
			}
		}
	};
	self.isOffScreen = function () {
		return self.y > 2732 + self.height || self.x > GAME_WIDTH + self.width;
	};
	return self;
});
var PlayAreaBoundary = Container.expand(function (isTop) {
	var self = Container.call(this);
	var line = self.attachAsset('blade', {
		anchorX: 0,
		anchorY: 0.5,
		width: GAME_WIDTH,
		height: 10
	});
	line.tint = 0xFFFFFF;
	line.alpha = 0.7;
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x3498DB
});
/**** 
* Game Code
****/ 
// Game constants
var GAME_WIDTH = 2048;
var GAME_HEIGHT = 2732;
var SPAWN_INTERVAL_MIN = 1000; // Decreased spawn interval minimum for more frequent spawning
var SPAWN_INTERVAL_MAX = 2000; // Decreased spawn interval maximum for more frequent spawning
var SPAWN_COUNT_MIN = 1;
var SPAWN_COUNT_MAX = 2; // Increased to spawn more fruits at once
var FRUIT_TYPES = ['watermelon', 'apple', 'orange', 'kiwi', 'strawberry', 'passion_fruit'];
var BOSS_FRUIT_TYPES = ['strawberry', 'kiwi', 'orange', 'apple', 'passion_fruit']; // Boss type matches newest fruit type introduced in each level
var LEVEL_THRESHOLDS = [5, 50, 150, 300, 450]; // Score thresholds for each level boss
var LEVEL_FRUITS = [['strawberry'],
// Level 1 fruits
['strawberry', 'kiwi'],
// Level 2 fruits
['strawberry', 'kiwi', 'orange'],
// Level 3 fruits
['strawberry', 'kiwi', 'orange', 'apple'],
// Level 4 fruits
['strawberry', 'kiwi', 'orange', 'apple', 'watermelon'] // Level 5 fruits
];
var BOMB_PROBABILITY = 0.2; // Increased bomb probability
// Game variables
var fruits = [];
var blade = null;
// Boss-related variables
var boss = null;
var bossActivated = false;
var slicedFruitsInLevel = 0; // Track how many fruits sliced in current level for boss activation
var bossFlashed = false; // Track if boss has been flashed in current level
// Bullet time variables
var bulletTimeActive = false;
var bulletTimeEndTime = 0;
var bulletTimeBar; // Progress bar for bullet time
var bulletTimeDuration = 10000; // 10 seconds
// Level tracking
var currentLevel = 1;
var nextLevelNotified = false;
var showingLevelText = false;
var levelTextTimer = 0;
var levelText; // Level notification text
var levelDisplay; // Text to display current level
// Spawn timers
var lastSpawnTime = 0;
var nextSpawnTime = 0;
// Combo system
var comboCount = 0;
var comboTimer = 0;
var comboTimeout = 1000; // ms to reset combo
var comboTxt; // Text to display combo
// Player state
var gameActive = true;
var playerLives = 3; // Player starts with 3 lives
var heartsDisplay; // Container for heart icons
var missedFruits = 0; // Counter for missed fruits
var missedText; // Text to display missed count
var lifeFruitSpawned = 0; // Track how many life fruits we've spawned
// Score-related
var scoreTxt; // Text to display score
var highScore = storage.highScore || 0; // Get high score from storage or default to 0
var highScoreText; // Text to display high score
// Leaderboard
var leaderboardButton; // Button to open leaderboard
var leaderboard; // Leaderboard UI component
// Parse leaderboard scores from storage or use empty array if none exists
var leaderboardScores = [];
if (storage.leaderboardScores) {
	var scoresArray = storage.leaderboardScores.split(';');
	for (var i = 0; i < scoresArray.length; i++) {
		if (scoresArray[i]) {
			var parts = scoresArray[i].split(',');
			var scoreObj = {
				score: parseInt(parts[0])
			};
			if (parts.length > 1) {
				scoreObj.username = parts[1];
			}
			leaderboardScores.push(scoreObj);
		}
	}
} // Global leaderboard data
var playerName = storage.playerName || "Player"; // Get saved player name or use default
// UI elements
var scoreTxt;
var comboTxt;
function setupGame() {
	// Prompt for player name if not already stored
	if (!storage.playerName) {
		var defaultName = "Player";
		// Skip popup for now and just use default name
		// LK.showPopup is not available in the current version
		storage.playerName = defaultName;
		playerName = defaultName;
	}
	// Create blade
	blade = game.addChild(new Blade());
	// Create boss reference but don't create the actual boss instance yet
	// We'll create it only when needed for the boss fight
	boss = null;
	// Set up score display
	scoreTxt = new Text2('0', {
		size: 100,
		fill: 0xFFFFFF,
		weight: 'bold' // Make text bold
	});
	scoreTxt.anchor.set(0.5, 0);
	scoreTxt.y = 30;
	LK.gui.top.addChild(scoreTxt);
	// Set up combo display
	comboTxt = new Text2('', {
		size: 60,
		fill: 0xFFFF00
	});
	comboTxt.anchor.set(0.5, 0);
	comboTxt.y = 140;
	comboTxt.alpha = 0;
	LK.gui.top.addChild(comboTxt);
	// Set up level text display
	levelText = new Text2('Level 1', {
		size: 120,
		fill: 0xFFFFFF
	});
	levelText.anchor.set(0.5, 0.5);
	levelText.x = GAME_WIDTH / 2;
	levelText.y = GAME_HEIGHT / 2;
	levelText.alpha = 0;
	game.addChild(levelText);
	// Add level display to top right
	levelDisplay = new Text2('Level: 1', {
		size: 100,
		fill: 0xFFFFFF,
		weight: 'bold' // Make text bold
	});
	levelDisplay.anchor.set(1, 0);
	levelDisplay.x = GAME_WIDTH - 50; // Right justified 50px from right wall
	levelDisplay.y = 100;
	game.addChild(levelDisplay);
	// Initialize missed counter
	missedFruits = 0;
	// Initialize the missed counter display through the dedicated function
	updateMissedCounter();
	// Set up high score display
	highScoreText = new Text2('Your High Score: ' + highScore, {
		size: 60,
		fill: 0xFFFFFF
	});
	highScoreText.anchor.set(0, 1);
	highScoreText.x = 50;
	highScoreText.y = -30; // Position at the bottom, moved 20 pixels below
	LK.gui.bottomLeft.addChild(highScoreText);
	// Create bullet time bar (initially hidden)
	bulletTimeBar = new Container();
	bulletTimeBar.x = GAME_WIDTH / 2;
	bulletTimeBar.y = 280; // Moved 80px down from the top
	bulletTimeBar.visible = false;
	game.addChild(bulletTimeBar);
	// Bullet time bar background
	var bulletTimeBarBg = LK.getAsset('blade', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 1000,
		height: 30
	});
	bulletTimeBarBg.tint = 0x333333;
	// Bullet time bar fill
	var bulletTimeBarFill = LK.getAsset('blade', {
		anchorX: 0,
		anchorY: 0.5,
		width: 1000,
		height: 30
	});
	bulletTimeBarFill.tint = 0x00BFFF; // Match bullet time powerup color
	bulletTimeBarFill.x = -500; // Center the bar
	// Bullet time text
	var bulletTimeText = new Text2('BULLET TIME', {
		size: 60,
		fill: 0xFFFFFF
	});
	bulletTimeText.anchor.set(0.5, 0.5);
	bulletTimeText.y = -60;
	// Add elements to bullet time bar
	bulletTimeBar.addChild(bulletTimeBarBg);
	bulletTimeBar.addChild(bulletTimeBarFill);
	bulletTimeBar.addChild(bulletTimeText);
	bulletTimeBar.barFill = bulletTimeBarFill; // Store reference to the fill for updates
	// Create hearts display for lives
	heartsDisplay = new Container();
	heartsDisplay.x = GAME_WIDTH - 100; // Right justified 100px from right wall
	heartsDisplay.y = 250; // 250px from top
	game.addChild(heartsDisplay);
	// Add initial hearts (3 lives)
	updateLivesDisplay();
	// Set up leaderboard button
	leaderboardButton = new LeaderboardButton();
	leaderboardButton.x = GAME_WIDTH - 250; // Moved 30px to the left (from 220 to 250)
	leaderboardButton.y = GAME_HEIGHT - 100;
	game.addChild(leaderboardButton);
	// Create and position leaderboard UI
	leaderboard = new Leaderboard();
	leaderboard.x = GAME_WIDTH / 2;
	leaderboard.y = GAME_HEIGHT / 2;
	leaderboard.visible = false;
	game.addChild(leaderboard);
	// Set initial spawn time
	nextSpawnTime = Date.now() + Math.random() * (SPAWN_INTERVAL_MAX - SPAWN_INTERVAL_MIN) + SPAWN_INTERVAL_MIN;
	// Special level 1 powerup spawning removed
	// Play background music
	LK.playMusic('gameMusic');
	// Reset all game state
	currentLevel = 1;
	bossActivated = false;
	nextLevelNotified = false;
	LK.setScore(0);
	missedFruits = 0;
	playerLives = 3; // Reset lives to 3
	lifeFruitSpawned = 0; // Reset life fruit spawn counter
	slicedFruitsInLevel = 0; // Reset sliced fruits counter
	comboCount = 0; // Reset combo counter
	comboTimer = 0; // Reset combo timer
	// Add play area boundary lines
	var topBoundary = new PlayAreaBoundary(true);
	topBoundary.y = 320; // Position 320px from the top
	game.addChild(topBoundary);
	var bottomBoundary = new PlayAreaBoundary(false);
	bottomBoundary.y = GAME_HEIGHT - 200; // Position 200px from the bottom
	game.addChild(bottomBoundary);
	// Show level 1 text at start
	showLevelText(1);
}
// Function to display level text and reset level-specific state
function showLevelText(level) {
	// Set level text content
	levelText.setText('Level ' + level);
	levelText.alpha = 0;
	showingLevelText = true;
	// Reset level-specific counters
	missedFruits = 0;
	updateMissedCounter();
	slicedFruitsInLevel = 0;
	// Reset boss state for new level
	bossActivated = false;
	bossFlashed = false; // Reset boss flash state for new level
	// Reset bullet time
	bulletTimeActive = false;
	bulletTimeBar.visible = false;
	// Update level display in top right
	levelDisplay.setText('Level: ' + level);
	// Animate the level text
	tween(levelText, {
		alpha: 1
	}, {
		duration: 500,
		easing: tween.easeOut,
		onFinish: function onFinish() {
			// Hold the text visible for a moment
			levelTextTimer = Date.now() + 2000;
		}
	});
}
function spawnFruits() {
	var count = currentLevel === 1 ? Math.ceil((Math.floor(Math.random() * (SPAWN_COUNT_MAX - SPAWN_COUNT_MIN + 1)) + SPAWN_COUNT_MIN) / 2) :
	// 50% reduction for level 1
	Math.floor(Math.random() * (SPAWN_COUNT_MAX - SPAWN_COUNT_MIN + 1)) + SPAWN_COUNT_MIN;
	// Get appropriate fruit types for current level
	var availableFruits = LEVEL_FRUITS[currentLevel - 1] || ['strawberry'];
	// Check if we should spawn a life fruit based on the current level
	var spawnLifeFruit = false;
	var spawnBulletTime = false;
	var spawnBlitz = false;
	var maxLifeFruits = currentLevel;
	if (currentLevel === 4) {
		maxLifeFruits = 3;
	} // Level 4 gets 3 life fruits
	if (currentLevel === 1) {
		maxLifeFruits = 3; // Level 1 gets 3 life fruits
	}
	if (lifeFruitSpawned < maxLifeFruits && Math.random() < 0.1) {
		// 10% chance to spawn a life fruit
		spawnLifeFruit = true;
		lifeFruitSpawned++;
	} else if (!bulletTimeActive && Math.random() < 0.05) {
		// 5% chance to spawn bullet time powerup if not already active
		spawnBulletTime = true;
	} else if (Math.random() < (currentLevel === 1 ? 0.12 : 0.05)) {
		// 12% chance to spawn blitz powerup in level 1, 5% in other levels
		spawnBlitz = true;
	}
	// Loop through and create fruits
	for (var i = 0; i < count; i++) {
		var fruit;
		// Create life fruit if it's time
		if (i === 0 && spawnLifeFruit) {
			fruit = new LifeFruit();
		} else if (i === 0 && spawnBulletTime) {
			fruit = new BulletTimePowerup();
		} else if (i === 0 && spawnBlitz) {
			fruit = new BlitzPowerup();
		} else {
			var isBomb = Math.random() < BOMB_PROBABILITY;
			var type = isBomb ? 'bomb' : availableFruits[Math.floor(Math.random() * availableFruits.length)];
			fruit = new Fruit(type);
		}
		// Determine flight pattern
		var pattern = Math.random();
		if (pattern < 0.5) {
			// Horizontal flight from left to right
			var x = -fruit.width;
			var y = Math.random() * (GAME_HEIGHT / 3) + 300; // Higher position range
			fruit.x = x;
			fruit.y = y;
			fruit.vx = fruit.baseSpeed + Math.random() * 2.5; // Slightly faster
			fruit.vy = -Math.random() * 2; // Add slight upward movement
		} else {
			// Vertical drop
			var x = Math.random() * (GAME_WIDTH - 200) + 100;
			var direction = Math.random(); // Random direction between 0 and 1
			fruit.init(x, GAME_HEIGHT, direction);
		}
		game.addChild(fruit);
		fruits.push(fruit);
	}
	// Schedule next spawn with appropriate delay based on level
	// Level 1, 2, & 3: 30% shorter delay
	// Level 4+: normal delay
	var delayMultiplier = 1;
	if (currentLevel === 1) {
		delayMultiplier = 0.7; // 30% shorter delay for level 1
	} else if (currentLevel === 2 || currentLevel === 3) {
		delayMultiplier = 0.7; // 30% shorter delay for level 2 and 3
	}
	nextSpawnTime = Date.now() + delayMultiplier * (Math.random() * (SPAWN_INTERVAL_MAX - SPAWN_INTERVAL_MIN) + SPAWN_INTERVAL_MIN);
}
function updateCombo() {
	if (comboCount > 1) {
		comboTxt.setText('COMBO x' + comboCount + '!');
		comboTxt.alpha = 1;
		// Add combo bonus points
		LK.setScore(LK.getScore() + comboCount * 2);
		// Play combo sound
		LK.getSound('combo').play();
		// Animate combo text
		tween(comboTxt, {
			alpha: 0
		}, {
			duration: 1000,
			easing: tween.easeOut
		});
	}
	comboCount = 0;
}
function handleBladeCollisions() {
	// Return early if the blade isn't active or doesn't have enough points to form a line
	if (!blade.active || blade.points.length < 2) {
		return;
	}
	// Process multiple segments for more accurate detection
	var segmentsToCheck = Math.min(5, blade.points.length - 1);
	// Check multiple segments of the blade for better sensitivity
	var hitFruits = {};
	var hitBoss = false;
	for (var j = 0; j < segmentsToCheck; j++) {
		var startPoint = blade.points[j];
		var endPoint = blade.points[j + 1];
		// Check boss collision if active
		if (boss && boss.active && !hitBoss && lineIntersectsCircle(startPoint.x, startPoint.y, endPoint.x, endPoint.y, boss.x, boss.y, boss.width / 3)) {
			// Hit the boss
			var defeated = boss.hit();
			// Play slice and squash sounds
			LK.getSound('slice').play();
			LK.getSound('squash').play();
			// Update combo
			comboCount++;
			comboTimer = Date.now() + comboTimeout;
			hitBoss = true;
		}
		// Check collisions with fruits
		for (var i = 0; i < fruits.length; i++) {
			var fruit = fruits[i];
			if (!fruit.sliced && !hitFruits[i] && lineIntersectsCircle(startPoint.x, startPoint.y, endPoint.x, endPoint.y, fruit.x, fruit.y, fruit.width / 2)) {
				hitFruits[i] = true;
				if (fruit.type === 'bomb') {
					// Lose a life when hitting a bomb
					LK.getSound('explosion').play();
					LK.effects.flashScreen(0xFF0000, 500);
					playerLives--; // Reduce lives by 1
					updateLivesDisplay(); // Update hearts display
					// If no lives left, game over
					if (playerLives <= 0) {
						// Update high score if current score is higher
						if (LK.getScore() > highScore) {
							highScore = LK.getScore();
							storage.highScore = highScore;
						}
						// Add score to global leaderboard
						addScoreToLeaderboard(LK.getScore());
						// Pass the current score and high score to game over display
						LK.showGameOver({
							score: LK.getScore(),
							highScore: highScore
						});
					}
					break; // Exit the inner loop since we hit a bomb
				}
			}
			// Handle life fruit
			else if (fruit.type === 'lifefruit') {
				// Slice the life fruit and gain an extra life
				fruit.slice();
				// Play a special sound
				LK.getSound('combo').play();
				// Flash green for the extra life
				LK.effects.flashScreen(0x00FF00, 300);
				// Update combo
				comboCount++;
				comboTimer = Date.now() + comboTimeout;
			} else {
				// Slice regular fruit
				var points = fruit.slice();
				LK.setScore(LK.getScore() + points);
				scoreTxt.setText(LK.getScore());
				// Increment sliced fruits counter for current level
				slicedFruitsInLevel++;
				// Play slice sound
				LK.getSound('slice').play();
				// Update combo
				comboCount++;
				comboTimer = Date.now() + comboTimeout;
			}
		}
	}
}
function lineIntersectsCircle(x1, y1, x2, y2, cx, cy, r) {
	// Increase detection radius by 30% to make blade more sensitive
	r = r * 1.3;
	// Find the closest point on the line segment to the circle center
	var dx = x2 - x1;
	var dy = y2 - y1;
	var len = Math.sqrt(dx * dx + dy * dy);
	// Normalize direction vector
	dx /= len;
	dy /= len;
	// Vector from line start to circle center
	var vx = cx - x1;
	var vy = cy - y1;
	// Project this vector onto the line direction
	var projection = vx * dx + vy * dy;
	// Clamp projection to line segment
	projection = Math.max(0, Math.min(len, projection));
	// Find the closest point on the line segment
	var closestX = x1 + projection * dx;
	var closestY = y1 + projection * dy;
	// Check if this point is within the circle
	var distanceSquared = (cx - closestX) * (cx - closestX) + (cy - closestY) * (cy - closestY);
	return distanceSquared <= r * r;
}
// Show the leaderboard UI
function showLeaderboard() {
	if (leaderboard) {
		leaderboard.show(leaderboardScores);
	}
}
// Update the hearts display based on current lives
function updateLivesDisplay() {
	// Clear existing hearts
	while (heartsDisplay.children.length > 0) {
		heartsDisplay.removeChildAt(0);
	}
	// Add new hearts based on current lives
	for (var i = 0; i < playerLives; i++) {
		var heart = new Heart();
		heart.x = -i * 80; // Space hearts horizontally from right to left
		heartsDisplay.addChild(heart);
	}
	// Update the missed counter
	updateMissedCounter();
}
// Dedicated function to update missed fruits counter and its color
function updateMissedCounter() {
	// Determine color based on missed count
	var missedColor;
	if (missedFruits <= 3) {
		missedColor = 0x00FF00; // Green for 0-3 misses
	} else if (missedFruits <= 6) {
		missedColor = 0xFFA500; // Orange for 4-6 misses
	} else {
		missedColor = 0xFF0000; // Red for 7-10 misses
	}
	// Remove old text from parent if it exists
	if (missedText && missedText.parent) {
		missedText.parent.removeChild(missedText);
	}
	// Create new Text2 with the appropriate color
	missedText = new Text2('Missed: ' + missedFruits + '/10', {
		size: 100,
		fill: missedColor,
		// Apply the color based on missed count
		weight: 'bold' // Make text bold
	});
	missedText.anchor.set(1, 0);
	missedText.x = GAME_WIDTH - 50;
	missedText.y = 10;
	game.addChild(missedText);
}
// Activate bullet time effect
function activateBulletTime() {
	bulletTimeActive = true;
	bulletTimeEndTime = Date.now() + bulletTimeDuration;
	bulletTimeBar.visible = true;
	// Flash screen blue to indicate bullet time activation
	LK.effects.flashScreen(0x00BFFF, 500);
	// Play a sound
	LK.getSound('combo').play();
}
// Update bullet time progress bar
function updateBulletTime() {
	if (!bulletTimeActive) {
		return;
	}
	var currentTime = Date.now();
	var remaining = bulletTimeEndTime - currentTime;
	if (remaining <= 0) {
		// Bullet time has ended
		bulletTimeActive = false;
		bulletTimeBar.visible = false;
		return;
	}
	// Update progress bar
	var progress = remaining / bulletTimeDuration;
	bulletTimeBar.barFill.width = 1000 * progress;
}
// Add a score to the leaderboard
function addScoreToLeaderboard(score) {
	// Only add score if it's greater than 0
	if (score <= 0) {
		return;
	}
	// Add new score to leaderboard with Upit username or 'Anon'
	var username = LK.getUptUsername ? LK.getUptUsername() : 'Anon';
	leaderboardScores.push({
		score: score,
		username: username
	});
	// Sort leaderboard by score (highest first)
	leaderboardScores.sort(function (a, b) {
		return b.score - a.score;
	});
	// Limit to top 10 scores
	if (leaderboardScores.length > 10) {
		leaderboardScores = leaderboardScores.slice(0, 10);
	}
	// Save to storage - convert to simple string format to avoid undefined JSON error
	var scoresString = '';
	for (var i = 0; i < leaderboardScores.length; i++) {
		scoresString += leaderboardScores[i].score + "," + (leaderboardScores[i].username || "Player");
		if (i < leaderboardScores.length - 1) {
			scoresString += ';';
		}
	}
	storage.leaderboardScores = scoresString;
}
;
// Game update function
game.update = function () {
	// Don't update game state if game is paused (leaderboard is shown)
	if (!gameActive) {
		return;
	}
	var currentTime = Date.now();
	// Handle level text animation
	if (showingLevelText && currentTime > levelTextTimer && levelText.alpha > 0) {
		tween(levelText, {
			alpha: 0
		}, {
			duration: 500,
			easing: tween.easeIn,
			onFinish: function onFinish() {
				showingLevelText = false;
			}
		});
	}
	// Check if we should flash the boss at 80% into the level (4 fruits sliced out of 5)
	if (currentLevel >= 1 && currentLevel <= 5 && slicedFruitsInLevel >= 4 && !bossFlashed && !bossActivated) {
		var _doMultipleFlashes = function doMultipleFlashes(flashCount) {
			if (flashCount <= 0) {
				tempBoss.destroy();
				return;
			}
			// Flash in
			tween(tempBoss, {
				alpha: 1
			}, {
				duration: 250,
				// Half second total per flash (250ms in, 250ms out)
				easing: tween.easeOut,
				onFinish: function onFinish() {
					// Flash out
					tween(tempBoss, {
						alpha: 0
					}, {
						duration: 250,
						// Half second total per flash (250ms in, 250ms out)
						easing: tween.easeIn,
						onFinish: function onFinish() {
							// Continue with next flash
							_doMultipleFlashes(flashCount - 1);
						}
					});
				}
			});
		}; // Start the sequence with 3 flashes
		bossFlashed = true;
		// Create a temporary boss image for flashing
		var tempBoss = new Boss(currentLevel);
		tempBoss.x = GAME_WIDTH / 2;
		tempBoss.y = GAME_HEIGHT / 2;
		tempBoss.alpha = 0;
		game.addChild(tempBoss);
		// Function to perform multiple boss flashes
		_doMultipleFlashes(3);
	}
	// Check if we should activate the boss fight based on fruit count
	// All levels: After 5 sliced fruits consistently
	var shouldActivateBoss = false;
	if (currentLevel >= 1 && currentLevel <= 5) {
		shouldActivateBoss = slicedFruitsInLevel >= 5 && !bossActivated && !nextLevelNotified;
	} else {
		// Fallback for any future levels beyond 5
		shouldActivateBoss = LK.getScore() >= LEVEL_THRESHOLDS[currentLevel - 1] && !bossActivated && !nextLevelNotified;
	}
	if (currentLevel <= 5 && shouldActivateBoss) {
		bossActivated = true;
		// Create a new boss for the current level
		if (boss) {
			boss.destroy();
		}
		boss = game.addChild(new Boss(currentLevel));
		boss.activate();
		// Clear existing fruits during boss transition
		for (var i = fruits.length - 1; i >= 0; i--) {
			fruits[i].destroy();
			fruits.splice(i, 1);
		}
	}
	// Only spawn normal fruits if we're not in a boss fight
	if (currentTime >= nextSpawnTime && (!bossActivated || !boss.active)) {
		spawnFruits();
	}
	// Update all fruits
	for (var i = fruits.length - 1; i >= 0; i--) {
		var fruit = fruits[i];
		fruit.update();
		// Remove fruits that are off-screen
		if (fruit.isOffScreen()) {
			// Only count missed fruits that aren't bombs or already sliced
			if (!fruit.sliced && fruit.type !== 'bomb') {
				missedFruits++;
				// Update the missed counter with new value and color
				updateMissedCounter();
				// If 10 fruits are missed, lose a life and reset miss counter
				if (missedFruits >= 10) {
					LK.effects.flashScreen(0xFF0000, 500);
					playerLives--; // Reduce lives by 1
					updateLivesDisplay(); // Update hearts display
					missedFruits = 0; // Reset missed fruits counter
					updateMissedCounter(); // Update missed counter display
					// Only show game over if no lives left
					if (playerLives <= 0) {
						// Update high score if current score is higher
						if (LK.getScore() > highScore) {
							highScore = LK.getScore();
							storage.highScore = highScore;
						}
						// Add score to global leaderboard
						addScoreToLeaderboard(LK.getScore());
						// Pass the current score and high score to game over display
						LK.showGameOver({
							score: LK.getScore(),
							highScore: highScore
						});
					}
				}
			}
			fruit.destroy();
			fruits.splice(i, 1);
		}
	}
	// Check for blade collisions
	handleBladeCollisions();
	// Update blade
	blade.update();
	// Update boss if active
	if (boss && boss.active) {
		boss.update(1 / 60); // Pass approximate delta time
	}
	// If boss was defeated, move to next level
	if (bossActivated && boss && !boss.active) {
		bossActivated = false;
		nextLevelNotified = false;
		// Move to next level if we haven't reached level 5 yet
		if (currentLevel < 5) {
			currentLevel++;
			// Show level notification
			showLevelText(currentLevel);
		} else if (currentLevel === 5) {
			// Player has beaten all levels
			LK.effects.flashScreen(0x00FF00, 800);
			// Show "You Win" screen after completing all levels
			if (LK.getScore() > highScore) {
				highScore = LK.getScore();
				storage.highScore = highScore;
			}
			// Add score to global leaderboard
			addScoreToLeaderboard(LK.getScore());
			// Show you win screen
			LK.showYouWin({
				score: LK.getScore(),
				highScore: highScore
			});
		}
	}
	// Check combo timer
	if (comboCount > 0 && Date.now() > comboTimer) {
		updateCombo();
	}
	// Update bullet time effect
	if (bulletTimeActive) {
		updateBulletTime();
	}
};
// Handle touch/mouse events
game.down = function (x, y, obj) {
	blade.active = true;
	blade.reset();
	blade.addPoint(x, y);
};
game.move = function (x, y, obj) {
	if (blade.active) {
		blade.addPoint(x, y);
		handleBladeCollisions();
	}
};
game.up = function (x, y, obj) {
	blade.active = false;
};
// Start the game
setupGame();
:quality(85)/https://cdn.frvr.ai/6813fb83a2f08cfafccd1760.png%3F3) 
 red bomb. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/68189a95cdeca07700bc34d2.png%3F3) 
 Head of pepe meme. each face shaped as a marble shaped face made in blender 3D. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/68189b6bcdeca07700bc34dd.png%3F3) 
 Head of doge meme. face shaped as a marble shaped face made in blender 3D. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6818a6eaabf9fe9560ef94c3.png%3F3) 
 Head of troll face meme. face shaped as a marble shaped face made in blender 3D. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6818a84cabf9fe9560ef94e3.png%3F3) 
 Head of think smart guy meme. face shaped as a marble shaped face made in blender 3D. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6818aa44abf9fe9560ef94fd.png%3F3) 
 Head of white y u no meme. face shaped as a marble shaped face made in blender 3D. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6818ace5abf9fe9560ef9509.png%3F3) 
 Explosion. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6818ada1abf9fe9560ef9511.png%3F3) 
 Clock. In-Game asset. 3d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6818afafabf9fe9560ef9539.png%3F3) 
 Red Heart. In-Game asset. 3d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/681933365ef7e5b120ac6a5b.png%3F3) 
 gattling gun. In-Game asset. 2d. High contrast. No shadows