/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
/**** 
* Classes
****/ 
var BossBullet = Container.expand(function () {
	var self = Container.call(this);
	var graphics = self.attachAsset('bossBullet', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 3; // Slow moving bullets
	self.velocityX = 0;
	self.velocityY = 0;
	self.damage = 25;
	self.update = function () {
		self.x += self.velocityX;
		self.y += self.velocityY;
	};
	return self;
});
var BossCreep = Container.expand(function () {
	var self = Container.call(this);
	var graphics = self.attachAsset('bossCreep', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.health = 12000; // Half the previous health for boss
	self.maxHealth = 12000;
	self.speed = 0.8; // Slower than elite creeps
	self.damage = 60; // More damage than elite creeps
	self.targetX = 0;
	self.targetY = 0;
	self.hasReachedPlayer = false;
	self.spawnedCreeps = []; // Track spawned rotating creeps
	self.lastSpawnTime = 0; // Track time for spawning
	self.rotationAngle = 0; // Current rotation angle for spawned creeps
	self.lastSpecialCreepSpawnTime = 0; // Track time for special creep spawning
	self.takeDamage = function (amount) {
		self.health -= amount;
		if (self.health <= 0) {
			return true; // Return true if boss is dead
		}
		return false;
	};
	self.update = function () {
		// Reset flag to allow continued movement after hitting player
		self.hasReachedPlayer = false;
		// Continuously update target to player's current position
		self.targetX = player.x;
		self.targetY = player.y;
		var dx = self.targetX - self.x;
		var dy = self.targetY - self.y;
		var distance = Math.sqrt(dx * dx + dy * dy);
		if (distance > 3) {
			// Calculate avoidance force from other creeps
			var avoidanceX = 0;
			var avoidanceY = 0;
			var avoidanceRadius = 240; // Largest avoidance radius for boss creeps
			for (var i = 0; i < creeps.length; i++) {
				var otherCreep = creeps[i];
				if (otherCreep !== self) {
					var otherDx = self.x - otherCreep.x;
					var otherDy = self.y - otherCreep.y;
					var otherDistance = Math.sqrt(otherDx * otherDx + otherDy * otherDy);
					if (otherDistance < avoidanceRadius && otherDistance > 0) {
						var avoidanceStrength = (avoidanceRadius - otherDistance) / avoidanceRadius;
						avoidanceX += otherDx / otherDistance * avoidanceStrength;
						avoidanceY += otherDy / otherDistance * avoidanceStrength;
					}
				}
			}
			// Combine movement towards player with avoidance
			var moveX = dx / distance * self.speed + avoidanceX * 0.3;
			var moveY = dy / distance * self.speed + avoidanceY * 0.3;
			self.x += moveX;
			self.y += moveY;
		} else {
			self.hasReachedPlayer = true;
		}
		// Calculate maximum rotating creeps based on wave number (10 for wave 10, 20 for wave 20, 30 for wave 30)
		var maxRotatingCreeps = Math.min(30, currentWave); // Cap at 30 for performance
		// Spawn rotating creeps around boss every second (60 ticks) - wave-based maximum
		if (LK.ticks - self.lastSpawnTime >= 60 && self.spawnedCreeps.length < maxRotatingCreeps) {
			self.lastSpawnTime = LK.ticks;
			// Create a new creep that will rotate around the boss
			var spawnedCreep = new Creep();
			spawnedCreep.health = 40; // Less health than normal creeps
			spawnedCreep.maxHealth = 40;
			spawnedCreep.speed = 0; // They don't move on their own
			// Base damage starts at 12 but increases with each spawn
			var baseDamage = 12;
			var damageIncrease = self.spawnedCreeps.length * 2; // Increase by 2 for each existing rotating creep
			spawnedCreep.damage = baseDamage + damageIncrease; // Damage increases with number of spawned creeps
			spawnedCreep.bossParent = self; // Reference to boss
			spawnedCreep.orbitRadius = 600; // Distance from boss center
			spawnedCreep.orbitAngle = Math.random() * Math.PI * 2; // Random starting angle
			// Position the creep initially
			spawnedCreep.x = self.x + Math.cos(spawnedCreep.orbitAngle) * spawnedCreep.orbitRadius;
			spawnedCreep.y = self.y + Math.sin(spawnedCreep.orbitAngle) * spawnedCreep.orbitRadius;
			self.spawnedCreeps.push(spawnedCreep);
			creeps.push(spawnedCreep);
			game.addChild(spawnedCreep);
		}
		// Update rotation angle
		self.rotationAngle += 0.02; // Rotation speed
		// Update positions of spawned creeps to rotate around boss
		for (var k = self.spawnedCreeps.length - 1; k >= 0; k--) {
			var spawnedCreep = self.spawnedCreeps[k];
			if (spawnedCreep && spawnedCreep.bossParent === self) {
				// Update orbit angle
				spawnedCreep.orbitAngle += 0.03; // Individual rotation speed
				// Calculate new position around boss
				spawnedCreep.x = self.x + Math.cos(spawnedCreep.orbitAngle) * spawnedCreep.orbitRadius;
				spawnedCreep.y = self.y + Math.sin(spawnedCreep.orbitAngle) * spawnedCreep.orbitRadius;
				// Override normal creep movement by setting hasReachedPlayer to prevent normal AI
				spawnedCreep.hasReachedPlayer = false;
				spawnedCreep.targetX = spawnedCreep.x;
				spawnedCreep.targetY = spawnedCreep.y;
			} else {
				// Remove reference if creep was destroyed
				self.spawnedCreeps.splice(k, 1);
			}
		}
		// Spawn special creep every 15 seconds (900 ticks at 60fps)
		if (LK.ticks - self.lastSpecialCreepSpawnTime >= 900) {
			self.lastSpecialCreepSpawnTime = LK.ticks;
			// Create a new special creep that moves towards player
			var specialCreep = new SpecialCreep();
			specialCreep.x = self.x;
			specialCreep.y = self.y;
			specialCreep.targetX = player.x;
			specialCreep.targetY = player.y;
			// Scale health based on current wave
			specialCreep.health += (currentWave - 1) * 60;
			// Apply 50% health increase every 5th wave
			var healthMultiplier = 1 + Math.floor(currentWave / 5) * 0.5;
			specialCreep.health = Math.floor(specialCreep.health * healthMultiplier);
			specialCreep.maxHealth = specialCreep.health;
			// Apply speed increase - 1% for every 5th wave
			var speedMultiplier = 1 + Math.floor(currentWave / 5) * 0.01;
			// Apply extra 2% speed increase per wave after wave 15
			if (currentWave > 15) {
				var extraSpeedMultiplier = 1 + (currentWave - 15) * 0.02;
				speedMultiplier *= extraSpeedMultiplier;
			}
			specialCreep.speed = specialCreep.speed * speedMultiplier;
			creeps.push(specialCreep);
			game.addChild(specialCreep);
		}
		// Boss bullet shooting every second (60 ticks at 60fps)
		if (LK.ticks % 60 === 0) {
			// Calculate direction to player
			var bulletDx = player.x - self.x;
			var bulletDy = player.y - self.y;
			var bulletDistance = Math.sqrt(bulletDx * bulletDx + bulletDy * bulletDy);
			if (bulletDistance > 0) {
				var normalizedX = bulletDx / bulletDistance;
				var normalizedY = bulletDy / bulletDistance;
				// Calculate number of bullets based on wave number (wave 10: 5 bullets, wave 20: 6 bullets, wave 30: 7 bullets)
				var bulletCount = 5; // Default for wave 10 boss
				if (currentWave >= 20) {
					bulletCount = 5 + Math.floor((currentWave - 10) / 10);
				}
				// Add extra bullet for all boss fights after wave 30
				if (currentWave > 30) {
					bulletCount += 1;
				}
				// Create bullets in a burst pattern
				for (var bulletIndex = 0; bulletIndex < bulletCount; bulletIndex++) {
					var bossBullet = new BossBullet();
					bossBullet.x = self.x;
					bossBullet.y = self.y;
					// Adjust angle spread based on bullet count for better distribution
					var spreadRange = bulletCount > 5 ? 0.4 : 0.3;
					var angleOffset = (bulletIndex - (bulletCount - 1) / 2) * spreadRange;
					var angle = Math.atan2(normalizedY, normalizedX) + angleOffset;
					bossBullet.velocityX = Math.cos(angle) * bossBullet.speed;
					bossBullet.velocityY = Math.sin(angle) * bossBullet.speed;
					// Add to boss bullets array (will be created in game code)
					bossBullets.push(bossBullet);
					game.addChild(bossBullet);
				}
			}
		}
	};
	return self;
});
var Bullet = Container.expand(function () {
	var self = Container.call(this);
	var graphics = self.attachAsset('bullet', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 8;
	self.velocityX = 0;
	self.velocityY = 0;
	self.damage = 20;
	self.update = function () {
		self.x += self.velocityX;
		self.y += self.velocityY;
	};
	return self;
});
var Creep = Container.expand(function () {
	var self = Container.call(this);
	var graphics = self.attachAsset('creep', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.health = 60; // Base health requiring 3 hits (20 damage per hit)
	self.maxHealth = 60;
	self.speed = 2.4;
	self.damage = 25;
	self.targetX = 0;
	self.targetY = 0;
	self.hasReachedPlayer = false;
	self.takeDamage = function (amount) {
		self.health -= amount;
		if (self.health <= 0) {
			return true; // Return true if creep is dead
		}
		return false;
	};
	self.update = function () {
		// Reset flag to allow continued movement after hitting player
		self.hasReachedPlayer = false;
		// Continuously update target to player's current position
		self.targetX = player.x;
		self.targetY = player.y;
		var dx = self.targetX - self.x;
		var dy = self.targetY - self.y;
		var distance = Math.sqrt(dx * dx + dy * dy);
		if (distance > 25) {
			// Calculate avoidance force from other creeps
			var avoidanceX = 0;
			var avoidanceY = 0;
			var avoidanceRadius = 120; // Distance to avoid other creeps
			for (var i = 0; i < creeps.length; i++) {
				var otherCreep = creeps[i];
				if (otherCreep !== self) {
					var otherDx = self.x - otherCreep.x;
					var otherDy = self.y - otherCreep.y;
					var otherDistance = Math.sqrt(otherDx * otherDx + otherDy * otherDy);
					if (otherDistance < avoidanceRadius && otherDistance > 0) {
						var avoidanceStrength = (avoidanceRadius - otherDistance) / avoidanceRadius;
						avoidanceX += otherDx / otherDistance * avoidanceStrength;
						avoidanceY += otherDy / otherDistance * avoidanceStrength;
					}
				}
			}
			// Combine movement towards player with avoidance
			var moveX = dx / distance * self.speed + avoidanceX * 0.5;
			var moveY = dy / distance * self.speed + avoidanceY * 0.5;
			self.x += moveX;
			self.y += moveY;
		} else {
			self.hasReachedPlayer = true;
		}
	};
	return self;
});
var EliteCreep = Container.expand(function () {
	var self = Container.call(this);
	var graphics = self.attachAsset('eliteCreep', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.health = 150; // Much higher base health
	self.maxHealth = 150;
	self.speed = 1.5; // Slower than regular creeps
	self.damage = 50; // More damage than regular creeps
	self.targetX = 0;
	self.targetY = 0;
	self.hasReachedPlayer = false;
	self.takeDamage = function (amount) {
		self.health -= amount;
		if (self.health <= 0) {
			return true; // Return true if creep is dead
		}
		return false;
	};
	self.update = function () {
		// Reset flag to allow continued movement after hitting player
		self.hasReachedPlayer = false;
		// Continuously update target to player's current position
		self.targetX = player.x;
		self.targetY = player.y;
		var dx = self.targetX - self.x;
		var dy = self.targetY - self.y;
		var distance = Math.sqrt(dx * dx + dy * dy);
		if (distance > 25) {
			// Calculate avoidance force from other creeps
			var avoidanceX = 0;
			var avoidanceY = 0;
			var avoidanceRadius = 180; // Larger avoidance radius for elite creeps
			for (var i = 0; i < creeps.length; i++) {
				var otherCreep = creeps[i];
				if (otherCreep !== self) {
					var otherDx = self.x - otherCreep.x;
					var otherDy = self.y - otherCreep.y;
					var otherDistance = Math.sqrt(otherDx * otherDx + otherDy * otherDy);
					if (otherDistance < avoidanceRadius && otherDistance > 0) {
						var avoidanceStrength = (avoidanceRadius - otherDistance) / avoidanceRadius;
						avoidanceX += otherDx / otherDistance * avoidanceStrength;
						avoidanceY += otherDy / otherDistance * avoidanceStrength;
					}
				}
			}
			// Combine movement towards player with avoidance
			var moveX = dx / distance * self.speed + avoidanceX * 0.5;
			var moveY = dy / distance * self.speed + avoidanceY * 0.5;
			self.x += moveX;
			self.y += moveY;
		} else {
			self.hasReachedPlayer = true;
		}
	};
	return self;
});
var Pickup = Container.expand(function (type) {
	var self = Container.call(this);
	self.type = type;
	var assetName;
	if (type === 'health') {
		assetName = 'healthPotion';
	} else if (type === 'damage') {
		assetName = 'damageUpgrade';
	} else if (type === 'speed') {
		assetName = 'speedUpgrade'; // Use dedicated speed upgrade asset
	} else if (type === 'attackSpeed') {
		assetName = 'damageUpgrade'; // Reuse red upgrade for attack speed
	} else if (type === 'shield') {
		assetName = 'shieldUpgrade';
	} else if (type === 'armor') {
		assetName = 'armorUpgrade';
	} else if (type === 'novaBlade') {
		assetName = 'novaBlade';
	}
	var graphics = self.attachAsset(assetName, {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.lifetime = 3600; // 60 seconds at 60fps
	self.update = function () {
		self.lifetime--;
		if (self.lifetime < 300) {
			// Start fading at 5 seconds remaining
			graphics.alpha = self.lifetime / 300;
		}
		// Magnetic pull effect when player is close
		if (player) {
			var dx = player.x - self.x;
			var dy = player.y - self.y;
			var distance = Math.sqrt(dx * dx + dy * dy);
			// Start pulling when within 150 pixels
			if (distance < 150 && distance > 10) {
				var pullSpeed = 8; // Fast pull speed
				var normalizedX = dx / distance;
				var normalizedY = dy / distance;
				self.x += normalizedX * pullSpeed;
				self.y += normalizedY * pullSpeed;
			}
		}
	};
	return self;
});
var Player = Container.expand(function () {
	var self = Container.call(this);
	var graphics = self.attachAsset('player', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 1.3,
		scaleY: 1.3
	});
	self.maxHealth = 100;
	self.health = 100;
	self.defense = 0;
	self.armor = 0;
	self.maxArmor = 50;
	self.baseDamage = 20; // Base damage that never changes
	self.damage = 20; // Current damage (base + upgrades)
	self.weaponUpgrades = 0; // Track weapon upgrades for double shot
	self.lastShootTime = 0;
	self.shootCooldown = 40; // Fixed cooldown that never changes
	self.baseSpeed = 4; // Base movement speed
	self.moveSpeed = 4; // Current movement speed (base + upgrades)
	self.shieldActive = false;
	self.shieldHealth = 0;
	self.shieldMaxHealth = 80;
	self.shieldDuration = 0; // In game ticks (60 fps)
	self.shieldAura = null;
	self.invincible = false;
	self.invincibilityTimer = 0;
	self.novaBladeActive = false;
	self.novaBladeTimer = 0;
	self.novaBladeLastActivation = 0;
	self.novaBladeLevel = 0;
	self.novaBladeProximity = 300; // Base proximity
	// Movement direction tracking
	self.lastX = 0;
	self.lastY = 0;
	self.currentDirection = 0; // 0 = north (default)
	self.takeDamage = function (amount) {
		// If player is invincible, ignore all damage
		if (self.invincible) {
			return;
		}
		if (self.shieldActive && self.shieldHealth > 0) {
			// Shield absorbs damage first
			self.shieldHealth -= amount;
			if (self.shieldHealth <= 0) {
				// Shield broken
				self.shieldHealth = 0;
				self.shieldActive = false;
				self.shieldDuration = 0;
				if (self.shieldAura) {
					self.shieldAura.destroy();
					self.shieldAura = null;
				}
			}
			// Flash blue when shield takes damage
			tween(graphics, {
				tint: 0x4444FF
			}, {
				duration: 100,
				onFinish: function onFinish() {
					tween(graphics, {
						tint: 0xFFFFFF
					}, {
						duration: 100
					});
				}
			});
		} else if (self.armor > 0) {
			// Armor absorbs damage second
			self.armor -= amount;
			if (self.armor < 0) {
				// Overflow damage goes to health
				self.health += self.armor; // armor is negative, so this subtracts from health
				self.armor = 0;
			}
			if (self.health < 0) self.health = 0;
			// Flash yellow when armor takes damage
			tween(graphics, {
				tint: 0xFFDD00
			}, {
				duration: 100,
				onFinish: function onFinish() {
					tween(graphics, {
						tint: 0xFFFFFF
					}, {
						duration: 100
					});
				}
			});
		} else {
			// Normal damage to health last
			self.health -= amount;
			if (self.health < 0) self.health = 0;
			// Flash red when taking damage
			tween(graphics, {
				tint: 0xFF0000
			}, {
				duration: 100,
				onFinish: function onFinish() {
					tween(graphics, {
						tint: 0xFFFFFF
					}, {
						duration: 100
					});
				}
			});
		}
		LK.getSound('hit').play();
	};
	self.heal = function (amount) {
		self.health = Math.min(self.maxHealth, self.health + amount);
	};
	self.addDamage = function (amount) {
		self.damage += amount;
		self.weaponUpgrades++; // Track weapon upgrades
	};
	self.addSpeed = function (amount) {
		// Cap movement speed upgrades at level 25 (24 upgrades from base level 1)
		if (self.weaponUpgrades < 24) {
			self.moveSpeed += amount;
		}
	};
	self.addArmor = function (amount) {
		self.armor = Math.min(50, self.armor + amount);
	};
	self.activateNovaBlade = function () {
		if (!self.novaBladeActive) {
			self.novaBladeActive = true;
			self.novaBladeLastActivation = LK.ticks;
			self.novaBladeLevel = 1;
			self.novaBladeProximity = 300;
		} else if (self.novaBladeLevel < 50) {
			// Increase Nova blade level and proximity up to level 50
			self.novaBladeLevel++;
			self.novaBladeProximity += 10;
		}
	};
	self.activateShield = function () {
		if (!self.shieldActive) {
			// First time activation
			self.shieldActive = true;
			self.shieldHealth = 40; // Start with 40 hit points
			self.shieldDuration = 3600; // 60 seconds at 60fps
			// Create shield visual
			self.shieldAura = self.addChild(LK.getAsset('shieldAura', {
				anchorX: 0.5,
				anchorY: 0.5,
				alpha: 0.6,
				tint: 0x6666FF
			}));
		} else {
			// Shield already active, add duration up to max 180 seconds
			self.shieldDuration = Math.min(10800, self.shieldDuration + 3600); // Max 180 seconds (60 seconds per upgrade)
			// Add shield health up to max 80 hit points
			self.shieldHealth = Math.min(80, self.shieldHealth + 40);
			// Ensure shield visual is displayed
			if (!self.shieldAura) {
				self.shieldAura = self.addChild(LK.getAsset('shieldAura', {
					anchorX: 0.5,
					anchorY: 0.5,
					alpha: 0.6,
					tint: 0x6666FF
				}));
			}
		}
	};
	self.canShoot = function () {
		return LK.ticks - self.lastShootTime > self.shootCooldown;
	};
	self.shoot = function (targetX, targetY) {
		if (!self.canShoot()) return null;
		self.lastShootTime = LK.ticks;
		var bullets = [];
		var dx = targetX - self.x;
		var dy = targetY - self.y;
		var distance = Math.sqrt(dx * dx + dy * dy);
		var normalizedX = dx / distance;
		var normalizedY = dy / distance;
		var angle = Math.atan2(normalizedY, normalizedX);
		if (self.weaponUpgrades >= 49) {
			// Level 50+: Six shots in burst fire pattern (Hexa Shot)
			var offsetDistance = 30;
			var perpX = -normalizedY;
			var perpY = normalizedX;
			// First bullet (left side, front)
			var bullet1 = new Bullet();
			bullet1.x = self.x + perpX * offsetDistance;
			bullet1.y = self.y + perpY * offsetDistance;
			bullet1.velocityX = normalizedX * bullet1.speed;
			bullet1.velocityY = normalizedY * bullet1.speed;
			bullet1.damage = self.damage;
			bullets.push(bullet1);
			// Second bullet (left side, back)
			var bullet2 = new Bullet();
			bullet2.x = self.x + perpX * offsetDistance - normalizedX * 25;
			bullet2.y = self.y + perpY * offsetDistance - normalizedY * 25;
			bullet2.velocityX = normalizedX * bullet2.speed;
			bullet2.velocityY = normalizedY * bullet2.speed;
			bullet2.damage = self.damage;
			bullets.push(bullet2);
			// Third bullet (right side, front)
			var bullet3 = new Bullet();
			bullet3.x = self.x - perpX * offsetDistance;
			bullet3.y = self.y - perpY * offsetDistance;
			bullet3.velocityX = normalizedX * bullet3.speed;
			bullet3.velocityY = normalizedY * bullet3.speed;
			bullet3.damage = self.damage;
			bullets.push(bullet3);
			// Fourth bullet (right side, back)
			var bullet4 = new Bullet();
			bullet4.x = self.x - perpX * offsetDistance - normalizedX * 25;
			bullet4.y = self.y - perpY * offsetDistance - normalizedY * 25;
			bullet4.velocityX = normalizedX * bullet4.speed;
			bullet4.velocityY = normalizedY * bullet4.speed;
			bullet4.damage = self.damage;
			bullets.push(bullet4);
			// Fifth bullet (center shot)
			var bullet5 = new Bullet();
			bullet5.x = self.x;
			bullet5.y = self.y;
			bullet5.velocityX = normalizedX * bullet5.speed;
			bullet5.velocityY = normalizedY * bullet5.speed;
			bullet5.damage = self.damage;
			bullets.push(bullet5);
			// Sixth bullet (center shot, back)
			var bullet6 = new Bullet();
			bullet6.x = self.x - normalizedX * 25;
			bullet6.y = self.y - normalizedY * 25;
			bullet6.velocityX = normalizedX * bullet6.speed;
			bullet6.velocityY = normalizedY * bullet6.speed;
			bullet6.damage = self.damage;
			bullets.push(bullet6);
		} else if (self.weaponUpgrades >= 39) {
			// Level 40+: Five shots in burst fire (two double shots + center shot)
			var offsetDistance = 25;
			var perpX = -normalizedY;
			var perpY = normalizedX;
			// First bullet (left side, front)
			var bullet1 = new Bullet();
			bullet1.x = self.x + perpX * offsetDistance;
			bullet1.y = self.y + perpY * offsetDistance;
			bullet1.velocityX = normalizedX * bullet1.speed;
			bullet1.velocityY = normalizedY * bullet1.speed;
			bullet1.damage = self.damage;
			bullets.push(bullet1);
			// Second bullet (left side, back)
			var bullet2 = new Bullet();
			bullet2.x = self.x + perpX * offsetDistance - normalizedX * 20;
			bullet2.y = self.y + perpY * offsetDistance - normalizedY * 20;
			bullet2.velocityX = normalizedX * bullet2.speed;
			bullet2.velocityY = normalizedY * bullet2.speed;
			bullet2.damage = self.damage;
			bullets.push(bullet2);
			// Third bullet (right side, front)
			var bullet3 = new Bullet();
			bullet3.x = self.x - perpX * offsetDistance;
			bullet3.y = self.y - perpY * offsetDistance;
			bullet3.velocityX = normalizedX * bullet3.speed;
			bullet3.velocityY = normalizedY * bullet3.speed;
			bullet3.damage = self.damage;
			bullets.push(bullet3);
			// Fourth bullet (right side, back)
			var bullet4 = new Bullet();
			bullet4.x = self.x - perpX * offsetDistance - normalizedX * 20;
			bullet4.y = self.y - perpY * offsetDistance - normalizedY * 20;
			bullet4.velocityX = normalizedX * bullet4.speed;
			bullet4.velocityY = normalizedY * bullet4.speed;
			bullet4.damage = self.damage;
			bullets.push(bullet4);
			// Fifth bullet (center shot)
			var bullet5 = new Bullet();
			bullet5.x = self.x;
			bullet5.y = self.y;
			bullet5.velocityX = normalizedX * bullet5.speed;
			bullet5.velocityY = normalizedY * bullet5.speed;
			bullet5.damage = self.damage;
			bullets.push(bullet5);
		} else if (self.weaponUpgrades >= 29) {
			// Level 30+: Four shots in burst fire (two double shots)
			var offsetDistance = 25;
			var perpX = -normalizedY;
			var perpY = normalizedX;
			// First bullet (left side, front)
			var bullet1 = new Bullet();
			bullet1.x = self.x + perpX * offsetDistance;
			bullet1.y = self.y + perpY * offsetDistance;
			bullet1.velocityX = normalizedX * bullet1.speed;
			bullet1.velocityY = normalizedY * bullet1.speed;
			bullet1.damage = self.damage;
			bullets.push(bullet1);
			// Second bullet (left side, back)
			var bullet2 = new Bullet();
			bullet2.x = self.x + perpX * offsetDistance - normalizedX * 20;
			bullet2.y = self.y + perpY * offsetDistance - normalizedY * 20;
			bullet2.velocityX = normalizedX * bullet2.speed;
			bullet2.velocityY = normalizedY * bullet2.speed;
			bullet2.damage = self.damage;
			bullets.push(bullet2);
			// Third bullet (right side, front)
			var bullet3 = new Bullet();
			bullet3.x = self.x - perpX * offsetDistance;
			bullet3.y = self.y - perpY * offsetDistance;
			bullet3.velocityX = normalizedX * bullet3.speed;
			bullet3.velocityY = normalizedY * bullet3.speed;
			bullet3.damage = self.damage;
			bullets.push(bullet3);
			// Fourth bullet (right side, back)
			var bullet4 = new Bullet();
			bullet4.x = self.x - perpX * offsetDistance - normalizedX * 20;
			bullet4.y = self.y - perpY * offsetDistance - normalizedY * 20;
			bullet4.velocityX = normalizedX * bullet4.speed;
			bullet4.velocityY = normalizedY * bullet4.speed;
			bullet4.damage = self.damage;
			bullets.push(bullet4);
		} else if (self.weaponUpgrades >= 19) {
			// Level 20+: Triple shot (3 parallel shots)
			var offsetDistance = 15;
			var perpX = -normalizedY;
			var perpY = normalizedX;
			// Center bullet
			var bullet1 = new Bullet();
			bullet1.x = self.x;
			bullet1.y = self.y;
			bullet1.velocityX = normalizedX * bullet1.speed;
			bullet1.velocityY = normalizedY * bullet1.speed;
			bullet1.damage = self.damage;
			bullets.push(bullet1);
			// Left bullet (parallel)
			var bullet2 = new Bullet();
			bullet2.x = self.x + perpX * offsetDistance;
			bullet2.y = self.y + perpY * offsetDistance;
			bullet2.velocityX = normalizedX * bullet2.speed;
			bullet2.velocityY = normalizedY * bullet2.speed;
			bullet2.damage = self.damage;
			bullets.push(bullet2);
			// Right bullet (parallel)
			var bullet3 = new Bullet();
			bullet3.x = self.x - perpX * offsetDistance;
			bullet3.y = self.y - perpY * offsetDistance;
			bullet3.velocityX = normalizedX * bullet3.speed;
			bullet3.velocityY = normalizedY * bullet3.speed;
			bullet3.damage = self.damage;
			bullets.push(bullet3);
		} else if (self.weaponUpgrades >= 9) {
			// Level 10+: Double shot
			var offsetDistance = 20;
			var perpX = -normalizedY;
			var perpY = normalizedX;
			// First bullet (left side)
			var bullet1 = new Bullet();
			bullet1.x = self.x + perpX * offsetDistance;
			bullet1.y = self.y + perpY * offsetDistance;
			bullet1.velocityX = normalizedX * bullet1.speed;
			bullet1.velocityY = normalizedY * bullet1.speed;
			bullet1.damage = self.damage;
			bullets.push(bullet1);
			// Second bullet (right side)
			var bullet2 = new Bullet();
			bullet2.x = self.x - perpX * offsetDistance;
			bullet2.y = self.y - perpY * offsetDistance;
			bullet2.velocityX = normalizedX * bullet2.speed;
			bullet2.velocityY = normalizedY * bullet2.speed;
			bullet2.damage = self.damage;
			bullets.push(bullet2);
		} else {
			// Single shot for levels < 10
			var bullet1 = new Bullet();
			bullet1.x = self.x;
			bullet1.y = self.y;
			bullet1.velocityX = normalizedX * bullet1.speed;
			bullet1.velocityY = normalizedY * bullet1.speed;
			bullet1.damage = self.damage;
			bullets.push(bullet1);
		}
		LK.getSound('shoot').play();
		return bullets;
	};
	self.update = function () {
		// Track movement direction and animate rotation
		if (self.lastX !== undefined && self.lastY !== undefined) {
			var deltaX = self.x - self.lastX;
			var deltaY = self.y - self.lastY;
			var moveDistance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
			// Only update direction if player is actually moving
			if (moveDistance > 0.5) {
				var targetDirection = Math.atan2(deltaY, deltaX);
				// Convert to 0-360 degree system where 0 is north
				targetDirection = targetDirection + Math.PI / 2;
				if (targetDirection < 0) targetDirection += Math.PI * 2;
				if (targetDirection > Math.PI * 2) targetDirection -= Math.PI * 2;
				// Smoothly rotate to face movement direction
				var currentRotation = graphics.rotation;
				var angleDiff = targetDirection - currentRotation;
				// Handle wrap around for shortest rotation path
				if (angleDiff > Math.PI) angleDiff -= Math.PI * 2;
				if (angleDiff < -Math.PI) angleDiff += Math.PI * 2;
				// Apply smooth rotation
				var rotationSpeed = 0.15;
				graphics.rotation += angleDiff * rotationSpeed;
			}
		}
		// Update invincibility timer
		if (self.invincible) {
			self.invincibilityTimer--;
			if (self.invincibilityTimer <= 0) {
				self.invincible = false;
				// Stop any tinting when invincibility ends
				tween.stop(graphics, {
					tint: true
				});
				graphics.tint = 0xFFFFFF;
				graphics.alpha = 1.0;
			}
		}
		// Update Nova blade timer and activation
		if (self.novaBladeActive) {
			// Check if 5 seconds (300 ticks) have passed since last activation
			if (LK.ticks - self.novaBladeLastActivation >= 300) {
				// Create expanding nova blade effect
				var aura = LK.getAsset('novaBladeEffect', {
					anchorX: 0.5,
					anchorY: 0.5,
					alpha: 0.8,
					tint: 0xFF6600,
					scaleX: 0.1,
					scaleY: 0.1
				});
				self.addChild(aura);
				// Knock back all creeps within proximity radius immediately
				for (var creepIdx = 0; creepIdx < creeps.length; creepIdx++) {
					var creep = creeps[creepIdx];
					var dx = creep.x - self.x;
					var dy = creep.y - self.y;
					var distance = Math.sqrt(dx * dx + dy * dy);
					if (distance <= self.novaBladeProximity) {
						// Calculate knockback direction
						if (distance > 0) {
							var normalizedX = dx / distance;
							var normalizedY = dy / distance;
							var knockbackDistance = self.novaBladeProximity - distance + 50; // Push them outside the radius
							// Apply knockback using tween for smooth animation
							tween(creep, {
								x: creep.x + normalizedX * knockbackDistance,
								y: creep.y + normalizedY * knockbackDistance
							}, {
								duration: 500,
								easing: tween.easeOut
							});
						}
					}
				}
				// Animate aura expansion from proximity 10 to current Nova blade proximity level
				var maxScale = self.novaBladeProximity / 80; // Convert proximity to scale (80 is base aura size)
				tween(aura, {
					scaleX: maxScale,
					scaleY: maxScale,
					alpha: 0.0
				}, {
					duration: 1000,
					easing: tween.easeOut,
					onFinish: function onFinish() {
						aura.destroy();
					}
				});
				// Reset timer for next activation
				self.novaBladeLastActivation = LK.ticks;
			}
		}
		// Update last position for next frame
		self.lastX = self.x;
		self.lastY = self.y;
	};
	return self;
});
var SpecialCreep = Container.expand(function () {
	var self = Container.call(this);
	var graphics = self.attachAsset('specialCreep', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.health = 450; // Three times elite creep health (150 * 3)
	self.maxHealth = 450;
	self.speed = 2.8; // Slightly faster than regular creeps (2.4)
	self.damage = 40; // Between regular and elite creep damage
	self.targetX = 0;
	self.targetY = 0;
	self.hasReachedPlayer = false;
	self.takeDamage = function (amount) {
		self.health -= amount;
		if (self.health <= 0) {
			return true; // Return true if creep is dead
		}
		return false;
	};
	self.update = function () {
		// Reset flag to allow continued movement after hitting player
		self.hasReachedPlayer = false;
		// Continuously update target to player's current position
		self.targetX = player.x;
		self.targetY = player.y;
		var dx = self.targetX - self.x;
		var dy = self.targetY - self.y;
		var distance = Math.sqrt(dx * dx + dy * dy);
		if (distance > 25) {
			// Calculate avoidance force from other creeps
			var avoidanceX = 0;
			var avoidanceY = 0;
			var avoidanceRadius = 200; // Medium avoidance radius between regular and elite
			for (var i = 0; i < creeps.length; i++) {
				var otherCreep = creeps[i];
				if (otherCreep !== self) {
					var otherDx = self.x - otherCreep.x;
					var otherDy = self.y - otherCreep.y;
					var otherDistance = Math.sqrt(otherDx * otherDx + otherDy * otherDy);
					if (otherDistance < avoidanceRadius && otherDistance > 0) {
						var avoidanceStrength = (avoidanceRadius - otherDistance) / avoidanceRadius;
						avoidanceX += otherDx / otherDistance * avoidanceStrength;
						avoidanceY += otherDy / otherDistance * avoidanceStrength;
					}
				}
			}
			// Combine movement towards player with avoidance
			var moveX = dx / distance * self.speed + avoidanceX * 0.5;
			var moveY = dy / distance * self.speed + avoidanceY * 0.5;
			self.x += moveX;
			self.y += moveY;
		} else {
			self.hasReachedPlayer = true;
		}
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	title: 'Galaxy Of Terror'
});
/**** 
* Game Code
****/ 
// Add background image
var background = game.addChild(LK.getAsset('background', {
	anchorX: 0,
	anchorY: 0,
	x: 0,
	y: 0
}));
// Game state variables
var gameStarted = false;
var startScreen = null;
// Create start screen
function createStartScreen() {
	startScreen = new Container();
	game.addChild(startScreen);
	// Start screen background
	var startBg = startScreen.addChild(LK.getAsset('startBackground', {
		anchorX: 0,
		anchorY: 0,
		x: 0,
		y: 0,
		alpha: 0.9,
		tint: 0x001122
	}));
	// Game title
	var titleText = new Text2('GALAXY OF TERROR', {
		size: 120,
		fill: 0xFFD700
	});
	titleText.anchor.set(0.5, 0.5);
	titleText.x = 1024;
	titleText.y = 800;
	startScreen.addChild(titleText);
	// Subtitle
	var subtitleText = new Text2('Survive the endless waves', {
		size: 60,
		fill: 0xFFFFFF
	});
	subtitleText.anchor.set(0.5, 0.5);
	subtitleText.x = 1024;
	subtitleText.y = 920;
	startScreen.addChild(subtitleText);
	// Play button background
	var playButton = startScreen.addChild(LK.getAsset('startButton', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: 1024,
		y: 1200,
		scaleX: 1.5,
		scaleY: 1.2,
		tint: 0x00AA44
	}));
	// Play button text
	var playButtonText = new Text2('TAP TO PLAY', {
		size: 80,
		fill: 0xFFFFFF
	});
	playButtonText.anchor.set(0.5, 0.5);
	playButtonText.x = 1024;
	playButtonText.y = 1200;
	startScreen.addChild(playButtonText);
	// Instructions
	var instructText = new Text2('Tap and drag to move\nAutomatic shooting', {
		size: 50,
		fill: 0xCCCCCC
	});
	instructText.anchor.set(0.5, 0.5);
	instructText.x = 1024;
	instructText.y = 1400;
	startScreen.addChild(instructText);
	// Handle start screen input
	startScreen.down = function (x, y, obj) {
		// Check if clicked on play button area
		var buttonDx = x - 1024;
		var buttonDy = y - 1200;
		var buttonDistance = Math.sqrt(buttonDx * buttonDx + buttonDy * buttonDy);
		if (buttonDistance < 150) {
			startGame();
		}
	};
}
function startGame() {
	if (startScreen) {
		startScreen.destroy();
		startScreen = null;
	}
	gameStarted = true;
	// Initialize player after game starts
	player = game.addChild(new Player());
	player.x = 1024;
	player.y = 1366;
}
// Initialize start screen
createStartScreen();
var player = null;
var creeps = [];
var bullets = [];
var bossBullets = [];
var pickups = [];
var currentWave = 1;
var creepsInWave = 5;
var creepsSpawned = 0;
var eliteCreepsInWave = 1; // Number of elite creeps equals wave number
var eliteCreepsSpawned = 0;
var specialCreepsInWave = 0; // Special creeps spawn on specific waves
var specialCreepsSpawned = 0;
var waveCompleted = false;
var nextWaveTimer = 0;
var spawnTimer = 0;
// Score tracking variables
var gameScore = 0;
// Boss system variables
var currentBoss = null;
var bossWave = false;
// Speed modifier for creeps - increases 1% every 5th wave
var creepSpeedMultiplier = 1.0;
// Track special 5th wave speed upgrade drops
var fifthWaveSpeedUpgradeDropped = false;
// Track upgrade drops per wave
var waveUpgradeDrops = {};
// UI Elements
var healthText = new Text2('Health: 100', {
	size: 40,
	fill: 0xFF0000
});
healthText.anchor.set(0, 0);
LK.gui.topLeft.addChild(healthText);
healthText.x = 120; // Offset from left edge
var armorText = new Text2('Armor: 0', {
	size: 40,
	fill: 0x00FF00
});
armorText.anchor.set(0, 0);
LK.gui.topLeft.addChild(armorText);
armorText.x = 120; // Offset from left edge
armorText.y = 45; // Below health text
var waveText = new Text2('Wave: 1', {
	size: 40,
	fill: 0xFFD700
});
waveText.anchor.set(0.5, 0);
LK.gui.top.addChild(waveText);
var weaponLevelText = new Text2('Weapon Level: 1', {
	size: 40,
	fill: 0xFFFFFF
});
weaponLevelText.anchor.set(1, 0);
LK.gui.topRight.addChild(weaponLevelText);
var weaponTypeText = new Text2('Blaster', {
	size: 40,
	fill: 0xFFFFFF
});
weaponTypeText.anchor.set(1, 0);
weaponTypeText.y = 45; // Position below weapon level text
LK.gui.topRight.addChild(weaponTypeText);
// Nova blade level text
var novaBladeText = new Text2('', {
	size: 40,
	fill: 0xFF6600
});
novaBladeText.anchor.set(1, 0);
novaBladeText.y = 90; // Position below weapon type text
LK.gui.topRight.addChild(novaBladeText);
// Score counter text
var scoreText = new Text2('Score: 0', {
	size: 40,
	fill: 0xFF1493 // Bright pink color
});
scoreText.anchor.set(1, 0);
scoreText.y = 135; // Position below Nova blade level text
LK.gui.topRight.addChild(scoreText);
// Boss health bar (initially hidden)
var bossHealthBar = new Text2('', {
	size: 35,
	fill: 0xFF4444
});
bossHealthBar.anchor.set(0.5, 0);
LK.gui.top.addChild(bossHealthBar);
bossHealthBar.y = 50;
bossHealthBar.alpha = 0; // Hidden initially
// Shield status text
var shieldText = new Text2('', {
	size: 35,
	fill: 0x4444FF
});
shieldText.anchor.set(0, 0);
LK.gui.topLeft.addChild(shieldText);
shieldText.x = 120; // Offset from left edge
shieldText.y = 90; // Below armor text
// Player will be initialized when game starts
function spawnCreep() {
	var creep = new Creep();
	// Spawn from random edge
	var side = Math.floor(Math.random() * 4);
	switch (side) {
		case 0:
			// Top
			creep.x = Math.random() * 2048;
			creep.y = -50;
			break;
		case 1:
			// Right
			creep.x = 2098;
			creep.y = Math.random() * 2732;
			break;
		case 2:
			// Bottom
			creep.x = Math.random() * 2048;
			creep.y = 2782;
			break;
		case 3:
			// Left
			creep.x = -50;
			creep.y = Math.random() * 2732;
			break;
	}
	creep.targetX = player.x;
	creep.targetY = player.y;
	creep.health += (currentWave - 1) * 20; // Scale health with wave (20 per wave)
	// Apply 50% health increase every 5th wave
	var healthMultiplier = 1 + Math.floor(currentWave / 5) * 0.5;
	creep.health = Math.floor(creep.health * healthMultiplier);
	creep.maxHealth = creep.health;
	// Apply speed increase - 1% for every 5th wave
	var speedMultiplier = 1 + Math.floor(currentWave / 5) * 0.01;
	// Apply extra 2% speed increase per wave after wave 15
	if (currentWave > 15) {
		var extraSpeedMultiplier = 1 + (currentWave - 15) * 0.02;
		speedMultiplier *= extraSpeedMultiplier;
	}
	creep.speed = creep.speed * speedMultiplier;
	creeps.push(creep);
	game.addChild(creep);
}
function spawnEliteCreep() {
	var eliteCreep = new EliteCreep();
	// Spawn from random edge
	var side = Math.floor(Math.random() * 4);
	switch (side) {
		case 0:
			// Top
			eliteCreep.x = Math.random() * 2048;
			eliteCreep.y = -50;
			break;
		case 1:
			// Right
			eliteCreep.x = 2098;
			eliteCreep.y = Math.random() * 2732;
			break;
		case 2:
			// Bottom
			eliteCreep.x = Math.random() * 2048;
			eliteCreep.y = 2782;
			break;
		case 3:
			// Left
			eliteCreep.x = -50;
			eliteCreep.y = Math.random() * 2732;
			break;
	}
	eliteCreep.targetX = player.x;
	eliteCreep.targetY = player.y;
	eliteCreep.health += (currentWave - 1) * 40; // Scale health with wave (40 per wave for elites)
	// Apply 50% health increase every 5th wave
	var healthMultiplier = 1 + Math.floor(currentWave / 5) * 0.5;
	eliteCreep.health = Math.floor(eliteCreep.health * healthMultiplier);
	eliteCreep.maxHealth = eliteCreep.health;
	// Apply speed increase - 1% for every 5th wave
	var speedMultiplier = 1 + Math.floor(currentWave / 5) * 0.01;
	// Apply extra 2% speed increase per wave after wave 15
	if (currentWave > 15) {
		var extraSpeedMultiplier = 1 + (currentWave - 15) * 0.02;
		speedMultiplier *= extraSpeedMultiplier;
	}
	eliteCreep.speed = eliteCreep.speed * speedMultiplier;
	creeps.push(eliteCreep);
	game.addChild(eliteCreep);
}
function spawnSpecialCreep() {
	var specialCreep = new SpecialCreep();
	// Spawn from random edge
	var side = Math.floor(Math.random() * 4);
	switch (side) {
		case 0:
			// Top
			specialCreep.x = Math.random() * 2048;
			specialCreep.y = -50;
			break;
		case 1:
			// Right
			specialCreep.x = 2098;
			specialCreep.y = Math.random() * 2732;
			break;
		case 2:
			// Bottom
			specialCreep.x = Math.random() * 2048;
			specialCreep.y = 2782;
			break;
		case 3:
			// Left
			specialCreep.x = -50;
			specialCreep.y = Math.random() * 2732;
			break;
	}
	specialCreep.targetX = player.x;
	specialCreep.targetY = player.y;
	specialCreep.health += (currentWave - 1) * 60; // Scale health with wave (60 per wave for special creeps)
	// Apply 50% health increase every 5th wave
	var healthMultiplier = 1 + Math.floor(currentWave / 5) * 0.5;
	specialCreep.health = Math.floor(specialCreep.health * healthMultiplier);
	specialCreep.maxHealth = specialCreep.health;
	// Apply speed increase - 1% for every 5th wave
	var speedMultiplier = 1 + Math.floor(currentWave / 5) * 0.01;
	// Apply extra 2% speed increase per wave after wave 15
	if (currentWave > 15) {
		var extraSpeedMultiplier = 1 + (currentWave - 15) * 0.02;
		speedMultiplier *= extraSpeedMultiplier;
	}
	specialCreep.speed = specialCreep.speed * speedMultiplier;
	creeps.push(specialCreep);
	game.addChild(specialCreep);
}
function spawnBoss() {
	var boss = new BossCreep();
	// Spawn from random edge
	var side = Math.floor(Math.random() * 4);
	switch (side) {
		case 0:
			// Top
			boss.x = Math.random() * 2048;
			boss.y = -75;
			break;
		case 1:
			// Right
			boss.x = 2123;
			boss.y = Math.random() * 2732;
			break;
		case 2:
			// Bottom
			boss.x = Math.random() * 2048;
			boss.y = 2807;
			break;
		case 3:
			// Left
			boss.x = -75;
			boss.y = Math.random() * 2732;
			break;
	}
	boss.targetX = player.x;
	boss.targetY = player.y;
	// Calculate boss health - starts at 12000, increases by 50% after first boss fight (wave 10)
	var bossNumber = Math.floor(currentWave / 10);
	if (bossNumber === 1) {
		// First boss fight on wave 10
		boss.health = 12000;
	} else {
		// Every boss fight after wave 10 gets 50% more health than previous
		boss.health = 12000 * Math.pow(1.5, bossNumber - 1);
	}
	// Apply 50% health increase every 5th wave
	var healthMultiplier = 1 + Math.floor(currentWave / 5) * 0.5;
	boss.health = Math.floor(boss.health * healthMultiplier);
	boss.maxHealth = boss.health;
	currentBoss = boss;
	creeps.push(boss);
	game.addChild(boss);
	// Show boss health bar
	bossHealthBar.alpha = 1;
	tween(bossHealthBar, {
		scaleX: 1.1,
		scaleY: 1.1
	}, {
		duration: 300,
		easing: tween.easeOut,
		onFinish: function onFinish() {
			tween(bossHealthBar, {
				scaleX: 1.0,
				scaleY: 1.0
			}, {
				duration: 200
			});
		}
	});
}
function createExplosionEffect(x, y) {
	var explosion = LK.getAsset('explosion', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 0.1,
		scaleY: 0.1,
		alpha: 1.0,
		tint: 0xFF4400 // Orange flame color
	});
	explosion.x = x;
	explosion.y = y;
	game.addChild(explosion);
	// Stage 1: Rapid expansion with orange flames
	tween(explosion, {
		scaleX: 2.0,
		scaleY: 2.0,
		tint: 0xFF6600,
		// Brighter orange
		alpha: 0.9
	}, {
		duration: 150,
		easing: tween.easeOut,
		onFinish: function onFinish() {
			// Stage 2: Peak explosion with bright red
			tween(explosion, {
				scaleX: 3.0,
				scaleY: 3.0,
				tint: 0xFF0000,
				// Bright red
				alpha: 0.8
			}, {
				duration: 100,
				easing: tween.easeOut,
				onFinish: function onFinish() {
					// Stage 3: Fade to dark red and shrink
					tween(explosion, {
						scaleX: 0.5,
						scaleY: 0.5,
						tint: 0x660000,
						// Dark red
						alpha: 0.0
					}, {
						duration: 250,
						easing: tween.easeIn,
						onFinish: function onFinish() {
							explosion.destroy();
						}
					});
				}
			});
		}
	});
}
function dropPickup(x, y, isEliteCreep) {
	// Check for special 5th wave speed upgrade drop first
	var isFifthWave = currentWave % 5 === 0;
	if (isFifthWave && !fifthWaveSpeedUpgradeDropped && player.weaponUpgrades < 9) {
		// 50% chance for speed upgrade on 5th wave (only once per wave)
		if (Math.random() < 0.5) {
			var speedPickup = new Pickup('speed');
			speedPickup.x = x;
			speedPickup.y = y;
			pickups.push(speedPickup);
			game.addChild(speedPickup);
			fifthWaveSpeedUpgradeDropped = true;
			return; // Exit early, no other drops this time
		}
	}
	// 25% chance to drop random upgrades (normal drops)
	if (Math.random() < 0.25) {
		var upgradeTypes = [];
		// Check wave-based upgrade limits
		var shieldDropsThisWave = waveUpgradeDrops.shield || 0;
		var weaponDropsThisWave = waveUpgradeDrops.weapon || 0;
		var speedDropsThisWave = waveUpgradeDrops.speed || 0;
		var armorDropsThisWave = waveUpgradeDrops.armor || 0;
		var healthDropsThisWave = waveUpgradeDrops.health || 0;
		// Shield upgrades: limited to 2 per wave with 15% drop chance
		if (shieldDropsThisWave < 2 && Math.random() < 0.15) {
			upgradeTypes.push('shield');
		}
		// Speed upgrades now have 5% chance and only if player speed level is below 10 and limit 1 per wave
		if (player.weaponUpgrades < 9 && speedDropsThisWave < 1 && Math.random() < 0.05) {
			upgradeTypes.push('speed');
		}
		// Only elite creeps and special creeps can drop health potions and armor upgrades, limited to 1 per wave each
		if (isEliteCreep) {
			if (healthDropsThisWave < 1 && Math.random() < 0.10) {
				upgradeTypes.push('health');
			}
			if (armorDropsThisWave < 1 && Math.random() < 0.10) {
				upgradeTypes.push('armor');
			}
		}
		// Only add damage upgrades if weapon has not reached maximum level and limit 2 per wave
		if (player.weaponUpgrades < 49 && weaponDropsThisWave < 2) {
			upgradeTypes.push('damage');
		}
		// Only add novaBlade to upgrade types if weapon has reached maximum level (50) with 25% chance and limit 2 per wave
		if (player.weaponUpgrades >= 49 && weaponDropsThisWave < 2 && Math.random() < 0.25) {
			// weaponUpgrades is 0-based, so 49 = level 50
			upgradeTypes.push('novaBlade');
		}
		// Only proceed if we have upgrade types available
		if (upgradeTypes.length > 0) {
			var randomType = upgradeTypes[Math.floor(Math.random() * upgradeTypes.length)];
			var pickup = new Pickup(randomType);
			pickup.x = x;
			pickup.y = y;
			pickups.push(pickup);
			game.addChild(pickup);
			// Track upgrade drops for this wave
			if (randomType === 'shield') {
				waveUpgradeDrops.shield = (waveUpgradeDrops.shield || 0) + 1;
			} else if (randomType === 'damage') {
				waveUpgradeDrops.weapon = (waveUpgradeDrops.weapon || 0) + 1;
			} else if (randomType === 'speed') {
				waveUpgradeDrops.speed = (waveUpgradeDrops.speed || 0) + 1;
			} else if (randomType === 'armor') {
				waveUpgradeDrops.armor = (waveUpgradeDrops.armor || 0) + 1;
			} else if (randomType === 'health') {
				waveUpgradeDrops.health = (waveUpgradeDrops.health || 0) + 1;
			} else if (randomType === 'novaBlade') {
				waveUpgradeDrops.weapon = (waveUpgradeDrops.weapon || 0) + 1;
			}
		}
	}
}
function startNextWave() {
	currentWave++;
	// Reset 5th wave speed upgrade flag for new wave
	fifthWaveSpeedUpgradeDropped = false;
	// Reset wave upgrade drop counters
	waveUpgradeDrops = {};
	// Check if this is a boss wave (every 10th wave)
	if (currentWave % 10 === 0) {
		bossWave = true;
		creepsInWave = 0; // No regular creeps on boss waves
		eliteCreepsInWave = 0; // No elite creeps on boss waves
		specialCreepsInWave = 0; // No special creeps on boss waves
	} else {
		bossWave = false;
		creepsInWave = 8 + Math.floor(currentWave * 2.5); // More creeps per wave
		// Add 2 extra creeps for every wave after wave 1
		if (currentWave > 1) {
			creepsInWave += 2;
		}
		eliteCreepsInWave = currentWave; // Number of elite creeps equals wave number
		// Special creeps spawn on waves 9, 19, 29, 39, etc. (one before each boss wave)
		if ((currentWave + 1) % 10 === 0 && currentWave >= 9) {
			// Calculate how many special creeps to spawn based on wave
			// Wave 9: 1 special creep, Wave 19: 2 special creeps, etc.
			specialCreepsInWave = Math.floor((currentWave + 1) / 10);
		} else {
			specialCreepsInWave = 0;
		}
	}
	creepsSpawned = 0;
	eliteCreepsSpawned = 0;
	specialCreepsSpawned = 0;
	waveCompleted = false;
	waveText.setText('Wave: ' + currentWave + (bossWave ? ' (BOSS)' : ''));
}
// Player movement variables
var targetX = 1024;
var targetY = 1366;
var isMoving = false;
game.down = function (x, y, obj) {
	if (!gameStarted) return;
	targetX = x;
	targetY = y;
	isMoving = true;
};
game.move = function (x, y, obj) {
	if (!gameStarted) return;
	if (isMoving) {
		targetX = x;
		targetY = y;
	}
};
game.up = function (x, y, obj) {
	if (!gameStarted) return;
	isMoving = false;
};
game.update = function () {
	// Don't update game logic until game has started
	if (!gameStarted) return;
	// Process pickups FIRST to ensure upgrades always activate before any damage
	for (var i = pickups.length - 1; i >= 0; i--) {
		var pickup = pickups[i];
		// Check pickup collection using both intersection and distance
		var dx = pickup.x - player.x;
		var dy = pickup.y - player.y;
		var distance = Math.sqrt(dx * dx + dy * dy);
		// Only player radius can pick up upgrades (Nova field does not interfere)
		var collected = pickup.intersects(player) || distance < 50;
		if (collected) {
			// Immediately activate upgrade effect and calculate points
			var pickupPoints = 150; // Default points
			switch (pickup.type) {
				case 'health':
					// Check if player is at full health before healing
					var wasAtFullHealth = player.health >= player.maxHealth;
					player.heal(50); // Boss health potions heal 50 hit points
					// Double points if player was at full health when picking up health potion
					if (wasAtFullHealth) {
						pickupPoints = 300;
					}
					break;
				case 'damage':
					player.addDamage(5);
					break;
				case 'speed':
					player.addSpeed(1);
					break;
				case 'shield':
					player.activateShield();
					break;
				case 'armor':
					// Check if player is at full armor before adding armor
					var wasAtFullArmor = player.armor >= player.maxArmor;
					player.addArmor(10); // Armor upgrade gives 10 armor points
					// Double points if player was at full armor when picking up armor upgrade
					if (wasAtFullArmor) {
						pickupPoints = 300;
					}
					break;
				case 'novaBlade':
					player.activateNovaBlade();
					break;
			}
			// Give points for collecting upgrades
			gameScore += pickupPoints;
			LK.setScore(LK.getScore() + pickupPoints);
			LK.getSound('pickup').play();
			pickup.destroy();
			pickups.splice(i, 1);
		} else if (pickup.lifetime <= 0) {
			pickup.destroy();
			pickups.splice(i, 1);
		}
	}
	// Player movement
	if (isMoving) {
		var dx = targetX - player.x;
		var dy = targetY - player.y;
		var distance = Math.sqrt(dx * dx + dy * dy);
		if (distance > 25) {
			player.x += dx / distance * player.moveSpeed;
			player.y += dy / distance * player.moveSpeed;
		}
	}
	// Automatic shooting at closest creep
	if (creeps.length > 0 && player.canShoot()) {
		var closestCreep = null;
		var closestDistance = Infinity;
		for (var i = 0; i < creeps.length; i++) {
			var creep = creeps[i];
			var dx = creep.x - player.x;
			var dy = creep.y - player.y;
			var distance = Math.sqrt(dx * dx + dy * dy);
			if (distance < closestDistance) {
				closestDistance = distance;
				closestCreep = creep;
			}
		}
		if (closestCreep) {
			var shotBullets = player.shoot(closestCreep.x, closestCreep.y);
			if (shotBullets) {
				for (var k = 0; k < shotBullets.length; k++) {
					bullets.push(shotBullets[k]);
					game.addChild(shotBullets[k]);
				}
			}
		}
	}
	// Update shield system
	if (player.shieldActive) {
		player.shieldDuration--;
		if (player.shieldDuration <= 0 || player.shieldHealth <= 0) {
			player.shieldActive = false;
			player.shieldHealth = 0;
			player.shieldDuration = 0;
			if (player.shieldAura) {
				player.shieldAura.destroy();
				player.shieldAura = null;
			}
		} else if (player.shieldAura) {
			// Animate shield aura
			player.shieldAura.rotation += 0.05;
			// Flash when shield is about to expire (last 5 seconds)
			if (player.shieldDuration < 300) {
				player.shieldAura.alpha = 0.3 + 0.3 * Math.sin(LK.ticks * 0.3);
			}
		}
	}
	// Update player health display
	healthText.setText('Health: ' + player.health);
	armorText.setText('Armor: ' + player.armor);
	// Display weapon level or max level indicator
	var weaponLevel = player.weaponUpgrades + 1;
	if (weaponLevel >= 50) {
		weaponLevelText.setText('Weapon Level: Max Level');
	} else {
		weaponLevelText.setText('Weapon Level: ' + weaponLevel);
	}
	// Update weapon type display based on level
	var weaponLevel = player.weaponUpgrades + 1;
	var weaponType = 'Blaster';
	if (weaponLevel >= 50) {
		weaponType = 'Hexa Shot';
	} else if (weaponLevel >= 40) {
		weaponType = 'Penta Shot';
	} else if (weaponLevel >= 30) {
		weaponType = 'Quad Shot';
	} else if (weaponLevel >= 20) {
		weaponType = 'Triple Shot';
	} else if (weaponLevel >= 10) {
		weaponType = 'Double Shot';
	}
	weaponTypeText.setText(weaponType);
	// Update Nova blade level display
	if (player.novaBladeActive && player.novaBladeLevel > 0) {
		if (player.novaBladeLevel >= 50) {
			novaBladeText.setText('Nova Field Level Max Level');
		} else {
			novaBladeText.setText('Nova Field Level ' + player.novaBladeLevel);
		}
	} else {
		novaBladeText.setText('');
	}
	// Update score display
	scoreText.setText('Score: ' + gameScore);
	// Update shield display
	if (player.shieldActive) {
		var shieldTimeLeft = Math.ceil(player.shieldDuration / 60);
		shieldText.setText('Shield: ' + player.shieldHealth + '/' + player.shieldMaxHealth + ' (' + shieldTimeLeft + 's)');
	} else {
		shieldText.setText('');
	}
	// Update boss health bar
	if (currentBoss && bossHealthBar.alpha > 0) {
		var healthPercent = Math.round(currentBoss.health / currentBoss.maxHealth * 100);
		bossHealthBar.setText('BOSS: ' + currentBoss.health + '/' + currentBoss.maxHealth + ' (' + healthPercent + '%)');
	}
	// Check game over
	if (player.health <= 0) {
		// Create explosion effect - player explodes in flames
		var playerGraphics = player.children[0]; // Get player graphics
		// Create flame explosion effect with multiple tween stages
		tween(playerGraphics, {
			scaleX: 2.0,
			scaleY: 2.0,
			tint: 0xFF4400,
			// Orange flame color
			alpha: 1.0
		}, {
			duration: 200,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				// Second stage - bright red explosion
				tween(playerGraphics, {
					scaleX: 3.0,
					scaleY: 3.0,
					tint: 0xFF0000,
					// Bright red
					alpha: 0.8
				}, {
					duration: 150,
					easing: tween.easeOut,
					onFinish: function onFinish() {
						// Final stage - fade to black and shrink
						tween(playerGraphics, {
							scaleX: 0.1,
							scaleY: 0.1,
							tint: 0x000000,
							// Black
							alpha: 0.0
						}, {
							duration: 300,
							easing: tween.easeInOut,
							onFinish: function onFinish() {
								// Show game over after explosion completes
								LK.showGameOver();
							}
						});
					}
				});
			}
		});
		return;
	}
	// Wave management
	if (!waveCompleted) {
		if (bossWave) {
			// Boss wave logic
			if (!currentBoss && creeps.length === 0) {
				spawnBoss();
			}
			// Check if boss wave is complete
			if (currentBoss && creeps.length === 0) {
				waveCompleted = true;
				nextWaveTimer = 180; // 3 second break
				currentBoss = null;
				// Hide boss health bar
				tween(bossHealthBar, {
					alpha: 0
				}, {
					duration: 500
				});
			}
		} else {
			// Regular wave logic
			// Spawn creeps
			if (creepsSpawned < creepsInWave || eliteCreepsSpawned < eliteCreepsInWave || specialCreepsSpawned < specialCreepsInWave) {
				spawnTimer++;
				if (spawnTimer >= 60) {
					// Spawn every second
					if (creepsSpawned < creepsInWave) {
						spawnCreep();
						creepsSpawned++;
					} else if (eliteCreepsSpawned < eliteCreepsInWave) {
						spawnEliteCreep();
						eliteCreepsSpawned++;
					} else if (specialCreepsSpawned < specialCreepsInWave) {
						spawnSpecialCreep();
						specialCreepsSpawned++;
					}
					spawnTimer = 0;
				}
			}
			// Check if wave is complete
			if (creepsSpawned >= creepsInWave && eliteCreepsSpawned >= eliteCreepsInWave && specialCreepsSpawned >= specialCreepsInWave && creeps.length === 0) {
				waveCompleted = true;
				nextWaveTimer = 180; // 3 second break
			}
		}
	} else {
		nextWaveTimer--;
		if (nextWaveTimer <= 0) {
			startNextWave();
		}
	}
	// Update boss bullets
	for (var i = bossBullets.length - 1; i >= 0; i--) {
		var bossBullet = bossBullets[i];
		// Check if boss bullet is off screen
		if (bossBullet.x < -50 || bossBullet.x > 2098 || bossBullet.y < -50 || bossBullet.y > 2782) {
			bossBullet.destroy();
			bossBullets.splice(i, 1);
			continue;
		}
		// Check boss bullet collision with player using base player radius only
		var bulletDx = bossBullet.x - player.x;
		var bulletDy = bossBullet.y - player.y;
		var bulletDistance = Math.sqrt(bulletDx * bulletDx + bulletDy * bulletDy);
		// Use player's base radius (55 pixels) regardless of Nova Field status
		if (bulletDistance < 55) {
			player.takeDamage(bossBullet.damage);
			bossBullet.destroy();
			bossBullets.splice(i, 1);
		}
	}
	// Update bullets
	for (var i = bullets.length - 1; i >= 0; i--) {
		var bullet = bullets[i];
		// Check if bullet is off screen
		if (bullet.x < -50 || bullet.x > 2098 || bullet.y < -50 || bullet.y > 2782) {
			bullet.destroy();
			bullets.splice(i, 1);
			continue;
		}
		// Check bullet-creep collisions
		var hitCreep = false;
		for (var j = creeps.length - 1; j >= 0; j--) {
			var creep = creeps[j];
			if (bullet.intersects(creep)) {
				var isDead = creep.takeDamage(bullet.damage);
				if (isDead) {
					// Create explosion effect at creep position
					createExplosionEffect(creep.x, creep.y);
					// Play explosion sound
					LK.getSound('explosion').play();
					// Give points for killing creeps
					var scoreValue;
					if (creep instanceof BossCreep) {
						scoreValue = 10000; // High score for boss
						// Clean up spawned creeps when boss dies
						for (var spawnIdx = creep.spawnedCreeps.length - 1; spawnIdx >= 0; spawnIdx--) {
							var spawnedCreep = creep.spawnedCreeps[spawnIdx];
							if (spawnedCreep) {
								// Find and remove from creeps array
								var creepIndex = creeps.indexOf(spawnedCreep);
								if (creepIndex !== -1) {
									spawnedCreep.destroy();
									creeps.splice(creepIndex, 1);
								}
							}
						}
						// Boss drops one speed upgrade, one armor upgrade, one health potion upgrade, and one weapon upgrade
						var speedPickup = new Pickup('speed');
						speedPickup.x = creep.x - 52.5; // Position far left with 35px spacing
						speedPickup.y = creep.y;
						pickups.push(speedPickup);
						game.addChild(speedPickup);
						var armorPickup = new Pickup('armor');
						armorPickup.x = creep.x - 17.5; // Position left of center with 35px spacing
						armorPickup.y = creep.y;
						pickups.push(armorPickup);
						game.addChild(armorPickup);
						var healthPickup = new Pickup('health');
						healthPickup.x = creep.x + 17.5; // Position right of center with 35px spacing
						healthPickup.y = creep.y;
						pickups.push(healthPickup);
						game.addChild(healthPickup);
						// Check player weapon level to determine weapon upgrade type
						var weaponPickup;
						if (player.weaponUpgrades >= 49) {
							// Replace weapon upgrade with nova blade upgrade if player is at level 50
							weaponPickup = new Pickup('novaBlade');
						} else {
							weaponPickup = new Pickup('damage');
						}
						weaponPickup.x = creep.x + 52.5; // Position far right with 35px spacing
						weaponPickup.y = creep.y;
						pickups.push(weaponPickup);
						game.addChild(weaponPickup);
					} else if (creep instanceof SpecialCreep) {
						scoreValue = 300; // Higher score for special creeps
					} else if (creep instanceof EliteCreep) {
						scoreValue = 200;
						// Elite creep upgrade drop chance reset to 0%
					} else {
						scoreValue = 100;
					}
					gameScore += scoreValue;
					LK.setScore(LK.getScore() + scoreValue);
					if (!(creep instanceof BossCreep)) {
						dropPickup(creep.x, creep.y, creep instanceof EliteCreep || creep instanceof SpecialCreep);
					}
					creep.destroy();
					creeps.splice(j, 1);
				}
				bullet.destroy();
				bullets.splice(i, 1);
				hitCreep = true;
				break;
			}
		}
	}
	// Nova blade damage dealing
	if (player.novaBladeActive && LK.ticks - player.novaBladeLastActivation >= 300) {
		// Check if any aura is currently active by checking for expanding aura
		var playerChildren = player.children;
		var auraActive = false;
		for (var childIdx = 0; childIdx < playerChildren.length; childIdx++) {
			var child = playerChildren[childIdx];
			// Check if this is an expanding aura (scale > 1.0 indicates expansion)
			if (child.tint === 0xFF6600 && child.scaleX > 1.0) {
				auraActive = true;
				var auraRadius = player.novaBladeProximity; // Use dynamic proximity range
				// Push all creeps away from player when Nova blade is active
				for (var creepIdx = creeps.length - 1; creepIdx >= 0; creepIdx--) {
					var creep = creeps[creepIdx];
					var dx = creep.x - player.x;
					var dy = creep.y - player.y;
					var distance = Math.sqrt(dx * dx + dy * dy);
					if (distance <= auraRadius) {
						// Push creep away from player
						if (distance > 0) {
							var normalizedPushX = dx / distance;
							var normalizedPushY = dy / distance;
							var pushStrength = 50; // Strong push away from Nova blade
							tween(creep, {
								x: creep.x + normalizedPushX * pushStrength,
								y: creep.y + normalizedPushY * pushStrength
							}, {
								duration: 300,
								easing: tween.easeOut
							});
						}
						var isDead = creep.takeDamage(25); // Fixed 25 damage
						if (isDead) {
							// Create explosion effect at creep position
							createExplosionEffect(creep.x, creep.y);
							// Play explosion sound
							LK.getSound('explosion').play();
							// Give points for killing creeps with Nova blade
							var scoreValue;
							if (creep instanceof BossCreep) {
								scoreValue = 10000;
								// Clean up spawned creeps when boss dies
								for (var spawnIdx = creep.spawnedCreeps.length - 1; spawnIdx >= 0; spawnIdx--) {
									var spawnedCreep = creep.spawnedCreeps[spawnIdx];
									if (spawnedCreep) {
										var creepIndex = creeps.indexOf(spawnedCreep);
										if (creepIndex !== -1) {
											spawnedCreep.destroy();
											creeps.splice(creepIndex, 1);
										}
									}
								}
								// Boss drops one speed upgrade, one armor upgrade, one health potion upgrade, and one weapon upgrade
								var speedPickup = new Pickup('speed');
								speedPickup.x = creep.x - 52.5; // Position far left with 35px spacing
								speedPickup.y = creep.y;
								pickups.push(speedPickup);
								game.addChild(speedPickup);
								var armorPickup = new Pickup('armor');
								armorPickup.x = creep.x - 17.5; // Position left of center with 35px spacing
								armorPickup.y = creep.y;
								pickups.push(armorPickup);
								game.addChild(armorPickup);
								var healthPickup = new Pickup('health');
								healthPickup.x = creep.x + 17.5; // Position right of center with 35px spacing
								healthPickup.y = creep.y;
								pickups.push(healthPickup);
								game.addChild(healthPickup);
								// Check player weapon level to determine weapon upgrade type
								var weaponPickup;
								if (player.weaponUpgrades >= 49) {
									// Replace weapon upgrade with nova blade upgrade if player is at level 50
									weaponPickup = new Pickup('novaBlade');
								} else {
									weaponPickup = new Pickup('damage');
								}
								weaponPickup.x = creep.x + 52.5; // Position far right with 35px spacing
								weaponPickup.y = creep.y;
								pickups.push(weaponPickup);
								game.addChild(weaponPickup);
							} else if (creep instanceof SpecialCreep) {
								scoreValue = 300; // Higher score for special creeps
							} else if (creep instanceof EliteCreep) {
								scoreValue = 200;
								// Elite creep upgrade drop chance reset to 0%
							} else {
								scoreValue = 100;
							}
							gameScore += scoreValue;
							LK.setScore(LK.getScore() + scoreValue);
							if (!(creep instanceof BossCreep)) {
								dropPickup(creep.x, creep.y, creep instanceof EliteCreep || creep instanceof SpecialCreep);
							}
							creep.destroy();
							creeps.splice(creepIdx, 1);
						}
					}
				}
				break; // Only process one active aura at a time
			}
		}
	}
	// Update creeps
	var _loop = function _loop() {
			creep = creeps[i]; // Check if creep reached player - adjust hit detection based on shield status
			canHitPlayer = false;
			// Always use distance-based hit detection for consistency
			dx = creep.x - player.x;
			dy = creep.y - player.y;
			distance = Math.sqrt(dx * dx + dy * dy);
			if (player.shieldActive) {
				// When shield is active, creeps can hit from slightly further away
				canHitPlayer = distance < 50; // Increased from 35 to 50 for better gameplay with shield
			} else {
				// Normal hit detection when no shield - increased threshold for easier creep hits
				canHitPlayer = distance < 85; // Increased from 70 to 85 for better gameplay
			}
			if (canHitPlayer) {
				if (!creep.hasReachedPlayer) {
					player.takeDamage(creep.damage);
					creep.hasReachedPlayer = true;
					// Calculate bump direction (away from creep)
					bumpDx = player.x - creep.x;
					bumpDy = player.y - creep.y;
					bumpDistance = Math.sqrt(bumpDx * bumpDx + bumpDy * bumpDy);
					if (bumpDistance > 0) {
						normalizedBumpX = bumpDx / bumpDistance;
						normalizedBumpY = bumpDy / bumpDistance;
						bumpStrength = 30; // How far to bump the player
						// Bump the player away from the creep
						tween(player, {
							x: player.x + normalizedBumpX * bumpStrength,
							y: player.y + normalizedBumpY * bumpStrength
						}, {
							duration: 200,
							easing: tween.easeOut
						});
					}
					// Make player invincible and add red flicker effect
					if (!player.invincible) {
						var _flicker = function flicker() {
							flickerCount++;
							if (flickerCount <= maxFlickers && player.invincible) {
								var playerGraphics = player.children[0]; // Get player graphics
								tween(playerGraphics, {
									tint: 0xFF0000,
									alpha: 0.5
								}, {
									duration: 50,
									onFinish: function onFinish() {
										tween(playerGraphics, {
											tint: 0xFFFFFF,
											alpha: 1.0
										}, {
											duration: 50,
											onFinish: function onFinish() {
												if (flickerCount < maxFlickers && player.invincible) {
													_flicker();
												}
											}
										});
									}
								});
							}
						};
						player.invincible = true;
						player.invincibilityTimer = 30; // 0.5 seconds at 60fps
						// Create flickering red effect during invincibility
						flickerCount = 0;
						maxFlickers = 10;
						_flicker();
					}
				}
				// Don't destroy creep - it stays alive after hitting player
			}
		},
		creep,
		canHitPlayer,
		dx,
		dy,
		distance,
		bumpDx,
		bumpDy,
		bumpDistance,
		normalizedBumpX,
		normalizedBumpY,
		bumpStrength,
		flickerCount,
		maxFlickers;
	for (var i = creeps.length - 1; i >= 0; i--) {
		_loop();
	}
	// Pickup processing moved to beginning of update loop
}; /**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
/**** 
* Classes
****/ 
var BossBullet = Container.expand(function () {
	var self = Container.call(this);
	var graphics = self.attachAsset('bossBullet', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 3; // Slow moving bullets
	self.velocityX = 0;
	self.velocityY = 0;
	self.damage = 25;
	self.update = function () {
		self.x += self.velocityX;
		self.y += self.velocityY;
	};
	return self;
});
var BossCreep = Container.expand(function () {
	var self = Container.call(this);
	var graphics = self.attachAsset('bossCreep', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.health = 12000; // Half the previous health for boss
	self.maxHealth = 12000;
	self.speed = 0.8; // Slower than elite creeps
	self.damage = 60; // More damage than elite creeps
	self.targetX = 0;
	self.targetY = 0;
	self.hasReachedPlayer = false;
	self.spawnedCreeps = []; // Track spawned rotating creeps
	self.lastSpawnTime = 0; // Track time for spawning
	self.rotationAngle = 0; // Current rotation angle for spawned creeps
	self.lastSpecialCreepSpawnTime = 0; // Track time for special creep spawning
	self.takeDamage = function (amount) {
		self.health -= amount;
		if (self.health <= 0) {
			return true; // Return true if boss is dead
		}
		return false;
	};
	self.update = function () {
		// Reset flag to allow continued movement after hitting player
		self.hasReachedPlayer = false;
		// Continuously update target to player's current position
		self.targetX = player.x;
		self.targetY = player.y;
		var dx = self.targetX - self.x;
		var dy = self.targetY - self.y;
		var distance = Math.sqrt(dx * dx + dy * dy);
		if (distance > 3) {
			// Calculate avoidance force from other creeps
			var avoidanceX = 0;
			var avoidanceY = 0;
			var avoidanceRadius = 240; // Largest avoidance radius for boss creeps
			for (var i = 0; i < creeps.length; i++) {
				var otherCreep = creeps[i];
				if (otherCreep !== self) {
					var otherDx = self.x - otherCreep.x;
					var otherDy = self.y - otherCreep.y;
					var otherDistance = Math.sqrt(otherDx * otherDx + otherDy * otherDy);
					if (otherDistance < avoidanceRadius && otherDistance > 0) {
						var avoidanceStrength = (avoidanceRadius - otherDistance) / avoidanceRadius;
						avoidanceX += otherDx / otherDistance * avoidanceStrength;
						avoidanceY += otherDy / otherDistance * avoidanceStrength;
					}
				}
			}
			// Combine movement towards player with avoidance
			var moveX = dx / distance * self.speed + avoidanceX * 0.3;
			var moveY = dy / distance * self.speed + avoidanceY * 0.3;
			self.x += moveX;
			self.y += moveY;
		} else {
			self.hasReachedPlayer = true;
		}
		// Calculate maximum rotating creeps based on wave number (10 for wave 10, 20 for wave 20, 30 for wave 30)
		var maxRotatingCreeps = Math.min(30, currentWave); // Cap at 30 for performance
		// Spawn rotating creeps around boss every second (60 ticks) - wave-based maximum
		if (LK.ticks - self.lastSpawnTime >= 60 && self.spawnedCreeps.length < maxRotatingCreeps) {
			self.lastSpawnTime = LK.ticks;
			// Create a new creep that will rotate around the boss
			var spawnedCreep = new Creep();
			spawnedCreep.health = 40; // Less health than normal creeps
			spawnedCreep.maxHealth = 40;
			spawnedCreep.speed = 0; // They don't move on their own
			// Base damage starts at 12 but increases with each spawn
			var baseDamage = 12;
			var damageIncrease = self.spawnedCreeps.length * 2; // Increase by 2 for each existing rotating creep
			spawnedCreep.damage = baseDamage + damageIncrease; // Damage increases with number of spawned creeps
			spawnedCreep.bossParent = self; // Reference to boss
			spawnedCreep.orbitRadius = 600; // Distance from boss center
			spawnedCreep.orbitAngle = Math.random() * Math.PI * 2; // Random starting angle
			// Position the creep initially
			spawnedCreep.x = self.x + Math.cos(spawnedCreep.orbitAngle) * spawnedCreep.orbitRadius;
			spawnedCreep.y = self.y + Math.sin(spawnedCreep.orbitAngle) * spawnedCreep.orbitRadius;
			self.spawnedCreeps.push(spawnedCreep);
			creeps.push(spawnedCreep);
			game.addChild(spawnedCreep);
		}
		// Update rotation angle
		self.rotationAngle += 0.02; // Rotation speed
		// Update positions of spawned creeps to rotate around boss
		for (var k = self.spawnedCreeps.length - 1; k >= 0; k--) {
			var spawnedCreep = self.spawnedCreeps[k];
			if (spawnedCreep && spawnedCreep.bossParent === self) {
				// Update orbit angle
				spawnedCreep.orbitAngle += 0.03; // Individual rotation speed
				// Calculate new position around boss
				spawnedCreep.x = self.x + Math.cos(spawnedCreep.orbitAngle) * spawnedCreep.orbitRadius;
				spawnedCreep.y = self.y + Math.sin(spawnedCreep.orbitAngle) * spawnedCreep.orbitRadius;
				// Override normal creep movement by setting hasReachedPlayer to prevent normal AI
				spawnedCreep.hasReachedPlayer = false;
				spawnedCreep.targetX = spawnedCreep.x;
				spawnedCreep.targetY = spawnedCreep.y;
			} else {
				// Remove reference if creep was destroyed
				self.spawnedCreeps.splice(k, 1);
			}
		}
		// Spawn special creep every 15 seconds (900 ticks at 60fps)
		if (LK.ticks - self.lastSpecialCreepSpawnTime >= 900) {
			self.lastSpecialCreepSpawnTime = LK.ticks;
			// Create a new special creep that moves towards player
			var specialCreep = new SpecialCreep();
			specialCreep.x = self.x;
			specialCreep.y = self.y;
			specialCreep.targetX = player.x;
			specialCreep.targetY = player.y;
			// Scale health based on current wave
			specialCreep.health += (currentWave - 1) * 60;
			// Apply 50% health increase every 5th wave
			var healthMultiplier = 1 + Math.floor(currentWave / 5) * 0.5;
			specialCreep.health = Math.floor(specialCreep.health * healthMultiplier);
			specialCreep.maxHealth = specialCreep.health;
			// Apply speed increase - 1% for every 5th wave
			var speedMultiplier = 1 + Math.floor(currentWave / 5) * 0.01;
			// Apply extra 2% speed increase per wave after wave 15
			if (currentWave > 15) {
				var extraSpeedMultiplier = 1 + (currentWave - 15) * 0.02;
				speedMultiplier *= extraSpeedMultiplier;
			}
			specialCreep.speed = specialCreep.speed * speedMultiplier;
			creeps.push(specialCreep);
			game.addChild(specialCreep);
		}
		// Boss bullet shooting every second (60 ticks at 60fps)
		if (LK.ticks % 60 === 0) {
			// Calculate direction to player
			var bulletDx = player.x - self.x;
			var bulletDy = player.y - self.y;
			var bulletDistance = Math.sqrt(bulletDx * bulletDx + bulletDy * bulletDy);
			if (bulletDistance > 0) {
				var normalizedX = bulletDx / bulletDistance;
				var normalizedY = bulletDy / bulletDistance;
				// Calculate number of bullets based on wave number (wave 10: 5 bullets, wave 20: 6 bullets, wave 30: 7 bullets)
				var bulletCount = 5; // Default for wave 10 boss
				if (currentWave >= 20) {
					bulletCount = 5 + Math.floor((currentWave - 10) / 10);
				}
				// Add extra bullet for all boss fights after wave 30
				if (currentWave > 30) {
					bulletCount += 1;
				}
				// Create bullets in a burst pattern
				for (var bulletIndex = 0; bulletIndex < bulletCount; bulletIndex++) {
					var bossBullet = new BossBullet();
					bossBullet.x = self.x;
					bossBullet.y = self.y;
					// Adjust angle spread based on bullet count for better distribution
					var spreadRange = bulletCount > 5 ? 0.4 : 0.3;
					var angleOffset = (bulletIndex - (bulletCount - 1) / 2) * spreadRange;
					var angle = Math.atan2(normalizedY, normalizedX) + angleOffset;
					bossBullet.velocityX = Math.cos(angle) * bossBullet.speed;
					bossBullet.velocityY = Math.sin(angle) * bossBullet.speed;
					// Add to boss bullets array (will be created in game code)
					bossBullets.push(bossBullet);
					game.addChild(bossBullet);
				}
			}
		}
	};
	return self;
});
var Bullet = Container.expand(function () {
	var self = Container.call(this);
	var graphics = self.attachAsset('bullet', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 8;
	self.velocityX = 0;
	self.velocityY = 0;
	self.damage = 20;
	self.update = function () {
		self.x += self.velocityX;
		self.y += self.velocityY;
	};
	return self;
});
var Creep = Container.expand(function () {
	var self = Container.call(this);
	var graphics = self.attachAsset('creep', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.health = 60; // Base health requiring 3 hits (20 damage per hit)
	self.maxHealth = 60;
	self.speed = 2.4;
	self.damage = 25;
	self.targetX = 0;
	self.targetY = 0;
	self.hasReachedPlayer = false;
	self.takeDamage = function (amount) {
		self.health -= amount;
		if (self.health <= 0) {
			return true; // Return true if creep is dead
		}
		return false;
	};
	self.update = function () {
		// Reset flag to allow continued movement after hitting player
		self.hasReachedPlayer = false;
		// Continuously update target to player's current position
		self.targetX = player.x;
		self.targetY = player.y;
		var dx = self.targetX - self.x;
		var dy = self.targetY - self.y;
		var distance = Math.sqrt(dx * dx + dy * dy);
		if (distance > 25) {
			// Calculate avoidance force from other creeps
			var avoidanceX = 0;
			var avoidanceY = 0;
			var avoidanceRadius = 120; // Distance to avoid other creeps
			for (var i = 0; i < creeps.length; i++) {
				var otherCreep = creeps[i];
				if (otherCreep !== self) {
					var otherDx = self.x - otherCreep.x;
					var otherDy = self.y - otherCreep.y;
					var otherDistance = Math.sqrt(otherDx * otherDx + otherDy * otherDy);
					if (otherDistance < avoidanceRadius && otherDistance > 0) {
						var avoidanceStrength = (avoidanceRadius - otherDistance) / avoidanceRadius;
						avoidanceX += otherDx / otherDistance * avoidanceStrength;
						avoidanceY += otherDy / otherDistance * avoidanceStrength;
					}
				}
			}
			// Combine movement towards player with avoidance
			var moveX = dx / distance * self.speed + avoidanceX * 0.5;
			var moveY = dy / distance * self.speed + avoidanceY * 0.5;
			self.x += moveX;
			self.y += moveY;
		} else {
			self.hasReachedPlayer = true;
		}
	};
	return self;
});
var EliteCreep = Container.expand(function () {
	var self = Container.call(this);
	var graphics = self.attachAsset('eliteCreep', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.health = 150; // Much higher base health
	self.maxHealth = 150;
	self.speed = 1.5; // Slower than regular creeps
	self.damage = 50; // More damage than regular creeps
	self.targetX = 0;
	self.targetY = 0;
	self.hasReachedPlayer = false;
	self.takeDamage = function (amount) {
		self.health -= amount;
		if (self.health <= 0) {
			return true; // Return true if creep is dead
		}
		return false;
	};
	self.update = function () {
		// Reset flag to allow continued movement after hitting player
		self.hasReachedPlayer = false;
		// Continuously update target to player's current position
		self.targetX = player.x;
		self.targetY = player.y;
		var dx = self.targetX - self.x;
		var dy = self.targetY - self.y;
		var distance = Math.sqrt(dx * dx + dy * dy);
		if (distance > 25) {
			// Calculate avoidance force from other creeps
			var avoidanceX = 0;
			var avoidanceY = 0;
			var avoidanceRadius = 180; // Larger avoidance radius for elite creeps
			for (var i = 0; i < creeps.length; i++) {
				var otherCreep = creeps[i];
				if (otherCreep !== self) {
					var otherDx = self.x - otherCreep.x;
					var otherDy = self.y - otherCreep.y;
					var otherDistance = Math.sqrt(otherDx * otherDx + otherDy * otherDy);
					if (otherDistance < avoidanceRadius && otherDistance > 0) {
						var avoidanceStrength = (avoidanceRadius - otherDistance) / avoidanceRadius;
						avoidanceX += otherDx / otherDistance * avoidanceStrength;
						avoidanceY += otherDy / otherDistance * avoidanceStrength;
					}
				}
			}
			// Combine movement towards player with avoidance
			var moveX = dx / distance * self.speed + avoidanceX * 0.5;
			var moveY = dy / distance * self.speed + avoidanceY * 0.5;
			self.x += moveX;
			self.y += moveY;
		} else {
			self.hasReachedPlayer = true;
		}
	};
	return self;
});
var Pickup = Container.expand(function (type) {
	var self = Container.call(this);
	self.type = type;
	var assetName;
	if (type === 'health') {
		assetName = 'healthPotion';
	} else if (type === 'damage') {
		assetName = 'damageUpgrade';
	} else if (type === 'speed') {
		assetName = 'speedUpgrade'; // Use dedicated speed upgrade asset
	} else if (type === 'attackSpeed') {
		assetName = 'damageUpgrade'; // Reuse red upgrade for attack speed
	} else if (type === 'shield') {
		assetName = 'shieldUpgrade';
	} else if (type === 'armor') {
		assetName = 'armorUpgrade';
	} else if (type === 'novaBlade') {
		assetName = 'novaBlade';
	}
	var graphics = self.attachAsset(assetName, {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.lifetime = 3600; // 60 seconds at 60fps
	self.update = function () {
		self.lifetime--;
		if (self.lifetime < 300) {
			// Start fading at 5 seconds remaining
			graphics.alpha = self.lifetime / 300;
		}
		// Magnetic pull effect when player is close
		if (player) {
			var dx = player.x - self.x;
			var dy = player.y - self.y;
			var distance = Math.sqrt(dx * dx + dy * dy);
			// Start pulling when within 150 pixels
			if (distance < 150 && distance > 10) {
				var pullSpeed = 8; // Fast pull speed
				var normalizedX = dx / distance;
				var normalizedY = dy / distance;
				self.x += normalizedX * pullSpeed;
				self.y += normalizedY * pullSpeed;
			}
		}
	};
	return self;
});
var Player = Container.expand(function () {
	var self = Container.call(this);
	var graphics = self.attachAsset('player', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 1.3,
		scaleY: 1.3
	});
	self.maxHealth = 100;
	self.health = 100;
	self.defense = 0;
	self.armor = 0;
	self.maxArmor = 50;
	self.baseDamage = 20; // Base damage that never changes
	self.damage = 20; // Current damage (base + upgrades)
	self.weaponUpgrades = 0; // Track weapon upgrades for double shot
	self.lastShootTime = 0;
	self.shootCooldown = 40; // Fixed cooldown that never changes
	self.baseSpeed = 4; // Base movement speed
	self.moveSpeed = 4; // Current movement speed (base + upgrades)
	self.shieldActive = false;
	self.shieldHealth = 0;
	self.shieldMaxHealth = 80;
	self.shieldDuration = 0; // In game ticks (60 fps)
	self.shieldAura = null;
	self.invincible = false;
	self.invincibilityTimer = 0;
	self.novaBladeActive = false;
	self.novaBladeTimer = 0;
	self.novaBladeLastActivation = 0;
	self.novaBladeLevel = 0;
	self.novaBladeProximity = 300; // Base proximity
	// Movement direction tracking
	self.lastX = 0;
	self.lastY = 0;
	self.currentDirection = 0; // 0 = north (default)
	self.takeDamage = function (amount) {
		// If player is invincible, ignore all damage
		if (self.invincible) {
			return;
		}
		if (self.shieldActive && self.shieldHealth > 0) {
			// Shield absorbs damage first
			self.shieldHealth -= amount;
			if (self.shieldHealth <= 0) {
				// Shield broken
				self.shieldHealth = 0;
				self.shieldActive = false;
				self.shieldDuration = 0;
				if (self.shieldAura) {
					self.shieldAura.destroy();
					self.shieldAura = null;
				}
			}
			// Flash blue when shield takes damage
			tween(graphics, {
				tint: 0x4444FF
			}, {
				duration: 100,
				onFinish: function onFinish() {
					tween(graphics, {
						tint: 0xFFFFFF
					}, {
						duration: 100
					});
				}
			});
		} else if (self.armor > 0) {
			// Armor absorbs damage second
			self.armor -= amount;
			if (self.armor < 0) {
				// Overflow damage goes to health
				self.health += self.armor; // armor is negative, so this subtracts from health
				self.armor = 0;
			}
			if (self.health < 0) self.health = 0;
			// Flash yellow when armor takes damage
			tween(graphics, {
				tint: 0xFFDD00
			}, {
				duration: 100,
				onFinish: function onFinish() {
					tween(graphics, {
						tint: 0xFFFFFF
					}, {
						duration: 100
					});
				}
			});
		} else {
			// Normal damage to health last
			self.health -= amount;
			if (self.health < 0) self.health = 0;
			// Flash red when taking damage
			tween(graphics, {
				tint: 0xFF0000
			}, {
				duration: 100,
				onFinish: function onFinish() {
					tween(graphics, {
						tint: 0xFFFFFF
					}, {
						duration: 100
					});
				}
			});
		}
		LK.getSound('hit').play();
	};
	self.heal = function (amount) {
		self.health = Math.min(self.maxHealth, self.health + amount);
	};
	self.addDamage = function (amount) {
		self.damage += amount;
		self.weaponUpgrades++; // Track weapon upgrades
	};
	self.addSpeed = function (amount) {
		// Cap movement speed upgrades at level 25 (24 upgrades from base level 1)
		if (self.weaponUpgrades < 24) {
			self.moveSpeed += amount;
		}
	};
	self.addArmor = function (amount) {
		self.armor = Math.min(50, self.armor + amount);
	};
	self.activateNovaBlade = function () {
		if (!self.novaBladeActive) {
			self.novaBladeActive = true;
			self.novaBladeLastActivation = LK.ticks;
			self.novaBladeLevel = 1;
			self.novaBladeProximity = 300;
		} else if (self.novaBladeLevel < 50) {
			// Increase Nova blade level and proximity up to level 50
			self.novaBladeLevel++;
			self.novaBladeProximity += 10;
		}
	};
	self.activateShield = function () {
		if (!self.shieldActive) {
			// First time activation
			self.shieldActive = true;
			self.shieldHealth = 40; // Start with 40 hit points
			self.shieldDuration = 3600; // 60 seconds at 60fps
			// Create shield visual
			self.shieldAura = self.addChild(LK.getAsset('shieldAura', {
				anchorX: 0.5,
				anchorY: 0.5,
				alpha: 0.6,
				tint: 0x6666FF
			}));
		} else {
			// Shield already active, add duration up to max 180 seconds
			self.shieldDuration = Math.min(10800, self.shieldDuration + 3600); // Max 180 seconds (60 seconds per upgrade)
			// Add shield health up to max 80 hit points
			self.shieldHealth = Math.min(80, self.shieldHealth + 40);
			// Ensure shield visual is displayed
			if (!self.shieldAura) {
				self.shieldAura = self.addChild(LK.getAsset('shieldAura', {
					anchorX: 0.5,
					anchorY: 0.5,
					alpha: 0.6,
					tint: 0x6666FF
				}));
			}
		}
	};
	self.canShoot = function () {
		return LK.ticks - self.lastShootTime > self.shootCooldown;
	};
	self.shoot = function (targetX, targetY) {
		if (!self.canShoot()) return null;
		self.lastShootTime = LK.ticks;
		var bullets = [];
		var dx = targetX - self.x;
		var dy = targetY - self.y;
		var distance = Math.sqrt(dx * dx + dy * dy);
		var normalizedX = dx / distance;
		var normalizedY = dy / distance;
		var angle = Math.atan2(normalizedY, normalizedX);
		if (self.weaponUpgrades >= 49) {
			// Level 50+: Six shots in burst fire pattern (Hexa Shot)
			var offsetDistance = 30;
			var perpX = -normalizedY;
			var perpY = normalizedX;
			// First bullet (left side, front)
			var bullet1 = new Bullet();
			bullet1.x = self.x + perpX * offsetDistance;
			bullet1.y = self.y + perpY * offsetDistance;
			bullet1.velocityX = normalizedX * bullet1.speed;
			bullet1.velocityY = normalizedY * bullet1.speed;
			bullet1.damage = self.damage;
			bullets.push(bullet1);
			// Second bullet (left side, back)
			var bullet2 = new Bullet();
			bullet2.x = self.x + perpX * offsetDistance - normalizedX * 25;
			bullet2.y = self.y + perpY * offsetDistance - normalizedY * 25;
			bullet2.velocityX = normalizedX * bullet2.speed;
			bullet2.velocityY = normalizedY * bullet2.speed;
			bullet2.damage = self.damage;
			bullets.push(bullet2);
			// Third bullet (right side, front)
			var bullet3 = new Bullet();
			bullet3.x = self.x - perpX * offsetDistance;
			bullet3.y = self.y - perpY * offsetDistance;
			bullet3.velocityX = normalizedX * bullet3.speed;
			bullet3.velocityY = normalizedY * bullet3.speed;
			bullet3.damage = self.damage;
			bullets.push(bullet3);
			// Fourth bullet (right side, back)
			var bullet4 = new Bullet();
			bullet4.x = self.x - perpX * offsetDistance - normalizedX * 25;
			bullet4.y = self.y - perpY * offsetDistance - normalizedY * 25;
			bullet4.velocityX = normalizedX * bullet4.speed;
			bullet4.velocityY = normalizedY * bullet4.speed;
			bullet4.damage = self.damage;
			bullets.push(bullet4);
			// Fifth bullet (center shot)
			var bullet5 = new Bullet();
			bullet5.x = self.x;
			bullet5.y = self.y;
			bullet5.velocityX = normalizedX * bullet5.speed;
			bullet5.velocityY = normalizedY * bullet5.speed;
			bullet5.damage = self.damage;
			bullets.push(bullet5);
			// Sixth bullet (center shot, back)
			var bullet6 = new Bullet();
			bullet6.x = self.x - normalizedX * 25;
			bullet6.y = self.y - normalizedY * 25;
			bullet6.velocityX = normalizedX * bullet6.speed;
			bullet6.velocityY = normalizedY * bullet6.speed;
			bullet6.damage = self.damage;
			bullets.push(bullet6);
		} else if (self.weaponUpgrades >= 39) {
			// Level 40+: Five shots in burst fire (two double shots + center shot)
			var offsetDistance = 25;
			var perpX = -normalizedY;
			var perpY = normalizedX;
			// First bullet (left side, front)
			var bullet1 = new Bullet();
			bullet1.x = self.x + perpX * offsetDistance;
			bullet1.y = self.y + perpY * offsetDistance;
			bullet1.velocityX = normalizedX * bullet1.speed;
			bullet1.velocityY = normalizedY * bullet1.speed;
			bullet1.damage = self.damage;
			bullets.push(bullet1);
			// Second bullet (left side, back)
			var bullet2 = new Bullet();
			bullet2.x = self.x + perpX * offsetDistance - normalizedX * 20;
			bullet2.y = self.y + perpY * offsetDistance - normalizedY * 20;
			bullet2.velocityX = normalizedX * bullet2.speed;
			bullet2.velocityY = normalizedY * bullet2.speed;
			bullet2.damage = self.damage;
			bullets.push(bullet2);
			// Third bullet (right side, front)
			var bullet3 = new Bullet();
			bullet3.x = self.x - perpX * offsetDistance;
			bullet3.y = self.y - perpY * offsetDistance;
			bullet3.velocityX = normalizedX * bullet3.speed;
			bullet3.velocityY = normalizedY * bullet3.speed;
			bullet3.damage = self.damage;
			bullets.push(bullet3);
			// Fourth bullet (right side, back)
			var bullet4 = new Bullet();
			bullet4.x = self.x - perpX * offsetDistance - normalizedX * 20;
			bullet4.y = self.y - perpY * offsetDistance - normalizedY * 20;
			bullet4.velocityX = normalizedX * bullet4.speed;
			bullet4.velocityY = normalizedY * bullet4.speed;
			bullet4.damage = self.damage;
			bullets.push(bullet4);
			// Fifth bullet (center shot)
			var bullet5 = new Bullet();
			bullet5.x = self.x;
			bullet5.y = self.y;
			bullet5.velocityX = normalizedX * bullet5.speed;
			bullet5.velocityY = normalizedY * bullet5.speed;
			bullet5.damage = self.damage;
			bullets.push(bullet5);
		} else if (self.weaponUpgrades >= 29) {
			// Level 30+: Four shots in burst fire (two double shots)
			var offsetDistance = 25;
			var perpX = -normalizedY;
			var perpY = normalizedX;
			// First bullet (left side, front)
			var bullet1 = new Bullet();
			bullet1.x = self.x + perpX * offsetDistance;
			bullet1.y = self.y + perpY * offsetDistance;
			bullet1.velocityX = normalizedX * bullet1.speed;
			bullet1.velocityY = normalizedY * bullet1.speed;
			bullet1.damage = self.damage;
			bullets.push(bullet1);
			// Second bullet (left side, back)
			var bullet2 = new Bullet();
			bullet2.x = self.x + perpX * offsetDistance - normalizedX * 20;
			bullet2.y = self.y + perpY * offsetDistance - normalizedY * 20;
			bullet2.velocityX = normalizedX * bullet2.speed;
			bullet2.velocityY = normalizedY * bullet2.speed;
			bullet2.damage = self.damage;
			bullets.push(bullet2);
			// Third bullet (right side, front)
			var bullet3 = new Bullet();
			bullet3.x = self.x - perpX * offsetDistance;
			bullet3.y = self.y - perpY * offsetDistance;
			bullet3.velocityX = normalizedX * bullet3.speed;
			bullet3.velocityY = normalizedY * bullet3.speed;
			bullet3.damage = self.damage;
			bullets.push(bullet3);
			// Fourth bullet (right side, back)
			var bullet4 = new Bullet();
			bullet4.x = self.x - perpX * offsetDistance - normalizedX * 20;
			bullet4.y = self.y - perpY * offsetDistance - normalizedY * 20;
			bullet4.velocityX = normalizedX * bullet4.speed;
			bullet4.velocityY = normalizedY * bullet4.speed;
			bullet4.damage = self.damage;
			bullets.push(bullet4);
		} else if (self.weaponUpgrades >= 19) {
			// Level 20+: Triple shot (3 parallel shots)
			var offsetDistance = 15;
			var perpX = -normalizedY;
			var perpY = normalizedX;
			// Center bullet
			var bullet1 = new Bullet();
			bullet1.x = self.x;
			bullet1.y = self.y;
			bullet1.velocityX = normalizedX * bullet1.speed;
			bullet1.velocityY = normalizedY * bullet1.speed;
			bullet1.damage = self.damage;
			bullets.push(bullet1);
			// Left bullet (parallel)
			var bullet2 = new Bullet();
			bullet2.x = self.x + perpX * offsetDistance;
			bullet2.y = self.y + perpY * offsetDistance;
			bullet2.velocityX = normalizedX * bullet2.speed;
			bullet2.velocityY = normalizedY * bullet2.speed;
			bullet2.damage = self.damage;
			bullets.push(bullet2);
			// Right bullet (parallel)
			var bullet3 = new Bullet();
			bullet3.x = self.x - perpX * offsetDistance;
			bullet3.y = self.y - perpY * offsetDistance;
			bullet3.velocityX = normalizedX * bullet3.speed;
			bullet3.velocityY = normalizedY * bullet3.speed;
			bullet3.damage = self.damage;
			bullets.push(bullet3);
		} else if (self.weaponUpgrades >= 9) {
			// Level 10+: Double shot
			var offsetDistance = 20;
			var perpX = -normalizedY;
			var perpY = normalizedX;
			// First bullet (left side)
			var bullet1 = new Bullet();
			bullet1.x = self.x + perpX * offsetDistance;
			bullet1.y = self.y + perpY * offsetDistance;
			bullet1.velocityX = normalizedX * bullet1.speed;
			bullet1.velocityY = normalizedY * bullet1.speed;
			bullet1.damage = self.damage;
			bullets.push(bullet1);
			// Second bullet (right side)
			var bullet2 = new Bullet();
			bullet2.x = self.x - perpX * offsetDistance;
			bullet2.y = self.y - perpY * offsetDistance;
			bullet2.velocityX = normalizedX * bullet2.speed;
			bullet2.velocityY = normalizedY * bullet2.speed;
			bullet2.damage = self.damage;
			bullets.push(bullet2);
		} else {
			// Single shot for levels < 10
			var bullet1 = new Bullet();
			bullet1.x = self.x;
			bullet1.y = self.y;
			bullet1.velocityX = normalizedX * bullet1.speed;
			bullet1.velocityY = normalizedY * bullet1.speed;
			bullet1.damage = self.damage;
			bullets.push(bullet1);
		}
		LK.getSound('shoot').play();
		return bullets;
	};
	self.update = function () {
		// Track movement direction and animate rotation
		if (self.lastX !== undefined && self.lastY !== undefined) {
			var deltaX = self.x - self.lastX;
			var deltaY = self.y - self.lastY;
			var moveDistance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
			// Only update direction if player is actually moving
			if (moveDistance > 0.5) {
				var targetDirection = Math.atan2(deltaY, deltaX);
				// Convert to 0-360 degree system where 0 is north
				targetDirection = targetDirection + Math.PI / 2;
				if (targetDirection < 0) targetDirection += Math.PI * 2;
				if (targetDirection > Math.PI * 2) targetDirection -= Math.PI * 2;
				// Smoothly rotate to face movement direction
				var currentRotation = graphics.rotation;
				var angleDiff = targetDirection - currentRotation;
				// Handle wrap around for shortest rotation path
				if (angleDiff > Math.PI) angleDiff -= Math.PI * 2;
				if (angleDiff < -Math.PI) angleDiff += Math.PI * 2;
				// Apply smooth rotation
				var rotationSpeed = 0.15;
				graphics.rotation += angleDiff * rotationSpeed;
			}
		}
		// Update invincibility timer
		if (self.invincible) {
			self.invincibilityTimer--;
			if (self.invincibilityTimer <= 0) {
				self.invincible = false;
				// Stop any tinting when invincibility ends
				tween.stop(graphics, {
					tint: true
				});
				graphics.tint = 0xFFFFFF;
				graphics.alpha = 1.0;
			}
		}
		// Update Nova blade timer and activation
		if (self.novaBladeActive) {
			// Check if 5 seconds (300 ticks) have passed since last activation
			if (LK.ticks - self.novaBladeLastActivation >= 300) {
				// Create expanding nova blade effect
				var aura = LK.getAsset('novaBladeEffect', {
					anchorX: 0.5,
					anchorY: 0.5,
					alpha: 0.8,
					tint: 0xFF6600,
					scaleX: 0.1,
					scaleY: 0.1
				});
				self.addChild(aura);
				// Knock back all creeps within proximity radius immediately
				for (var creepIdx = 0; creepIdx < creeps.length; creepIdx++) {
					var creep = creeps[creepIdx];
					var dx = creep.x - self.x;
					var dy = creep.y - self.y;
					var distance = Math.sqrt(dx * dx + dy * dy);
					if (distance <= self.novaBladeProximity) {
						// Calculate knockback direction
						if (distance > 0) {
							var normalizedX = dx / distance;
							var normalizedY = dy / distance;
							var knockbackDistance = self.novaBladeProximity - distance + 50; // Push them outside the radius
							// Apply knockback using tween for smooth animation
							tween(creep, {
								x: creep.x + normalizedX * knockbackDistance,
								y: creep.y + normalizedY * knockbackDistance
							}, {
								duration: 500,
								easing: tween.easeOut
							});
						}
					}
				}
				// Animate aura expansion from proximity 10 to current Nova blade proximity level
				var maxScale = self.novaBladeProximity / 80; // Convert proximity to scale (80 is base aura size)
				tween(aura, {
					scaleX: maxScale,
					scaleY: maxScale,
					alpha: 0.0
				}, {
					duration: 1000,
					easing: tween.easeOut,
					onFinish: function onFinish() {
						aura.destroy();
					}
				});
				// Reset timer for next activation
				self.novaBladeLastActivation = LK.ticks;
			}
		}
		// Update last position for next frame
		self.lastX = self.x;
		self.lastY = self.y;
	};
	return self;
});
var SpecialCreep = Container.expand(function () {
	var self = Container.call(this);
	var graphics = self.attachAsset('specialCreep', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.health = 450; // Three times elite creep health (150 * 3)
	self.maxHealth = 450;
	self.speed = 2.8; // Slightly faster than regular creeps (2.4)
	self.damage = 40; // Between regular and elite creep damage
	self.targetX = 0;
	self.targetY = 0;
	self.hasReachedPlayer = false;
	self.takeDamage = function (amount) {
		self.health -= amount;
		if (self.health <= 0) {
			return true; // Return true if creep is dead
		}
		return false;
	};
	self.update = function () {
		// Reset flag to allow continued movement after hitting player
		self.hasReachedPlayer = false;
		// Continuously update target to player's current position
		self.targetX = player.x;
		self.targetY = player.y;
		var dx = self.targetX - self.x;
		var dy = self.targetY - self.y;
		var distance = Math.sqrt(dx * dx + dy * dy);
		if (distance > 25) {
			// Calculate avoidance force from other creeps
			var avoidanceX = 0;
			var avoidanceY = 0;
			var avoidanceRadius = 200; // Medium avoidance radius between regular and elite
			for (var i = 0; i < creeps.length; i++) {
				var otherCreep = creeps[i];
				if (otherCreep !== self) {
					var otherDx = self.x - otherCreep.x;
					var otherDy = self.y - otherCreep.y;
					var otherDistance = Math.sqrt(otherDx * otherDx + otherDy * otherDy);
					if (otherDistance < avoidanceRadius && otherDistance > 0) {
						var avoidanceStrength = (avoidanceRadius - otherDistance) / avoidanceRadius;
						avoidanceX += otherDx / otherDistance * avoidanceStrength;
						avoidanceY += otherDy / otherDistance * avoidanceStrength;
					}
				}
			}
			// Combine movement towards player with avoidance
			var moveX = dx / distance * self.speed + avoidanceX * 0.5;
			var moveY = dy / distance * self.speed + avoidanceY * 0.5;
			self.x += moveX;
			self.y += moveY;
		} else {
			self.hasReachedPlayer = true;
		}
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	title: 'Galaxy Of Terror'
});
/**** 
* Game Code
****/ 
// Add background image
var background = game.addChild(LK.getAsset('background', {
	anchorX: 0,
	anchorY: 0,
	x: 0,
	y: 0
}));
// Game state variables
var gameStarted = false;
var startScreen = null;
// Create start screen
function createStartScreen() {
	startScreen = new Container();
	game.addChild(startScreen);
	// Start screen background
	var startBg = startScreen.addChild(LK.getAsset('startBackground', {
		anchorX: 0,
		anchorY: 0,
		x: 0,
		y: 0,
		alpha: 0.9,
		tint: 0x001122
	}));
	// Game title
	var titleText = new Text2('GALAXY OF TERROR', {
		size: 120,
		fill: 0xFFD700
	});
	titleText.anchor.set(0.5, 0.5);
	titleText.x = 1024;
	titleText.y = 800;
	startScreen.addChild(titleText);
	// Subtitle
	var subtitleText = new Text2('Survive the endless waves', {
		size: 60,
		fill: 0xFFFFFF
	});
	subtitleText.anchor.set(0.5, 0.5);
	subtitleText.x = 1024;
	subtitleText.y = 920;
	startScreen.addChild(subtitleText);
	// Play button background
	var playButton = startScreen.addChild(LK.getAsset('startButton', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: 1024,
		y: 1200,
		scaleX: 1.5,
		scaleY: 1.2,
		tint: 0x00AA44
	}));
	// Play button text
	var playButtonText = new Text2('TAP TO PLAY', {
		size: 80,
		fill: 0xFFFFFF
	});
	playButtonText.anchor.set(0.5, 0.5);
	playButtonText.x = 1024;
	playButtonText.y = 1200;
	startScreen.addChild(playButtonText);
	// Instructions
	var instructText = new Text2('Tap and drag to move\nAutomatic shooting', {
		size: 50,
		fill: 0xCCCCCC
	});
	instructText.anchor.set(0.5, 0.5);
	instructText.x = 1024;
	instructText.y = 1400;
	startScreen.addChild(instructText);
	// Handle start screen input
	startScreen.down = function (x, y, obj) {
		// Check if clicked on play button area
		var buttonDx = x - 1024;
		var buttonDy = y - 1200;
		var buttonDistance = Math.sqrt(buttonDx * buttonDx + buttonDy * buttonDy);
		if (buttonDistance < 150) {
			startGame();
		}
	};
}
function startGame() {
	if (startScreen) {
		startScreen.destroy();
		startScreen = null;
	}
	gameStarted = true;
	// Initialize player after game starts
	player = game.addChild(new Player());
	player.x = 1024;
	player.y = 1366;
}
// Initialize start screen
createStartScreen();
var player = null;
var creeps = [];
var bullets = [];
var bossBullets = [];
var pickups = [];
var currentWave = 1;
var creepsInWave = 5;
var creepsSpawned = 0;
var eliteCreepsInWave = 1; // Number of elite creeps equals wave number
var eliteCreepsSpawned = 0;
var specialCreepsInWave = 0; // Special creeps spawn on specific waves
var specialCreepsSpawned = 0;
var waveCompleted = false;
var nextWaveTimer = 0;
var spawnTimer = 0;
// Score tracking variables
var gameScore = 0;
// Boss system variables
var currentBoss = null;
var bossWave = false;
// Speed modifier for creeps - increases 1% every 5th wave
var creepSpeedMultiplier = 1.0;
// Track special 5th wave speed upgrade drops
var fifthWaveSpeedUpgradeDropped = false;
// Track upgrade drops per wave
var waveUpgradeDrops = {};
// UI Elements
var healthText = new Text2('Health: 100', {
	size: 40,
	fill: 0xFF0000
});
healthText.anchor.set(0, 0);
LK.gui.topLeft.addChild(healthText);
healthText.x = 120; // Offset from left edge
var armorText = new Text2('Armor: 0', {
	size: 40,
	fill: 0x00FF00
});
armorText.anchor.set(0, 0);
LK.gui.topLeft.addChild(armorText);
armorText.x = 120; // Offset from left edge
armorText.y = 45; // Below health text
var waveText = new Text2('Wave: 1', {
	size: 40,
	fill: 0xFFD700
});
waveText.anchor.set(0.5, 0);
LK.gui.top.addChild(waveText);
var weaponLevelText = new Text2('Weapon Level: 1', {
	size: 40,
	fill: 0xFFFFFF
});
weaponLevelText.anchor.set(1, 0);
LK.gui.topRight.addChild(weaponLevelText);
var weaponTypeText = new Text2('Blaster', {
	size: 40,
	fill: 0xFFFFFF
});
weaponTypeText.anchor.set(1, 0);
weaponTypeText.y = 45; // Position below weapon level text
LK.gui.topRight.addChild(weaponTypeText);
// Nova blade level text
var novaBladeText = new Text2('', {
	size: 40,
	fill: 0xFF6600
});
novaBladeText.anchor.set(1, 0);
novaBladeText.y = 90; // Position below weapon type text
LK.gui.topRight.addChild(novaBladeText);
// Score counter text
var scoreText = new Text2('Score: 0', {
	size: 40,
	fill: 0xFF1493 // Bright pink color
});
scoreText.anchor.set(1, 0);
scoreText.y = 135; // Position below Nova blade level text
LK.gui.topRight.addChild(scoreText);
// Boss health bar (initially hidden)
var bossHealthBar = new Text2('', {
	size: 35,
	fill: 0xFF4444
});
bossHealthBar.anchor.set(0.5, 0);
LK.gui.top.addChild(bossHealthBar);
bossHealthBar.y = 50;
bossHealthBar.alpha = 0; // Hidden initially
// Shield status text
var shieldText = new Text2('', {
	size: 35,
	fill: 0x4444FF
});
shieldText.anchor.set(0, 0);
LK.gui.topLeft.addChild(shieldText);
shieldText.x = 120; // Offset from left edge
shieldText.y = 90; // Below armor text
// Player will be initialized when game starts
function spawnCreep() {
	var creep = new Creep();
	// Spawn from random edge
	var side = Math.floor(Math.random() * 4);
	switch (side) {
		case 0:
			// Top
			creep.x = Math.random() * 2048;
			creep.y = -50;
			break;
		case 1:
			// Right
			creep.x = 2098;
			creep.y = Math.random() * 2732;
			break;
		case 2:
			// Bottom
			creep.x = Math.random() * 2048;
			creep.y = 2782;
			break;
		case 3:
			// Left
			creep.x = -50;
			creep.y = Math.random() * 2732;
			break;
	}
	creep.targetX = player.x;
	creep.targetY = player.y;
	creep.health += (currentWave - 1) * 20; // Scale health with wave (20 per wave)
	// Apply 50% health increase every 5th wave
	var healthMultiplier = 1 + Math.floor(currentWave / 5) * 0.5;
	creep.health = Math.floor(creep.health * healthMultiplier);
	creep.maxHealth = creep.health;
	// Apply speed increase - 1% for every 5th wave
	var speedMultiplier = 1 + Math.floor(currentWave / 5) * 0.01;
	// Apply extra 2% speed increase per wave after wave 15
	if (currentWave > 15) {
		var extraSpeedMultiplier = 1 + (currentWave - 15) * 0.02;
		speedMultiplier *= extraSpeedMultiplier;
	}
	creep.speed = creep.speed * speedMultiplier;
	creeps.push(creep);
	game.addChild(creep);
}
function spawnEliteCreep() {
	var eliteCreep = new EliteCreep();
	// Spawn from random edge
	var side = Math.floor(Math.random() * 4);
	switch (side) {
		case 0:
			// Top
			eliteCreep.x = Math.random() * 2048;
			eliteCreep.y = -50;
			break;
		case 1:
			// Right
			eliteCreep.x = 2098;
			eliteCreep.y = Math.random() * 2732;
			break;
		case 2:
			// Bottom
			eliteCreep.x = Math.random() * 2048;
			eliteCreep.y = 2782;
			break;
		case 3:
			// Left
			eliteCreep.x = -50;
			eliteCreep.y = Math.random() * 2732;
			break;
	}
	eliteCreep.targetX = player.x;
	eliteCreep.targetY = player.y;
	eliteCreep.health += (currentWave - 1) * 40; // Scale health with wave (40 per wave for elites)
	// Apply 50% health increase every 5th wave
	var healthMultiplier = 1 + Math.floor(currentWave / 5) * 0.5;
	eliteCreep.health = Math.floor(eliteCreep.health * healthMultiplier);
	eliteCreep.maxHealth = eliteCreep.health;
	// Apply speed increase - 1% for every 5th wave
	var speedMultiplier = 1 + Math.floor(currentWave / 5) * 0.01;
	// Apply extra 2% speed increase per wave after wave 15
	if (currentWave > 15) {
		var extraSpeedMultiplier = 1 + (currentWave - 15) * 0.02;
		speedMultiplier *= extraSpeedMultiplier;
	}
	eliteCreep.speed = eliteCreep.speed * speedMultiplier;
	creeps.push(eliteCreep);
	game.addChild(eliteCreep);
}
function spawnSpecialCreep() {
	var specialCreep = new SpecialCreep();
	// Spawn from random edge
	var side = Math.floor(Math.random() * 4);
	switch (side) {
		case 0:
			// Top
			specialCreep.x = Math.random() * 2048;
			specialCreep.y = -50;
			break;
		case 1:
			// Right
			specialCreep.x = 2098;
			specialCreep.y = Math.random() * 2732;
			break;
		case 2:
			// Bottom
			specialCreep.x = Math.random() * 2048;
			specialCreep.y = 2782;
			break;
		case 3:
			// Left
			specialCreep.x = -50;
			specialCreep.y = Math.random() * 2732;
			break;
	}
	specialCreep.targetX = player.x;
	specialCreep.targetY = player.y;
	specialCreep.health += (currentWave - 1) * 60; // Scale health with wave (60 per wave for special creeps)
	// Apply 50% health increase every 5th wave
	var healthMultiplier = 1 + Math.floor(currentWave / 5) * 0.5;
	specialCreep.health = Math.floor(specialCreep.health * healthMultiplier);
	specialCreep.maxHealth = specialCreep.health;
	// Apply speed increase - 1% for every 5th wave
	var speedMultiplier = 1 + Math.floor(currentWave / 5) * 0.01;
	// Apply extra 2% speed increase per wave after wave 15
	if (currentWave > 15) {
		var extraSpeedMultiplier = 1 + (currentWave - 15) * 0.02;
		speedMultiplier *= extraSpeedMultiplier;
	}
	specialCreep.speed = specialCreep.speed * speedMultiplier;
	creeps.push(specialCreep);
	game.addChild(specialCreep);
}
function spawnBoss() {
	var boss = new BossCreep();
	// Spawn from random edge
	var side = Math.floor(Math.random() * 4);
	switch (side) {
		case 0:
			// Top
			boss.x = Math.random() * 2048;
			boss.y = -75;
			break;
		case 1:
			// Right
			boss.x = 2123;
			boss.y = Math.random() * 2732;
			break;
		case 2:
			// Bottom
			boss.x = Math.random() * 2048;
			boss.y = 2807;
			break;
		case 3:
			// Left
			boss.x = -75;
			boss.y = Math.random() * 2732;
			break;
	}
	boss.targetX = player.x;
	boss.targetY = player.y;
	// Calculate boss health - starts at 12000, increases by 50% after first boss fight (wave 10)
	var bossNumber = Math.floor(currentWave / 10);
	if (bossNumber === 1) {
		// First boss fight on wave 10
		boss.health = 12000;
	} else {
		// Every boss fight after wave 10 gets 50% more health than previous
		boss.health = 12000 * Math.pow(1.5, bossNumber - 1);
	}
	// Apply 50% health increase every 5th wave
	var healthMultiplier = 1 + Math.floor(currentWave / 5) * 0.5;
	boss.health = Math.floor(boss.health * healthMultiplier);
	boss.maxHealth = boss.health;
	currentBoss = boss;
	creeps.push(boss);
	game.addChild(boss);
	// Show boss health bar
	bossHealthBar.alpha = 1;
	tween(bossHealthBar, {
		scaleX: 1.1,
		scaleY: 1.1
	}, {
		duration: 300,
		easing: tween.easeOut,
		onFinish: function onFinish() {
			tween(bossHealthBar, {
				scaleX: 1.0,
				scaleY: 1.0
			}, {
				duration: 200
			});
		}
	});
}
function createExplosionEffect(x, y) {
	var explosion = LK.getAsset('explosion', {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 0.1,
		scaleY: 0.1,
		alpha: 1.0,
		tint: 0xFF4400 // Orange flame color
	});
	explosion.x = x;
	explosion.y = y;
	game.addChild(explosion);
	// Stage 1: Rapid expansion with orange flames
	tween(explosion, {
		scaleX: 2.0,
		scaleY: 2.0,
		tint: 0xFF6600,
		// Brighter orange
		alpha: 0.9
	}, {
		duration: 150,
		easing: tween.easeOut,
		onFinish: function onFinish() {
			// Stage 2: Peak explosion with bright red
			tween(explosion, {
				scaleX: 3.0,
				scaleY: 3.0,
				tint: 0xFF0000,
				// Bright red
				alpha: 0.8
			}, {
				duration: 100,
				easing: tween.easeOut,
				onFinish: function onFinish() {
					// Stage 3: Fade to dark red and shrink
					tween(explosion, {
						scaleX: 0.5,
						scaleY: 0.5,
						tint: 0x660000,
						// Dark red
						alpha: 0.0
					}, {
						duration: 250,
						easing: tween.easeIn,
						onFinish: function onFinish() {
							explosion.destroy();
						}
					});
				}
			});
		}
	});
}
function dropPickup(x, y, isEliteCreep) {
	// Check for special 5th wave speed upgrade drop first
	var isFifthWave = currentWave % 5 === 0;
	if (isFifthWave && !fifthWaveSpeedUpgradeDropped && player.weaponUpgrades < 9) {
		// 50% chance for speed upgrade on 5th wave (only once per wave)
		if (Math.random() < 0.5) {
			var speedPickup = new Pickup('speed');
			speedPickup.x = x;
			speedPickup.y = y;
			pickups.push(speedPickup);
			game.addChild(speedPickup);
			fifthWaveSpeedUpgradeDropped = true;
			return; // Exit early, no other drops this time
		}
	}
	// 25% chance to drop random upgrades (normal drops)
	if (Math.random() < 0.25) {
		var upgradeTypes = [];
		// Check wave-based upgrade limits
		var shieldDropsThisWave = waveUpgradeDrops.shield || 0;
		var weaponDropsThisWave = waveUpgradeDrops.weapon || 0;
		var speedDropsThisWave = waveUpgradeDrops.speed || 0;
		var armorDropsThisWave = waveUpgradeDrops.armor || 0;
		var healthDropsThisWave = waveUpgradeDrops.health || 0;
		// Shield upgrades: limited to 2 per wave with 15% drop chance
		if (shieldDropsThisWave < 2 && Math.random() < 0.15) {
			upgradeTypes.push('shield');
		}
		// Speed upgrades now have 5% chance and only if player speed level is below 10 and limit 1 per wave
		if (player.weaponUpgrades < 9 && speedDropsThisWave < 1 && Math.random() < 0.05) {
			upgradeTypes.push('speed');
		}
		// Only elite creeps and special creeps can drop health potions and armor upgrades, limited to 1 per wave each
		if (isEliteCreep) {
			if (healthDropsThisWave < 1 && Math.random() < 0.10) {
				upgradeTypes.push('health');
			}
			if (armorDropsThisWave < 1 && Math.random() < 0.10) {
				upgradeTypes.push('armor');
			}
		}
		// Only add damage upgrades if weapon has not reached maximum level and limit 2 per wave
		if (player.weaponUpgrades < 49 && weaponDropsThisWave < 2) {
			upgradeTypes.push('damage');
		}
		// Only add novaBlade to upgrade types if weapon has reached maximum level (50) with 25% chance and limit 2 per wave
		if (player.weaponUpgrades >= 49 && weaponDropsThisWave < 2 && Math.random() < 0.25) {
			// weaponUpgrades is 0-based, so 49 = level 50
			upgradeTypes.push('novaBlade');
		}
		// Only proceed if we have upgrade types available
		if (upgradeTypes.length > 0) {
			var randomType = upgradeTypes[Math.floor(Math.random() * upgradeTypes.length)];
			var pickup = new Pickup(randomType);
			pickup.x = x;
			pickup.y = y;
			pickups.push(pickup);
			game.addChild(pickup);
			// Track upgrade drops for this wave
			if (randomType === 'shield') {
				waveUpgradeDrops.shield = (waveUpgradeDrops.shield || 0) + 1;
			} else if (randomType === 'damage') {
				waveUpgradeDrops.weapon = (waveUpgradeDrops.weapon || 0) + 1;
			} else if (randomType === 'speed') {
				waveUpgradeDrops.speed = (waveUpgradeDrops.speed || 0) + 1;
			} else if (randomType === 'armor') {
				waveUpgradeDrops.armor = (waveUpgradeDrops.armor || 0) + 1;
			} else if (randomType === 'health') {
				waveUpgradeDrops.health = (waveUpgradeDrops.health || 0) + 1;
			} else if (randomType === 'novaBlade') {
				waveUpgradeDrops.weapon = (waveUpgradeDrops.weapon || 0) + 1;
			}
		}
	}
}
function startNextWave() {
	currentWave++;
	// Reset 5th wave speed upgrade flag for new wave
	fifthWaveSpeedUpgradeDropped = false;
	// Reset wave upgrade drop counters
	waveUpgradeDrops = {};
	// Check if this is a boss wave (every 10th wave)
	if (currentWave % 10 === 0) {
		bossWave = true;
		creepsInWave = 0; // No regular creeps on boss waves
		eliteCreepsInWave = 0; // No elite creeps on boss waves
		specialCreepsInWave = 0; // No special creeps on boss waves
	} else {
		bossWave = false;
		creepsInWave = 8 + Math.floor(currentWave * 2.5); // More creeps per wave
		// Add 2 extra creeps for every wave after wave 1
		if (currentWave > 1) {
			creepsInWave += 2;
		}
		eliteCreepsInWave = currentWave; // Number of elite creeps equals wave number
		// Special creeps spawn on waves 9, 19, 29, 39, etc. (one before each boss wave)
		if ((currentWave + 1) % 10 === 0 && currentWave >= 9) {
			// Calculate how many special creeps to spawn based on wave
			// Wave 9: 1 special creep, Wave 19: 2 special creeps, etc.
			specialCreepsInWave = Math.floor((currentWave + 1) / 10);
		} else {
			specialCreepsInWave = 0;
		}
	}
	creepsSpawned = 0;
	eliteCreepsSpawned = 0;
	specialCreepsSpawned = 0;
	waveCompleted = false;
	waveText.setText('Wave: ' + currentWave + (bossWave ? ' (BOSS)' : ''));
}
// Player movement variables
var targetX = 1024;
var targetY = 1366;
var isMoving = false;
game.down = function (x, y, obj) {
	if (!gameStarted) return;
	targetX = x;
	targetY = y;
	isMoving = true;
};
game.move = function (x, y, obj) {
	if (!gameStarted) return;
	if (isMoving) {
		targetX = x;
		targetY = y;
	}
};
game.up = function (x, y, obj) {
	if (!gameStarted) return;
	isMoving = false;
};
game.update = function () {
	// Don't update game logic until game has started
	if (!gameStarted) return;
	// Process pickups FIRST to ensure upgrades always activate before any damage
	for (var i = pickups.length - 1; i >= 0; i--) {
		var pickup = pickups[i];
		// Check pickup collection using both intersection and distance
		var dx = pickup.x - player.x;
		var dy = pickup.y - player.y;
		var distance = Math.sqrt(dx * dx + dy * dy);
		// Only player radius can pick up upgrades (Nova field does not interfere)
		var collected = pickup.intersects(player) || distance < 50;
		if (collected) {
			// Immediately activate upgrade effect and calculate points
			var pickupPoints = 150; // Default points
			switch (pickup.type) {
				case 'health':
					// Check if player is at full health before healing
					var wasAtFullHealth = player.health >= player.maxHealth;
					player.heal(50); // Boss health potions heal 50 hit points
					// Double points if player was at full health when picking up health potion
					if (wasAtFullHealth) {
						pickupPoints = 300;
					}
					break;
				case 'damage':
					player.addDamage(5);
					break;
				case 'speed':
					player.addSpeed(1);
					break;
				case 'shield':
					player.activateShield();
					break;
				case 'armor':
					// Check if player is at full armor before adding armor
					var wasAtFullArmor = player.armor >= player.maxArmor;
					player.addArmor(10); // Armor upgrade gives 10 armor points
					// Double points if player was at full armor when picking up armor upgrade
					if (wasAtFullArmor) {
						pickupPoints = 300;
					}
					break;
				case 'novaBlade':
					player.activateNovaBlade();
					break;
			}
			// Give points for collecting upgrades
			gameScore += pickupPoints;
			LK.setScore(LK.getScore() + pickupPoints);
			LK.getSound('pickup').play();
			pickup.destroy();
			pickups.splice(i, 1);
		} else if (pickup.lifetime <= 0) {
			pickup.destroy();
			pickups.splice(i, 1);
		}
	}
	// Player movement
	if (isMoving) {
		var dx = targetX - player.x;
		var dy = targetY - player.y;
		var distance = Math.sqrt(dx * dx + dy * dy);
		if (distance > 25) {
			player.x += dx / distance * player.moveSpeed;
			player.y += dy / distance * player.moveSpeed;
		}
	}
	// Automatic shooting at closest creep
	if (creeps.length > 0 && player.canShoot()) {
		var closestCreep = null;
		var closestDistance = Infinity;
		for (var i = 0; i < creeps.length; i++) {
			var creep = creeps[i];
			var dx = creep.x - player.x;
			var dy = creep.y - player.y;
			var distance = Math.sqrt(dx * dx + dy * dy);
			if (distance < closestDistance) {
				closestDistance = distance;
				closestCreep = creep;
			}
		}
		if (closestCreep) {
			var shotBullets = player.shoot(closestCreep.x, closestCreep.y);
			if (shotBullets) {
				for (var k = 0; k < shotBullets.length; k++) {
					bullets.push(shotBullets[k]);
					game.addChild(shotBullets[k]);
				}
			}
		}
	}
	// Update shield system
	if (player.shieldActive) {
		player.shieldDuration--;
		if (player.shieldDuration <= 0 || player.shieldHealth <= 0) {
			player.shieldActive = false;
			player.shieldHealth = 0;
			player.shieldDuration = 0;
			if (player.shieldAura) {
				player.shieldAura.destroy();
				player.shieldAura = null;
			}
		} else if (player.shieldAura) {
			// Animate shield aura
			player.shieldAura.rotation += 0.05;
			// Flash when shield is about to expire (last 5 seconds)
			if (player.shieldDuration < 300) {
				player.shieldAura.alpha = 0.3 + 0.3 * Math.sin(LK.ticks * 0.3);
			}
		}
	}
	// Update player health display
	healthText.setText('Health: ' + player.health);
	armorText.setText('Armor: ' + player.armor);
	// Display weapon level or max level indicator
	var weaponLevel = player.weaponUpgrades + 1;
	if (weaponLevel >= 50) {
		weaponLevelText.setText('Weapon Level: Max Level');
	} else {
		weaponLevelText.setText('Weapon Level: ' + weaponLevel);
	}
	// Update weapon type display based on level
	var weaponLevel = player.weaponUpgrades + 1;
	var weaponType = 'Blaster';
	if (weaponLevel >= 50) {
		weaponType = 'Hexa Shot';
	} else if (weaponLevel >= 40) {
		weaponType = 'Penta Shot';
	} else if (weaponLevel >= 30) {
		weaponType = 'Quad Shot';
	} else if (weaponLevel >= 20) {
		weaponType = 'Triple Shot';
	} else if (weaponLevel >= 10) {
		weaponType = 'Double Shot';
	}
	weaponTypeText.setText(weaponType);
	// Update Nova blade level display
	if (player.novaBladeActive && player.novaBladeLevel > 0) {
		if (player.novaBladeLevel >= 50) {
			novaBladeText.setText('Nova Field Level Max Level');
		} else {
			novaBladeText.setText('Nova Field Level ' + player.novaBladeLevel);
		}
	} else {
		novaBladeText.setText('');
	}
	// Update score display
	scoreText.setText('Score: ' + gameScore);
	// Update shield display
	if (player.shieldActive) {
		var shieldTimeLeft = Math.ceil(player.shieldDuration / 60);
		shieldText.setText('Shield: ' + player.shieldHealth + '/' + player.shieldMaxHealth + ' (' + shieldTimeLeft + 's)');
	} else {
		shieldText.setText('');
	}
	// Update boss health bar
	if (currentBoss && bossHealthBar.alpha > 0) {
		var healthPercent = Math.round(currentBoss.health / currentBoss.maxHealth * 100);
		bossHealthBar.setText('BOSS: ' + currentBoss.health + '/' + currentBoss.maxHealth + ' (' + healthPercent + '%)');
	}
	// Check game over
	if (player.health <= 0) {
		// Create explosion effect - player explodes in flames
		var playerGraphics = player.children[0]; // Get player graphics
		// Create flame explosion effect with multiple tween stages
		tween(playerGraphics, {
			scaleX: 2.0,
			scaleY: 2.0,
			tint: 0xFF4400,
			// Orange flame color
			alpha: 1.0
		}, {
			duration: 200,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				// Second stage - bright red explosion
				tween(playerGraphics, {
					scaleX: 3.0,
					scaleY: 3.0,
					tint: 0xFF0000,
					// Bright red
					alpha: 0.8
				}, {
					duration: 150,
					easing: tween.easeOut,
					onFinish: function onFinish() {
						// Final stage - fade to black and shrink
						tween(playerGraphics, {
							scaleX: 0.1,
							scaleY: 0.1,
							tint: 0x000000,
							// Black
							alpha: 0.0
						}, {
							duration: 300,
							easing: tween.easeInOut,
							onFinish: function onFinish() {
								// Show game over after explosion completes
								LK.showGameOver();
							}
						});
					}
				});
			}
		});
		return;
	}
	// Wave management
	if (!waveCompleted) {
		if (bossWave) {
			// Boss wave logic
			if (!currentBoss && creeps.length === 0) {
				spawnBoss();
			}
			// Check if boss wave is complete
			if (currentBoss && creeps.length === 0) {
				waveCompleted = true;
				nextWaveTimer = 180; // 3 second break
				currentBoss = null;
				// Hide boss health bar
				tween(bossHealthBar, {
					alpha: 0
				}, {
					duration: 500
				});
			}
		} else {
			// Regular wave logic
			// Spawn creeps
			if (creepsSpawned < creepsInWave || eliteCreepsSpawned < eliteCreepsInWave || specialCreepsSpawned < specialCreepsInWave) {
				spawnTimer++;
				if (spawnTimer >= 60) {
					// Spawn every second
					if (creepsSpawned < creepsInWave) {
						spawnCreep();
						creepsSpawned++;
					} else if (eliteCreepsSpawned < eliteCreepsInWave) {
						spawnEliteCreep();
						eliteCreepsSpawned++;
					} else if (specialCreepsSpawned < specialCreepsInWave) {
						spawnSpecialCreep();
						specialCreepsSpawned++;
					}
					spawnTimer = 0;
				}
			}
			// Check if wave is complete
			if (creepsSpawned >= creepsInWave && eliteCreepsSpawned >= eliteCreepsInWave && specialCreepsSpawned >= specialCreepsInWave && creeps.length === 0) {
				waveCompleted = true;
				nextWaveTimer = 180; // 3 second break
			}
		}
	} else {
		nextWaveTimer--;
		if (nextWaveTimer <= 0) {
			startNextWave();
		}
	}
	// Update boss bullets
	for (var i = bossBullets.length - 1; i >= 0; i--) {
		var bossBullet = bossBullets[i];
		// Check if boss bullet is off screen
		if (bossBullet.x < -50 || bossBullet.x > 2098 || bossBullet.y < -50 || bossBullet.y > 2782) {
			bossBullet.destroy();
			bossBullets.splice(i, 1);
			continue;
		}
		// Check boss bullet collision with player using base player radius only
		var bulletDx = bossBullet.x - player.x;
		var bulletDy = bossBullet.y - player.y;
		var bulletDistance = Math.sqrt(bulletDx * bulletDx + bulletDy * bulletDy);
		// Use player's base radius (55 pixels) regardless of Nova Field status
		if (bulletDistance < 55) {
			player.takeDamage(bossBullet.damage);
			bossBullet.destroy();
			bossBullets.splice(i, 1);
		}
	}
	// Update bullets
	for (var i = bullets.length - 1; i >= 0; i--) {
		var bullet = bullets[i];
		// Check if bullet is off screen
		if (bullet.x < -50 || bullet.x > 2098 || bullet.y < -50 || bullet.y > 2782) {
			bullet.destroy();
			bullets.splice(i, 1);
			continue;
		}
		// Check bullet-creep collisions
		var hitCreep = false;
		for (var j = creeps.length - 1; j >= 0; j--) {
			var creep = creeps[j];
			if (bullet.intersects(creep)) {
				var isDead = creep.takeDamage(bullet.damage);
				if (isDead) {
					// Create explosion effect at creep position
					createExplosionEffect(creep.x, creep.y);
					// Play explosion sound
					LK.getSound('explosion').play();
					// Give points for killing creeps
					var scoreValue;
					if (creep instanceof BossCreep) {
						scoreValue = 10000; // High score for boss
						// Clean up spawned creeps when boss dies
						for (var spawnIdx = creep.spawnedCreeps.length - 1; spawnIdx >= 0; spawnIdx--) {
							var spawnedCreep = creep.spawnedCreeps[spawnIdx];
							if (spawnedCreep) {
								// Find and remove from creeps array
								var creepIndex = creeps.indexOf(spawnedCreep);
								if (creepIndex !== -1) {
									spawnedCreep.destroy();
									creeps.splice(creepIndex, 1);
								}
							}
						}
						// Boss drops one speed upgrade, one armor upgrade, one health potion upgrade, and one weapon upgrade
						var speedPickup = new Pickup('speed');
						speedPickup.x = creep.x - 52.5; // Position far left with 35px spacing
						speedPickup.y = creep.y;
						pickups.push(speedPickup);
						game.addChild(speedPickup);
						var armorPickup = new Pickup('armor');
						armorPickup.x = creep.x - 17.5; // Position left of center with 35px spacing
						armorPickup.y = creep.y;
						pickups.push(armorPickup);
						game.addChild(armorPickup);
						var healthPickup = new Pickup('health');
						healthPickup.x = creep.x + 17.5; // Position right of center with 35px spacing
						healthPickup.y = creep.y;
						pickups.push(healthPickup);
						game.addChild(healthPickup);
						// Check player weapon level to determine weapon upgrade type
						var weaponPickup;
						if (player.weaponUpgrades >= 49) {
							// Replace weapon upgrade with nova blade upgrade if player is at level 50
							weaponPickup = new Pickup('novaBlade');
						} else {
							weaponPickup = new Pickup('damage');
						}
						weaponPickup.x = creep.x + 52.5; // Position far right with 35px spacing
						weaponPickup.y = creep.y;
						pickups.push(weaponPickup);
						game.addChild(weaponPickup);
					} else if (creep instanceof SpecialCreep) {
						scoreValue = 300; // Higher score for special creeps
					} else if (creep instanceof EliteCreep) {
						scoreValue = 200;
						// Elite creep upgrade drop chance reset to 0%
					} else {
						scoreValue = 100;
					}
					gameScore += scoreValue;
					LK.setScore(LK.getScore() + scoreValue);
					if (!(creep instanceof BossCreep)) {
						dropPickup(creep.x, creep.y, creep instanceof EliteCreep || creep instanceof SpecialCreep);
					}
					creep.destroy();
					creeps.splice(j, 1);
				}
				bullet.destroy();
				bullets.splice(i, 1);
				hitCreep = true;
				break;
			}
		}
	}
	// Nova blade damage dealing
	if (player.novaBladeActive && LK.ticks - player.novaBladeLastActivation >= 300) {
		// Check if any aura is currently active by checking for expanding aura
		var playerChildren = player.children;
		var auraActive = false;
		for (var childIdx = 0; childIdx < playerChildren.length; childIdx++) {
			var child = playerChildren[childIdx];
			// Check if this is an expanding aura (scale > 1.0 indicates expansion)
			if (child.tint === 0xFF6600 && child.scaleX > 1.0) {
				auraActive = true;
				var auraRadius = player.novaBladeProximity; // Use dynamic proximity range
				// Push all creeps away from player when Nova blade is active
				for (var creepIdx = creeps.length - 1; creepIdx >= 0; creepIdx--) {
					var creep = creeps[creepIdx];
					var dx = creep.x - player.x;
					var dy = creep.y - player.y;
					var distance = Math.sqrt(dx * dx + dy * dy);
					if (distance <= auraRadius) {
						// Push creep away from player
						if (distance > 0) {
							var normalizedPushX = dx / distance;
							var normalizedPushY = dy / distance;
							var pushStrength = 50; // Strong push away from Nova blade
							tween(creep, {
								x: creep.x + normalizedPushX * pushStrength,
								y: creep.y + normalizedPushY * pushStrength
							}, {
								duration: 300,
								easing: tween.easeOut
							});
						}
						var isDead = creep.takeDamage(25); // Fixed 25 damage
						if (isDead) {
							// Create explosion effect at creep position
							createExplosionEffect(creep.x, creep.y);
							// Play explosion sound
							LK.getSound('explosion').play();
							// Give points for killing creeps with Nova blade
							var scoreValue;
							if (creep instanceof BossCreep) {
								scoreValue = 10000;
								// Clean up spawned creeps when boss dies
								for (var spawnIdx = creep.spawnedCreeps.length - 1; spawnIdx >= 0; spawnIdx--) {
									var spawnedCreep = creep.spawnedCreeps[spawnIdx];
									if (spawnedCreep) {
										var creepIndex = creeps.indexOf(spawnedCreep);
										if (creepIndex !== -1) {
											spawnedCreep.destroy();
											creeps.splice(creepIndex, 1);
										}
									}
								}
								// Boss drops one speed upgrade, one armor upgrade, one health potion upgrade, and one weapon upgrade
								var speedPickup = new Pickup('speed');
								speedPickup.x = creep.x - 52.5; // Position far left with 35px spacing
								speedPickup.y = creep.y;
								pickups.push(speedPickup);
								game.addChild(speedPickup);
								var armorPickup = new Pickup('armor');
								armorPickup.x = creep.x - 17.5; // Position left of center with 35px spacing
								armorPickup.y = creep.y;
								pickups.push(armorPickup);
								game.addChild(armorPickup);
								var healthPickup = new Pickup('health');
								healthPickup.x = creep.x + 17.5; // Position right of center with 35px spacing
								healthPickup.y = creep.y;
								pickups.push(healthPickup);
								game.addChild(healthPickup);
								// Check player weapon level to determine weapon upgrade type
								var weaponPickup;
								if (player.weaponUpgrades >= 49) {
									// Replace weapon upgrade with nova blade upgrade if player is at level 50
									weaponPickup = new Pickup('novaBlade');
								} else {
									weaponPickup = new Pickup('damage');
								}
								weaponPickup.x = creep.x + 52.5; // Position far right with 35px spacing
								weaponPickup.y = creep.y;
								pickups.push(weaponPickup);
								game.addChild(weaponPickup);
							} else if (creep instanceof SpecialCreep) {
								scoreValue = 300; // Higher score for special creeps
							} else if (creep instanceof EliteCreep) {
								scoreValue = 200;
								// Elite creep upgrade drop chance reset to 0%
							} else {
								scoreValue = 100;
							}
							gameScore += scoreValue;
							LK.setScore(LK.getScore() + scoreValue);
							if (!(creep instanceof BossCreep)) {
								dropPickup(creep.x, creep.y, creep instanceof EliteCreep || creep instanceof SpecialCreep);
							}
							creep.destroy();
							creeps.splice(creepIdx, 1);
						}
					}
				}
				break; // Only process one active aura at a time
			}
		}
	}
	// Update creeps
	var _loop = function _loop() {
			creep = creeps[i]; // Check if creep reached player - adjust hit detection based on shield status
			canHitPlayer = false;
			// Always use distance-based hit detection for consistency
			dx = creep.x - player.x;
			dy = creep.y - player.y;
			distance = Math.sqrt(dx * dx + dy * dy);
			if (player.shieldActive) {
				// When shield is active, creeps can hit from slightly further away
				canHitPlayer = distance < 50; // Increased from 35 to 50 for better gameplay with shield
			} else {
				// Normal hit detection when no shield - increased threshold for easier creep hits
				canHitPlayer = distance < 85; // Increased from 70 to 85 for better gameplay
			}
			if (canHitPlayer) {
				if (!creep.hasReachedPlayer) {
					player.takeDamage(creep.damage);
					creep.hasReachedPlayer = true;
					// Calculate bump direction (away from creep)
					bumpDx = player.x - creep.x;
					bumpDy = player.y - creep.y;
					bumpDistance = Math.sqrt(bumpDx * bumpDx + bumpDy * bumpDy);
					if (bumpDistance > 0) {
						normalizedBumpX = bumpDx / bumpDistance;
						normalizedBumpY = bumpDy / bumpDistance;
						bumpStrength = 30; // How far to bump the player
						// Bump the player away from the creep
						tween(player, {
							x: player.x + normalizedBumpX * bumpStrength,
							y: player.y + normalizedBumpY * bumpStrength
						}, {
							duration: 200,
							easing: tween.easeOut
						});
					}
					// Make player invincible and add red flicker effect
					if (!player.invincible) {
						var _flicker = function flicker() {
							flickerCount++;
							if (flickerCount <= maxFlickers && player.invincible) {
								var playerGraphics = player.children[0]; // Get player graphics
								tween(playerGraphics, {
									tint: 0xFF0000,
									alpha: 0.5
								}, {
									duration: 50,
									onFinish: function onFinish() {
										tween(playerGraphics, {
											tint: 0xFFFFFF,
											alpha: 1.0
										}, {
											duration: 50,
											onFinish: function onFinish() {
												if (flickerCount < maxFlickers && player.invincible) {
													_flicker();
												}
											}
										});
									}
								});
							}
						};
						player.invincible = true;
						player.invincibilityTimer = 30; // 0.5 seconds at 60fps
						// Create flickering red effect during invincibility
						flickerCount = 0;
						maxFlickers = 10;
						_flicker();
					}
				}
				// Don't destroy creep - it stays alive after hitting player
			}
		},
		creep,
		canHitPlayer,
		dx,
		dy,
		distance,
		bumpDx,
		bumpDy,
		bumpDistance,
		normalizedBumpX,
		normalizedBumpY,
		bumpStrength,
		flickerCount,
		maxFlickers;
	for (var i = creeps.length - 1; i >= 0; i--) {
		_loop();
	}
	// Pickup processing moved to beginning of update loop
};
:quality(85)/https://cdn.frvr.ai/6856a595a707587439b6b73a.png%3F3) 
 An space fighter jet viewed from the top. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6858111cb3bdb63b7487f580.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/6858120f3bede27c210e4532.png%3F3) 
 An large circle of electric energy an circular force field shield. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685813693bede27c210e4540.png%3F3) 
 An alien space mine that has spikes. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685815813bede27c210e4563.png%3F3) 
 Alien mothership with spikes and glowing patterns and alien eye in middle. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6858163a3bede27c210e456c.png%3F3) 
 an Symbol for an Shield Force shield of electric power. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/68583e773bede27c210e45ca.png%3F3) 
 An solid plasma ball of electrical force emanating power filled with reds yellows and green electric power. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685845ee3bede27c210e4672.png%3F3) 
 Symbol for spaceship weapon upgrade with green arrow pointing up. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6858504b3bede27c210e46d4.png%3F3) 
 Alien spherical bullet with spikes emanating energy. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6858cac99b955c7245775c60.png%3F3) 
 Symbol for a spaceship armor upgrade using an green arrow pointing up and white coloring. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6858ccad9b955c7245775c78.png%3F3) 
 symbol for spaceship speed upgrade increase. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6858cd369b955c7245775c84.png%3F3) 
 Symbol for spaceship health increase with green arrow pointing up and red plus. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6858cdc39b955c7245775c90.png%3F3) 
 Symbol for space ship upgrade nova force field around it, with an white spaceship and orange electric circle surrounding it and an green arrow pointing up. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6858e3ce8396bed165134539.png%3F3) 
 Symbol for an play button wide screen. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/68590f328396bed1651345f7.png%3F3) 
 An alien space mine with spikes and red glowing center. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685912ee8396bed165134620.png%3F3) 
 explosion in space. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/685920178396bed165134660.png%3F3) 
 Play again button. In-Game asset. 2d. High contrast. No shadows