/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
	highScore: 0,
	shipColor: 3447003
});
/**** 
* Classes
****/ 
var Enemy = Container.expand(function () {
	var self = Container.call(this);
	var enemyGraphics = self.attachAsset('enemyShip', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Type: 0 = basic, 1 = shooter, 2 = fast
	self.type = 0;
	self.health = 1;
	self.points = 100;
	self.moveSpeed = 2;
	self.shotFrequency = 120; // frames between shots
	self.shotCounter = Math.floor(Math.random() * 60); // Random initial delay
	self.init = function (type) {
		self.type = type || 0;
		if (self.type === 0) {
			// Basic enemy
			enemyGraphics.tint = 0xe74c3c;
			self.health = 1;
			self.points = 100;
			self.moveSpeed = 2;
			self.shotFrequency = 0; // Doesn't shoot
		} else if (self.type === 1) {
			// Shooter enemy
			enemyGraphics.tint = 0xf39c12;
			self.health = 2;
			self.points = 200;
			self.moveSpeed = 1;
			self.shotFrequency = 120;
		} else if (self.type === 2) {
			// Fast enemy
			enemyGraphics.tint = 0x9b59b6;
			self.health = 1;
			self.points = 150;
			self.moveSpeed = 4;
			self.shotFrequency = 0;
		}
		return self;
	};
	self.movePattern = function () {
		// Default movement pattern
		self.y += self.moveSpeed;
		if (self.type === 2) {
			// Fast enemy zigzags
			self.x += Math.sin(LK.ticks / 10) * 5;
		}
	};
	self.tryShoot = function () {
		if (self.shotFrequency === 0) {
			return null;
		}
		self.shotCounter++;
		if (self.shotCounter >= self.shotFrequency) {
			self.shotCounter = 0;
			return true;
		}
		return false;
	};
	self.takeDamage = function (amount) {
		self.health -= amount;
		// Flash red when hit
		tween(enemyGraphics, {
			tint: 0xff0000
		}, {
			duration: 100,
			onFinish: function onFinish() {
				if (self.type === 0) {
					tween(enemyGraphics, {
						tint: 0xe74c3c
					}, {
						duration: 100
					});
				} else if (self.type === 1) {
					tween(enemyGraphics, {
						tint: 0xf39c12
					}, {
						duration: 100
					});
				} else if (self.type === 2) {
					tween(enemyGraphics, {
						tint: 0x9b59b6
					}, {
						duration: 100
					});
				}
			}
		});
		return self.health <= 0;
	};
	self.update = function () {
		self.movePattern();
	};
	return self;
});
var EnemyBullet = Container.expand(function () {
	var self = Container.call(this);
	var bulletGraphics = self.attachAsset('enemyBullet', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 10;
	self.power = 1;
	self.update = function () {
		self.y += self.speed;
	};
	return self;
});
var Explosion = Container.expand(function () {
	var self = Container.call(this);
	var explosionGraphics = self.attachAsset('explosion', {
		anchorX: 0.5,
		anchorY: 0.5,
		alpha: 0.9
	});
	self.lifespan = 30; // frames
	self.update = function () {
		self.lifespan--;
		if (self.lifespan <= 0) {
			self.destroy();
			return;
		}
		// Gradually fade out and expand
		explosionGraphics.alpha = self.lifespan / 30;
		explosionGraphics.scale.x = 1 + (1 - self.lifespan / 30) * 2;
		explosionGraphics.scale.y = 1 + (1 - self.lifespan / 30) * 2;
	};
	return self;
});
var Player = Container.expand(function () {
	var self = Container.call(this);
	var playerGraphics = self.attachAsset('playerShip', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Set the ship color from storage if available
	playerGraphics.tint = storage.shipColor || 0x3498db;
	self.lives = 3;
	self.score = 0;
	self.fireRate = 15; // frames between shots
	self.fireCounter = 0;
	self.doubleFire = false;
	self.doubleFireduration = 0;
	self.shield = false;
	self.shieldDuration = 0;
	self.invulnerable = false;
	self.invulnerableDuration = 0;
	// Shield visual
	var shieldGraphics = self.attachAsset('powerUp', {
		anchorX: 0.5,
		anchorY: 0.5,
		alpha: 0,
		tint: 0x3498db,
		scaleX: 1.5,
		scaleY: 1.5
	});
	self.canFire = function () {
		self.fireCounter++;
		if (self.fireCounter >= self.fireRate) {
			self.fireCounter = 0;
			return true;
		}
		return false;
	};
	self.takeDamage = function () {
		if (self.invulnerable || self.shield) {
			if (self.shield) {
				// Remove shield instead of taking damage
				self.shield = false;
				shieldGraphics.alpha = 0;
				// Flash effect
				LK.effects.flashObject(self, 0x3498db, 500);
			}
			return false;
		}
		self.lives--;
		// Become temporarily invulnerable
		self.invulnerable = true;
		self.invulnerableDuration = 90; // 1.5 seconds
		// Flash effect
		LK.effects.flashObject(self, 0xff0000, 500);
		return self.lives <= 0;
	};
	self.applyPowerUp = function (type) {
		if (type === 0) {
			// Double fire
			self.doubleFire = true;
			self.doubleFireduration = 300; // 5 seconds
		} else if (type === 1) {
			// Shield
			self.shield = true;
			shieldGraphics.alpha = 0.7;
			self.shieldDuration = 300; // 5 seconds
		} else if (type === 2) {
			// Extra life
			self.lives++;
		}
	};
	self.update = function () {
		// Update power-ups durations
		if (self.doubleFire) {
			self.doubleFireduration--;
			if (self.doubleFireduration <= 0) {
				self.doubleFire = false;
			}
		}
		if (self.shield) {
			self.shieldDuration--;
			if (self.shieldDuration <= 0) {
				self.shield = false;
				shieldGraphics.alpha = 0;
			} else {
				// Pulsate shield
				shieldGraphics.alpha = 0.5 + Math.sin(LK.ticks / 10) * 0.2;
			}
		}
		if (self.invulnerable) {
			self.invulnerableDuration--;
			if (self.invulnerableDuration <= 0) {
				self.invulnerable = false;
			}
			// Blink when invulnerable
			self.alpha = Math.floor(LK.ticks / 5) % 2 ? 0.5 : 1;
		} else {
			self.alpha = 1;
		}
	};
	return self;
});
var PlayerBullet = Container.expand(function () {
	var self = Container.call(this);
	var bulletGraphics = self.attachAsset('playerBullet', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = -15;
	self.power = 1;
	self.update = function () {
		self.y += self.speed;
	};
	return self;
});
var PowerUp = Container.expand(function () {
	var self = Container.call(this);
	var powerUpGraphics = self.attachAsset('powerUp', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// PowerUp types: 0 = double fire, 1 = shield, 2 = extra life
	self.type = Math.floor(Math.random() * 3);
	// Set color based on type
	if (self.type === 0) {
		powerUpGraphics.tint = 0xff5500; // orange for double fire
	} else if (self.type === 1) {
		powerUpGraphics.tint = 0x3498db; // blue for shield
	} else {
		powerUpGraphics.tint = 0x2ecc71; // green for extra life
	}
	self.speed = 3;
	self.update = function () {
		self.y += self.speed;
		// Pulsate effect
		if (LK.ticks % 10 === 0) {
			tween(powerUpGraphics.scale, {
				x: 1.1,
				y: 1.1
			}, {
				duration: 500,
				easing: tween.easeInOut,
				onFinish: function onFinish() {
					tween(powerUpGraphics.scale, {
						x: 1,
						y: 1
					}, {
						duration: 500,
						easing: tween.easeInOut
					});
				}
			});
		}
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x000000
});
/**** 
* Game Code
****/ 
// Set the game's background
game.setBackgroundColor(0x0a0a2a); // Deep space blue
// Game state variables
var player;
var enemies = [];
var playerBullets = [];
var enemyBullets = [];
var powerUps = [];
var explosions = [];
var score = 0;
var level = 1;
var enemySpawnRate = 60; // frames between enemy spawns
var enemySpawnCounter = 0;
var powerUpChance = 0.1; // 10% chance on enemy death
var gameActive = true;
var dragNode = null;
var isPaused = false;
// UI elements
var scoreText = new Text2('SCORE: 0', {
	size: 70,
	fill: 0xFFFFFF
});
scoreText.anchor.set(0, 0);
LK.gui.topRight.addChild(scoreText);
scoreText.y = 20;
scoreText.x = -scoreText.width - 20;
var livesText = new Text2('LIVES: 3', {
	size: 70,
	fill: 0xFFFFFF
});
livesText.anchor.set(1, 0);
LK.gui.topLeft.addChild(livesText);
livesText.y = 20;
livesText.x = 120; // Keep away from top-left corner menu icon
var levelText = new Text2('LEVEL: 1', {
	size: 70,
	fill: 0xFFFFFF
});
levelText.anchor.set(0.5, 0);
LK.gui.top.addChild(levelText);
levelText.y = 20;
// Initialize the player
player = new Player();
player.x = 2048 / 2;
player.y = 2732 - 300;
game.addChild(player);
// Create stars for background
var stars = [];
function createStars() {
	for (var i = 0; i < 100; i++) {
		var star = LK.getAsset('playerBullet', {
			anchorX: 0.5,
			anchorY: 0.5,
			scaleX: 0.3 + Math.random() * 0.7,
			scaleY: 0.3 + Math.random() * 0.7,
			alpha: 0.3 + Math.random() * 0.7,
			tint: 0xffffff
		});
		star.x = Math.random() * 2048;
		star.y = Math.random() * 2732;
		star.speed = 0.5 + Math.random() * 2;
		stars.push(star);
		game.addChild(star);
	}
}
createStars();
// Start background music
LK.playMusic('gameMusic', {
	fade: {
		start: 0,
		end: 0.7,
		duration: 1000
	}
});
// Spawn a new enemy
function spawnEnemy() {
	// Choose enemy type based on level
	var typeChances = [0.7, 0.2, 0.1]; // Default chances
	// Adjust chances based on level
	if (level >= 3) {
		typeChances = [0.5, 0.3, 0.2];
	}
	if (level >= 5) {
		typeChances = [0.4, 0.3, 0.3];
	}
	if (level >= 8) {
		typeChances = [0.3, 0.4, 0.3];
	}
	// Determine enemy type
	var rand = Math.random();
	var enemyType = 0;
	if (rand > typeChances[0]) {
		enemyType = rand > typeChances[0] + typeChances[1] ? 2 : 1;
	}
	var enemy = new Enemy().init(enemyType);
	enemy.x = 200 + Math.random() * (2048 - 400);
	enemy.y = -100;
	enemies.push(enemy);
	game.addChild(enemy);
}
// Fire a bullet from the player
function firePlayerBullet(offsetX) {
	offsetX = offsetX || 0;
	var bullet = new PlayerBullet();
	bullet.x = player.x + offsetX;
	bullet.y = player.y - 50;
	playerBullets.push(bullet);
	game.addChild(bullet);
	LK.getSound('playerShoot').play();
}
// Fire a bullet from an enemy
function fireEnemyBullet(enemy) {
	var bullet = new EnemyBullet();
	bullet.x = enemy.x;
	bullet.y = enemy.y + 50;
	enemyBullets.push(bullet);
	game.addChild(bullet);
	LK.getSound('enemyShoot').play();
}
// Create an explosion
function createExplosion(x, y, size) {
	var explosion = new Explosion();
	explosion.x = x;
	explosion.y = y;
	explosion.scale.set(size || 1);
	explosions.push(explosion);
	game.addChild(explosion);
	LK.getSound('explosion').play();
}
// Spawn a power-up
function spawnPowerUp(x, y) {
	var powerUp = new PowerUp();
	powerUp.x = x;
	powerUp.y = y;
	powerUps.push(powerUp);
	game.addChild(powerUp);
}
// Update score display
function updateScore(newScore) {
	score = newScore;
	scoreText.setText("SCORE: " + score);
	// Check for level up (every 1000 points)
	var newLevel = Math.floor(score / 1000) + 1;
	if (newLevel > level) {
		level = newLevel;
		levelText.setText("LEVEL: " + level);
		// Increase difficulty with level
		enemySpawnRate = Math.max(20, 60 - (level - 1) * 5);
	}
	// Set score in LK system
	LK.setScore(score);
	// Update high score if needed
	if (score > storage.highScore) {
		storage.highScore = score;
	}
}
// Update lives display
function updateLives() {
	livesText.setText("LIVES: " + player.lives);
}
// Handle player and enemy movement
function handleGameInput(x, y) {
	if (dragNode && gameActive && !isPaused) {
		dragNode.x = Math.max(dragNode.width / 2, Math.min(2048 - dragNode.width / 2, x));
		// Restrict vertical movement to bottom third of screen
		dragNode.y = Math.max(2732 / 3 * 2, Math.min(2732 - dragNode.height / 2, y));
	}
}
// Mouse or touch down on the game
game.down = function (x, y, obj) {
	if (!gameActive || isPaused) {
		return;
	}
	// Set drag node to player if within bounds
	if (Math.abs(x - player.x) < 100 && Math.abs(y - player.y) < 100) {
		dragNode = player;
	} else {
		// Fire when tapping elsewhere
		if (player.canFire()) {
			if (player.doubleFire) {
				firePlayerBullet(-30);
				firePlayerBullet(30);
			} else {
				firePlayerBullet(0);
			}
		}
	}
	// Call move handler for immediate response
	handleGameInput(x, y);
};
// Mouse or touch move on the game
game.move = function (x, y, obj) {
	handleGameInput(x, y);
};
// Mouse or touch up on the game
game.up = function (x, y, obj) {
	dragNode = null;
};
// Main game update loop
game.update = function () {
	if (!gameActive || isPaused) {
		return;
	}
	// Update stars (background)
	for (var i = 0; i < stars.length; i++) {
		stars[i].y += stars[i].speed;
		if (stars[i].y > 2732) {
			stars[i].y = 0;
			stars[i].x = Math.random() * 2048;
		}
	}
	// Spawn enemies
	enemySpawnCounter++;
	if (enemySpawnCounter >= enemySpawnRate) {
		enemySpawnCounter = 0;
		spawnEnemy();
	}
	// Auto-fire for player (if holding down)
	if (dragNode === player && player.canFire()) {
		if (player.doubleFire) {
			firePlayerBullet(-30);
			firePlayerBullet(30);
		} else {
			firePlayerBullet(0);
		}
	}
	// Update player
	player.update();
	// Update bullets
	for (var i = playerBullets.length - 1; i >= 0; i--) {
		var bullet = playerBullets[i];
		// Check if bullet is off screen
		if (bullet.y < -50) {
			bullet.destroy();
			playerBullets.splice(i, 1);
			continue;
		}
		// Check for collision with enemies
		for (var j = enemies.length - 1; j >= 0; j--) {
			var enemy = enemies[j];
			if (bullet.intersects(enemy)) {
				// Handle enemy hit
				if (enemy.takeDamage(bullet.power)) {
					// Enemy destroyed
					createExplosion(enemy.x, enemy.y, 1);
					updateScore(score + enemy.points);
					// Chance to spawn power-up
					if (Math.random() < powerUpChance) {
						spawnPowerUp(enemy.x, enemy.y);
					}
					enemy.destroy();
					enemies.splice(j, 1);
				}
				// Remove bullet
				bullet.destroy();
				playerBullets.splice(i, 1);
				break;
			}
		}
	}
	// Update enemy bullets
	for (var i = enemyBullets.length - 1; i >= 0; i--) {
		var bullet = enemyBullets[i];
		// Check if bullet is off screen
		if (bullet.y > 2732 + 50) {
			bullet.destroy();
			enemyBullets.splice(i, 1);
			continue;
		}
		// Check for collision with player
		if (bullet.intersects(player)) {
			// Handle player hit
			if (player.takeDamage()) {
				// Game over
				gameActive = false;
				createExplosion(player.x, player.y, 2);
				LK.setTimeout(function () {
					LK.showGameOver();
				}, 1500);
			}
			updateLives();
			// Remove bullet
			bullet.destroy();
			enemyBullets.splice(i, 1);
		}
	}
	// Update enemies
	for (var i = enemies.length - 1; i >= 0; i--) {
		var enemy = enemies[i];
		// Check if enemy is off screen
		if (enemy.y > 2732 + 100) {
			enemy.destroy();
			enemies.splice(i, 1);
			continue;
		}
		// Check for collision with player
		if (enemy.intersects(player)) {
			// Handle player collision with enemy
			if (player.takeDamage()) {
				// Game over
				gameActive = false;
				createExplosion(player.x, player.y, 2);
				LK.setTimeout(function () {
					LK.showGameOver();
				}, 1500);
			}
			updateLives();
			// Destroy enemy
			createExplosion(enemy.x, enemy.y, 1);
			enemy.destroy();
			enemies.splice(i, 1);
			continue;
		}
		// Enemy shooting
		if (enemy.tryShoot()) {
			fireEnemyBullet(enemy);
		}
		// Update enemy
		enemy.update();
	}
	// Update power-ups
	for (var i = powerUps.length - 1; i >= 0; i--) {
		var powerUp = powerUps[i];
		// Check if power-up is off screen
		if (powerUp.y > 2732 + 50) {
			powerUp.destroy();
			powerUps.splice(i, 1);
			continue;
		}
		// Check for collision with player
		if (powerUp.intersects(player)) {
			// Apply power-up effect
			player.applyPowerUp(powerUp.type);
			// Play sound and add points
			LK.getSound('powerUp').play();
			updateScore(score + 50);
			// Remove power-up
			powerUp.destroy();
			powerUps.splice(i, 1);
			continue;
		}
		// Update power-up
		powerUp.update();
	}
	// Update explosions
	for (var i = explosions.length - 1; i >= 0; i--) {
		explosions[i].update();
		if (explosions[i].lifespan <= 0) {
			explosions.splice(i, 1);
		}
	}
}; /**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
	highScore: 0,
	shipColor: 3447003
});
/**** 
* Classes
****/ 
var Enemy = Container.expand(function () {
	var self = Container.call(this);
	var enemyGraphics = self.attachAsset('enemyShip', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Type: 0 = basic, 1 = shooter, 2 = fast
	self.type = 0;
	self.health = 1;
	self.points = 100;
	self.moveSpeed = 2;
	self.shotFrequency = 120; // frames between shots
	self.shotCounter = Math.floor(Math.random() * 60); // Random initial delay
	self.init = function (type) {
		self.type = type || 0;
		if (self.type === 0) {
			// Basic enemy
			enemyGraphics.tint = 0xe74c3c;
			self.health = 1;
			self.points = 100;
			self.moveSpeed = 2;
			self.shotFrequency = 0; // Doesn't shoot
		} else if (self.type === 1) {
			// Shooter enemy
			enemyGraphics.tint = 0xf39c12;
			self.health = 2;
			self.points = 200;
			self.moveSpeed = 1;
			self.shotFrequency = 120;
		} else if (self.type === 2) {
			// Fast enemy
			enemyGraphics.tint = 0x9b59b6;
			self.health = 1;
			self.points = 150;
			self.moveSpeed = 4;
			self.shotFrequency = 0;
		}
		return self;
	};
	self.movePattern = function () {
		// Default movement pattern
		self.y += self.moveSpeed;
		if (self.type === 2) {
			// Fast enemy zigzags
			self.x += Math.sin(LK.ticks / 10) * 5;
		}
	};
	self.tryShoot = function () {
		if (self.shotFrequency === 0) {
			return null;
		}
		self.shotCounter++;
		if (self.shotCounter >= self.shotFrequency) {
			self.shotCounter = 0;
			return true;
		}
		return false;
	};
	self.takeDamage = function (amount) {
		self.health -= amount;
		// Flash red when hit
		tween(enemyGraphics, {
			tint: 0xff0000
		}, {
			duration: 100,
			onFinish: function onFinish() {
				if (self.type === 0) {
					tween(enemyGraphics, {
						tint: 0xe74c3c
					}, {
						duration: 100
					});
				} else if (self.type === 1) {
					tween(enemyGraphics, {
						tint: 0xf39c12
					}, {
						duration: 100
					});
				} else if (self.type === 2) {
					tween(enemyGraphics, {
						tint: 0x9b59b6
					}, {
						duration: 100
					});
				}
			}
		});
		return self.health <= 0;
	};
	self.update = function () {
		self.movePattern();
	};
	return self;
});
var EnemyBullet = Container.expand(function () {
	var self = Container.call(this);
	var bulletGraphics = self.attachAsset('enemyBullet', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 10;
	self.power = 1;
	self.update = function () {
		self.y += self.speed;
	};
	return self;
});
var Explosion = Container.expand(function () {
	var self = Container.call(this);
	var explosionGraphics = self.attachAsset('explosion', {
		anchorX: 0.5,
		anchorY: 0.5,
		alpha: 0.9
	});
	self.lifespan = 30; // frames
	self.update = function () {
		self.lifespan--;
		if (self.lifespan <= 0) {
			self.destroy();
			return;
		}
		// Gradually fade out and expand
		explosionGraphics.alpha = self.lifespan / 30;
		explosionGraphics.scale.x = 1 + (1 - self.lifespan / 30) * 2;
		explosionGraphics.scale.y = 1 + (1 - self.lifespan / 30) * 2;
	};
	return self;
});
var Player = Container.expand(function () {
	var self = Container.call(this);
	var playerGraphics = self.attachAsset('playerShip', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Set the ship color from storage if available
	playerGraphics.tint = storage.shipColor || 0x3498db;
	self.lives = 3;
	self.score = 0;
	self.fireRate = 15; // frames between shots
	self.fireCounter = 0;
	self.doubleFire = false;
	self.doubleFireduration = 0;
	self.shield = false;
	self.shieldDuration = 0;
	self.invulnerable = false;
	self.invulnerableDuration = 0;
	// Shield visual
	var shieldGraphics = self.attachAsset('powerUp', {
		anchorX: 0.5,
		anchorY: 0.5,
		alpha: 0,
		tint: 0x3498db,
		scaleX: 1.5,
		scaleY: 1.5
	});
	self.canFire = function () {
		self.fireCounter++;
		if (self.fireCounter >= self.fireRate) {
			self.fireCounter = 0;
			return true;
		}
		return false;
	};
	self.takeDamage = function () {
		if (self.invulnerable || self.shield) {
			if (self.shield) {
				// Remove shield instead of taking damage
				self.shield = false;
				shieldGraphics.alpha = 0;
				// Flash effect
				LK.effects.flashObject(self, 0x3498db, 500);
			}
			return false;
		}
		self.lives--;
		// Become temporarily invulnerable
		self.invulnerable = true;
		self.invulnerableDuration = 90; // 1.5 seconds
		// Flash effect
		LK.effects.flashObject(self, 0xff0000, 500);
		return self.lives <= 0;
	};
	self.applyPowerUp = function (type) {
		if (type === 0) {
			// Double fire
			self.doubleFire = true;
			self.doubleFireduration = 300; // 5 seconds
		} else if (type === 1) {
			// Shield
			self.shield = true;
			shieldGraphics.alpha = 0.7;
			self.shieldDuration = 300; // 5 seconds
		} else if (type === 2) {
			// Extra life
			self.lives++;
		}
	};
	self.update = function () {
		// Update power-ups durations
		if (self.doubleFire) {
			self.doubleFireduration--;
			if (self.doubleFireduration <= 0) {
				self.doubleFire = false;
			}
		}
		if (self.shield) {
			self.shieldDuration--;
			if (self.shieldDuration <= 0) {
				self.shield = false;
				shieldGraphics.alpha = 0;
			} else {
				// Pulsate shield
				shieldGraphics.alpha = 0.5 + Math.sin(LK.ticks / 10) * 0.2;
			}
		}
		if (self.invulnerable) {
			self.invulnerableDuration--;
			if (self.invulnerableDuration <= 0) {
				self.invulnerable = false;
			}
			// Blink when invulnerable
			self.alpha = Math.floor(LK.ticks / 5) % 2 ? 0.5 : 1;
		} else {
			self.alpha = 1;
		}
	};
	return self;
});
var PlayerBullet = Container.expand(function () {
	var self = Container.call(this);
	var bulletGraphics = self.attachAsset('playerBullet', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = -15;
	self.power = 1;
	self.update = function () {
		self.y += self.speed;
	};
	return self;
});
var PowerUp = Container.expand(function () {
	var self = Container.call(this);
	var powerUpGraphics = self.attachAsset('powerUp', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// PowerUp types: 0 = double fire, 1 = shield, 2 = extra life
	self.type = Math.floor(Math.random() * 3);
	// Set color based on type
	if (self.type === 0) {
		powerUpGraphics.tint = 0xff5500; // orange for double fire
	} else if (self.type === 1) {
		powerUpGraphics.tint = 0x3498db; // blue for shield
	} else {
		powerUpGraphics.tint = 0x2ecc71; // green for extra life
	}
	self.speed = 3;
	self.update = function () {
		self.y += self.speed;
		// Pulsate effect
		if (LK.ticks % 10 === 0) {
			tween(powerUpGraphics.scale, {
				x: 1.1,
				y: 1.1
			}, {
				duration: 500,
				easing: tween.easeInOut,
				onFinish: function onFinish() {
					tween(powerUpGraphics.scale, {
						x: 1,
						y: 1
					}, {
						duration: 500,
						easing: tween.easeInOut
					});
				}
			});
		}
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x000000
});
/**** 
* Game Code
****/ 
// Set the game's background
game.setBackgroundColor(0x0a0a2a); // Deep space blue
// Game state variables
var player;
var enemies = [];
var playerBullets = [];
var enemyBullets = [];
var powerUps = [];
var explosions = [];
var score = 0;
var level = 1;
var enemySpawnRate = 60; // frames between enemy spawns
var enemySpawnCounter = 0;
var powerUpChance = 0.1; // 10% chance on enemy death
var gameActive = true;
var dragNode = null;
var isPaused = false;
// UI elements
var scoreText = new Text2('SCORE: 0', {
	size: 70,
	fill: 0xFFFFFF
});
scoreText.anchor.set(0, 0);
LK.gui.topRight.addChild(scoreText);
scoreText.y = 20;
scoreText.x = -scoreText.width - 20;
var livesText = new Text2('LIVES: 3', {
	size: 70,
	fill: 0xFFFFFF
});
livesText.anchor.set(1, 0);
LK.gui.topLeft.addChild(livesText);
livesText.y = 20;
livesText.x = 120; // Keep away from top-left corner menu icon
var levelText = new Text2('LEVEL: 1', {
	size: 70,
	fill: 0xFFFFFF
});
levelText.anchor.set(0.5, 0);
LK.gui.top.addChild(levelText);
levelText.y = 20;
// Initialize the player
player = new Player();
player.x = 2048 / 2;
player.y = 2732 - 300;
game.addChild(player);
// Create stars for background
var stars = [];
function createStars() {
	for (var i = 0; i < 100; i++) {
		var star = LK.getAsset('playerBullet', {
			anchorX: 0.5,
			anchorY: 0.5,
			scaleX: 0.3 + Math.random() * 0.7,
			scaleY: 0.3 + Math.random() * 0.7,
			alpha: 0.3 + Math.random() * 0.7,
			tint: 0xffffff
		});
		star.x = Math.random() * 2048;
		star.y = Math.random() * 2732;
		star.speed = 0.5 + Math.random() * 2;
		stars.push(star);
		game.addChild(star);
	}
}
createStars();
// Start background music
LK.playMusic('gameMusic', {
	fade: {
		start: 0,
		end: 0.7,
		duration: 1000
	}
});
// Spawn a new enemy
function spawnEnemy() {
	// Choose enemy type based on level
	var typeChances = [0.7, 0.2, 0.1]; // Default chances
	// Adjust chances based on level
	if (level >= 3) {
		typeChances = [0.5, 0.3, 0.2];
	}
	if (level >= 5) {
		typeChances = [0.4, 0.3, 0.3];
	}
	if (level >= 8) {
		typeChances = [0.3, 0.4, 0.3];
	}
	// Determine enemy type
	var rand = Math.random();
	var enemyType = 0;
	if (rand > typeChances[0]) {
		enemyType = rand > typeChances[0] + typeChances[1] ? 2 : 1;
	}
	var enemy = new Enemy().init(enemyType);
	enemy.x = 200 + Math.random() * (2048 - 400);
	enemy.y = -100;
	enemies.push(enemy);
	game.addChild(enemy);
}
// Fire a bullet from the player
function firePlayerBullet(offsetX) {
	offsetX = offsetX || 0;
	var bullet = new PlayerBullet();
	bullet.x = player.x + offsetX;
	bullet.y = player.y - 50;
	playerBullets.push(bullet);
	game.addChild(bullet);
	LK.getSound('playerShoot').play();
}
// Fire a bullet from an enemy
function fireEnemyBullet(enemy) {
	var bullet = new EnemyBullet();
	bullet.x = enemy.x;
	bullet.y = enemy.y + 50;
	enemyBullets.push(bullet);
	game.addChild(bullet);
	LK.getSound('enemyShoot').play();
}
// Create an explosion
function createExplosion(x, y, size) {
	var explosion = new Explosion();
	explosion.x = x;
	explosion.y = y;
	explosion.scale.set(size || 1);
	explosions.push(explosion);
	game.addChild(explosion);
	LK.getSound('explosion').play();
}
// Spawn a power-up
function spawnPowerUp(x, y) {
	var powerUp = new PowerUp();
	powerUp.x = x;
	powerUp.y = y;
	powerUps.push(powerUp);
	game.addChild(powerUp);
}
// Update score display
function updateScore(newScore) {
	score = newScore;
	scoreText.setText("SCORE: " + score);
	// Check for level up (every 1000 points)
	var newLevel = Math.floor(score / 1000) + 1;
	if (newLevel > level) {
		level = newLevel;
		levelText.setText("LEVEL: " + level);
		// Increase difficulty with level
		enemySpawnRate = Math.max(20, 60 - (level - 1) * 5);
	}
	// Set score in LK system
	LK.setScore(score);
	// Update high score if needed
	if (score > storage.highScore) {
		storage.highScore = score;
	}
}
// Update lives display
function updateLives() {
	livesText.setText("LIVES: " + player.lives);
}
// Handle player and enemy movement
function handleGameInput(x, y) {
	if (dragNode && gameActive && !isPaused) {
		dragNode.x = Math.max(dragNode.width / 2, Math.min(2048 - dragNode.width / 2, x));
		// Restrict vertical movement to bottom third of screen
		dragNode.y = Math.max(2732 / 3 * 2, Math.min(2732 - dragNode.height / 2, y));
	}
}
// Mouse or touch down on the game
game.down = function (x, y, obj) {
	if (!gameActive || isPaused) {
		return;
	}
	// Set drag node to player if within bounds
	if (Math.abs(x - player.x) < 100 && Math.abs(y - player.y) < 100) {
		dragNode = player;
	} else {
		// Fire when tapping elsewhere
		if (player.canFire()) {
			if (player.doubleFire) {
				firePlayerBullet(-30);
				firePlayerBullet(30);
			} else {
				firePlayerBullet(0);
			}
		}
	}
	// Call move handler for immediate response
	handleGameInput(x, y);
};
// Mouse or touch move on the game
game.move = function (x, y, obj) {
	handleGameInput(x, y);
};
// Mouse or touch up on the game
game.up = function (x, y, obj) {
	dragNode = null;
};
// Main game update loop
game.update = function () {
	if (!gameActive || isPaused) {
		return;
	}
	// Update stars (background)
	for (var i = 0; i < stars.length; i++) {
		stars[i].y += stars[i].speed;
		if (stars[i].y > 2732) {
			stars[i].y = 0;
			stars[i].x = Math.random() * 2048;
		}
	}
	// Spawn enemies
	enemySpawnCounter++;
	if (enemySpawnCounter >= enemySpawnRate) {
		enemySpawnCounter = 0;
		spawnEnemy();
	}
	// Auto-fire for player (if holding down)
	if (dragNode === player && player.canFire()) {
		if (player.doubleFire) {
			firePlayerBullet(-30);
			firePlayerBullet(30);
		} else {
			firePlayerBullet(0);
		}
	}
	// Update player
	player.update();
	// Update bullets
	for (var i = playerBullets.length - 1; i >= 0; i--) {
		var bullet = playerBullets[i];
		// Check if bullet is off screen
		if (bullet.y < -50) {
			bullet.destroy();
			playerBullets.splice(i, 1);
			continue;
		}
		// Check for collision with enemies
		for (var j = enemies.length - 1; j >= 0; j--) {
			var enemy = enemies[j];
			if (bullet.intersects(enemy)) {
				// Handle enemy hit
				if (enemy.takeDamage(bullet.power)) {
					// Enemy destroyed
					createExplosion(enemy.x, enemy.y, 1);
					updateScore(score + enemy.points);
					// Chance to spawn power-up
					if (Math.random() < powerUpChance) {
						spawnPowerUp(enemy.x, enemy.y);
					}
					enemy.destroy();
					enemies.splice(j, 1);
				}
				// Remove bullet
				bullet.destroy();
				playerBullets.splice(i, 1);
				break;
			}
		}
	}
	// Update enemy bullets
	for (var i = enemyBullets.length - 1; i >= 0; i--) {
		var bullet = enemyBullets[i];
		// Check if bullet is off screen
		if (bullet.y > 2732 + 50) {
			bullet.destroy();
			enemyBullets.splice(i, 1);
			continue;
		}
		// Check for collision with player
		if (bullet.intersects(player)) {
			// Handle player hit
			if (player.takeDamage()) {
				// Game over
				gameActive = false;
				createExplosion(player.x, player.y, 2);
				LK.setTimeout(function () {
					LK.showGameOver();
				}, 1500);
			}
			updateLives();
			// Remove bullet
			bullet.destroy();
			enemyBullets.splice(i, 1);
		}
	}
	// Update enemies
	for (var i = enemies.length - 1; i >= 0; i--) {
		var enemy = enemies[i];
		// Check if enemy is off screen
		if (enemy.y > 2732 + 100) {
			enemy.destroy();
			enemies.splice(i, 1);
			continue;
		}
		// Check for collision with player
		if (enemy.intersects(player)) {
			// Handle player collision with enemy
			if (player.takeDamage()) {
				// Game over
				gameActive = false;
				createExplosion(player.x, player.y, 2);
				LK.setTimeout(function () {
					LK.showGameOver();
				}, 1500);
			}
			updateLives();
			// Destroy enemy
			createExplosion(enemy.x, enemy.y, 1);
			enemy.destroy();
			enemies.splice(i, 1);
			continue;
		}
		// Enemy shooting
		if (enemy.tryShoot()) {
			fireEnemyBullet(enemy);
		}
		// Update enemy
		enemy.update();
	}
	// Update power-ups
	for (var i = powerUps.length - 1; i >= 0; i--) {
		var powerUp = powerUps[i];
		// Check if power-up is off screen
		if (powerUp.y > 2732 + 50) {
			powerUp.destroy();
			powerUps.splice(i, 1);
			continue;
		}
		// Check for collision with player
		if (powerUp.intersects(player)) {
			// Apply power-up effect
			player.applyPowerUp(powerUp.type);
			// Play sound and add points
			LK.getSound('powerUp').play();
			updateScore(score + 50);
			// Remove power-up
			powerUp.destroy();
			powerUps.splice(i, 1);
			continue;
		}
		// Update power-up
		powerUp.update();
	}
	// Update explosions
	for (var i = explosions.length - 1; i >= 0; i--) {
		explosions[i].update();
		if (explosions[i].lifespan <= 0) {
			explosions.splice(i, 1);
		}
	}
};