User prompt
Do not create bullet time counter or display for blitz powerup
User prompt
Do not show bullet time counter during blitzkrieg
User prompt
Do not show bullet time counter during blitzkrieg
User prompt
Dont slow the screen in blitzkrieg
User prompt
Blitz powerup should not have a counter. When triggered just scream "Blitzkrieg!" Then shake the screen, then make an explosive sound and squash all the fruits on the screen. Then continue gameplay βͺπ‘ Consider importing and using the following plugins: @upit/tween.v1
User prompt
Spawn 2 blitz, 2 bullet time and 2 lifefruits in level 1
User prompt
Create new powerup called Blitz that squashes all the fruits currently on screen
User prompt
Move bullet time counter 80px from top
User prompt
Create new powerup called bullettime. When this type is smashed, the entire fruits on screen go into very slow motion for the next 10 secons. Show countdown bar
User prompt
Make level 1 balls 30% slower
User prompt
Remove the boss image showing in the top left corner of level 1
User prompt
Make the leaderboard brighter
User prompt
Let it be multiple flashes of half second each
User prompt
Flash an image of the boss 80% into a level βͺπ‘ Consider importing and using the following plugins: @upit/tween.v1
User prompt
Reduce boss 1 size by 35% and reduce boss 2 size by 30%
User prompt
Move boss 1 position lower by 70px and move boss 2 lower by 40px
User prompt
Reduce boss 5 size by 30% and spawn speed by 25%
User prompt
Reverse the sizes of the fruits in the various levels making it big to small. Do not modify the boss sizes but let the first boss be smaller than the others
User prompt
Do not use fruit sizes to calculate boss sizes. Make boss size start from 250px and increase in steps of 100px for each subsequent level
User prompt
Reverse the sizes of the fruits in the various levels making it big to small. Leave the boss sizes as is
User prompt
Dont change the original boss sizes, just the fruits only
User prompt
Reverse the sizes of the fruits in the various levels making it big to small
User prompt
Let level one boss also spawn random level 1 fruits
User prompt
Increase level 5 boss spawn speed by 50%
User prompt
Increase it by 50%
/**** 
* 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 = 10;
	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 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 boss
		var fruitCount = self.level === 5 || self.level === 1 ? 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 or level 1, also spawn random fruits
		if (self.level === 5 || self.level === 1) {
			for (var j = 0; j < fruitCount; j++) {
				// Select a random fruit type
				// For level 1, only use level 1 fruits (strawberry)
				var fruitType = self.level === 1 ? 'strawberry' : FRUIT_TYPES[Math.floor(Math.random() * FRUIT_TYPES.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 sound
		LK.getSound('slice').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
		var speed = (self.baseSpeed + Math.random() * 0.8) * levelMultiplier; // Further reduced random speed component
		// 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 || self.type === 'bomb') {
			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 sound
		LK.getSound('slice').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
				// 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 = 0x3498db; // Brighter blue color instead of dark slate
	panel.alpha = 1.0; // Fully opaque 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 sound
		LK.getSound('slice').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;
	// 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 = 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 maxLifeFruits = currentLevel;
	if (currentLevel === 4) {
		maxLifeFruits = 3;
	} // Level 4 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;
	}
	// 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 {
			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
	nextSpawnTime = Date.now() + 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;
	}
	var startPoint = blade.points[0];
	var endPoint = blade.points[1];
	// Check boss collision if active
	if (boss && boss.active && 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 sound
		LK.getSound('slice').play();
		// Update combo
		comboCount++;
		comboTimer = Date.now() + comboTimeout;
	}
	// Check collisions with fruits
	for (var i = 0; i < fruits.length; i++) {
		var fruit = fruits[i];
		if (!fruit.sliced && lineIntersectsCircle(startPoint.x, startPoint.y, endPoint.x, endPoint.y, fruit.x, fruit.y, fruit.width / 2)) {
			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
					});
				}
				return;
			}
			// 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) {
	// 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(); ===================================================================
--- original.js
+++ change.js
@@ -1020,9 +1020,9 @@
 	LK.gui.bottomLeft.addChild(highScoreText);
 	// Create bullet time bar (initially hidden)
 	bulletTimeBar = new Container();
 	bulletTimeBar.x = GAME_WIDTH / 2;
-	bulletTimeBar.y = 200;
+	bulletTimeBar.y = 280; // Moved 80px down from the top
 	bulletTimeBar.visible = false;
 	game.addChild(bulletTimeBar);
 	// Bullet time bar background
 	var bulletTimeBarBg = LK.getAsset('blade', {
: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