/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
var facekit = LK.import("@upit/facekit.v1");
/**** 
* Classes
****/ 
var Alien = Container.expand(function () {
	var self = Container.call(this);
	var alienGraphics = self.attachAsset('alien', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.health = 1;
	self.speed = 1;
	self.direction = 1;
	self.moveRange = 200;
	self.startX = 0;
	self.active = true;
	self.lastWasHit = false;
	self.takeDamage = function () {
		self.health--;
		if (self.health <= 0) {
			self.active = false;
			LK.getSound('alienDestroy').play();
			// Flash effect before destruction
			tween(alienGraphics, {
				alpha: 0,
				scaleX: 1.5,
				scaleY: 1.5
			}, {
				duration: 300,
				onFinish: function onFinish() {
					self.destroy();
				}
			});
		} else {
			LK.getSound('alienHit').play();
			// Flash red when hit
			LK.effects.flashObject(self, 0xff0000, 200);
		}
	};
	self.update = function () {
		if (!self.active) return;
		// Move alien horizontally
		self.x += self.direction * self.speed;
		// Reverse direction when reaching movement limits
		if (self.x > self.startX + self.moveRange || self.x < self.startX - self.moveRange) {
			self.direction *= -1;
		}
		// Keep alien within screen bounds
		if (self.x < 40) {
			self.x = 40;
			self.direction = 1;
		}
		if (self.x > 2008) {
			self.x = 2008;
			self.direction = -1;
		}
	};
	return self;
});
var Bomb = Container.expand(function () {
	var self = Container.call(this);
	var bombGraphics = self.attachAsset('bomb', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.active = true;
	self.rotationSpeed = 0.05;
	self.pulseSpeed = 0.08;
	self.lastWasIntersecting = false;
	self.update = function () {
		// Rotate bomb slowly for menacing effect
		bombGraphics.rotation += self.rotationSpeed;
		// Pulsing scale effect to make it more noticeable
		var pulseScale = 1 + Math.sin(LK.ticks * self.pulseSpeed) * 0.2;
		bombGraphics.scaleX = pulseScale;
		bombGraphics.scaleY = pulseScale;
		// Red tinting that pulses to indicate danger
		var redIntensity = 0.5 + Math.sin(LK.ticks * self.pulseSpeed * 2) * 0.5;
		bombGraphics.tint = 0xff << 16 | Math.floor((1 - redIntensity) * 255) << 8 | Math.floor((1 - redIntensity) * 255);
	};
	return self;
});
var Bullet = Container.expand(function () {
	var self = Container.call(this);
	var bulletGraphics = self.attachAsset('bullet', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 15;
	self.direction = {
		x: 0,
		y: -1
	}; // Default upward direction
	self.active = true;
	self.update = function () {
		// Find nearest alien to auto-target
		var nearestAlien = null;
		var nearestDistance = Infinity;
		for (var i = 0; i < aliens.length; i++) {
			var alien = aliens[i];
			if (alien.active) {
				var distance = Math.sqrt(Math.pow(self.x - alien.x, 2) + Math.pow(self.y - alien.y, 2));
				if (distance < nearestDistance) {
					nearestDistance = distance;
					nearestAlien = alien;
				}
			}
		}
		// If there's an alien to target, automatically steer towards it
		if (nearestAlien) {
			var targetX = nearestAlien.x - self.x;
			var targetY = nearestAlien.y - self.y;
			var targetDistance = Math.sqrt(targetX * targetX + targetY * targetY);
			if (targetDistance > 0) {
				// Normalize direction towards target
				self.direction.x = targetX / targetDistance;
				self.direction.y = targetY / targetDistance;
			}
		}
		self.x += self.direction.x * self.speed;
		self.y += self.direction.y * self.speed;
		// Remove bullet if it goes off screen
		if (self.y < cameraY - 200 || self.y > cameraY + 2732 + 200 || self.x < -100 || self.x > 2148) {
			self.active = false;
		}
	};
	return self;
});
var Coin = Container.expand(function () {
	var self = Container.call(this);
	var coinGraphics = self.attachAsset('coin', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.collected = false;
	self.rotationSpeed = 0.1;
	self.update = function () {
		// Rotate coin for visual appeal
		coinGraphics.rotation += self.rotationSpeed;
		// Float up and down slightly
		self.y += Math.sin(LK.ticks * 0.05) * 0.5;
	};
	return self;
});
var Dude = Container.expand(function () {
	var self = Container.call(this);
	var dudeGraphics = self.attachAsset('dude', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.velocityY = 0;
	self.velocityX = 0;
	self.isJumping = false;
	self.isOnPlatform = false;
	self.jumpPower = 35;
	self.gravity = 0.8;
	self.maxFallSpeed = 15;
	self.horizontalSpeed = 12;
	self.airResistance = 0.85;
	self.invincible = false;
	self.invincibleTimer = 0;
	self.health = 4;
	self.maxHealth = 4;
	self.jump = function () {
		if (self.isOnPlatform) {
			self.velocityY = -self.jumpPower;
			self.isJumping = true;
			self.isOnPlatform = false;
			LK.getSound('jump').play();
		}
	};
	self.update = function () {
		// Auto jump when on platform (only if not flying)
		if (self.isOnPlatform && !self.canFly) {
			self.jump();
		}
		// Apply gravity (reduced if flying)
		if (self.canFly) {
			self.velocityY += self.gravity * 0.5; // Reduced gravity for flying
		} else {
			self.velocityY += self.gravity;
		}
		if (self.velocityY > self.maxFallSpeed) {
			self.velocityY = self.maxFallSpeed;
		}
		// Update position
		self.y += self.velocityY;
		self.x += self.velocityX;
		// Apply continuous horizontal movement while pressed
		if (isPressed && pressedSide !== 0) {
			self.velocityX += pressedSide * self.horizontalSpeed * 0.3;
		}
		// Apply air resistance to horizontal movement
		self.velocityX *= self.airResistance;
		// Handle invincibility timer
		if (self.invincible) {
			self.invincibleTimer--;
			if (self.invincibleTimer <= 0) {
				self.invincible = false;
				dudeGraphics.alpha = 1;
			} else {
				dudeGraphics.alpha = Math.sin(self.invincibleTimer * 0.3) * 0.5 + 0.5;
			}
		}
		// Allow infinite horizontal movement - no bounds restriction
		// Character can now move infinitely left and right
		// Check if fallen off screen
		if (self.y > cameraY + 2732 + 200) {
			// Reset gold to zero when player falls off screen
			gold = 0;
			storage.gold = 0;
			goldTxt.setText('Gold: ' + gold);
			// Reset total height when player dies
			totalHeight = 0;
			storage.totalHeight = 0;
			// Reset spawn rate multipliers when character dies
			alienSpawnMultiplier = 1.0;
			sawSpawnMultiplier = 1.0;
			LK.showGameOver();
		}
	};
	self.takeDamage = function () {
		if (self.invincible) return;
		self.health--;
		self.invincible = true;
		self.invincibleTimer = 180; // 3 seconds of invincibility
		LK.effects.flashObject(self, 0xff0000, 500);
		updateHealthDisplay();
		if (self.health <= 0) {
			// Reset gold to zero when player dies
			gold = 0;
			storage.gold = 0;
			goldTxt.setText('Gold: ' + gold);
			// Reset total height when player dies
			totalHeight = 0;
			storage.totalHeight = 0;
			// Reset spawn rate multipliers when character dies
			alienSpawnMultiplier = 1.0;
			sawSpawnMultiplier = 1.0;
			LK.showGameOver();
		}
	};
	self.shoot = function (direction) {
		var bullet = new Bullet();
		bullet.x = self.x;
		bullet.y = self.y;
		// Set bullet direction based on parameter
		if (direction === 'up') {
			bullet.direction = {
				x: 0,
				y: -1
			};
			bullet.y = self.y - 30;
		} else if (direction === 'down') {
			bullet.direction = {
				x: 0,
				y: 1
			};
			bullet.y = self.y + 30;
		} else if (direction === 'left') {
			bullet.direction = {
				x: -1,
				y: 0
			};
			bullet.x = self.x - 30;
		} else if (direction === 'right') {
			bullet.direction = {
				x: 1,
				y: 0
			};
			bullet.x = self.x + 30;
		}
		bullets.push(bullet);
		game.addChild(bullet);
		LK.getSound('shoot').play();
	};
	return self;
});
var FlashBomb = Container.expand(function () {
	var self = Container.call(this);
	var flashBombGraphics = self.attachAsset('flashBomb', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.active = true;
	self.rotationSpeed = 0.05;
	self.pulseSpeed = 0.08;
	self.lastWasIntersecting = false;
	// Make flash bomb visually different - white tint
	flashBombGraphics.tint = 0xffffff;
	self.update = function () {
		// Rotate flash bomb slowly
		flashBombGraphics.rotation += self.rotationSpeed;
		// Pulsing scale effect
		var pulseScale = 1 + Math.sin(LK.ticks * self.pulseSpeed) * 0.2;
		flashBombGraphics.scaleX = pulseScale;
		flashBombGraphics.scaleY = pulseScale;
		// White tinting that pulses to indicate flash effect
		var whiteIntensity = 0.7 + Math.sin(LK.ticks * self.pulseSpeed * 2) * 0.3;
		flashBombGraphics.tint = Math.floor(whiteIntensity * 255) << 16 | Math.floor(whiteIntensity * 255) << 8 | Math.floor(whiteIntensity * 255);
	};
	return self;
});
var Platform = Container.expand(function (type) {
	var self = Container.call(this);
	self.type = type || 'normal';
	self.landed = false;
	self.disappearing = false;
	self.moveDirection = 1;
	self.moveRange = 300;
	self.startX = 0;
	var platformGraphics;
	if (self.type === 'moving') {
		platformGraphics = self.attachAsset('movingPlatform', {
			anchorX: 0.5,
			anchorY: 0.5
		});
	} else if (self.type === 'disappearing') {
		platformGraphics = self.attachAsset('disappearingPlatform', {
			anchorX: 0.5,
			anchorY: 0.5
		});
	} else if (self.type === 'powerup') {
		platformGraphics = self.attachAsset('powerUpPlatform', {
			anchorX: 0.5,
			anchorY: 0.5
		});
	} else {
		platformGraphics = self.attachAsset('platform', {
			anchorX: 0.5,
			anchorY: 0.5
		});
	}
	self.update = function () {
		// Moving platform behavior
		if (self.type === 'moving') {
			self.x += self.moveDirection * 2;
			if (self.x > self.startX + self.moveRange || self.x < self.startX - self.moveRange) {
				self.moveDirection *= -1;
			}
		}
		// Disappearing platform behavior
		if (self.type === 'disappearing' && self.landed && !self.disappearing) {
			self.disappearing = true;
			tween(platformGraphics, {
				alpha: 0
			}, {
				duration: 1000,
				onFinish: function onFinish() {
					self.active = false;
				}
			});
		}
	};
	return self;
});
var Saw = Container.expand(function () {
	var self = Container.call(this);
	var sawGraphics = self.attachAsset('saw', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.active = true;
	self.rotationSpeed = 0.3;
	self.lastWasIntersecting = false;
	self.moveDirection = Math.random() < 0.5 ? -1 : 1; // Random initial direction
	self.moveSpeed = 2;
	self.moveRange = 150;
	self.startX = 0;
	self.update = function () {
		// Move saw horizontally
		self.x += self.moveDirection * self.moveSpeed;
		// Reverse direction when reaching movement limits
		if (self.x > self.startX + self.moveRange || self.x < self.startX - self.moveRange) {
			self.moveDirection *= -1;
		}
		// Keep saw within screen bounds
		if (self.x < 60) {
			self.x = 60;
			self.moveDirection = 1;
		}
		if (self.x > 1988) {
			self.x = 1988;
			self.moveDirection = -1;
		}
	};
	return self;
});
var SpecialItem = Container.expand(function (itemType) {
	var self = Container.call(this);
	self.itemType = itemType || 1;
	var assetId = 'specialItem' + self.itemType;
	var itemGraphics = self.attachAsset(assetId, {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Make special items larger
	itemGraphics.scaleX = 2;
	itemGraphics.scaleY = 2;
	self.collected = false;
	self.active = true;
	self.rotationSpeed = 0.15;
	self.floatOffset = Math.random() * Math.PI * 2;
	self.update = function () {
		// Float up and down with more pronounced animation
		self.y += Math.sin(LK.ticks * 0.06 + self.floatOffset) * 1.2;
		// Pulsing scale effect
		var pulseScale = 2 + Math.sin(LK.ticks * 0.08) * 0.3;
		itemGraphics.scaleX = pulseScale;
		itemGraphics.scaleY = pulseScale;
	};
	return self;
});
var Trampoline = Container.expand(function () {
	var self = Container.call(this);
	var trampolineGraphics = self.attachAsset('trampoline', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.bounced = false;
	self.active = true;
	self.bounce = function () {
		// Animate trampoline compression and expansion
		tween(trampolineGraphics, {
			scaleY: 0.5
		}, {
			duration: 100,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				tween(trampolineGraphics, {
					scaleY: 1.2
				}, {
					duration: 200,
					easing: tween.bounceOut,
					onFinish: function onFinish() {
						tween(trampolineGraphics, {
							scaleY: 1
						}, {
							duration: 100,
							easing: tween.easeOut
						});
					}
				});
			}
		});
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x87ceeb
});
/**** 
* Game Code
****/ 
var dude = game.addChild(new Dude());
var platforms = [];
var coins = [];
var bullets = [];
var trampolines = [];
var cameraY = 0;
var highestY = 2400;
var lastPlatformY = 2400;
var platformSpacing = 200;
var coinsCollected = 0;
var gold = storage.gold || 0;
var totalHeight = storage.totalHeight || 0;
var lastShootTime = 0;
var shootCooldown = 20; // 20 ticks between shots
var aliens = [];
var aliensKilled = 0;
var saws = [];
var specialItems = [];
var specialItemsCollected = 0;
var totalSpecialItems = 4;
var zombiesKilled = 0;
var bombs = [];
var flashBombs = [];
// Create score display
var scoreTxt = new Text2('0', {
	size: 60,
	fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Create height display
var heightTxt = new Text2('Height: 0m', {
	size: 40,
	fill: 0xFFFFFF
});
heightTxt.anchor.set(1, 0);
heightTxt.x = -20;
heightTxt.y = 20;
LK.gui.topRight.addChild(heightTxt);
// Create coin counter display
var coinTxt = new Text2('Coins: 0', {
	size: 40,
	fill: 0xffd700
});
coinTxt.anchor.set(0, 0);
coinTxt.x = 20;
coinTxt.y = 20;
LK.gui.topLeft.addChild(coinTxt);
// Create gold display
var goldTxt = new Text2('Gold: ' + gold, {
	size: 40,
	fill: 0xffd700
});
goldTxt.anchor.set(0, 0);
goldTxt.x = 20;
goldTxt.y = 120;
LK.gui.topLeft.addChild(goldTxt);
// Create special items display
var specialItemsTxt = new Text2('Special Items: 0/' + totalSpecialItems, {
	size: 40,
	fill: 0xff0000
});
specialItemsTxt.anchor.set(0, 0);
specialItemsTxt.x = 20;
specialItemsTxt.y = 170;
LK.gui.topLeft.addChild(specialItemsTxt);
// Create health display
var hearts = [];
function createHealthDisplay() {
	for (var i = 0; i < dude.maxHealth; i++) {
		var heart = LK.getAsset('heart', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		heart.x = 20 + i * 50;
		heart.y = 80;
		hearts.push(heart);
		LK.gui.topLeft.addChild(heart);
	}
}
function updateHealthDisplay() {
	for (var i = 0; i < hearts.length; i++) {
		hearts[i].alpha = i < dude.health ? 1 : 0.3;
	}
}
// Initialize dude position
dude.x = 1024;
dude.y = 2400;
// Initialize health display
createHealthDisplay();
updateHealthDisplay();
// Create fire buttons for 4 directions
var fireButtonUp = LK.getAsset('fireButton', {
	anchorX: 0.5,
	anchorY: 0.5,
	scaleX: 1.5,
	scaleY: 1.5
});
fireButtonUp.x = -120;
fireButtonUp.y = -300;
LK.gui.bottomRight.addChild(fireButtonUp);
var fireButtonDown = LK.getAsset('fireButton', {
	anchorX: 0.5,
	anchorY: 0.5,
	scaleX: 1.5,
	scaleY: 1.5
});
fireButtonDown.x = -120;
fireButtonDown.y = -100;
fireButtonDown.rotation = Math.PI; // Rotate 180 degrees
LK.gui.bottomRight.addChild(fireButtonDown);
var fireButtonLeft = LK.getAsset('fireButton', {
	anchorX: 0.5,
	anchorY: 0.5,
	scaleX: 1.5,
	scaleY: 1.5
});
fireButtonLeft.x = -220;
fireButtonLeft.y = -200;
fireButtonLeft.rotation = Math.PI * 1.5; // Rotate 270 degrees
LK.gui.bottomRight.addChild(fireButtonLeft);
var fireButtonRight = LK.getAsset('fireButton', {
	anchorX: 0.5,
	anchorY: 0.5,
	scaleX: 1.5,
	scaleY: 1.5
});
fireButtonRight.x = -20;
fireButtonRight.y = -200;
fireButtonRight.rotation = Math.PI * 0.5; // Rotate 90 degrees
LK.gui.bottomRight.addChild(fireButtonRight);
// Create initial platforms
function createPlatform(x, y, type) {
	var platform = new Platform(type);
	platform.x = x;
	platform.y = y;
	platform.startX = x;
	platform.active = true;
	platforms.push(platform);
	game.addChild(platform);
	return platform;
}
// Create starting platform
createPlatform(1024, 2450, 'normal');
// Generate initial platforms
for (var i = 0; i < 20; i++) {
	generateNextPlatform();
}
function generateNextPlatform() {
	lastPlatformY -= platformSpacing + Math.random() * 100;
	var x = 200 + Math.random() * 1648;
	// Determine platform type based on height
	var type = 'normal';
	var height = Math.abs(lastPlatformY - 2400);
	if (height > 1000) {
		var rand = Math.random();
		var powerupChance = spaceThemeActivated ? 0.8 : 0.6; // Increased from 0.6 to 0.8 in space theme
		if (rand < 0.3) {
			type = 'moving';
		} else if (rand < 0.5) {
			type = 'disappearing';
		} else if (rand < powerupChance) {
			type = 'powerup';
		}
	}
	createPlatform(x, lastPlatformY, type);
	// Generate coins near platforms with increased rate after 1255m
	var currentGameHeight = Math.abs(lastPlatformY - 2400);
	var coinChance = currentGameHeight > 1255 ? 0.98 : 0.85; // 98% chance after 1255m, 85% before
	if (Math.random() < coinChance) {
		generateCoin(x + (Math.random() - 0.5) * 200, lastPlatformY - 80);
	}
	// Generate trampolines more frequently (25% chance, 40% in space theme)
	var trampolineChance = spaceThemeActivated ? 0.40 : 0.25;
	if (Math.random() < trampolineChance) {
		createTrampoline(x, lastPlatformY - 100);
	}
	// Generate aliens with 15% chance
	var alienChance = 0.15; // 15% chance
	if (Math.random() < alienChance) {
		createAlien(x + (Math.random() - 0.5) * 300, lastPlatformY - 150);
	}
	// Kittens removed from game
	// Generate saws more frequently (25% chance)
	var baseSawChance = 0.25; // 25% chance (increased from 10%)
	var sawChance = baseSawChance * sawSpawnMultiplier;
	if (Math.random() < sawChance) {
		createSaw(x + (Math.random() - 0.5) * 300, lastPlatformY - 100);
	}
	// Generate bombs with 5% chance after reaching 500m height
	var currentGameHeight = Math.abs(lastPlatformY - 2400);
	if (currentGameHeight > 500 && Math.random() < 0.05) {
		createBomb(x + (Math.random() - 0.5) * 300, lastPlatformY - 120);
	}
	// Generate flash bombs more frequently (20% chance after reaching 800m height)
	if (currentGameHeight > 800 && Math.random() < 0.20) {
		createFlashBomb(x + (Math.random() - 0.5) * 300, lastPlatformY - 120);
	}
	// Generate special items frequently (10% chance) and only if we haven't collected all yet
	if (Math.random() < 0.10 && specialItemsCollected < totalSpecialItems) {
		var nextItemType = specialItemsCollected + 1;
		createSpecialItem(x + (Math.random() - 0.5) * 200, lastPlatformY - 150, nextItemType);
	}
}
function generateCoin(x, y) {
	var coin = new Coin();
	coin.x = x;
	coin.y = y;
	coin.active = true;
	coins.push(coin);
	game.addChild(coin);
}
function createTrampoline(x, y) {
	var trampoline = new Trampoline();
	trampoline.x = x;
	trampoline.y = y;
	trampoline.active = true;
	trampolines.push(trampoline);
	game.addChild(trampoline);
	return trampoline;
}
function createAlien(x, y) {
	var alien = new Alien();
	alien.x = x;
	alien.y = y;
	alien.startX = x;
	alien.active = true;
	aliens.push(alien);
	game.addChild(alien);
	return alien;
}
function createSaw(x, y) {
	var saw = new Saw();
	saw.x = x;
	saw.y = y;
	saw.startX = x;
	saw.active = true;
	saw.lastWasIntersecting = false;
	saws.push(saw);
	game.addChild(saw);
	return saw;
}
function createBomb(x, y) {
	var bomb = new Bomb();
	bomb.x = x;
	bomb.y = y;
	bomb.active = true;
	bomb.lastWasIntersecting = false;
	bombs.push(bomb);
	game.addChild(bomb);
	return bomb;
}
function createFlashBomb(x, y) {
	var flashBomb = new FlashBomb();
	flashBomb.x = x;
	flashBomb.y = y;
	flashBomb.active = true;
	flashBomb.lastWasIntersecting = false;
	flashBombs.push(flashBomb);
	game.addChild(flashBomb);
	return flashBomb;
}
function createSpecialItem(x, y, itemType) {
	var item = new SpecialItem(itemType);
	item.x = x;
	item.y = y;
	item.active = true;
	specialItems.push(item);
	game.addChild(item);
	return item;
}
function updateCamera() {
	var targetY = dude.y - 1800;
	if (targetY < cameraY) {
		cameraY = targetY;
		game.y = -cameraY;
		// Update highest position
		if (dude.y < highestY) {
			highestY = dude.y;
			var currentHeight = Math.floor((2400 - highestY) / 10);
			var displayHeight = totalHeight + currentHeight;
			LK.setScore(displayHeight);
			scoreTxt.setText(LK.getScore());
			heightTxt.setText('Height: ' + displayHeight + 'm');
		}
	}
}
function checkPlatformCollisions() {
	for (var i = 0; i < platforms.length; i++) {
		var platform = platforms[i];
		if (!platform.active) continue;
		// Define dude and platform boundaries
		var dudeLeft = dude.x - 40;
		var dudeRight = dude.x + 40;
		var dudeTop = dude.y - 40;
		var dudeBottom = dude.y + 40;
		var platformLeft = platform.x - 150;
		var platformRight = platform.x + 150;
		var platformTop = platform.y - 15;
		var platformBottom = platform.y + 15;
		// Check if dude and platform are overlapping horizontally and vertically
		var horizontalOverlap = dudeRight > platformLeft && dudeLeft < platformRight;
		var verticalOverlap = dudeBottom > platformTop && dudeTop < platformBottom;
		if (horizontalOverlap && verticalOverlap) {
			// Calculate overlap distances for each direction
			var overlapLeft = dudeRight - platformLeft;
			var overlapRight = platformRight - dudeLeft;
			var overlapTop = dudeBottom - platformTop;
			var overlapBottom = platformBottom - dudeTop;
			// Find the smallest overlap to determine collision direction
			var minOverlap = Math.min(overlapLeft, overlapRight, overlapTop, overlapBottom);
			// Handle collision based on the direction with smallest overlap
			if (minOverlap === overlapTop && dude.velocityY > 0) {
				// Landing on top of platform (falling down)
				dude.y = platformTop - 40;
				dude.velocityY = 0;
				dude.isOnPlatform = true;
				dude.isJumping = false;
				if (!platform.landed) {
					platform.landed = true;
					LK.getSound('land').play();
					// Handle special platform effects
					if (platform.type === 'powerup') {
						dude.invincible = true;
						dude.invincibleTimer = 300;
						dude.jumpPower = 70; // Double the normal jump power (35 * 2)
						LK.getSound('powerup').play();
						// Reset jump power after 1 second using tween for precise timing
						LK.setTimeout(function () {
							dude.jumpPower = 35; // Reset to normal jump power
						}, 1000); // Changed from 3000ms to 1000ms (1 second)
					}
				}
			} else if (minOverlap === overlapLeft && dude.velocityX > 0) {
				// Hitting platform from the left (moving right)
				dude.x = platformLeft - 40;
				dude.velocityX = 0;
			} else if (minOverlap === overlapRight && dude.velocityX < 0) {
				// Hitting platform from the right (moving left)
				dude.x = platformRight + 40;
				dude.velocityX = 0;
			}
			break;
		}
	}
}
function checkCoinCollisions() {
	for (var i = coins.length - 1; i >= 0; i--) {
		var coin = coins[i];
		if (!coin.active || coin.collected) continue;
		// Check if dude is close enough to collect coin
		var distance = Math.sqrt(Math.pow(dude.x - coin.x, 2) + Math.pow(dude.y - coin.y, 2));
		if (distance < 50) {
			// Collect coin
			coin.collected = true;
			coin.active = false;
			coinsCollected++;
			coinTxt.setText('Coins: ' + coinsCollected);
			LK.getSound('coinCollect').play();
			// Check if player reached 20 coins
			if (coinsCollected >= 20) {
				// Show bravo message
				LK.showYouWin();
			}
			// Remove coin with fade effect
			tween(coin, {
				alpha: 0,
				scaleX: 1.5,
				scaleY: 1.5
			}, {
				duration: 200,
				onFinish: function onFinish() {
					coin.destroy();
					coins.splice(i, 1);
				}
			});
		}
	}
}
function checkTrampolineCollisions() {
	if (dude.velocityY <= 0) return; // Only check when falling
	for (var i = 0; i < trampolines.length; i++) {
		var trampoline = trampolines[i];
		if (!trampoline.active) continue;
		var dudeBottom = dude.y + 40;
		var trampolineTop = trampoline.y - 30;
		var trampolineBottom = trampoline.y + 30;
		if (dudeBottom >= trampolineTop && dudeBottom <= trampolineBottom + 20) {
			if (dude.x >= trampoline.x - 150 && dude.x <= trampoline.x + 150) {
				// Bounce off trampoline with super jump
				dude.velocityY = -60; // Much higher than normal jump
				dude.isJumping = true;
				dude.isOnPlatform = false;
				trampoline.bounce();
				LK.getSound('jump').play();
				break;
			}
		}
	}
}
function checkBulletAlienCollisions() {
	for (var i = bullets.length - 1; i >= 0; i--) {
		var bullet = bullets[i];
		if (!bullet.active) continue;
		for (var j = aliens.length - 1; j >= 0; j--) {
			var alien = aliens[j];
			if (!alien.active) continue;
			// Check collision between bullet and alien
			var distance = Math.sqrt(Math.pow(bullet.x - alien.x, 2) + Math.pow(bullet.y - alien.y, 2));
			if (distance < 50) {
				// Hit detected
				bullet.active = false;
				bullet.destroy();
				bullets.splice(i, 1);
				alien.takeDamage();
				if (!alien.active) {
					aliensKilled++;
					zombiesKilled++;
					aliens.splice(j, 1);
					// Increase score for killing alien
					LK.setScore(LK.getScore() + 10);
					scoreTxt.setText(LK.getScore());
					// Give gold reward with 50% chance (100/2 = 50%)
					if (Math.random() < 0.5) {
						gold += 1;
						storage.gold = gold;
						goldTxt.setText('Gold: ' + gold);
					}
					// Check if player killed 10 zombies
					if (zombiesKilled >= 10) {
						// Show you win message
						LK.showYouWin();
					}
				}
				break;
			}
		}
	}
}
function cleanupPlatforms() {
	for (var i = platforms.length - 1; i >= 0; i--) {
		var platform = platforms[i];
		if (platform.y > cameraY + 3000 || !platform.active) {
			platform.destroy();
			platforms.splice(i, 1);
		}
	}
}
function cleanupCoins() {
	for (var i = coins.length - 1; i >= 0; i--) {
		var coin = coins[i];
		if (coin.y > cameraY + 3000 || !coin.active) {
			coin.destroy();
			coins.splice(i, 1);
		}
	}
}
function cleanupBullets() {
	for (var i = bullets.length - 1; i >= 0; i--) {
		var bullet = bullets[i];
		if (bullet.y < cameraY - 200 || !bullet.active) {
			bullet.destroy();
			bullets.splice(i, 1);
		}
	}
}
function cleanupTrampolines() {
	for (var i = trampolines.length - 1; i >= 0; i--) {
		var trampoline = trampolines[i];
		if (trampoline.y > cameraY + 3000 || !trampoline.active) {
			trampoline.destroy();
			trampolines.splice(i, 1);
		}
	}
}
function checkSpecialItemCollisions() {
	for (var i = specialItems.length - 1; i >= 0; i--) {
		var item = specialItems[i];
		if (!item.active || item.collected) continue;
		// Check if dude is close enough to collect special item
		var distance = Math.sqrt(Math.pow(dude.x - item.x, 2) + Math.pow(dude.y - item.y, 2));
		if (distance < 60) {
			// Collect special item
			item.collected = true;
			item.active = false;
			specialItemsCollected++;
			specialItemsTxt.setText('Special Items: ' + specialItemsCollected + '/' + totalSpecialItems);
			// Visual feedback - dramatic collection effect
			LK.effects.flashScreen(0xff0000, 500);
			tween(item, {
				alpha: 0,
				scaleX: 4,
				scaleY: 4
			}, {
				duration: 500,
				onFinish: function onFinish() {
					item.destroy();
					specialItems.splice(i, 1);
				}
			});
			// Check if all special items collected
			if (specialItemsCollected >= totalSpecialItems) {
				// Show you win message
				LK.showYouWin();
			}
			break;
		}
	}
}
function checkAlienPlayerCollisions() {
	if (dude.invincible) return;
	for (var i = 0; i < aliens.length; i++) {
		var alien = aliens[i];
		if (!alien.active) continue;
		var distance = Math.sqrt(Math.pow(dude.x - alien.x, 2) + Math.pow(dude.y - alien.y, 2));
		if (distance < 60) {
			dude.takeDamage();
			break;
		}
	}
}
function checkBombPlayerCollisions() {
	if (dude.invincible) return;
	for (var i = 0; i < bombs.length; i++) {
		var bomb = bombs[i];
		if (!bomb.active) continue;
		var distance = Math.sqrt(Math.pow(dude.x - bomb.x, 2) + Math.pow(dude.y - bomb.y, 2));
		var currentIntersecting = distance < 60;
		// Check for transition from not intersecting to intersecting
		if (!bomb.lastWasIntersecting && currentIntersecting) {
			// Take 3 damage from bomb
			dude.health -= 3;
			if (dude.health < 0) dude.health = 0;
			dude.invincible = true;
			dude.invincibleTimer = 180; // 3 seconds of invincibility
			// Dramatic explosion effect
			LK.effects.flashScreen(0xff4444, 1000);
			LK.effects.flashObject(dude, 0xff0000, 800);
			updateHealthDisplay();
			// Destroy the bomb after explosion
			bomb.active = false;
			bomb.destroy();
			bombs.splice(i, 1);
			if (dude.health <= 0) {
				// Reset gold to zero when player dies
				gold = 0;
				storage.gold = 0;
				goldTxt.setText('Gold: ' + gold);
				// Reset total height when player dies
				totalHeight = 0;
				storage.totalHeight = 0;
				// Reset spawn rate multipliers when character dies
				alienSpawnMultiplier = 1.0;
				sawSpawnMultiplier = 1.0;
				LK.showGameOver();
			}
			break;
		}
		// Update last intersecting state
		bomb.lastWasIntersecting = currentIntersecting;
	}
}
function checkFlashBombPlayerCollisions() {
	for (var i = 0; i < flashBombs.length; i++) {
		var flashBomb = flashBombs[i];
		if (!flashBomb.active) continue;
		var distance = Math.sqrt(Math.pow(dude.x - flashBomb.x, 2) + Math.pow(dude.y - flashBomb.y, 2));
		var currentIntersecting = distance < 60;
		// Check for transition from not intersecting to intersecting
		if (!flashBomb.lastWasIntersecting && currentIntersecting) {
			// Create a white overlay that covers the entire screen for 3 seconds
			var whiteOverlay = LK.getAsset('bullet', {
				anchorX: 0.5,
				anchorY: 0.5,
				scaleX: 100,
				scaleY: 150,
				alpha: 0
			});
			whiteOverlay.tint = 0xffffff;
			whiteOverlay.x = 1024; // Center of screen
			whiteOverlay.y = 1366; // Center of screen
			LK.gui.center.addChild(whiteOverlay);
			// Tween the overlay to full opacity immediately, then gradually fade out over 3 seconds
			tween(whiteOverlay, {
				alpha: 1
			}, {
				duration: 50,
				onFinish: function onFinish() {
					// Gradually fade out the white screen over 3 seconds
					tween(whiteOverlay, {
						alpha: 0
					}, {
						duration: 3000,
						easing: tween.easeOut,
						onFinish: function onFinish() {
							whiteOverlay.destroy();
						}
					});
				}
			});
			// Destroy the flash bomb after activation
			flashBomb.active = false;
			flashBomb.destroy();
			flashBombs.splice(i, 1);
			break;
		}
		// Update last intersecting state
		flashBomb.lastWasIntersecting = currentIntersecting;
	}
}
function checkSawPlayerCollisions() {
	if (dude.invincible) return;
	for (var i = 0; i < saws.length; i++) {
		var saw = saws[i];
		if (!saw.active) continue;
		var distance = Math.sqrt(Math.pow(dude.x - saw.x, 2) + Math.pow(dude.y - saw.y, 2));
		var currentIntersecting = distance < 70;
		// Check for transition from not intersecting to intersecting
		if (!saw.lastWasIntersecting && currentIntersecting) {
			dude.takeDamage();
		}
		// Update last intersecting state
		saw.lastWasIntersecting = currentIntersecting;
	}
}
function cleanupAliens() {
	for (var i = aliens.length - 1; i >= 0; i--) {
		var alien = aliens[i];
		if (alien.y > cameraY + 3000 || !alien.active) {
			if (alien.active) {
				alien.destroy();
			}
			aliens.splice(i, 1);
		}
	}
}
function cleanupSaws() {
	for (var i = saws.length - 1; i >= 0; i--) {
		var saw = saws[i];
		if (saw.y > cameraY + 3000 || !saw.active) {
			if (saw.active) {
				saw.destroy();
			}
			saws.splice(i, 1);
		}
	}
}
function cleanupBombs() {
	for (var i = bombs.length - 1; i >= 0; i--) {
		var bomb = bombs[i];
		if (bomb.y > cameraY + 3000 || !bomb.active) {
			if (bomb.active) {
				bomb.destroy();
			}
			bombs.splice(i, 1);
		}
	}
}
function cleanupFlashBombs() {
	for (var i = flashBombs.length - 1; i >= 0; i--) {
		var flashBomb = flashBombs[i];
		if (flashBomb.y > cameraY + 3000 || !flashBomb.active) {
			if (flashBomb.active) {
				flashBomb.destroy();
			}
			flashBombs.splice(i, 1);
		}
	}
}
function cleanupSpecialItems() {
	for (var i = specialItems.length - 1; i >= 0; i--) {
		var item = specialItems[i];
		if (item.y > cameraY + 3000 || !item.active) {
			if (item.active) {
				item.destroy();
			}
			specialItems.splice(i, 1);
		}
	}
}
function generateMorePlatforms() {
	while (lastPlatformY > cameraY - 1000) {
		generateNextPlatform();
	}
}
// Touch controls
var isPressed = false;
var pressedSide = 0; // -1 for left, 1 for right, 0 for center
game.down = function (x, y, obj) {
	dude.jump();
	isPressed = true;
	// Determine which side was pressed
	var screenCenter = 1024; // Half of 2048
	var touchOffset = x - screenCenter;
	if (touchOffset > 50) {
		pressedSide = 1; // Right side
	} else if (touchOffset < -50) {
		pressedSide = -1; // Left side
	} else {
		pressedSide = 0; // Center
	}
	// Shoot when touching center area
	if (Math.abs(touchOffset) <= 50 && LK.ticks - lastShootTime >= shootCooldown) {
		dude.shoot('up');
		lastShootTime = LK.ticks;
	}
};
game.up = function (x, y, obj) {
	isPressed = false;
	pressedSide = 0;
};
// Fire button touch handlers for 4 directions
function createFireButtonHandler(button, direction) {
	button.down = function (x, y, obj) {
		if (LK.ticks - lastShootTime >= shootCooldown) {
			dude.shoot(direction);
			lastShootTime = LK.ticks;
			// Visual feedback - scale animation
			tween(button, {
				scaleX: 1.2,
				scaleY: 1.2
			}, {
				duration: 100,
				onFinish: function onFinish() {
					tween(button, {
						scaleX: 1.5,
						scaleY: 1.5
					}, {
						duration: 100
					});
				}
			});
		}
	};
}
createFireButtonHandler(fireButtonUp, 'up');
createFireButtonHandler(fireButtonDown, 'down');
createFireButtonHandler(fireButtonLeft, 'left');
createFireButtonHandler(fireButtonRight, 'right');
// Track if space theme has been activated
var spaceThemeActivated = false;
// Track if 1500m jump boost has been applied
var jumpBoostApplied = false;
// Track if 1200m horizontal speed boost has been applied
var speedBoostApplied = false;
// Track if 4000m jumpscare has been triggered
var jumpscareTriggered = false;
// Track spawn rate multipliers that increase on restart
var alienSpawnMultiplier = 1.0;
var sawSpawnMultiplier = 1.0;
var hasRestarted = false;
var stars = [];
function createStar(x, y) {
	var star = LK.getAsset('star', {
		anchorX: 0.5,
		anchorY: 0.5,
		alpha: 0.6 + Math.random() * 0.4
	});
	star.x = x;
	star.y = y;
	star.twinkleSpeed = 0.02 + Math.random() * 0.03;
	star.twinkleOffset = Math.random() * Math.PI * 2;
	stars.push(star);
	game.addChild(star);
	return star;
}
function generateStars() {
	// Generate stars in the visible area and above
	for (var i = 0; i < 50; i++) {
		var x = Math.random() * 2048;
		var y = cameraY - 1000 + Math.random() * 3732;
		createStar(x, y);
	}
}
// Initialize stars
generateStars();
// Main game loop
game.update = function () {
	updateCamera();
	checkPlatformCollisions();
	checkTrampolineCollisions();
	checkCoinCollisions();
	checkSpecialItemCollisions();
	checkBulletAlienCollisions();
	checkAlienPlayerCollisions();
	checkSawPlayerCollisions();
	checkBombPlayerCollisions();
	checkFlashBombPlayerCollisions();
	generateMorePlatforms();
	// Calculate current and total height
	var currentHeight = Math.floor((2400 - dude.y) / 10);
	var displayHeight = totalHeight + currentHeight;
	// Check if player reached 4000m height for jumpscare
	if (displayHeight >= 4000 && !jumpscareTriggered) {
		jumpscareTriggered = true;
		// Create scary alien jumpscare that covers the entire screen
		var jumpscareAlien = LK.getAsset('alien', {
			anchorX: 0.5,
			anchorY: 0.5,
			scaleX: 20,
			scaleY: 20,
			alpha: 0
		});
		jumpscareAlien.x = 1024; // Center of screen
		jumpscareAlien.y = 1366; // Center of screen
		LK.gui.center.addChild(jumpscareAlien);
		// Play loud scary scream sound with maximum volume for jumpscare effect
		var jumpscareSound = LK.getSound('jumpscare');
		jumpscareSound.volume = 1.0; // Maximum volume for scary effect
		jumpscareSound.play();
		// Additional sound effect layering for more intensity
		LK.setTimeout(function () {
			jumpscareSound.play(); // Play again for echo effect
		}, 200);
		// Jumpscare animation with red flash and massive scaling
		LK.effects.flashScreen(0xff0000, 3000); // Red flash for 3 seconds
		tween(jumpscareAlien, {
			alpha: 1,
			scaleX: 25,
			scaleY: 25
		}, {
			duration: 150,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				// Hold for a longer moment with terrifying effect
				LK.setTimeout(function () {
					tween(jumpscareAlien, {
						alpha: 0,
						scaleX: 30,
						scaleY: 30
					}, {
						duration: 1500,
						onFinish: function onFinish() {
							jumpscareAlien.destroy();
						}
					});
				}, 2000);
			}
		});
	}
	// Check if player reached height 1200 and reset to starting position
	if (currentHeight >= 1200 && !speedBoostApplied) {
		speedBoostApplied = true;
		// Add current height to total height before reset
		totalHeight += 1200;
		storage.totalHeight = totalHeight;
		// Activate space theme when resetting after 1200m
		if (!spaceThemeActivated) {
			spaceThemeActivated = true;
			// Change background to dark space color
			game.setBackgroundColor(0x0a0a2e); // Dark blue-purple space color
			// Flash screen to indicate theme change
			LK.effects.flashScreen(0x8a2be2, 1000); // Purple flash for 1 second
		}
		// Reset character to starting position
		dude.x = 1024;
		dude.y = 2400;
		dude.velocityY = 0;
		dude.velocityX = 0;
		dude.isJumping = false;
		dude.isOnPlatform = false;
		// Reset camera
		cameraY = 0;
		game.y = -cameraY;
		highestY = 2400;
		// Reset current height tracking but keep total
		var newDisplayHeight = totalHeight;
		LK.setScore(newDisplayHeight);
		scoreTxt.setText(newDisplayHeight.toString());
		heightTxt.setText('Height: ' + newDisplayHeight + 'm');
		// Reset boost flags for next cycle
		jumpBoostApplied = false;
		speedBoostApplied = false;
		// Increase spawn rates on restart (100% aliens, 35% saws)
		if (!hasRestarted) {
			hasRestarted = true;
			alienSpawnMultiplier = 2.0; // 100% increase (double the rate)
			sawSpawnMultiplier = 1.35; // 35% increase
		} else {
			// Continue increasing on subsequent restarts
			alienSpawnMultiplier += 1.0; // Additional 100% each restart
			sawSpawnMultiplier += 0.35; // Additional 35% each restart
		}
		// Visual feedback for reset
		LK.effects.flashScreen(0x00ff00, 500); // Green flash
	}
	// Check if player reached height 1500 and boost jump power
	if (displayHeight >= 1500 && !jumpBoostApplied) {
		jumpBoostApplied = true;
		// Boost jump power by 1.5x (0.5x more than normal)
		dude.jumpPower = 52.5; // 35 * 1.5 = 52.5
		// Visual feedback for power boost
		LK.effects.flashObject(dude, 0x00ff00, 500); // Green flash
	}
	// Update star twinkling animation
	for (var s = 0; s < stars.length; s++) {
		var star = stars[s];
		star.alpha = 0.3 + Math.sin(LK.ticks * star.twinkleSpeed + star.twinkleOffset) * 0.4;
	}
	// Generate more stars as camera moves up
	if (LK.ticks % 120 === 0) {
		// Add new stars above the visible area
		for (var i = 0; i < 10; i++) {
			var x = Math.random() * 2048;
			var y = cameraY - 500 + Math.random() * 500;
			createStar(x, y);
		}
	}
	// Remove platforms that are too far down
	if (LK.ticks % 60 === 0) {
		cleanupCoins();
		cleanupBullets();
		cleanupTrampolines();
		cleanupAliens();
		cleanupSaws();
		cleanupBombs();
		cleanupFlashBombs();
		cleanupSpecialItems();
		// Cleanup stars that are too far below
		for (var s = stars.length - 1; s >= 0; s--) {
			var star = stars[s];
			if (star.y > cameraY + 3000) {
				star.destroy();
				stars.splice(s, 1);
			}
		}
	}
}; /**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
var facekit = LK.import("@upit/facekit.v1");
/**** 
* Classes
****/ 
var Alien = Container.expand(function () {
	var self = Container.call(this);
	var alienGraphics = self.attachAsset('alien', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.health = 1;
	self.speed = 1;
	self.direction = 1;
	self.moveRange = 200;
	self.startX = 0;
	self.active = true;
	self.lastWasHit = false;
	self.takeDamage = function () {
		self.health--;
		if (self.health <= 0) {
			self.active = false;
			LK.getSound('alienDestroy').play();
			// Flash effect before destruction
			tween(alienGraphics, {
				alpha: 0,
				scaleX: 1.5,
				scaleY: 1.5
			}, {
				duration: 300,
				onFinish: function onFinish() {
					self.destroy();
				}
			});
		} else {
			LK.getSound('alienHit').play();
			// Flash red when hit
			LK.effects.flashObject(self, 0xff0000, 200);
		}
	};
	self.update = function () {
		if (!self.active) return;
		// Move alien horizontally
		self.x += self.direction * self.speed;
		// Reverse direction when reaching movement limits
		if (self.x > self.startX + self.moveRange || self.x < self.startX - self.moveRange) {
			self.direction *= -1;
		}
		// Keep alien within screen bounds
		if (self.x < 40) {
			self.x = 40;
			self.direction = 1;
		}
		if (self.x > 2008) {
			self.x = 2008;
			self.direction = -1;
		}
	};
	return self;
});
var Bomb = Container.expand(function () {
	var self = Container.call(this);
	var bombGraphics = self.attachAsset('bomb', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.active = true;
	self.rotationSpeed = 0.05;
	self.pulseSpeed = 0.08;
	self.lastWasIntersecting = false;
	self.update = function () {
		// Rotate bomb slowly for menacing effect
		bombGraphics.rotation += self.rotationSpeed;
		// Pulsing scale effect to make it more noticeable
		var pulseScale = 1 + Math.sin(LK.ticks * self.pulseSpeed) * 0.2;
		bombGraphics.scaleX = pulseScale;
		bombGraphics.scaleY = pulseScale;
		// Red tinting that pulses to indicate danger
		var redIntensity = 0.5 + Math.sin(LK.ticks * self.pulseSpeed * 2) * 0.5;
		bombGraphics.tint = 0xff << 16 | Math.floor((1 - redIntensity) * 255) << 8 | Math.floor((1 - redIntensity) * 255);
	};
	return self;
});
var Bullet = Container.expand(function () {
	var self = Container.call(this);
	var bulletGraphics = self.attachAsset('bullet', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 15;
	self.direction = {
		x: 0,
		y: -1
	}; // Default upward direction
	self.active = true;
	self.update = function () {
		// Find nearest alien to auto-target
		var nearestAlien = null;
		var nearestDistance = Infinity;
		for (var i = 0; i < aliens.length; i++) {
			var alien = aliens[i];
			if (alien.active) {
				var distance = Math.sqrt(Math.pow(self.x - alien.x, 2) + Math.pow(self.y - alien.y, 2));
				if (distance < nearestDistance) {
					nearestDistance = distance;
					nearestAlien = alien;
				}
			}
		}
		// If there's an alien to target, automatically steer towards it
		if (nearestAlien) {
			var targetX = nearestAlien.x - self.x;
			var targetY = nearestAlien.y - self.y;
			var targetDistance = Math.sqrt(targetX * targetX + targetY * targetY);
			if (targetDistance > 0) {
				// Normalize direction towards target
				self.direction.x = targetX / targetDistance;
				self.direction.y = targetY / targetDistance;
			}
		}
		self.x += self.direction.x * self.speed;
		self.y += self.direction.y * self.speed;
		// Remove bullet if it goes off screen
		if (self.y < cameraY - 200 || self.y > cameraY + 2732 + 200 || self.x < -100 || self.x > 2148) {
			self.active = false;
		}
	};
	return self;
});
var Coin = Container.expand(function () {
	var self = Container.call(this);
	var coinGraphics = self.attachAsset('coin', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.collected = false;
	self.rotationSpeed = 0.1;
	self.update = function () {
		// Rotate coin for visual appeal
		coinGraphics.rotation += self.rotationSpeed;
		// Float up and down slightly
		self.y += Math.sin(LK.ticks * 0.05) * 0.5;
	};
	return self;
});
var Dude = Container.expand(function () {
	var self = Container.call(this);
	var dudeGraphics = self.attachAsset('dude', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.velocityY = 0;
	self.velocityX = 0;
	self.isJumping = false;
	self.isOnPlatform = false;
	self.jumpPower = 35;
	self.gravity = 0.8;
	self.maxFallSpeed = 15;
	self.horizontalSpeed = 12;
	self.airResistance = 0.85;
	self.invincible = false;
	self.invincibleTimer = 0;
	self.health = 4;
	self.maxHealth = 4;
	self.jump = function () {
		if (self.isOnPlatform) {
			self.velocityY = -self.jumpPower;
			self.isJumping = true;
			self.isOnPlatform = false;
			LK.getSound('jump').play();
		}
	};
	self.update = function () {
		// Auto jump when on platform (only if not flying)
		if (self.isOnPlatform && !self.canFly) {
			self.jump();
		}
		// Apply gravity (reduced if flying)
		if (self.canFly) {
			self.velocityY += self.gravity * 0.5; // Reduced gravity for flying
		} else {
			self.velocityY += self.gravity;
		}
		if (self.velocityY > self.maxFallSpeed) {
			self.velocityY = self.maxFallSpeed;
		}
		// Update position
		self.y += self.velocityY;
		self.x += self.velocityX;
		// Apply continuous horizontal movement while pressed
		if (isPressed && pressedSide !== 0) {
			self.velocityX += pressedSide * self.horizontalSpeed * 0.3;
		}
		// Apply air resistance to horizontal movement
		self.velocityX *= self.airResistance;
		// Handle invincibility timer
		if (self.invincible) {
			self.invincibleTimer--;
			if (self.invincibleTimer <= 0) {
				self.invincible = false;
				dudeGraphics.alpha = 1;
			} else {
				dudeGraphics.alpha = Math.sin(self.invincibleTimer * 0.3) * 0.5 + 0.5;
			}
		}
		// Allow infinite horizontal movement - no bounds restriction
		// Character can now move infinitely left and right
		// Check if fallen off screen
		if (self.y > cameraY + 2732 + 200) {
			// Reset gold to zero when player falls off screen
			gold = 0;
			storage.gold = 0;
			goldTxt.setText('Gold: ' + gold);
			// Reset total height when player dies
			totalHeight = 0;
			storage.totalHeight = 0;
			// Reset spawn rate multipliers when character dies
			alienSpawnMultiplier = 1.0;
			sawSpawnMultiplier = 1.0;
			LK.showGameOver();
		}
	};
	self.takeDamage = function () {
		if (self.invincible) return;
		self.health--;
		self.invincible = true;
		self.invincibleTimer = 180; // 3 seconds of invincibility
		LK.effects.flashObject(self, 0xff0000, 500);
		updateHealthDisplay();
		if (self.health <= 0) {
			// Reset gold to zero when player dies
			gold = 0;
			storage.gold = 0;
			goldTxt.setText('Gold: ' + gold);
			// Reset total height when player dies
			totalHeight = 0;
			storage.totalHeight = 0;
			// Reset spawn rate multipliers when character dies
			alienSpawnMultiplier = 1.0;
			sawSpawnMultiplier = 1.0;
			LK.showGameOver();
		}
	};
	self.shoot = function (direction) {
		var bullet = new Bullet();
		bullet.x = self.x;
		bullet.y = self.y;
		// Set bullet direction based on parameter
		if (direction === 'up') {
			bullet.direction = {
				x: 0,
				y: -1
			};
			bullet.y = self.y - 30;
		} else if (direction === 'down') {
			bullet.direction = {
				x: 0,
				y: 1
			};
			bullet.y = self.y + 30;
		} else if (direction === 'left') {
			bullet.direction = {
				x: -1,
				y: 0
			};
			bullet.x = self.x - 30;
		} else if (direction === 'right') {
			bullet.direction = {
				x: 1,
				y: 0
			};
			bullet.x = self.x + 30;
		}
		bullets.push(bullet);
		game.addChild(bullet);
		LK.getSound('shoot').play();
	};
	return self;
});
var FlashBomb = Container.expand(function () {
	var self = Container.call(this);
	var flashBombGraphics = self.attachAsset('flashBomb', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.active = true;
	self.rotationSpeed = 0.05;
	self.pulseSpeed = 0.08;
	self.lastWasIntersecting = false;
	// Make flash bomb visually different - white tint
	flashBombGraphics.tint = 0xffffff;
	self.update = function () {
		// Rotate flash bomb slowly
		flashBombGraphics.rotation += self.rotationSpeed;
		// Pulsing scale effect
		var pulseScale = 1 + Math.sin(LK.ticks * self.pulseSpeed) * 0.2;
		flashBombGraphics.scaleX = pulseScale;
		flashBombGraphics.scaleY = pulseScale;
		// White tinting that pulses to indicate flash effect
		var whiteIntensity = 0.7 + Math.sin(LK.ticks * self.pulseSpeed * 2) * 0.3;
		flashBombGraphics.tint = Math.floor(whiteIntensity * 255) << 16 | Math.floor(whiteIntensity * 255) << 8 | Math.floor(whiteIntensity * 255);
	};
	return self;
});
var Platform = Container.expand(function (type) {
	var self = Container.call(this);
	self.type = type || 'normal';
	self.landed = false;
	self.disappearing = false;
	self.moveDirection = 1;
	self.moveRange = 300;
	self.startX = 0;
	var platformGraphics;
	if (self.type === 'moving') {
		platformGraphics = self.attachAsset('movingPlatform', {
			anchorX: 0.5,
			anchorY: 0.5
		});
	} else if (self.type === 'disappearing') {
		platformGraphics = self.attachAsset('disappearingPlatform', {
			anchorX: 0.5,
			anchorY: 0.5
		});
	} else if (self.type === 'powerup') {
		platformGraphics = self.attachAsset('powerUpPlatform', {
			anchorX: 0.5,
			anchorY: 0.5
		});
	} else {
		platformGraphics = self.attachAsset('platform', {
			anchorX: 0.5,
			anchorY: 0.5
		});
	}
	self.update = function () {
		// Moving platform behavior
		if (self.type === 'moving') {
			self.x += self.moveDirection * 2;
			if (self.x > self.startX + self.moveRange || self.x < self.startX - self.moveRange) {
				self.moveDirection *= -1;
			}
		}
		// Disappearing platform behavior
		if (self.type === 'disappearing' && self.landed && !self.disappearing) {
			self.disappearing = true;
			tween(platformGraphics, {
				alpha: 0
			}, {
				duration: 1000,
				onFinish: function onFinish() {
					self.active = false;
				}
			});
		}
	};
	return self;
});
var Saw = Container.expand(function () {
	var self = Container.call(this);
	var sawGraphics = self.attachAsset('saw', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.active = true;
	self.rotationSpeed = 0.3;
	self.lastWasIntersecting = false;
	self.moveDirection = Math.random() < 0.5 ? -1 : 1; // Random initial direction
	self.moveSpeed = 2;
	self.moveRange = 150;
	self.startX = 0;
	self.update = function () {
		// Move saw horizontally
		self.x += self.moveDirection * self.moveSpeed;
		// Reverse direction when reaching movement limits
		if (self.x > self.startX + self.moveRange || self.x < self.startX - self.moveRange) {
			self.moveDirection *= -1;
		}
		// Keep saw within screen bounds
		if (self.x < 60) {
			self.x = 60;
			self.moveDirection = 1;
		}
		if (self.x > 1988) {
			self.x = 1988;
			self.moveDirection = -1;
		}
	};
	return self;
});
var SpecialItem = Container.expand(function (itemType) {
	var self = Container.call(this);
	self.itemType = itemType || 1;
	var assetId = 'specialItem' + self.itemType;
	var itemGraphics = self.attachAsset(assetId, {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Make special items larger
	itemGraphics.scaleX = 2;
	itemGraphics.scaleY = 2;
	self.collected = false;
	self.active = true;
	self.rotationSpeed = 0.15;
	self.floatOffset = Math.random() * Math.PI * 2;
	self.update = function () {
		// Float up and down with more pronounced animation
		self.y += Math.sin(LK.ticks * 0.06 + self.floatOffset) * 1.2;
		// Pulsing scale effect
		var pulseScale = 2 + Math.sin(LK.ticks * 0.08) * 0.3;
		itemGraphics.scaleX = pulseScale;
		itemGraphics.scaleY = pulseScale;
	};
	return self;
});
var Trampoline = Container.expand(function () {
	var self = Container.call(this);
	var trampolineGraphics = self.attachAsset('trampoline', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.bounced = false;
	self.active = true;
	self.bounce = function () {
		// Animate trampoline compression and expansion
		tween(trampolineGraphics, {
			scaleY: 0.5
		}, {
			duration: 100,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				tween(trampolineGraphics, {
					scaleY: 1.2
				}, {
					duration: 200,
					easing: tween.bounceOut,
					onFinish: function onFinish() {
						tween(trampolineGraphics, {
							scaleY: 1
						}, {
							duration: 100,
							easing: tween.easeOut
						});
					}
				});
			}
		});
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x87ceeb
});
/**** 
* Game Code
****/ 
var dude = game.addChild(new Dude());
var platforms = [];
var coins = [];
var bullets = [];
var trampolines = [];
var cameraY = 0;
var highestY = 2400;
var lastPlatformY = 2400;
var platformSpacing = 200;
var coinsCollected = 0;
var gold = storage.gold || 0;
var totalHeight = storage.totalHeight || 0;
var lastShootTime = 0;
var shootCooldown = 20; // 20 ticks between shots
var aliens = [];
var aliensKilled = 0;
var saws = [];
var specialItems = [];
var specialItemsCollected = 0;
var totalSpecialItems = 4;
var zombiesKilled = 0;
var bombs = [];
var flashBombs = [];
// Create score display
var scoreTxt = new Text2('0', {
	size: 60,
	fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Create height display
var heightTxt = new Text2('Height: 0m', {
	size: 40,
	fill: 0xFFFFFF
});
heightTxt.anchor.set(1, 0);
heightTxt.x = -20;
heightTxt.y = 20;
LK.gui.topRight.addChild(heightTxt);
// Create coin counter display
var coinTxt = new Text2('Coins: 0', {
	size: 40,
	fill: 0xffd700
});
coinTxt.anchor.set(0, 0);
coinTxt.x = 20;
coinTxt.y = 20;
LK.gui.topLeft.addChild(coinTxt);
// Create gold display
var goldTxt = new Text2('Gold: ' + gold, {
	size: 40,
	fill: 0xffd700
});
goldTxt.anchor.set(0, 0);
goldTxt.x = 20;
goldTxt.y = 120;
LK.gui.topLeft.addChild(goldTxt);
// Create special items display
var specialItemsTxt = new Text2('Special Items: 0/' + totalSpecialItems, {
	size: 40,
	fill: 0xff0000
});
specialItemsTxt.anchor.set(0, 0);
specialItemsTxt.x = 20;
specialItemsTxt.y = 170;
LK.gui.topLeft.addChild(specialItemsTxt);
// Create health display
var hearts = [];
function createHealthDisplay() {
	for (var i = 0; i < dude.maxHealth; i++) {
		var heart = LK.getAsset('heart', {
			anchorX: 0.5,
			anchorY: 0.5
		});
		heart.x = 20 + i * 50;
		heart.y = 80;
		hearts.push(heart);
		LK.gui.topLeft.addChild(heart);
	}
}
function updateHealthDisplay() {
	for (var i = 0; i < hearts.length; i++) {
		hearts[i].alpha = i < dude.health ? 1 : 0.3;
	}
}
// Initialize dude position
dude.x = 1024;
dude.y = 2400;
// Initialize health display
createHealthDisplay();
updateHealthDisplay();
// Create fire buttons for 4 directions
var fireButtonUp = LK.getAsset('fireButton', {
	anchorX: 0.5,
	anchorY: 0.5,
	scaleX: 1.5,
	scaleY: 1.5
});
fireButtonUp.x = -120;
fireButtonUp.y = -300;
LK.gui.bottomRight.addChild(fireButtonUp);
var fireButtonDown = LK.getAsset('fireButton', {
	anchorX: 0.5,
	anchorY: 0.5,
	scaleX: 1.5,
	scaleY: 1.5
});
fireButtonDown.x = -120;
fireButtonDown.y = -100;
fireButtonDown.rotation = Math.PI; // Rotate 180 degrees
LK.gui.bottomRight.addChild(fireButtonDown);
var fireButtonLeft = LK.getAsset('fireButton', {
	anchorX: 0.5,
	anchorY: 0.5,
	scaleX: 1.5,
	scaleY: 1.5
});
fireButtonLeft.x = -220;
fireButtonLeft.y = -200;
fireButtonLeft.rotation = Math.PI * 1.5; // Rotate 270 degrees
LK.gui.bottomRight.addChild(fireButtonLeft);
var fireButtonRight = LK.getAsset('fireButton', {
	anchorX: 0.5,
	anchorY: 0.5,
	scaleX: 1.5,
	scaleY: 1.5
});
fireButtonRight.x = -20;
fireButtonRight.y = -200;
fireButtonRight.rotation = Math.PI * 0.5; // Rotate 90 degrees
LK.gui.bottomRight.addChild(fireButtonRight);
// Create initial platforms
function createPlatform(x, y, type) {
	var platform = new Platform(type);
	platform.x = x;
	platform.y = y;
	platform.startX = x;
	platform.active = true;
	platforms.push(platform);
	game.addChild(platform);
	return platform;
}
// Create starting platform
createPlatform(1024, 2450, 'normal');
// Generate initial platforms
for (var i = 0; i < 20; i++) {
	generateNextPlatform();
}
function generateNextPlatform() {
	lastPlatformY -= platformSpacing + Math.random() * 100;
	var x = 200 + Math.random() * 1648;
	// Determine platform type based on height
	var type = 'normal';
	var height = Math.abs(lastPlatformY - 2400);
	if (height > 1000) {
		var rand = Math.random();
		var powerupChance = spaceThemeActivated ? 0.8 : 0.6; // Increased from 0.6 to 0.8 in space theme
		if (rand < 0.3) {
			type = 'moving';
		} else if (rand < 0.5) {
			type = 'disappearing';
		} else if (rand < powerupChance) {
			type = 'powerup';
		}
	}
	createPlatform(x, lastPlatformY, type);
	// Generate coins near platforms with increased rate after 1255m
	var currentGameHeight = Math.abs(lastPlatformY - 2400);
	var coinChance = currentGameHeight > 1255 ? 0.98 : 0.85; // 98% chance after 1255m, 85% before
	if (Math.random() < coinChance) {
		generateCoin(x + (Math.random() - 0.5) * 200, lastPlatformY - 80);
	}
	// Generate trampolines more frequently (25% chance, 40% in space theme)
	var trampolineChance = spaceThemeActivated ? 0.40 : 0.25;
	if (Math.random() < trampolineChance) {
		createTrampoline(x, lastPlatformY - 100);
	}
	// Generate aliens with 15% chance
	var alienChance = 0.15; // 15% chance
	if (Math.random() < alienChance) {
		createAlien(x + (Math.random() - 0.5) * 300, lastPlatformY - 150);
	}
	// Kittens removed from game
	// Generate saws more frequently (25% chance)
	var baseSawChance = 0.25; // 25% chance (increased from 10%)
	var sawChance = baseSawChance * sawSpawnMultiplier;
	if (Math.random() < sawChance) {
		createSaw(x + (Math.random() - 0.5) * 300, lastPlatformY - 100);
	}
	// Generate bombs with 5% chance after reaching 500m height
	var currentGameHeight = Math.abs(lastPlatformY - 2400);
	if (currentGameHeight > 500 && Math.random() < 0.05) {
		createBomb(x + (Math.random() - 0.5) * 300, lastPlatformY - 120);
	}
	// Generate flash bombs more frequently (20% chance after reaching 800m height)
	if (currentGameHeight > 800 && Math.random() < 0.20) {
		createFlashBomb(x + (Math.random() - 0.5) * 300, lastPlatformY - 120);
	}
	// Generate special items frequently (10% chance) and only if we haven't collected all yet
	if (Math.random() < 0.10 && specialItemsCollected < totalSpecialItems) {
		var nextItemType = specialItemsCollected + 1;
		createSpecialItem(x + (Math.random() - 0.5) * 200, lastPlatformY - 150, nextItemType);
	}
}
function generateCoin(x, y) {
	var coin = new Coin();
	coin.x = x;
	coin.y = y;
	coin.active = true;
	coins.push(coin);
	game.addChild(coin);
}
function createTrampoline(x, y) {
	var trampoline = new Trampoline();
	trampoline.x = x;
	trampoline.y = y;
	trampoline.active = true;
	trampolines.push(trampoline);
	game.addChild(trampoline);
	return trampoline;
}
function createAlien(x, y) {
	var alien = new Alien();
	alien.x = x;
	alien.y = y;
	alien.startX = x;
	alien.active = true;
	aliens.push(alien);
	game.addChild(alien);
	return alien;
}
function createSaw(x, y) {
	var saw = new Saw();
	saw.x = x;
	saw.y = y;
	saw.startX = x;
	saw.active = true;
	saw.lastWasIntersecting = false;
	saws.push(saw);
	game.addChild(saw);
	return saw;
}
function createBomb(x, y) {
	var bomb = new Bomb();
	bomb.x = x;
	bomb.y = y;
	bomb.active = true;
	bomb.lastWasIntersecting = false;
	bombs.push(bomb);
	game.addChild(bomb);
	return bomb;
}
function createFlashBomb(x, y) {
	var flashBomb = new FlashBomb();
	flashBomb.x = x;
	flashBomb.y = y;
	flashBomb.active = true;
	flashBomb.lastWasIntersecting = false;
	flashBombs.push(flashBomb);
	game.addChild(flashBomb);
	return flashBomb;
}
function createSpecialItem(x, y, itemType) {
	var item = new SpecialItem(itemType);
	item.x = x;
	item.y = y;
	item.active = true;
	specialItems.push(item);
	game.addChild(item);
	return item;
}
function updateCamera() {
	var targetY = dude.y - 1800;
	if (targetY < cameraY) {
		cameraY = targetY;
		game.y = -cameraY;
		// Update highest position
		if (dude.y < highestY) {
			highestY = dude.y;
			var currentHeight = Math.floor((2400 - highestY) / 10);
			var displayHeight = totalHeight + currentHeight;
			LK.setScore(displayHeight);
			scoreTxt.setText(LK.getScore());
			heightTxt.setText('Height: ' + displayHeight + 'm');
		}
	}
}
function checkPlatformCollisions() {
	for (var i = 0; i < platforms.length; i++) {
		var platform = platforms[i];
		if (!platform.active) continue;
		// Define dude and platform boundaries
		var dudeLeft = dude.x - 40;
		var dudeRight = dude.x + 40;
		var dudeTop = dude.y - 40;
		var dudeBottom = dude.y + 40;
		var platformLeft = platform.x - 150;
		var platformRight = platform.x + 150;
		var platformTop = platform.y - 15;
		var platformBottom = platform.y + 15;
		// Check if dude and platform are overlapping horizontally and vertically
		var horizontalOverlap = dudeRight > platformLeft && dudeLeft < platformRight;
		var verticalOverlap = dudeBottom > platformTop && dudeTop < platformBottom;
		if (horizontalOverlap && verticalOverlap) {
			// Calculate overlap distances for each direction
			var overlapLeft = dudeRight - platformLeft;
			var overlapRight = platformRight - dudeLeft;
			var overlapTop = dudeBottom - platformTop;
			var overlapBottom = platformBottom - dudeTop;
			// Find the smallest overlap to determine collision direction
			var minOverlap = Math.min(overlapLeft, overlapRight, overlapTop, overlapBottom);
			// Handle collision based on the direction with smallest overlap
			if (minOverlap === overlapTop && dude.velocityY > 0) {
				// Landing on top of platform (falling down)
				dude.y = platformTop - 40;
				dude.velocityY = 0;
				dude.isOnPlatform = true;
				dude.isJumping = false;
				if (!platform.landed) {
					platform.landed = true;
					LK.getSound('land').play();
					// Handle special platform effects
					if (platform.type === 'powerup') {
						dude.invincible = true;
						dude.invincibleTimer = 300;
						dude.jumpPower = 70; // Double the normal jump power (35 * 2)
						LK.getSound('powerup').play();
						// Reset jump power after 1 second using tween for precise timing
						LK.setTimeout(function () {
							dude.jumpPower = 35; // Reset to normal jump power
						}, 1000); // Changed from 3000ms to 1000ms (1 second)
					}
				}
			} else if (minOverlap === overlapLeft && dude.velocityX > 0) {
				// Hitting platform from the left (moving right)
				dude.x = platformLeft - 40;
				dude.velocityX = 0;
			} else if (minOverlap === overlapRight && dude.velocityX < 0) {
				// Hitting platform from the right (moving left)
				dude.x = platformRight + 40;
				dude.velocityX = 0;
			}
			break;
		}
	}
}
function checkCoinCollisions() {
	for (var i = coins.length - 1; i >= 0; i--) {
		var coin = coins[i];
		if (!coin.active || coin.collected) continue;
		// Check if dude is close enough to collect coin
		var distance = Math.sqrt(Math.pow(dude.x - coin.x, 2) + Math.pow(dude.y - coin.y, 2));
		if (distance < 50) {
			// Collect coin
			coin.collected = true;
			coin.active = false;
			coinsCollected++;
			coinTxt.setText('Coins: ' + coinsCollected);
			LK.getSound('coinCollect').play();
			// Check if player reached 20 coins
			if (coinsCollected >= 20) {
				// Show bravo message
				LK.showYouWin();
			}
			// Remove coin with fade effect
			tween(coin, {
				alpha: 0,
				scaleX: 1.5,
				scaleY: 1.5
			}, {
				duration: 200,
				onFinish: function onFinish() {
					coin.destroy();
					coins.splice(i, 1);
				}
			});
		}
	}
}
function checkTrampolineCollisions() {
	if (dude.velocityY <= 0) return; // Only check when falling
	for (var i = 0; i < trampolines.length; i++) {
		var trampoline = trampolines[i];
		if (!trampoline.active) continue;
		var dudeBottom = dude.y + 40;
		var trampolineTop = trampoline.y - 30;
		var trampolineBottom = trampoline.y + 30;
		if (dudeBottom >= trampolineTop && dudeBottom <= trampolineBottom + 20) {
			if (dude.x >= trampoline.x - 150 && dude.x <= trampoline.x + 150) {
				// Bounce off trampoline with super jump
				dude.velocityY = -60; // Much higher than normal jump
				dude.isJumping = true;
				dude.isOnPlatform = false;
				trampoline.bounce();
				LK.getSound('jump').play();
				break;
			}
		}
	}
}
function checkBulletAlienCollisions() {
	for (var i = bullets.length - 1; i >= 0; i--) {
		var bullet = bullets[i];
		if (!bullet.active) continue;
		for (var j = aliens.length - 1; j >= 0; j--) {
			var alien = aliens[j];
			if (!alien.active) continue;
			// Check collision between bullet and alien
			var distance = Math.sqrt(Math.pow(bullet.x - alien.x, 2) + Math.pow(bullet.y - alien.y, 2));
			if (distance < 50) {
				// Hit detected
				bullet.active = false;
				bullet.destroy();
				bullets.splice(i, 1);
				alien.takeDamage();
				if (!alien.active) {
					aliensKilled++;
					zombiesKilled++;
					aliens.splice(j, 1);
					// Increase score for killing alien
					LK.setScore(LK.getScore() + 10);
					scoreTxt.setText(LK.getScore());
					// Give gold reward with 50% chance (100/2 = 50%)
					if (Math.random() < 0.5) {
						gold += 1;
						storage.gold = gold;
						goldTxt.setText('Gold: ' + gold);
					}
					// Check if player killed 10 zombies
					if (zombiesKilled >= 10) {
						// Show you win message
						LK.showYouWin();
					}
				}
				break;
			}
		}
	}
}
function cleanupPlatforms() {
	for (var i = platforms.length - 1; i >= 0; i--) {
		var platform = platforms[i];
		if (platform.y > cameraY + 3000 || !platform.active) {
			platform.destroy();
			platforms.splice(i, 1);
		}
	}
}
function cleanupCoins() {
	for (var i = coins.length - 1; i >= 0; i--) {
		var coin = coins[i];
		if (coin.y > cameraY + 3000 || !coin.active) {
			coin.destroy();
			coins.splice(i, 1);
		}
	}
}
function cleanupBullets() {
	for (var i = bullets.length - 1; i >= 0; i--) {
		var bullet = bullets[i];
		if (bullet.y < cameraY - 200 || !bullet.active) {
			bullet.destroy();
			bullets.splice(i, 1);
		}
	}
}
function cleanupTrampolines() {
	for (var i = trampolines.length - 1; i >= 0; i--) {
		var trampoline = trampolines[i];
		if (trampoline.y > cameraY + 3000 || !trampoline.active) {
			trampoline.destroy();
			trampolines.splice(i, 1);
		}
	}
}
function checkSpecialItemCollisions() {
	for (var i = specialItems.length - 1; i >= 0; i--) {
		var item = specialItems[i];
		if (!item.active || item.collected) continue;
		// Check if dude is close enough to collect special item
		var distance = Math.sqrt(Math.pow(dude.x - item.x, 2) + Math.pow(dude.y - item.y, 2));
		if (distance < 60) {
			// Collect special item
			item.collected = true;
			item.active = false;
			specialItemsCollected++;
			specialItemsTxt.setText('Special Items: ' + specialItemsCollected + '/' + totalSpecialItems);
			// Visual feedback - dramatic collection effect
			LK.effects.flashScreen(0xff0000, 500);
			tween(item, {
				alpha: 0,
				scaleX: 4,
				scaleY: 4
			}, {
				duration: 500,
				onFinish: function onFinish() {
					item.destroy();
					specialItems.splice(i, 1);
				}
			});
			// Check if all special items collected
			if (specialItemsCollected >= totalSpecialItems) {
				// Show you win message
				LK.showYouWin();
			}
			break;
		}
	}
}
function checkAlienPlayerCollisions() {
	if (dude.invincible) return;
	for (var i = 0; i < aliens.length; i++) {
		var alien = aliens[i];
		if (!alien.active) continue;
		var distance = Math.sqrt(Math.pow(dude.x - alien.x, 2) + Math.pow(dude.y - alien.y, 2));
		if (distance < 60) {
			dude.takeDamage();
			break;
		}
	}
}
function checkBombPlayerCollisions() {
	if (dude.invincible) return;
	for (var i = 0; i < bombs.length; i++) {
		var bomb = bombs[i];
		if (!bomb.active) continue;
		var distance = Math.sqrt(Math.pow(dude.x - bomb.x, 2) + Math.pow(dude.y - bomb.y, 2));
		var currentIntersecting = distance < 60;
		// Check for transition from not intersecting to intersecting
		if (!bomb.lastWasIntersecting && currentIntersecting) {
			// Take 3 damage from bomb
			dude.health -= 3;
			if (dude.health < 0) dude.health = 0;
			dude.invincible = true;
			dude.invincibleTimer = 180; // 3 seconds of invincibility
			// Dramatic explosion effect
			LK.effects.flashScreen(0xff4444, 1000);
			LK.effects.flashObject(dude, 0xff0000, 800);
			updateHealthDisplay();
			// Destroy the bomb after explosion
			bomb.active = false;
			bomb.destroy();
			bombs.splice(i, 1);
			if (dude.health <= 0) {
				// Reset gold to zero when player dies
				gold = 0;
				storage.gold = 0;
				goldTxt.setText('Gold: ' + gold);
				// Reset total height when player dies
				totalHeight = 0;
				storage.totalHeight = 0;
				// Reset spawn rate multipliers when character dies
				alienSpawnMultiplier = 1.0;
				sawSpawnMultiplier = 1.0;
				LK.showGameOver();
			}
			break;
		}
		// Update last intersecting state
		bomb.lastWasIntersecting = currentIntersecting;
	}
}
function checkFlashBombPlayerCollisions() {
	for (var i = 0; i < flashBombs.length; i++) {
		var flashBomb = flashBombs[i];
		if (!flashBomb.active) continue;
		var distance = Math.sqrt(Math.pow(dude.x - flashBomb.x, 2) + Math.pow(dude.y - flashBomb.y, 2));
		var currentIntersecting = distance < 60;
		// Check for transition from not intersecting to intersecting
		if (!flashBomb.lastWasIntersecting && currentIntersecting) {
			// Create a white overlay that covers the entire screen for 3 seconds
			var whiteOverlay = LK.getAsset('bullet', {
				anchorX: 0.5,
				anchorY: 0.5,
				scaleX: 100,
				scaleY: 150,
				alpha: 0
			});
			whiteOverlay.tint = 0xffffff;
			whiteOverlay.x = 1024; // Center of screen
			whiteOverlay.y = 1366; // Center of screen
			LK.gui.center.addChild(whiteOverlay);
			// Tween the overlay to full opacity immediately, then gradually fade out over 3 seconds
			tween(whiteOverlay, {
				alpha: 1
			}, {
				duration: 50,
				onFinish: function onFinish() {
					// Gradually fade out the white screen over 3 seconds
					tween(whiteOverlay, {
						alpha: 0
					}, {
						duration: 3000,
						easing: tween.easeOut,
						onFinish: function onFinish() {
							whiteOverlay.destroy();
						}
					});
				}
			});
			// Destroy the flash bomb after activation
			flashBomb.active = false;
			flashBomb.destroy();
			flashBombs.splice(i, 1);
			break;
		}
		// Update last intersecting state
		flashBomb.lastWasIntersecting = currentIntersecting;
	}
}
function checkSawPlayerCollisions() {
	if (dude.invincible) return;
	for (var i = 0; i < saws.length; i++) {
		var saw = saws[i];
		if (!saw.active) continue;
		var distance = Math.sqrt(Math.pow(dude.x - saw.x, 2) + Math.pow(dude.y - saw.y, 2));
		var currentIntersecting = distance < 70;
		// Check for transition from not intersecting to intersecting
		if (!saw.lastWasIntersecting && currentIntersecting) {
			dude.takeDamage();
		}
		// Update last intersecting state
		saw.lastWasIntersecting = currentIntersecting;
	}
}
function cleanupAliens() {
	for (var i = aliens.length - 1; i >= 0; i--) {
		var alien = aliens[i];
		if (alien.y > cameraY + 3000 || !alien.active) {
			if (alien.active) {
				alien.destroy();
			}
			aliens.splice(i, 1);
		}
	}
}
function cleanupSaws() {
	for (var i = saws.length - 1; i >= 0; i--) {
		var saw = saws[i];
		if (saw.y > cameraY + 3000 || !saw.active) {
			if (saw.active) {
				saw.destroy();
			}
			saws.splice(i, 1);
		}
	}
}
function cleanupBombs() {
	for (var i = bombs.length - 1; i >= 0; i--) {
		var bomb = bombs[i];
		if (bomb.y > cameraY + 3000 || !bomb.active) {
			if (bomb.active) {
				bomb.destroy();
			}
			bombs.splice(i, 1);
		}
	}
}
function cleanupFlashBombs() {
	for (var i = flashBombs.length - 1; i >= 0; i--) {
		var flashBomb = flashBombs[i];
		if (flashBomb.y > cameraY + 3000 || !flashBomb.active) {
			if (flashBomb.active) {
				flashBomb.destroy();
			}
			flashBombs.splice(i, 1);
		}
	}
}
function cleanupSpecialItems() {
	for (var i = specialItems.length - 1; i >= 0; i--) {
		var item = specialItems[i];
		if (item.y > cameraY + 3000 || !item.active) {
			if (item.active) {
				item.destroy();
			}
			specialItems.splice(i, 1);
		}
	}
}
function generateMorePlatforms() {
	while (lastPlatformY > cameraY - 1000) {
		generateNextPlatform();
	}
}
// Touch controls
var isPressed = false;
var pressedSide = 0; // -1 for left, 1 for right, 0 for center
game.down = function (x, y, obj) {
	dude.jump();
	isPressed = true;
	// Determine which side was pressed
	var screenCenter = 1024; // Half of 2048
	var touchOffset = x - screenCenter;
	if (touchOffset > 50) {
		pressedSide = 1; // Right side
	} else if (touchOffset < -50) {
		pressedSide = -1; // Left side
	} else {
		pressedSide = 0; // Center
	}
	// Shoot when touching center area
	if (Math.abs(touchOffset) <= 50 && LK.ticks - lastShootTime >= shootCooldown) {
		dude.shoot('up');
		lastShootTime = LK.ticks;
	}
};
game.up = function (x, y, obj) {
	isPressed = false;
	pressedSide = 0;
};
// Fire button touch handlers for 4 directions
function createFireButtonHandler(button, direction) {
	button.down = function (x, y, obj) {
		if (LK.ticks - lastShootTime >= shootCooldown) {
			dude.shoot(direction);
			lastShootTime = LK.ticks;
			// Visual feedback - scale animation
			tween(button, {
				scaleX: 1.2,
				scaleY: 1.2
			}, {
				duration: 100,
				onFinish: function onFinish() {
					tween(button, {
						scaleX: 1.5,
						scaleY: 1.5
					}, {
						duration: 100
					});
				}
			});
		}
	};
}
createFireButtonHandler(fireButtonUp, 'up');
createFireButtonHandler(fireButtonDown, 'down');
createFireButtonHandler(fireButtonLeft, 'left');
createFireButtonHandler(fireButtonRight, 'right');
// Track if space theme has been activated
var spaceThemeActivated = false;
// Track if 1500m jump boost has been applied
var jumpBoostApplied = false;
// Track if 1200m horizontal speed boost has been applied
var speedBoostApplied = false;
// Track if 4000m jumpscare has been triggered
var jumpscareTriggered = false;
// Track spawn rate multipliers that increase on restart
var alienSpawnMultiplier = 1.0;
var sawSpawnMultiplier = 1.0;
var hasRestarted = false;
var stars = [];
function createStar(x, y) {
	var star = LK.getAsset('star', {
		anchorX: 0.5,
		anchorY: 0.5,
		alpha: 0.6 + Math.random() * 0.4
	});
	star.x = x;
	star.y = y;
	star.twinkleSpeed = 0.02 + Math.random() * 0.03;
	star.twinkleOffset = Math.random() * Math.PI * 2;
	stars.push(star);
	game.addChild(star);
	return star;
}
function generateStars() {
	// Generate stars in the visible area and above
	for (var i = 0; i < 50; i++) {
		var x = Math.random() * 2048;
		var y = cameraY - 1000 + Math.random() * 3732;
		createStar(x, y);
	}
}
// Initialize stars
generateStars();
// Main game loop
game.update = function () {
	updateCamera();
	checkPlatformCollisions();
	checkTrampolineCollisions();
	checkCoinCollisions();
	checkSpecialItemCollisions();
	checkBulletAlienCollisions();
	checkAlienPlayerCollisions();
	checkSawPlayerCollisions();
	checkBombPlayerCollisions();
	checkFlashBombPlayerCollisions();
	generateMorePlatforms();
	// Calculate current and total height
	var currentHeight = Math.floor((2400 - dude.y) / 10);
	var displayHeight = totalHeight + currentHeight;
	// Check if player reached 4000m height for jumpscare
	if (displayHeight >= 4000 && !jumpscareTriggered) {
		jumpscareTriggered = true;
		// Create scary alien jumpscare that covers the entire screen
		var jumpscareAlien = LK.getAsset('alien', {
			anchorX: 0.5,
			anchorY: 0.5,
			scaleX: 20,
			scaleY: 20,
			alpha: 0
		});
		jumpscareAlien.x = 1024; // Center of screen
		jumpscareAlien.y = 1366; // Center of screen
		LK.gui.center.addChild(jumpscareAlien);
		// Play loud scary scream sound with maximum volume for jumpscare effect
		var jumpscareSound = LK.getSound('jumpscare');
		jumpscareSound.volume = 1.0; // Maximum volume for scary effect
		jumpscareSound.play();
		// Additional sound effect layering for more intensity
		LK.setTimeout(function () {
			jumpscareSound.play(); // Play again for echo effect
		}, 200);
		// Jumpscare animation with red flash and massive scaling
		LK.effects.flashScreen(0xff0000, 3000); // Red flash for 3 seconds
		tween(jumpscareAlien, {
			alpha: 1,
			scaleX: 25,
			scaleY: 25
		}, {
			duration: 150,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				// Hold for a longer moment with terrifying effect
				LK.setTimeout(function () {
					tween(jumpscareAlien, {
						alpha: 0,
						scaleX: 30,
						scaleY: 30
					}, {
						duration: 1500,
						onFinish: function onFinish() {
							jumpscareAlien.destroy();
						}
					});
				}, 2000);
			}
		});
	}
	// Check if player reached height 1200 and reset to starting position
	if (currentHeight >= 1200 && !speedBoostApplied) {
		speedBoostApplied = true;
		// Add current height to total height before reset
		totalHeight += 1200;
		storage.totalHeight = totalHeight;
		// Activate space theme when resetting after 1200m
		if (!spaceThemeActivated) {
			spaceThemeActivated = true;
			// Change background to dark space color
			game.setBackgroundColor(0x0a0a2e); // Dark blue-purple space color
			// Flash screen to indicate theme change
			LK.effects.flashScreen(0x8a2be2, 1000); // Purple flash for 1 second
		}
		// Reset character to starting position
		dude.x = 1024;
		dude.y = 2400;
		dude.velocityY = 0;
		dude.velocityX = 0;
		dude.isJumping = false;
		dude.isOnPlatform = false;
		// Reset camera
		cameraY = 0;
		game.y = -cameraY;
		highestY = 2400;
		// Reset current height tracking but keep total
		var newDisplayHeight = totalHeight;
		LK.setScore(newDisplayHeight);
		scoreTxt.setText(newDisplayHeight.toString());
		heightTxt.setText('Height: ' + newDisplayHeight + 'm');
		// Reset boost flags for next cycle
		jumpBoostApplied = false;
		speedBoostApplied = false;
		// Increase spawn rates on restart (100% aliens, 35% saws)
		if (!hasRestarted) {
			hasRestarted = true;
			alienSpawnMultiplier = 2.0; // 100% increase (double the rate)
			sawSpawnMultiplier = 1.35; // 35% increase
		} else {
			// Continue increasing on subsequent restarts
			alienSpawnMultiplier += 1.0; // Additional 100% each restart
			sawSpawnMultiplier += 0.35; // Additional 35% each restart
		}
		// Visual feedback for reset
		LK.effects.flashScreen(0x00ff00, 500); // Green flash
	}
	// Check if player reached height 1500 and boost jump power
	if (displayHeight >= 1500 && !jumpBoostApplied) {
		jumpBoostApplied = true;
		// Boost jump power by 1.5x (0.5x more than normal)
		dude.jumpPower = 52.5; // 35 * 1.5 = 52.5
		// Visual feedback for power boost
		LK.effects.flashObject(dude, 0x00ff00, 500); // Green flash
	}
	// Update star twinkling animation
	for (var s = 0; s < stars.length; s++) {
		var star = stars[s];
		star.alpha = 0.3 + Math.sin(LK.ticks * star.twinkleSpeed + star.twinkleOffset) * 0.4;
	}
	// Generate more stars as camera moves up
	if (LK.ticks % 120 === 0) {
		// Add new stars above the visible area
		for (var i = 0; i < 10; i++) {
			var x = Math.random() * 2048;
			var y = cameraY - 500 + Math.random() * 500;
			createStar(x, y);
		}
	}
	// Remove platforms that are too far down
	if (LK.ticks % 60 === 0) {
		cleanupCoins();
		cleanupBullets();
		cleanupTrampolines();
		cleanupAliens();
		cleanupSaws();
		cleanupBombs();
		cleanupFlashBombs();
		cleanupSpecialItems();
		// Cleanup stars that are too far below
		for (var s = stars.length - 1; s >= 0; s--) {
			var star = stars[s];
			if (star.y > cameraY + 3000) {
				star.destroy();
				stars.splice(s, 1);
			}
		}
	}
};
:quality(85)/https://cdn.frvr.ai/6862675ce3591cb5ba7007eb.png%3F3) 
 bir sevimli gülen yüzlü uzaylı. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6863bb7a4b7bdd96e5e7590d.png%3F3) 
 coin. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6863bc734b7bdd96e5e75918.png%3F3) 
 trambolin. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6863bd6b4b7bdd96e5e75926.png%3F3) 
 çirkin korkutucu uzaylı. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6863bdaa4b7bdd96e5e75930.png%3F3) 
 kalp. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6863c0864b7bdd96e5e7594a.png%3F3) 
 bir düğme ama içinde kurukafa .işareti olsun şeffaf. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6864e9b4d36ea7781b69937e.png%3F3) 
 platform. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6864ea3ad36ea7781b69938b.png%3F3) 
 güç platformu. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6864eb18d36ea7781b699399.png%3F3) 
 yuvarlak yeşil top. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6864ec90d36ea7781b6993ce.png%3F3) 
 sevimli bana yardım edin diyen bir uzaylı. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6864f6d3947f8ff41f490813.png%3F3) 
 ufo. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/689c4e11c6528b9bc2ec794b.png%3F3) 
 bomba. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/689c4ef7c6528b9bc2ec7953.png%3F3) 
 falsh bombası. In-Game asset. 2d. High contrast. No shadows