/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
/**** 
* Classes
****/ 
var BossShip = Container.expand(function () {
	var self = Container.call(this);
	var shipGraphics = self.attachAsset('enemyShip', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	shipGraphics.scaleX = 5;
	shipGraphics.scaleY = 5;
	shipGraphics.tint = 0xFF0000;
	self.health = 10;
	self.maxHealth = 10;
	self.shootCooldown = 0;
	self.attackPattern = 0;
	self.update = function () {
		// Boss stays stationary - no movement
		// New attack pattern - orange and cyan attacks
		if (self.shootCooldown <= 0) {
			if (self.attackPattern % 2 === 0) {
				// Orange attack pattern - 3 orange attacks tracking player
				var playerDx = player.x - self.x;
				var playerDy = player.y - self.y;
				var playerDistance = Math.sqrt(playerDx * playerDx + playerDy * playerDy);
				var playerDirX = playerDx / playerDistance;
				var playerDirY = playerDy / playerDistance;
				for (var i = 0; i < 3; i++) {
					var orangeAttack = new OrangeAttack();
					orangeAttack.x = self.x + (i - 1) * 120; // Spread attacks
					orangeAttack.y = self.y + 100;
					// Set tracking direction with spread
					var spreadAngle = (i - 1) * 0.2;
					orangeAttack.dirX = playerDirX * Math.cos(spreadAngle) - playerDirY * Math.sin(spreadAngle);
					orangeAttack.dirY = playerDirX * Math.sin(spreadAngle) + playerDirY * Math.cos(spreadAngle);
					game.addChild(orangeAttack);
					orangeAttacks.push(orangeAttack);
				}
				self.shootCooldown = 80;
			} else {
				// Cyan attack pattern - 2 cyan attacks tracking player
				var playerDx = player.x - self.x;
				var playerDy = player.y - self.y;
				var playerDistance = Math.sqrt(playerDx * playerDx + playerDy * playerDy);
				var playerDirX = playerDx / playerDistance;
				var playerDirY = playerDy / playerDistance;
				for (var i = 0; i < 2; i++) {
					var cyanAttack = new CyanAttack();
					cyanAttack.x = self.x + (i === 0 ? -100 : 100);
					cyanAttack.y = self.y + 100;
					// Set tracking direction
					cyanAttack.dirX = playerDirX;
					cyanAttack.dirY = playerDirY;
					game.addChild(cyanAttack);
					cyanAttacks.push(cyanAttack);
				}
				self.shootCooldown = 90;
			}
			self.attackPattern++;
		}
		if (self.shootCooldown > 0) {
			self.shootCooldown--;
		}
		// Pulsing effect based on health
		var healthRatio = self.health / self.maxHealth;
		var pulseScale = 5 + Math.sin(LK.ticks * 0.1) * 0.5 * (1 - healthRatio);
		shipGraphics.scaleX = pulseScale;
		shipGraphics.scaleY = pulseScale;
	};
	self.takeDamage = function (damage, isChargedAttack) {
		// Boss is immune to charged attacks
		if (isChargedAttack) {
			return;
		}
		self.health -= damage;
		LK.effects.flashObject(self, 0xFFFFFF, 200);
		if (self.health <= 0) {
			LK.setScore(LK.getScore() + 10);
			LK.getSound('enemyDestroy').play();
			self.destroy();
			bossActive = false;
			boss = null;
			gameLevel++; // Increment level when boss is defeated
			levelResetFlag = true; // Flag to show level indicator
			LK.showGameOver();
		}
	};
	return self;
});
var BossWideLaser = Container.expand(function () {
	var self = Container.call(this);
	var laserGraphics = self.attachAsset('bossWideLaser', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 8;
	self.damage = 3;
	self.update = function () {
		// Move towards player if direction is set, otherwise move straight down
		if (self.dirX !== undefined && self.dirY !== undefined) {
			self.x += self.dirX * self.speed;
			self.y += self.dirY * self.speed;
		} else {
			self.y += self.speed;
		}
	};
	return self;
});
var ChargedPlayerLaser = Container.expand(function () {
	var self = Container.call(this);
	var laserGraphics = self.attachAsset('chargedPlayerLaser', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = -10;
	self.damage = 3;
	self.update = function () {
		self.y += self.speed;
	};
	return self;
});
var CyanAttack = Container.expand(function () {
	var self = Container.call(this);
	var attackGraphics = self.attachAsset('cyanAttack', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 8;
	self.damage = 2;
	self.checkTimer = 0;
	self.update = function () {
		// Move towards player if direction is set, otherwise move straight down
		if (self.dirX !== undefined && self.dirY !== undefined) {
			self.x += self.dirX * self.speed;
			self.y += self.dirY * self.speed;
		} else {
			self.y += self.speed;
		}
		// Add pulsing cyan effect
		var pulse = 1 + Math.sin(LK.ticks * 0.2) * 0.3;
		attackGraphics.scaleX = pulse;
		attackGraphics.scaleY = pulse;
	};
	return self;
});
var EnemyProjectile = Container.expand(function () {
	var self = Container.call(this);
	var projectileGraphics = self.attachAsset('enemyProjectile', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 6;
	self.update = function () {
		self.y += self.speed;
	};
	return self;
});
var EnemyShip = Container.expand(function () {
	var self = Container.call(this);
	var shipGraphics = self.attachAsset('enemyShip', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 8;
	self.health = 3;
	self.shootCooldown = Math.random() * 60 + 30; // Random initial cooldown
	self.update = function () {
		self.y += self.speed;
		// Enemy shooting
		if (self.shootCooldown <= 0) {
			var projectile = new EnemyProjectile();
			projectile.x = self.x;
			projectile.y = self.y + 40;
			game.addChild(projectile);
			enemyProjectiles.push(projectile);
			self.shootCooldown = Math.random() * 90 + 60; // Random cooldown between shots
		}
		if (self.shootCooldown > 0) {
			self.shootCooldown--;
		}
	};
	return self;
});
var Level2EnemyShip = Container.expand(function () {
	var self = Container.call(this);
	var shipGraphics = self.attachAsset('enemyShip', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Level 2 enemies are larger and have different color
	shipGraphics.scaleX = 1.5;
	shipGraphics.scaleY = 1.5;
	shipGraphics.tint = 0xFF6600; // Orange tint for level 2
	self.speed = 10; // Faster than regular enemies
	self.health = 5; // More health than regular enemies
	self.shootCooldown = Math.random() * 40 + 20; // Shoots more frequently
	self.zigzagTimer = 0;
	self.zigzagDirection = Math.random() > 0.5 ? 1 : -1;
	self.update = function () {
		self.y += self.speed;
		// Zigzag movement pattern
		self.zigzagTimer++;
		if (self.zigzagTimer % 30 === 0) {
			self.zigzagDirection *= -1;
		}
		self.x += self.zigzagDirection * 3;
		// Keep within screen bounds
		if (self.x < 100) {
			self.x = 100;
			self.zigzagDirection = 1;
		}
		if (self.x > 1948) {
			self.x = 1948;
			self.zigzagDirection = -1;
		}
		// Enhanced shooting - shoots 2 projectiles
		if (self.shootCooldown <= 0) {
			for (var i = 0; i < 2; i++) {
				var projectile = new EnemyProjectile();
				projectile.x = self.x + (i === 0 ? -20 : 20);
				projectile.y = self.y + 40;
				projectile.speed = 8; // Faster projectiles
				game.addChild(projectile);
				enemyProjectiles.push(projectile);
			}
			self.shootCooldown = Math.random() * 60 + 40;
		}
		if (self.shootCooldown > 0) {
			self.shootCooldown--;
		}
	};
	return self;
});
var OrangeAttack = Container.expand(function () {
	var self = Container.call(this);
	var attackGraphics = self.attachAsset('orangeAttack', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 8;
	self.damage = 2;
	self.checkTimer = 0;
	self.update = function () {
		// Move towards player if direction is set, otherwise move straight down
		if (self.dirX !== undefined && self.dirY !== undefined) {
			self.x += self.dirX * self.speed;
			self.y += self.dirY * self.speed;
		} else {
			self.y += self.speed;
		}
		// Add pulsing orange effect
		var pulse = 1 + Math.sin(LK.ticks * 0.2) * 0.3;
		attackGraphics.scaleX = pulse;
		attackGraphics.scaleY = pulse;
	};
	return self;
});
var PlayerLaser = Container.expand(function () {
	var self = Container.call(this);
	var laserGraphics = self.attachAsset('playerLaser', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = -8;
	self.damage = 1;
	self.update = function () {
		self.y += self.speed;
	};
	return self;
});
var PlayerShip = Container.expand(function () {
	var self = Container.call(this);
	var shipGraphics = self.attachAsset('playerShip', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	var chargeIndicator = self.attachAsset('chargeIndicator', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	chargeIndicator.x = 0;
	chargeIndicator.y = -80;
	chargeIndicator.visible = false;
	self.health = 3;
	self.shootCooldown = 0;
	self.chargeAttackTime = 0;
	self.isCharging = false;
	self.update = function () {
		if (self.shootCooldown > 0) {
			self.shootCooldown--;
		}
		if (self.isCharging) {
			self.chargeAttackTime++;
			// Create pulsing animation while charging
			var pulseIntensity = Math.min(self.chargeAttackTime / 60, 1); // 0 to 1
			var pulseScale = 1 + Math.sin(LK.ticks * 0.3) * 0.15 * pulseIntensity;
			self.scaleX = pulseScale;
			self.scaleY = pulseScale;
			// Add color tint that gets stronger as charge builds
			var tintIntensity = Math.floor(pulseIntensity * 100);
			self.tint = 0xFFFFFF + (tintIntensity << 8); // Add green tint
			// When fully charged, show green square indicator
			if (self.chargeAttackTime >= 60) {
				var readyPulse = 1.2 + Math.sin(LK.ticks * 0.5) * 0.3;
				self.scaleX = readyPulse;
				self.scaleY = readyPulse;
				self.tint = 0x00FF00; // Bright green when ready
				chargeIndicator.visible = true;
			}
		} else {
			// Reset scale and tint when not charging
			self.scaleX = 1;
			self.scaleY = 1;
			self.tint = 0xFFFFFF;
			chargeIndicator.visible = false;
		}
	};
	self.shoot = function () {
		if (self.shootCooldown <= 0) {
			var laser;
			// Create charged laser if charge time is sufficient
			if (self.chargeAttackTime >= 60) {
				laser = new ChargedPlayerLaser();
				// Add spawn animation for charged laser
				laser.scaleX = 0.3;
				laser.scaleY = 0.3;
				tween(laser, {
					scaleX: 1,
					scaleY: 1
				}, {
					duration: 200,
					easing: tween.easeOut
				});
				// Add tint effect
				laser.tint = 0x00FF00;
				tween(laser, {
					tint: 0xFFFFFF
				}, {
					duration: 300
				});
			} else {
				laser = new PlayerLaser();
			}
			laser.x = self.x;
			laser.y = self.y - 60;
			game.addChild(laser);
			playerLasers.push(laser);
			self.shootCooldown = 10;
			LK.getSound('shoot').play();
		}
	};
	self.takeDamage = function () {
		self.health--;
		LK.getSound('playerHit').play();
		LK.effects.flashObject(self, 0xff0000, 500);
		if (self.health <= 0) {
			LK.showGameOver();
		}
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x000011
});
/**** 
* Game Code
****/ 
var player = new PlayerShip();
player.x = 2048 / 2;
player.y = 2732 - 200;
game.addChild(player);
var enemies = [];
var playerLasers = [];
var enemyProjectiles = [];
var spawnTimer = 0;
var gameSpeed = 1;
var playerShootCooldown = 0;
var isFireButtonPressed = false;
var bossActive = false;
var boss = null;
var bossProjectiles = [];
var bossLasers = [];
var bossWideLasers = [];
var orangeAttacks = [];
var cyanAttacks = [];
var playerLastX = 0;
var playerLastY = 0;
var playerIsMoving = false;
var gameLevel = 1;
var levelResetFlag = false;
var scoreTxt = new Text2('Score: 0', {
	size: 80,
	fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var healthTxt = new Text2('Health: 3', {
	size: 60,
	fill: 0xFF4444
});
healthTxt.anchor.set(0, 0);
healthTxt.x = 150;
healthTxt.y = 50;
LK.gui.topLeft.addChild(healthTxt);
var fireButton = new Text2('FIRE', {
	size: 120,
	fill: 0x00FF00
});
fireButton.anchor.set(1, 0);
LK.gui.topRight.addChild(fireButton);
var levelTxt = new Text2('Level: 1', {
	size: 60,
	fill: 0xFFFF00
});
levelTxt.anchor.set(0.5, 0);
levelTxt.x = 0;
levelTxt.y = 150;
LK.gui.top.addChild(levelTxt);
var dragNode = null;
fireButton.down = function (x, y, obj) {
	isFireButtonPressed = true;
	player.isCharging = true;
	player.chargeAttackTime = 0;
	if (playerShootCooldown <= 0) {
		player.shoot();
		playerShootCooldown = 20;
	}
};
fireButton.up = function (x, y, obj) {
	isFireButtonPressed = false;
	// Shoot charged laser if player was charging
	if (player.isCharging && player.chargeAttackTime >= 60) {
		if (playerShootCooldown <= 0) {
			player.shoot();
			playerShootCooldown = 20;
		}
	}
	player.isCharging = false;
	player.chargeAttackTime = 0;
};
game.down = function (x, y, obj) {
	dragNode = player;
	player.isCharging = true;
	player.chargeAttackTime = 0;
	if (playerShootCooldown <= 0) {
		player.shoot();
		playerShootCooldown = 20;
	}
};
game.move = function (x, y, obj) {
	if (dragNode) {
		dragNode.x = Math.max(100, Math.min(1948, x));
	}
};
game.up = function (x, y, obj) {
	dragNode = null;
	// Shoot charged laser if player was charging
	if (player.isCharging && player.chargeAttackTime >= 60) {
		if (playerShootCooldown <= 0) {
			player.shoot();
			playerShootCooldown = 20;
		}
	}
	player.isCharging = false;
	player.chargeAttackTime = 0;
};
game.update = function () {
	// Update cooldown
	if (playerShootCooldown > 0) {
		playerShootCooldown--;
	}
	// Track player movement
	var currentPlayerMoving = Math.abs(player.x - playerLastX) > 1 || Math.abs(player.y - playerLastY) > 1;
	playerIsMoving = currentPlayerMoving;
	playerLastX = player.x;
	playerLastY = player.y;
	// Update UI
	scoreTxt.setText('Score: ' + LK.getScore());
	healthTxt.setText('Health: ' + player.health);
	levelTxt.setText('Level: ' + gameLevel);
	// Show level indicator when level changes
	if (levelResetFlag) {
		LK.effects.flashScreen(0x00FF00, 800); // Green flash for level up
		levelResetFlag = false;
	}
	// Boss spawn when player reaches score threshold based on level
	var bossSpawnThreshold = 100 * gameLevel;
	if (LK.getScore() >= bossSpawnThreshold && !bossActive) {
		boss = new BossShip();
		boss.x = 2048 / 2;
		boss.y = 200;
		// Scale boss health with level
		boss.health = 10 + (gameLevel - 1) * 5;
		boss.maxHealth = boss.health;
		game.addChild(boss);
		bossActive = true;
	}
	// Spawn regular enemies (only when boss is not active)
	if (!bossActive) {
		spawnTimer++;
		var spawnRate = Math.max(120 - Math.floor(LK.getScore() / 10) * 10, 60);
		if (spawnTimer >= spawnRate) {
			var enemy;
			// Spawn level 2 enemies if we're on level 2 or higher
			if (gameLevel >= 2) {
				// Mix of regular and level 2 enemies, with more level 2 enemies on higher levels
				if (Math.random() < 0.7) {
					enemy = new Level2EnemyShip();
				} else {
					enemy = new EnemyShip();
				}
			} else {
				enemy = new EnemyShip();
			}
			enemy.x = Math.random() * 1848 + 100;
			enemy.y = -50;
			if (enemy.speed === undefined) {
				enemy.speed = 6 + Math.floor(LK.getScore() / 15) * 1.5;
			}
			enemies.push(enemy);
			game.addChild(enemy);
			spawnTimer = 0;
		}
	}
	// Update and check player lasers
	for (var i = playerLasers.length - 1; i >= 0; i--) {
		var laser = playerLasers[i];
		if (laser.lastY === undefined) laser.lastY = laser.y;
		// Remove lasers that go off screen
		if (laser.lastY >= -50 && laser.y < -50) {
			laser.destroy();
			playerLasers.splice(i, 1);
			continue;
		}
		// Check collision with enemies
		var hitEnemy = false;
		for (var j = enemies.length - 1; j >= 0; j--) {
			var enemy = enemies[j];
			if (laser.intersects(enemy)) {
				enemy.health -= laser.damage;
				laser.destroy();
				playerLasers.splice(i, 1);
				hitEnemy = true;
				if (enemy.health <= 0) {
					LK.setScore(LK.getScore() + 10);
					LK.getSound('enemyDestroy').play();
					enemy.destroy();
					enemies.splice(j, 1);
				}
				break;
			}
		}
		// Check collision with boss
		if (bossActive && boss && laser.intersects(boss)) {
			var isChargedAttack = laser.damage > 1;
			boss.takeDamage(laser.damage, isChargedAttack);
			laser.destroy();
			playerLasers.splice(i, 1);
			hitEnemy = true;
		}
		if (!hitEnemy) {
			laser.lastY = laser.y;
		}
	}
	// Update and check enemies
	for (var i = enemies.length - 1; i >= 0; i--) {
		var enemy = enemies[i];
		if (enemy.lastY === undefined) enemy.lastY = enemy.y;
		// Remove enemies that reach bottom
		if (enemy.lastY <= 2732 && enemy.y > 2732) {
			enemy.destroy();
			enemies.splice(i, 1);
			continue;
		}
		// Check collision with player
		if (enemy.intersects(player)) {
			enemy.destroy();
			enemies.splice(i, 1);
			player.takeDamage();
			continue;
		}
		enemy.lastY = enemy.y;
	}
	// Check boss collision with player
	if (bossActive && boss && boss.intersects(player)) {
		player.takeDamage();
		player.takeDamage(); // Boss does double damage
	}
	// Update and check enemy projectiles
	for (var i = enemyProjectiles.length - 1; i >= 0; i--) {
		var projectile = enemyProjectiles[i];
		if (projectile.lastY === undefined) projectile.lastY = projectile.y;
		// Remove projectiles that go off screen
		if (projectile.lastY <= 2732 && projectile.y > 2732) {
			projectile.destroy();
			enemyProjectiles.splice(i, 1);
			continue;
		}
		// Check collision with player
		if (projectile.intersects(player)) {
			projectile.destroy();
			enemyProjectiles.splice(i, 1);
			// Enemy projectiles no longer cause damage - just destroy on contact
			// Enhanced damage for boss projectiles
			if (projectile.damage && projectile.damage > 1) {
				// player.takeDamage();
				// player.takeDamage();
			} else {
				// player.takeDamage();
			}
			continue;
		}
		projectile.lastY = projectile.y;
	}
	// Update and check boss projectiles
	for (var i = bossProjectiles.length - 1; i >= 0; i--) {
		var projectile = bossProjectiles[i];
		// Remove projectiles if boss is dead or projectiles go too far
		var shouldRemove = false;
		if (!boss) {
			shouldRemove = true;
		} else {
			var distanceFromBoss = Math.sqrt(Math.pow(projectile.x - boss.x, 2) + Math.pow(projectile.y - boss.y, 2));
			shouldRemove = distanceFromBoss > 800;
		}
		if (shouldRemove || projectile.y > 2732 || projectile.y < -100 || projectile.x < -100 || projectile.x > 2148) {
			projectile.destroy();
			bossProjectiles.splice(i, 1);
			continue;
		}
		// Check collision with player
		if (projectile.intersects(player)) {
			projectile.destroy();
			bossProjectiles.splice(i, 1);
			// Giant projectiles do massive damage
			player.takeDamage();
			player.takeDamage();
			player.takeDamage();
			continue;
		}
	}
	// Update and check boss lasers
	for (var i = bossLasers.length - 1; i >= 0; i--) {
		var laser = bossLasers[i];
		if (laser.lastY === undefined) laser.lastY = laser.y;
		// Remove lasers that go off screen
		if (laser.lastY <= 2732 && laser.y > 2732) {
			laser.destroy();
			bossLasers.splice(i, 1);
			continue;
		}
		// Check collision with player
		if (laser.intersects(player)) {
			laser.destroy();
			bossLasers.splice(i, 1);
			player.takeDamage();
			player.takeDamage(); // Boss lasers do double damage
			continue;
		}
		laser.lastY = laser.y;
	}
	// Update and check boss wide lasers
	for (var i = bossWideLasers.length - 1; i >= 0; i--) {
		var laser = bossWideLasers[i];
		if (laser.lastY === undefined) laser.lastY = laser.y;
		// Remove lasers that go off screen
		if (laser.lastY <= 2732 && laser.y > 2732) {
			laser.destroy();
			bossWideLasers.splice(i, 1);
			continue;
		}
		// Check collision with player
		if (laser.intersects(player)) {
			laser.destroy();
			bossWideLasers.splice(i, 1);
			// Wide lasers do massive damage
			player.takeDamage();
			player.takeDamage();
			player.takeDamage();
			continue;
		}
		laser.lastY = laser.y;
	}
	// Update and check orange attacks
	for (var i = orangeAttacks.length - 1; i >= 0; i--) {
		var attack = orangeAttacks[i];
		if (attack.lastY === undefined) attack.lastY = attack.y;
		// Remove attacks that go off screen
		if (attack.lastY <= 2732 && attack.y > 2732) {
			attack.destroy();
			orangeAttacks.splice(i, 1);
			continue;
		}
		// Check collision with player - damage only when player is NOT moving
		if (attack.intersects(player)) {
			attack.destroy();
			orangeAttacks.splice(i, 1);
			// Orange attacks damage player when NOT moving
			if (!playerIsMoving) {
				player.takeDamage();
			}
			continue;
		}
		attack.lastY = attack.y;
	}
	// Update and check cyan attacks
	for (var i = cyanAttacks.length - 1; i >= 0; i--) {
		var attack = cyanAttacks[i];
		if (attack.lastY === undefined) attack.lastY = attack.y;
		// Remove attacks that go off screen
		if (attack.lastY <= 2732 && attack.y > 2732) {
			attack.destroy();
			cyanAttacks.splice(i, 1);
			continue;
		}
		// Check collision with player - damage only when player IS moving
		if (attack.intersects(player)) {
			attack.destroy();
			cyanAttacks.splice(i, 1);
			// Cyan attacks damage player when moving
			if (playerIsMoving) {
				player.takeDamage();
			}
			continue;
		}
		attack.lastY = attack.y;
	}
}; /**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
/**** 
* Classes
****/ 
var BossShip = Container.expand(function () {
	var self = Container.call(this);
	var shipGraphics = self.attachAsset('enemyShip', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	shipGraphics.scaleX = 5;
	shipGraphics.scaleY = 5;
	shipGraphics.tint = 0xFF0000;
	self.health = 10;
	self.maxHealth = 10;
	self.shootCooldown = 0;
	self.attackPattern = 0;
	self.update = function () {
		// Boss stays stationary - no movement
		// New attack pattern - orange and cyan attacks
		if (self.shootCooldown <= 0) {
			if (self.attackPattern % 2 === 0) {
				// Orange attack pattern - 3 orange attacks tracking player
				var playerDx = player.x - self.x;
				var playerDy = player.y - self.y;
				var playerDistance = Math.sqrt(playerDx * playerDx + playerDy * playerDy);
				var playerDirX = playerDx / playerDistance;
				var playerDirY = playerDy / playerDistance;
				for (var i = 0; i < 3; i++) {
					var orangeAttack = new OrangeAttack();
					orangeAttack.x = self.x + (i - 1) * 120; // Spread attacks
					orangeAttack.y = self.y + 100;
					// Set tracking direction with spread
					var spreadAngle = (i - 1) * 0.2;
					orangeAttack.dirX = playerDirX * Math.cos(spreadAngle) - playerDirY * Math.sin(spreadAngle);
					orangeAttack.dirY = playerDirX * Math.sin(spreadAngle) + playerDirY * Math.cos(spreadAngle);
					game.addChild(orangeAttack);
					orangeAttacks.push(orangeAttack);
				}
				self.shootCooldown = 80;
			} else {
				// Cyan attack pattern - 2 cyan attacks tracking player
				var playerDx = player.x - self.x;
				var playerDy = player.y - self.y;
				var playerDistance = Math.sqrt(playerDx * playerDx + playerDy * playerDy);
				var playerDirX = playerDx / playerDistance;
				var playerDirY = playerDy / playerDistance;
				for (var i = 0; i < 2; i++) {
					var cyanAttack = new CyanAttack();
					cyanAttack.x = self.x + (i === 0 ? -100 : 100);
					cyanAttack.y = self.y + 100;
					// Set tracking direction
					cyanAttack.dirX = playerDirX;
					cyanAttack.dirY = playerDirY;
					game.addChild(cyanAttack);
					cyanAttacks.push(cyanAttack);
				}
				self.shootCooldown = 90;
			}
			self.attackPattern++;
		}
		if (self.shootCooldown > 0) {
			self.shootCooldown--;
		}
		// Pulsing effect based on health
		var healthRatio = self.health / self.maxHealth;
		var pulseScale = 5 + Math.sin(LK.ticks * 0.1) * 0.5 * (1 - healthRatio);
		shipGraphics.scaleX = pulseScale;
		shipGraphics.scaleY = pulseScale;
	};
	self.takeDamage = function (damage, isChargedAttack) {
		// Boss is immune to charged attacks
		if (isChargedAttack) {
			return;
		}
		self.health -= damage;
		LK.effects.flashObject(self, 0xFFFFFF, 200);
		if (self.health <= 0) {
			LK.setScore(LK.getScore() + 10);
			LK.getSound('enemyDestroy').play();
			self.destroy();
			bossActive = false;
			boss = null;
			gameLevel++; // Increment level when boss is defeated
			levelResetFlag = true; // Flag to show level indicator
			LK.showGameOver();
		}
	};
	return self;
});
var BossWideLaser = Container.expand(function () {
	var self = Container.call(this);
	var laserGraphics = self.attachAsset('bossWideLaser', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 8;
	self.damage = 3;
	self.update = function () {
		// Move towards player if direction is set, otherwise move straight down
		if (self.dirX !== undefined && self.dirY !== undefined) {
			self.x += self.dirX * self.speed;
			self.y += self.dirY * self.speed;
		} else {
			self.y += self.speed;
		}
	};
	return self;
});
var ChargedPlayerLaser = Container.expand(function () {
	var self = Container.call(this);
	var laserGraphics = self.attachAsset('chargedPlayerLaser', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = -10;
	self.damage = 3;
	self.update = function () {
		self.y += self.speed;
	};
	return self;
});
var CyanAttack = Container.expand(function () {
	var self = Container.call(this);
	var attackGraphics = self.attachAsset('cyanAttack', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 8;
	self.damage = 2;
	self.checkTimer = 0;
	self.update = function () {
		// Move towards player if direction is set, otherwise move straight down
		if (self.dirX !== undefined && self.dirY !== undefined) {
			self.x += self.dirX * self.speed;
			self.y += self.dirY * self.speed;
		} else {
			self.y += self.speed;
		}
		// Add pulsing cyan effect
		var pulse = 1 + Math.sin(LK.ticks * 0.2) * 0.3;
		attackGraphics.scaleX = pulse;
		attackGraphics.scaleY = pulse;
	};
	return self;
});
var EnemyProjectile = Container.expand(function () {
	var self = Container.call(this);
	var projectileGraphics = self.attachAsset('enemyProjectile', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 6;
	self.update = function () {
		self.y += self.speed;
	};
	return self;
});
var EnemyShip = Container.expand(function () {
	var self = Container.call(this);
	var shipGraphics = self.attachAsset('enemyShip', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 8;
	self.health = 3;
	self.shootCooldown = Math.random() * 60 + 30; // Random initial cooldown
	self.update = function () {
		self.y += self.speed;
		// Enemy shooting
		if (self.shootCooldown <= 0) {
			var projectile = new EnemyProjectile();
			projectile.x = self.x;
			projectile.y = self.y + 40;
			game.addChild(projectile);
			enemyProjectiles.push(projectile);
			self.shootCooldown = Math.random() * 90 + 60; // Random cooldown between shots
		}
		if (self.shootCooldown > 0) {
			self.shootCooldown--;
		}
	};
	return self;
});
var Level2EnemyShip = Container.expand(function () {
	var self = Container.call(this);
	var shipGraphics = self.attachAsset('enemyShip', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Level 2 enemies are larger and have different color
	shipGraphics.scaleX = 1.5;
	shipGraphics.scaleY = 1.5;
	shipGraphics.tint = 0xFF6600; // Orange tint for level 2
	self.speed = 10; // Faster than regular enemies
	self.health = 5; // More health than regular enemies
	self.shootCooldown = Math.random() * 40 + 20; // Shoots more frequently
	self.zigzagTimer = 0;
	self.zigzagDirection = Math.random() > 0.5 ? 1 : -1;
	self.update = function () {
		self.y += self.speed;
		// Zigzag movement pattern
		self.zigzagTimer++;
		if (self.zigzagTimer % 30 === 0) {
			self.zigzagDirection *= -1;
		}
		self.x += self.zigzagDirection * 3;
		// Keep within screen bounds
		if (self.x < 100) {
			self.x = 100;
			self.zigzagDirection = 1;
		}
		if (self.x > 1948) {
			self.x = 1948;
			self.zigzagDirection = -1;
		}
		// Enhanced shooting - shoots 2 projectiles
		if (self.shootCooldown <= 0) {
			for (var i = 0; i < 2; i++) {
				var projectile = new EnemyProjectile();
				projectile.x = self.x + (i === 0 ? -20 : 20);
				projectile.y = self.y + 40;
				projectile.speed = 8; // Faster projectiles
				game.addChild(projectile);
				enemyProjectiles.push(projectile);
			}
			self.shootCooldown = Math.random() * 60 + 40;
		}
		if (self.shootCooldown > 0) {
			self.shootCooldown--;
		}
	};
	return self;
});
var OrangeAttack = Container.expand(function () {
	var self = Container.call(this);
	var attackGraphics = self.attachAsset('orangeAttack', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 8;
	self.damage = 2;
	self.checkTimer = 0;
	self.update = function () {
		// Move towards player if direction is set, otherwise move straight down
		if (self.dirX !== undefined && self.dirY !== undefined) {
			self.x += self.dirX * self.speed;
			self.y += self.dirY * self.speed;
		} else {
			self.y += self.speed;
		}
		// Add pulsing orange effect
		var pulse = 1 + Math.sin(LK.ticks * 0.2) * 0.3;
		attackGraphics.scaleX = pulse;
		attackGraphics.scaleY = pulse;
	};
	return self;
});
var PlayerLaser = Container.expand(function () {
	var self = Container.call(this);
	var laserGraphics = self.attachAsset('playerLaser', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = -8;
	self.damage = 1;
	self.update = function () {
		self.y += self.speed;
	};
	return self;
});
var PlayerShip = Container.expand(function () {
	var self = Container.call(this);
	var shipGraphics = self.attachAsset('playerShip', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	var chargeIndicator = self.attachAsset('chargeIndicator', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	chargeIndicator.x = 0;
	chargeIndicator.y = -80;
	chargeIndicator.visible = false;
	self.health = 3;
	self.shootCooldown = 0;
	self.chargeAttackTime = 0;
	self.isCharging = false;
	self.update = function () {
		if (self.shootCooldown > 0) {
			self.shootCooldown--;
		}
		if (self.isCharging) {
			self.chargeAttackTime++;
			// Create pulsing animation while charging
			var pulseIntensity = Math.min(self.chargeAttackTime / 60, 1); // 0 to 1
			var pulseScale = 1 + Math.sin(LK.ticks * 0.3) * 0.15 * pulseIntensity;
			self.scaleX = pulseScale;
			self.scaleY = pulseScale;
			// Add color tint that gets stronger as charge builds
			var tintIntensity = Math.floor(pulseIntensity * 100);
			self.tint = 0xFFFFFF + (tintIntensity << 8); // Add green tint
			// When fully charged, show green square indicator
			if (self.chargeAttackTime >= 60) {
				var readyPulse = 1.2 + Math.sin(LK.ticks * 0.5) * 0.3;
				self.scaleX = readyPulse;
				self.scaleY = readyPulse;
				self.tint = 0x00FF00; // Bright green when ready
				chargeIndicator.visible = true;
			}
		} else {
			// Reset scale and tint when not charging
			self.scaleX = 1;
			self.scaleY = 1;
			self.tint = 0xFFFFFF;
			chargeIndicator.visible = false;
		}
	};
	self.shoot = function () {
		if (self.shootCooldown <= 0) {
			var laser;
			// Create charged laser if charge time is sufficient
			if (self.chargeAttackTime >= 60) {
				laser = new ChargedPlayerLaser();
				// Add spawn animation for charged laser
				laser.scaleX = 0.3;
				laser.scaleY = 0.3;
				tween(laser, {
					scaleX: 1,
					scaleY: 1
				}, {
					duration: 200,
					easing: tween.easeOut
				});
				// Add tint effect
				laser.tint = 0x00FF00;
				tween(laser, {
					tint: 0xFFFFFF
				}, {
					duration: 300
				});
			} else {
				laser = new PlayerLaser();
			}
			laser.x = self.x;
			laser.y = self.y - 60;
			game.addChild(laser);
			playerLasers.push(laser);
			self.shootCooldown = 10;
			LK.getSound('shoot').play();
		}
	};
	self.takeDamage = function () {
		self.health--;
		LK.getSound('playerHit').play();
		LK.effects.flashObject(self, 0xff0000, 500);
		if (self.health <= 0) {
			LK.showGameOver();
		}
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x000011
});
/**** 
* Game Code
****/ 
var player = new PlayerShip();
player.x = 2048 / 2;
player.y = 2732 - 200;
game.addChild(player);
var enemies = [];
var playerLasers = [];
var enemyProjectiles = [];
var spawnTimer = 0;
var gameSpeed = 1;
var playerShootCooldown = 0;
var isFireButtonPressed = false;
var bossActive = false;
var boss = null;
var bossProjectiles = [];
var bossLasers = [];
var bossWideLasers = [];
var orangeAttacks = [];
var cyanAttacks = [];
var playerLastX = 0;
var playerLastY = 0;
var playerIsMoving = false;
var gameLevel = 1;
var levelResetFlag = false;
var scoreTxt = new Text2('Score: 0', {
	size: 80,
	fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var healthTxt = new Text2('Health: 3', {
	size: 60,
	fill: 0xFF4444
});
healthTxt.anchor.set(0, 0);
healthTxt.x = 150;
healthTxt.y = 50;
LK.gui.topLeft.addChild(healthTxt);
var fireButton = new Text2('FIRE', {
	size: 120,
	fill: 0x00FF00
});
fireButton.anchor.set(1, 0);
LK.gui.topRight.addChild(fireButton);
var levelTxt = new Text2('Level: 1', {
	size: 60,
	fill: 0xFFFF00
});
levelTxt.anchor.set(0.5, 0);
levelTxt.x = 0;
levelTxt.y = 150;
LK.gui.top.addChild(levelTxt);
var dragNode = null;
fireButton.down = function (x, y, obj) {
	isFireButtonPressed = true;
	player.isCharging = true;
	player.chargeAttackTime = 0;
	if (playerShootCooldown <= 0) {
		player.shoot();
		playerShootCooldown = 20;
	}
};
fireButton.up = function (x, y, obj) {
	isFireButtonPressed = false;
	// Shoot charged laser if player was charging
	if (player.isCharging && player.chargeAttackTime >= 60) {
		if (playerShootCooldown <= 0) {
			player.shoot();
			playerShootCooldown = 20;
		}
	}
	player.isCharging = false;
	player.chargeAttackTime = 0;
};
game.down = function (x, y, obj) {
	dragNode = player;
	player.isCharging = true;
	player.chargeAttackTime = 0;
	if (playerShootCooldown <= 0) {
		player.shoot();
		playerShootCooldown = 20;
	}
};
game.move = function (x, y, obj) {
	if (dragNode) {
		dragNode.x = Math.max(100, Math.min(1948, x));
	}
};
game.up = function (x, y, obj) {
	dragNode = null;
	// Shoot charged laser if player was charging
	if (player.isCharging && player.chargeAttackTime >= 60) {
		if (playerShootCooldown <= 0) {
			player.shoot();
			playerShootCooldown = 20;
		}
	}
	player.isCharging = false;
	player.chargeAttackTime = 0;
};
game.update = function () {
	// Update cooldown
	if (playerShootCooldown > 0) {
		playerShootCooldown--;
	}
	// Track player movement
	var currentPlayerMoving = Math.abs(player.x - playerLastX) > 1 || Math.abs(player.y - playerLastY) > 1;
	playerIsMoving = currentPlayerMoving;
	playerLastX = player.x;
	playerLastY = player.y;
	// Update UI
	scoreTxt.setText('Score: ' + LK.getScore());
	healthTxt.setText('Health: ' + player.health);
	levelTxt.setText('Level: ' + gameLevel);
	// Show level indicator when level changes
	if (levelResetFlag) {
		LK.effects.flashScreen(0x00FF00, 800); // Green flash for level up
		levelResetFlag = false;
	}
	// Boss spawn when player reaches score threshold based on level
	var bossSpawnThreshold = 100 * gameLevel;
	if (LK.getScore() >= bossSpawnThreshold && !bossActive) {
		boss = new BossShip();
		boss.x = 2048 / 2;
		boss.y = 200;
		// Scale boss health with level
		boss.health = 10 + (gameLevel - 1) * 5;
		boss.maxHealth = boss.health;
		game.addChild(boss);
		bossActive = true;
	}
	// Spawn regular enemies (only when boss is not active)
	if (!bossActive) {
		spawnTimer++;
		var spawnRate = Math.max(120 - Math.floor(LK.getScore() / 10) * 10, 60);
		if (spawnTimer >= spawnRate) {
			var enemy;
			// Spawn level 2 enemies if we're on level 2 or higher
			if (gameLevel >= 2) {
				// Mix of regular and level 2 enemies, with more level 2 enemies on higher levels
				if (Math.random() < 0.7) {
					enemy = new Level2EnemyShip();
				} else {
					enemy = new EnemyShip();
				}
			} else {
				enemy = new EnemyShip();
			}
			enemy.x = Math.random() * 1848 + 100;
			enemy.y = -50;
			if (enemy.speed === undefined) {
				enemy.speed = 6 + Math.floor(LK.getScore() / 15) * 1.5;
			}
			enemies.push(enemy);
			game.addChild(enemy);
			spawnTimer = 0;
		}
	}
	// Update and check player lasers
	for (var i = playerLasers.length - 1; i >= 0; i--) {
		var laser = playerLasers[i];
		if (laser.lastY === undefined) laser.lastY = laser.y;
		// Remove lasers that go off screen
		if (laser.lastY >= -50 && laser.y < -50) {
			laser.destroy();
			playerLasers.splice(i, 1);
			continue;
		}
		// Check collision with enemies
		var hitEnemy = false;
		for (var j = enemies.length - 1; j >= 0; j--) {
			var enemy = enemies[j];
			if (laser.intersects(enemy)) {
				enemy.health -= laser.damage;
				laser.destroy();
				playerLasers.splice(i, 1);
				hitEnemy = true;
				if (enemy.health <= 0) {
					LK.setScore(LK.getScore() + 10);
					LK.getSound('enemyDestroy').play();
					enemy.destroy();
					enemies.splice(j, 1);
				}
				break;
			}
		}
		// Check collision with boss
		if (bossActive && boss && laser.intersects(boss)) {
			var isChargedAttack = laser.damage > 1;
			boss.takeDamage(laser.damage, isChargedAttack);
			laser.destroy();
			playerLasers.splice(i, 1);
			hitEnemy = true;
		}
		if (!hitEnemy) {
			laser.lastY = laser.y;
		}
	}
	// Update and check enemies
	for (var i = enemies.length - 1; i >= 0; i--) {
		var enemy = enemies[i];
		if (enemy.lastY === undefined) enemy.lastY = enemy.y;
		// Remove enemies that reach bottom
		if (enemy.lastY <= 2732 && enemy.y > 2732) {
			enemy.destroy();
			enemies.splice(i, 1);
			continue;
		}
		// Check collision with player
		if (enemy.intersects(player)) {
			enemy.destroy();
			enemies.splice(i, 1);
			player.takeDamage();
			continue;
		}
		enemy.lastY = enemy.y;
	}
	// Check boss collision with player
	if (bossActive && boss && boss.intersects(player)) {
		player.takeDamage();
		player.takeDamage(); // Boss does double damage
	}
	// Update and check enemy projectiles
	for (var i = enemyProjectiles.length - 1; i >= 0; i--) {
		var projectile = enemyProjectiles[i];
		if (projectile.lastY === undefined) projectile.lastY = projectile.y;
		// Remove projectiles that go off screen
		if (projectile.lastY <= 2732 && projectile.y > 2732) {
			projectile.destroy();
			enemyProjectiles.splice(i, 1);
			continue;
		}
		// Check collision with player
		if (projectile.intersects(player)) {
			projectile.destroy();
			enemyProjectiles.splice(i, 1);
			// Enemy projectiles no longer cause damage - just destroy on contact
			// Enhanced damage for boss projectiles
			if (projectile.damage && projectile.damage > 1) {
				// player.takeDamage();
				// player.takeDamage();
			} else {
				// player.takeDamage();
			}
			continue;
		}
		projectile.lastY = projectile.y;
	}
	// Update and check boss projectiles
	for (var i = bossProjectiles.length - 1; i >= 0; i--) {
		var projectile = bossProjectiles[i];
		// Remove projectiles if boss is dead or projectiles go too far
		var shouldRemove = false;
		if (!boss) {
			shouldRemove = true;
		} else {
			var distanceFromBoss = Math.sqrt(Math.pow(projectile.x - boss.x, 2) + Math.pow(projectile.y - boss.y, 2));
			shouldRemove = distanceFromBoss > 800;
		}
		if (shouldRemove || projectile.y > 2732 || projectile.y < -100 || projectile.x < -100 || projectile.x > 2148) {
			projectile.destroy();
			bossProjectiles.splice(i, 1);
			continue;
		}
		// Check collision with player
		if (projectile.intersects(player)) {
			projectile.destroy();
			bossProjectiles.splice(i, 1);
			// Giant projectiles do massive damage
			player.takeDamage();
			player.takeDamage();
			player.takeDamage();
			continue;
		}
	}
	// Update and check boss lasers
	for (var i = bossLasers.length - 1; i >= 0; i--) {
		var laser = bossLasers[i];
		if (laser.lastY === undefined) laser.lastY = laser.y;
		// Remove lasers that go off screen
		if (laser.lastY <= 2732 && laser.y > 2732) {
			laser.destroy();
			bossLasers.splice(i, 1);
			continue;
		}
		// Check collision with player
		if (laser.intersects(player)) {
			laser.destroy();
			bossLasers.splice(i, 1);
			player.takeDamage();
			player.takeDamage(); // Boss lasers do double damage
			continue;
		}
		laser.lastY = laser.y;
	}
	// Update and check boss wide lasers
	for (var i = bossWideLasers.length - 1; i >= 0; i--) {
		var laser = bossWideLasers[i];
		if (laser.lastY === undefined) laser.lastY = laser.y;
		// Remove lasers that go off screen
		if (laser.lastY <= 2732 && laser.y > 2732) {
			laser.destroy();
			bossWideLasers.splice(i, 1);
			continue;
		}
		// Check collision with player
		if (laser.intersects(player)) {
			laser.destroy();
			bossWideLasers.splice(i, 1);
			// Wide lasers do massive damage
			player.takeDamage();
			player.takeDamage();
			player.takeDamage();
			continue;
		}
		laser.lastY = laser.y;
	}
	// Update and check orange attacks
	for (var i = orangeAttacks.length - 1; i >= 0; i--) {
		var attack = orangeAttacks[i];
		if (attack.lastY === undefined) attack.lastY = attack.y;
		// Remove attacks that go off screen
		if (attack.lastY <= 2732 && attack.y > 2732) {
			attack.destroy();
			orangeAttacks.splice(i, 1);
			continue;
		}
		// Check collision with player - damage only when player is NOT moving
		if (attack.intersects(player)) {
			attack.destroy();
			orangeAttacks.splice(i, 1);
			// Orange attacks damage player when NOT moving
			if (!playerIsMoving) {
				player.takeDamage();
			}
			continue;
		}
		attack.lastY = attack.y;
	}
	// Update and check cyan attacks
	for (var i = cyanAttacks.length - 1; i >= 0; i--) {
		var attack = cyanAttacks[i];
		if (attack.lastY === undefined) attack.lastY = attack.y;
		// Remove attacks that go off screen
		if (attack.lastY <= 2732 && attack.y > 2732) {
			attack.destroy();
			cyanAttacks.splice(i, 1);
			continue;
		}
		// Check collision with player - damage only when player IS moving
		if (attack.intersects(player)) {
			attack.destroy();
			cyanAttacks.splice(i, 1);
			// Cyan attacks damage player when moving
			if (playerIsMoving) {
				player.takeDamage();
			}
			continue;
		}
		attack.lastY = attack.y;
	}
};
 Una nave de Star wars mirada desde arriba. In-Game asset. 2d. High contrast. No shadows
 Ataque verde de Star wars mirada desde arriba llendo para adelante. In-Game asset. 2d. High contrast. No shadows
 Meteorito llendo hacia abajo con el fuego arriba. In-Game asset. 2d. High contrast. No shadows
 Explosión verde. In-Game asset. 2d. High contrast. No shadows
 Star wars la estrella de la muerte. In-Game asset. 2d. High contrast. No shadows