/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
/**** 
* Classes
****/ 
// Alien invader
var Alien = Container.expand(function () {
	var self = Container.call(this);
	var alien = self.attachAsset('alien', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.width = alien.width;
	self.height = alien.height;
	self.row = 0;
	self.col = 0;
	self.direction = 1; // 1: right, -1: left
	self.speed = 2;
	self.shootCooldown = 0;
	self.alive = true;
	// Alien shoots
	self.shoot = function () {
		var bullet = new AlienBullet();
		bullet.x = self.x;
		bullet.y = self.y + self.height / 2 + bullet.height / 2;
		alienBullets.push(bullet);
		game.addChild(bullet);
		LK.getSound('alienShoot').play();
	};
	return self;
});
// Alien bullet
var AlienBullet = Container.expand(function () {
	var self = Container.call(this);
	var bullet = self.attachAsset('alienBullet', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.width = bullet.width;
	self.height = bullet.height;
	self.speed = 18;
	self.update = function () {
		self.y += self.speed;
	};
	return self;
});
// Player spaceship
var Player = Container.expand(function () {
	var self = Container.call(this);
	var ship = self.attachAsset('playerShip', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.width = ship.width;
	self.height = ship.height;
	self.canShoot = true;
	self.shootCooldown = 0;
	self.lives = 3;
	self.invincible = false;
	self.invincibleTimer = 0;
	self.poweredUp = false;
	self.powerupTimer = 0;
	// Shoot a bullet
	self.shoot = function () {
		if (!self.canShoot) return;
		var bullet = new PlayerBullet();
		bullet.x = self.x;
		bullet.y = self.y - self.height / 2 - bullet.height / 2;
		playerBullets.push(bullet);
		game.addChild(bullet);
		LK.getSound('shoot').play();
		self.canShoot = false;
		self.shootCooldown = 18; // 18 ticks ~0.3s
	};
	// Power-up effect
	self.activatePowerup = function () {
		self.poweredUp = true;
		self.powerupTimer = 360; // 6 seconds
		// Visual feedback: flash ship
		tween(self, {
			alpha: 0.5
		}, {
			duration: 120,
			easing: tween.easeIn,
			onFinish: function onFinish() {
				tween(self, {
					alpha: 1
				}, {
					duration: 120,
					easing: tween.easeOut
				});
			}
		});
	};
	// Invincibility effect
	self.setInvincible = function (duration) {
		self.invincible = true;
		self.invincibleTimer = duration;
		// Visual feedback: flicker
	};
	return self;
});
// Player bullet
var PlayerBullet = Container.expand(function () {
	var self = Container.call(this);
	var bullet = self.attachAsset('playerBullet', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.width = bullet.width;
	self.height = bullet.height;
	self.speed = -18;
	self.update = function () {
		self.y += self.speed;
	};
	return self;
});
// Power-up
var Powerup = Container.expand(function () {
	var self = Container.call(this);
	var p = self.attachAsset('powerup', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.width = p.width;
	self.height = p.height;
	self.speed = 10;
	self.type = 'rapid'; // Only one type for MVP
	self.update = function () {
		self.y += self.speed;
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x000010
});
/**** 
* Game Code
****/ 
// Music
// Sound effects
// Power-up
// Alien bullet
// Player bullet
// Alien invader
// Spaceship (player)
// Game constants
var GAME_WIDTH = 2048;
var GAME_HEIGHT = 2732;
var PLAYER_Y = GAME_HEIGHT - 220;
var ALIEN_ROWS = 4;
var ALIEN_COLS = 8;
var ALIEN_X_MARGIN = 120;
var ALIEN_Y_MARGIN = 120;
var ALIEN_SPACING_X = 180;
var ALIEN_SPACING_Y = 160;
var ALIEN_START_Y = 320;
var ALIEN_MOVE_DOWN = 60;
var ALIEN_BASE_SPEED = 2;
var ALIEN_SPEEDUP_PER_WAVE = 0.5;
var ALIEN_SHOOT_CHANCE = 0.008; // Per alien per tick
var POWERUP_CHANCE = 0.015; // Per tick, if no powerup present
// Game state
var player;
var aliens = [];
var playerBullets = [];
var alienBullets = [];
var powerups = [];
var wave = 1;
var score = 0;
var lives = 3;
var gameOver = false;
var youWin = false;
var moveDir = 1; // 1: right, -1: left
var moveDownPending = false;
var alienSpeed = ALIEN_BASE_SPEED;
var dragNode = null;
var lastTouchX = 0;
var lastTouchY = 0;
// GUI
var scoreTxt = new Text2('0', {
	size: 120,
	fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Heart icons for lives
var heartIcons = [];
var heartSpacing = 120;
for (var i = 0; i < 3; i++) {
	var heart = LK.getAsset('powerup', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: 120 + i * heartSpacing,
		y: 100,
		scaleX: 0.7,
		scaleY: 0.7
	});
	LK.gui.top.addChild(heart);
	heartIcons.push(heart);
}
var livesTxt = new Text2('', {
	size: 100,
	fill: 0xFF4444
});
livesTxt.anchor.set(0.5, 0);
LK.gui.topRight.addChild(livesTxt);
var waveTxt = new Text2('Wave 1', {
	size: 80,
	fill: 0x00FFCC
});
waveTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(waveTxt);
// Helper: update GUI
function updateGUI() {
	scoreTxt.setText(score);
	// Update heart icons visibility
	for (var i = 0; i < heartIcons.length; i++) {
		heartIcons[i].visible = i < lives;
	}
	var hearts = '';
	for (var i = 0; i < lives; i++) hearts += '♥';
	livesTxt.setText(hearts);
	waveTxt.setText('Wave ' + wave);
}
// Helper: spawn aliens in grid
function spawnAliens() {
	aliens = [];
	var totalWidth = (ALIEN_COLS - 1) * ALIEN_SPACING_X;
	var startX = (GAME_WIDTH - totalWidth) / 2;
	for (var row = 0; row < ALIEN_ROWS; row++) {
		for (var col = 0; col < ALIEN_COLS; col++) {
			var alien = new Alien();
			alien.x = startX + col * ALIEN_SPACING_X;
			alien.y = ALIEN_START_Y + row * ALIEN_SPACING_Y;
			alien.row = row;
			alien.col = col;
			alien.direction = moveDir;
			alien.speed = alienSpeed;
			aliens.push(alien);
			game.addChild(alien);
		}
	}
}
// Helper: start new wave
function startWave() {
	alienSpeed = ALIEN_BASE_SPEED + (wave - 1) * ALIEN_SPEEDUP_PER_WAVE;
	spawnAliens();
	moveDir = 1;
	moveDownPending = false;
	waveTxt.setText('Wave ' + wave);
}
// Helper: reset game
function resetGame() {
	// Remove all objects
	for (var i = 0; i < aliens.length; i++) aliens[i].destroy();
	for (var i = 0; i < playerBullets.length; i++) playerBullets[i].destroy();
	for (var i = 0; i < alienBullets.length; i++) alienBullets[i].destroy();
	for (var i = 0; i < powerups.length; i++) powerups[i].destroy();
	aliens = [];
	playerBullets = [];
	alienBullets = [];
	powerups = [];
	wave = 1;
	score = 0;
	lives = 3;
	gameOver = false;
	youWin = false;
	updateGUI();
	// Reset player
	if (player) player.destroy();
	player = new Player();
	player.x = GAME_WIDTH / 2;
	player.y = PLAYER_Y;
	game.addChild(player);
	startWave();
}
// Helper: show game over
function triggerGameOver() {
	if (gameOver) return;
	gameOver = true;
	LK.getSound('loseLife').play();
	LK.effects.flashScreen(0xff0000, 1200);
	LK.showGameOver();
}
// Helper: show win
function triggerYouWin() {
	if (youWin) return;
	youWin = true;
	LK.effects.flashScreen(0x00ff00, 1200);
	LK.showYouWin();
}
// Helper: spawn powerup
function spawnPowerup() {
	var p = new Powerup();
	p.x = 200 + Math.random() * (GAME_WIDTH - 400);
	p.y = 200;
	powerups.push(p);
	game.addChild(p);
}
// --- Start Screen Implementation ---
var startScreenOverlay = new Container();
var startBg = LK.getAsset('centerCircle', {
	anchorX: 0.5,
	anchorY: 0.5,
	x: GAME_WIDTH / 2,
	y: GAME_HEIGHT / 2,
	scaleX: 16,
	scaleY: 22,
	tint: 0x000010
});
startScreenOverlay.addChild(startBg);
var titleTxt = new Text2('SPACE INVADERS', {
	size: 220,
	fill: 0xFFFF00
});
titleTxt.anchor.set(0.5, 0.5);
titleTxt.x = GAME_WIDTH / 2;
titleTxt.y = GAME_HEIGHT / 2 - 320;
startScreenOverlay.addChild(titleTxt);
// Decorative player ship (centered, above button)
var decorPlayer = LK.getAsset('playerShip', {
	anchorX: 0.5,
	anchorY: 0.5,
	x: GAME_WIDTH / 2,
	y: GAME_HEIGHT / 2 - 80,
	scaleX: 1.2,
	scaleY: 1.2
});
startScreenOverlay.addChild(decorPlayer);
// Decorative powerups (left and right of player ship)
var decorPowerupLeft = LK.getAsset('powerup', {
	anchorX: 0.5,
	anchorY: 0.5,
	x: GAME_WIDTH / 2 - 220,
	y: GAME_HEIGHT / 2 - 80,
	scaleX: 0.9,
	scaleY: 0.9
});
var decorPowerupRight = LK.getAsset('powerup', {
	anchorX: 0.5,
	anchorY: 0.5,
	x: GAME_WIDTH / 2 + 220,
	y: GAME_HEIGHT / 2 - 80,
	scaleX: 0.9,
	scaleY: 0.9
});
startScreenOverlay.addChild(decorPowerupLeft);
startScreenOverlay.addChild(decorPowerupRight);
// Start button
var startBtn = new Text2('Start', {
	size: 140,
	fill: 0x00FFCC,
	background: 0x222222,
	padding: 60,
	radius: 60
});
startBtn.anchor.set(0.5, 0.5);
startBtn.x = GAME_WIDTH / 2;
startBtn.y = GAME_HEIGHT / 2 + 120;
startScreenOverlay.addChild(startBtn);
// Start button press handler
startBtn.down = function (x, y, obj) {
	if (!gameStarted) {
		gameStarted = true;
		startScreenOverlay.visible = false;
		resetGame();
		LK.playMusic('arcadebg', {
			fade: {
				start: 0,
				end: 1,
				duration: 1200
			}
		});
	}
};
// Decorative aliens removed from start screen
var creditsTxt = new Text2('by FRVR', {
	size: 80,
	fill: 0x00FFCC
});
creditsTxt.anchor.set(0.5, 0.5);
creditsTxt.x = GAME_WIDTH / 2;
creditsTxt.y = GAME_HEIGHT / 2 + 320;
startScreenOverlay.addChild(creditsTxt);
// No aliens on start screen!
game.addChild(startScreenOverlay);
// Ensure no aliens are deleted from the game on the start screen
for (var i = 0; i < aliens.length; i++) {
	if (aliens[i]) {
		aliens[i].destroy();
	}
}
aliens = [];
var gameStarted = false;
// Only allow tap to start when on start screen
game.down = function (x, y, obj) {
	if (gameOver || youWin) return;
	// Check if touch is on player ship
	if (player && y > player.y - player.height / 2 && y < player.y + player.height / 2 && x > player.x - player.width / 2 && x < player.x + player.width / 2) {
		draggingPlayer = true;
		dragOffsetX = x - player.x;
	} else {
		// Tap elsewhere: do nothing (auto-shoot enabled)
	}
};
// --- End Start Screen Implementation ---
// Drag-to-move and tap-to-shoot controls
var draggingPlayer = false;
var dragOffsetX = 0;
game.down = function (x, y, obj) {
	if (gameOver || youWin) return;
	// Check if touch is on player ship
	if (player && y > player.y - player.height / 2 && y < player.y + player.height / 2 && x > player.x - player.width / 2 && x < player.x + player.width / 2) {
		draggingPlayer = true;
		dragOffsetX = x - player.x;
	} else {
		// Tap elsewhere: do nothing (auto-shoot enabled)
	}
};
game.move = function (x, y, obj) {
	if (draggingPlayer && !gameOver && !youWin) {
		// Clamp player within screen bounds
		var minX = player.width / 2;
		var maxX = GAME_WIDTH - player.width / 2;
		var newX = Math.max(minX, Math.min(x - dragOffsetX, maxX));
		player.x = newX;
	}
};
game.up = function (x, y, obj) {
	draggingPlayer = false;
};
// Main game loop
game.update = function () {
	if (gameOver || youWin) return;
	// Player auto-shooting
	if (player && !player.canShoot) {
		player.shootCooldown--;
		if (player.shootCooldown <= 0) player.canShoot = true;
	}
	if (player && player.canShoot) {
		player.shoot();
	}
	// Powerup timer
	if (player && player.poweredUp) {
		player.powerupTimer--;
		if (player.powerupTimer <= 0) {
			player.poweredUp = false;
		}
	}
	// Invincibility timer
	if (player && player.invincible) {
		player.invincibleTimer--;
		// Flicker effect
		player.alpha = LK.ticks % 10 < 5 ? 0.4 : 1;
		if (player.invincibleTimer <= 0) {
			player.invincible = false;
			player.alpha = 1;
		}
	}
	// Move aliens
	var leftmost = GAME_WIDTH,
		rightmost = 0,
		bottommost = 0;
	for (var i = 0; i < aliens.length; i++) {
		var a = aliens[i];
		if (!a.alive) continue;
		a.x += moveDir * alienSpeed;
		if (a.x - a.width / 2 < leftmost) leftmost = a.x - a.width / 2;
		if (a.x + a.width / 2 > rightmost) rightmost = a.x + a.width / 2;
		if (a.y + a.height / 2 > bottommost) bottommost = a.y + a.height / 2;
	}
	// Change direction if at edge
	if (!moveDownPending && (leftmost < ALIEN_X_MARGIN || rightmost > GAME_WIDTH - ALIEN_X_MARGIN)) {
		moveDir *= -1;
		moveDownPending = true;
	}
	if (moveDownPending) {
		for (var i = 0; i < aliens.length; i++) {
			var a = aliens[i];
			if (!a.alive) continue;
			a.y += ALIEN_MOVE_DOWN;
		}
		moveDownPending = false;
	}
	// Aliens shoot randomly, but only bottom-most alive in each column can shoot
	var bottomAliens = {};
	for (var i = 0; i < aliens.length; i++) {
		var a = aliens[i];
		if (!a.alive) continue;
		// Track the bottom-most alive alien in each column
		if (!bottomAliens[a.col] || a.y > bottomAliens[a.col].y) {
			bottomAliens[a.col] = a;
		}
	}
	// Only allow a few (e.g. 2) random bottom aliens to shoot per tick
	var shootableAliens = [];
	for (var col in bottomAliens) {
		shootableAliens.push(bottomAliens[col]);
	}
	var maxShooters = 2;
	for (var s = 0; s < maxShooters && shootableAliens.length > 0; s++) {
		var idx = Math.floor(Math.random() * shootableAliens.length);
		var a = shootableAliens[idx];
		if (Math.random() < ALIEN_SHOOT_CHANCE + 0.001 * wave) {
			a.shoot();
		}
		shootableAliens.splice(idx, 1);
	}
	// Update player bullets
	for (var i = playerBullets.length - 1; i >= 0; i--) {
		var b = playerBullets[i];
		b.update();
		// Remove if off screen
		if (b.y < -b.height) {
			b.destroy();
			playerBullets.splice(i, 1);
			continue;
		}
		// Check collision with aliens
		for (var j = 0; j < aliens.length; j++) {
			var a = aliens[j];
			if (!a.alive) continue;
			if (b.intersects(a)) {
				a.alive = false;
				a.visible = false;
				b.destroy();
				playerBullets.splice(i, 1);
				LK.getSound('alienExplode').play();
				score += 10;
				updateGUI();
				break;
			}
		}
	}
	// Update alien bullets
	for (var i = alienBullets.length - 1; i >= 0; i--) {
		var b = alienBullets[i];
		b.update();
		// Remove if off screen
		if (b.y > GAME_HEIGHT + b.height) {
			b.destroy();
			alienBullets.splice(i, 1);
			continue;
		}
		// Check collision with player
		if (player && !player.invincible && b.intersects(player)) {
			b.destroy();
			alienBullets.splice(i, 1);
			// Lose life
			lives--;
			updateGUI();
			LK.getSound('hit').play();
			if (lives <= 0) {
				triggerGameOver();
				return;
			} else {
				player.setInvincible(90); // 1.5s invincibility
			}
		}
	}
	// Update powerups
	for (var i = powerups.length - 1; i >= 0; i--) {
		var p = powerups[i];
		p.update();
		if (p.y > GAME_HEIGHT + p.height) {
			p.destroy();
			powerups.splice(i, 1);
			continue;
		}
		if (p.intersects(player)) {
			LK.getSound('powerup').play();
			// Only restore up to 3 hearts
			if (lives < 3) {
				lives = 3;
				updateGUI();
			}
			p.destroy();
			powerups.splice(i, 1);
		}
	}
	// Powerup spawn
	if (powerups.length === 0 && Math.random() < POWERUP_CHANCE) {
		spawnPowerup();
	}
	// Check if aliens reach player
	for (var i = 0; i < aliens.length; i++) {
		var a = aliens[i];
		if (!a.alive) continue;
		if (player && a.y + a.height / 2 >= player.y - player.height / 2) {
			triggerGameOver();
			return;
		}
	}
	// Next wave if all aliens dead
	var anyAlive = false;
	for (var i = 0; i < aliens.length; i++) {
		if (aliens[i].alive) {
			anyAlive = true;
			break;
		}
	}
	if (!anyAlive) {
		wave++;
		if (wave > 10) {
			triggerYouWin();
			return;
		}
		startWave();
	}
};
// Clean up on game over or reset
game.on('destroy', function () {
	LK.stopMusic();
}); /**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
/**** 
* Classes
****/ 
// Alien invader
var Alien = Container.expand(function () {
	var self = Container.call(this);
	var alien = self.attachAsset('alien', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.width = alien.width;
	self.height = alien.height;
	self.row = 0;
	self.col = 0;
	self.direction = 1; // 1: right, -1: left
	self.speed = 2;
	self.shootCooldown = 0;
	self.alive = true;
	// Alien shoots
	self.shoot = function () {
		var bullet = new AlienBullet();
		bullet.x = self.x;
		bullet.y = self.y + self.height / 2 + bullet.height / 2;
		alienBullets.push(bullet);
		game.addChild(bullet);
		LK.getSound('alienShoot').play();
	};
	return self;
});
// Alien bullet
var AlienBullet = Container.expand(function () {
	var self = Container.call(this);
	var bullet = self.attachAsset('alienBullet', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.width = bullet.width;
	self.height = bullet.height;
	self.speed = 18;
	self.update = function () {
		self.y += self.speed;
	};
	return self;
});
// Player spaceship
var Player = Container.expand(function () {
	var self = Container.call(this);
	var ship = self.attachAsset('playerShip', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.width = ship.width;
	self.height = ship.height;
	self.canShoot = true;
	self.shootCooldown = 0;
	self.lives = 3;
	self.invincible = false;
	self.invincibleTimer = 0;
	self.poweredUp = false;
	self.powerupTimer = 0;
	// Shoot a bullet
	self.shoot = function () {
		if (!self.canShoot) return;
		var bullet = new PlayerBullet();
		bullet.x = self.x;
		bullet.y = self.y - self.height / 2 - bullet.height / 2;
		playerBullets.push(bullet);
		game.addChild(bullet);
		LK.getSound('shoot').play();
		self.canShoot = false;
		self.shootCooldown = 18; // 18 ticks ~0.3s
	};
	// Power-up effect
	self.activatePowerup = function () {
		self.poweredUp = true;
		self.powerupTimer = 360; // 6 seconds
		// Visual feedback: flash ship
		tween(self, {
			alpha: 0.5
		}, {
			duration: 120,
			easing: tween.easeIn,
			onFinish: function onFinish() {
				tween(self, {
					alpha: 1
				}, {
					duration: 120,
					easing: tween.easeOut
				});
			}
		});
	};
	// Invincibility effect
	self.setInvincible = function (duration) {
		self.invincible = true;
		self.invincibleTimer = duration;
		// Visual feedback: flicker
	};
	return self;
});
// Player bullet
var PlayerBullet = Container.expand(function () {
	var self = Container.call(this);
	var bullet = self.attachAsset('playerBullet', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.width = bullet.width;
	self.height = bullet.height;
	self.speed = -18;
	self.update = function () {
		self.y += self.speed;
	};
	return self;
});
// Power-up
var Powerup = Container.expand(function () {
	var self = Container.call(this);
	var p = self.attachAsset('powerup', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.width = p.width;
	self.height = p.height;
	self.speed = 10;
	self.type = 'rapid'; // Only one type for MVP
	self.update = function () {
		self.y += self.speed;
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x000010
});
/**** 
* Game Code
****/ 
// Music
// Sound effects
// Power-up
// Alien bullet
// Player bullet
// Alien invader
// Spaceship (player)
// Game constants
var GAME_WIDTH = 2048;
var GAME_HEIGHT = 2732;
var PLAYER_Y = GAME_HEIGHT - 220;
var ALIEN_ROWS = 4;
var ALIEN_COLS = 8;
var ALIEN_X_MARGIN = 120;
var ALIEN_Y_MARGIN = 120;
var ALIEN_SPACING_X = 180;
var ALIEN_SPACING_Y = 160;
var ALIEN_START_Y = 320;
var ALIEN_MOVE_DOWN = 60;
var ALIEN_BASE_SPEED = 2;
var ALIEN_SPEEDUP_PER_WAVE = 0.5;
var ALIEN_SHOOT_CHANCE = 0.008; // Per alien per tick
var POWERUP_CHANCE = 0.015; // Per tick, if no powerup present
// Game state
var player;
var aliens = [];
var playerBullets = [];
var alienBullets = [];
var powerups = [];
var wave = 1;
var score = 0;
var lives = 3;
var gameOver = false;
var youWin = false;
var moveDir = 1; // 1: right, -1: left
var moveDownPending = false;
var alienSpeed = ALIEN_BASE_SPEED;
var dragNode = null;
var lastTouchX = 0;
var lastTouchY = 0;
// GUI
var scoreTxt = new Text2('0', {
	size: 120,
	fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Heart icons for lives
var heartIcons = [];
var heartSpacing = 120;
for (var i = 0; i < 3; i++) {
	var heart = LK.getAsset('powerup', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: 120 + i * heartSpacing,
		y: 100,
		scaleX: 0.7,
		scaleY: 0.7
	});
	LK.gui.top.addChild(heart);
	heartIcons.push(heart);
}
var livesTxt = new Text2('', {
	size: 100,
	fill: 0xFF4444
});
livesTxt.anchor.set(0.5, 0);
LK.gui.topRight.addChild(livesTxt);
var waveTxt = new Text2('Wave 1', {
	size: 80,
	fill: 0x00FFCC
});
waveTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(waveTxt);
// Helper: update GUI
function updateGUI() {
	scoreTxt.setText(score);
	// Update heart icons visibility
	for (var i = 0; i < heartIcons.length; i++) {
		heartIcons[i].visible = i < lives;
	}
	var hearts = '';
	for (var i = 0; i < lives; i++) hearts += '♥';
	livesTxt.setText(hearts);
	waveTxt.setText('Wave ' + wave);
}
// Helper: spawn aliens in grid
function spawnAliens() {
	aliens = [];
	var totalWidth = (ALIEN_COLS - 1) * ALIEN_SPACING_X;
	var startX = (GAME_WIDTH - totalWidth) / 2;
	for (var row = 0; row < ALIEN_ROWS; row++) {
		for (var col = 0; col < ALIEN_COLS; col++) {
			var alien = new Alien();
			alien.x = startX + col * ALIEN_SPACING_X;
			alien.y = ALIEN_START_Y + row * ALIEN_SPACING_Y;
			alien.row = row;
			alien.col = col;
			alien.direction = moveDir;
			alien.speed = alienSpeed;
			aliens.push(alien);
			game.addChild(alien);
		}
	}
}
// Helper: start new wave
function startWave() {
	alienSpeed = ALIEN_BASE_SPEED + (wave - 1) * ALIEN_SPEEDUP_PER_WAVE;
	spawnAliens();
	moveDir = 1;
	moveDownPending = false;
	waveTxt.setText('Wave ' + wave);
}
// Helper: reset game
function resetGame() {
	// Remove all objects
	for (var i = 0; i < aliens.length; i++) aliens[i].destroy();
	for (var i = 0; i < playerBullets.length; i++) playerBullets[i].destroy();
	for (var i = 0; i < alienBullets.length; i++) alienBullets[i].destroy();
	for (var i = 0; i < powerups.length; i++) powerups[i].destroy();
	aliens = [];
	playerBullets = [];
	alienBullets = [];
	powerups = [];
	wave = 1;
	score = 0;
	lives = 3;
	gameOver = false;
	youWin = false;
	updateGUI();
	// Reset player
	if (player) player.destroy();
	player = new Player();
	player.x = GAME_WIDTH / 2;
	player.y = PLAYER_Y;
	game.addChild(player);
	startWave();
}
// Helper: show game over
function triggerGameOver() {
	if (gameOver) return;
	gameOver = true;
	LK.getSound('loseLife').play();
	LK.effects.flashScreen(0xff0000, 1200);
	LK.showGameOver();
}
// Helper: show win
function triggerYouWin() {
	if (youWin) return;
	youWin = true;
	LK.effects.flashScreen(0x00ff00, 1200);
	LK.showYouWin();
}
// Helper: spawn powerup
function spawnPowerup() {
	var p = new Powerup();
	p.x = 200 + Math.random() * (GAME_WIDTH - 400);
	p.y = 200;
	powerups.push(p);
	game.addChild(p);
}
// --- Start Screen Implementation ---
var startScreenOverlay = new Container();
var startBg = LK.getAsset('centerCircle', {
	anchorX: 0.5,
	anchorY: 0.5,
	x: GAME_WIDTH / 2,
	y: GAME_HEIGHT / 2,
	scaleX: 16,
	scaleY: 22,
	tint: 0x000010
});
startScreenOverlay.addChild(startBg);
var titleTxt = new Text2('SPACE INVADERS', {
	size: 220,
	fill: 0xFFFF00
});
titleTxt.anchor.set(0.5, 0.5);
titleTxt.x = GAME_WIDTH / 2;
titleTxt.y = GAME_HEIGHT / 2 - 320;
startScreenOverlay.addChild(titleTxt);
// Decorative player ship (centered, above button)
var decorPlayer = LK.getAsset('playerShip', {
	anchorX: 0.5,
	anchorY: 0.5,
	x: GAME_WIDTH / 2,
	y: GAME_HEIGHT / 2 - 80,
	scaleX: 1.2,
	scaleY: 1.2
});
startScreenOverlay.addChild(decorPlayer);
// Decorative powerups (left and right of player ship)
var decorPowerupLeft = LK.getAsset('powerup', {
	anchorX: 0.5,
	anchorY: 0.5,
	x: GAME_WIDTH / 2 - 220,
	y: GAME_HEIGHT / 2 - 80,
	scaleX: 0.9,
	scaleY: 0.9
});
var decorPowerupRight = LK.getAsset('powerup', {
	anchorX: 0.5,
	anchorY: 0.5,
	x: GAME_WIDTH / 2 + 220,
	y: GAME_HEIGHT / 2 - 80,
	scaleX: 0.9,
	scaleY: 0.9
});
startScreenOverlay.addChild(decorPowerupLeft);
startScreenOverlay.addChild(decorPowerupRight);
// Start button
var startBtn = new Text2('Start', {
	size: 140,
	fill: 0x00FFCC,
	background: 0x222222,
	padding: 60,
	radius: 60
});
startBtn.anchor.set(0.5, 0.5);
startBtn.x = GAME_WIDTH / 2;
startBtn.y = GAME_HEIGHT / 2 + 120;
startScreenOverlay.addChild(startBtn);
// Start button press handler
startBtn.down = function (x, y, obj) {
	if (!gameStarted) {
		gameStarted = true;
		startScreenOverlay.visible = false;
		resetGame();
		LK.playMusic('arcadebg', {
			fade: {
				start: 0,
				end: 1,
				duration: 1200
			}
		});
	}
};
// Decorative aliens removed from start screen
var creditsTxt = new Text2('by FRVR', {
	size: 80,
	fill: 0x00FFCC
});
creditsTxt.anchor.set(0.5, 0.5);
creditsTxt.x = GAME_WIDTH / 2;
creditsTxt.y = GAME_HEIGHT / 2 + 320;
startScreenOverlay.addChild(creditsTxt);
// No aliens on start screen!
game.addChild(startScreenOverlay);
// Ensure no aliens are deleted from the game on the start screen
for (var i = 0; i < aliens.length; i++) {
	if (aliens[i]) {
		aliens[i].destroy();
	}
}
aliens = [];
var gameStarted = false;
// Only allow tap to start when on start screen
game.down = function (x, y, obj) {
	if (gameOver || youWin) return;
	// Check if touch is on player ship
	if (player && y > player.y - player.height / 2 && y < player.y + player.height / 2 && x > player.x - player.width / 2 && x < player.x + player.width / 2) {
		draggingPlayer = true;
		dragOffsetX = x - player.x;
	} else {
		// Tap elsewhere: do nothing (auto-shoot enabled)
	}
};
// --- End Start Screen Implementation ---
// Drag-to-move and tap-to-shoot controls
var draggingPlayer = false;
var dragOffsetX = 0;
game.down = function (x, y, obj) {
	if (gameOver || youWin) return;
	// Check if touch is on player ship
	if (player && y > player.y - player.height / 2 && y < player.y + player.height / 2 && x > player.x - player.width / 2 && x < player.x + player.width / 2) {
		draggingPlayer = true;
		dragOffsetX = x - player.x;
	} else {
		// Tap elsewhere: do nothing (auto-shoot enabled)
	}
};
game.move = function (x, y, obj) {
	if (draggingPlayer && !gameOver && !youWin) {
		// Clamp player within screen bounds
		var minX = player.width / 2;
		var maxX = GAME_WIDTH - player.width / 2;
		var newX = Math.max(minX, Math.min(x - dragOffsetX, maxX));
		player.x = newX;
	}
};
game.up = function (x, y, obj) {
	draggingPlayer = false;
};
// Main game loop
game.update = function () {
	if (gameOver || youWin) return;
	// Player auto-shooting
	if (player && !player.canShoot) {
		player.shootCooldown--;
		if (player.shootCooldown <= 0) player.canShoot = true;
	}
	if (player && player.canShoot) {
		player.shoot();
	}
	// Powerup timer
	if (player && player.poweredUp) {
		player.powerupTimer--;
		if (player.powerupTimer <= 0) {
			player.poweredUp = false;
		}
	}
	// Invincibility timer
	if (player && player.invincible) {
		player.invincibleTimer--;
		// Flicker effect
		player.alpha = LK.ticks % 10 < 5 ? 0.4 : 1;
		if (player.invincibleTimer <= 0) {
			player.invincible = false;
			player.alpha = 1;
		}
	}
	// Move aliens
	var leftmost = GAME_WIDTH,
		rightmost = 0,
		bottommost = 0;
	for (var i = 0; i < aliens.length; i++) {
		var a = aliens[i];
		if (!a.alive) continue;
		a.x += moveDir * alienSpeed;
		if (a.x - a.width / 2 < leftmost) leftmost = a.x - a.width / 2;
		if (a.x + a.width / 2 > rightmost) rightmost = a.x + a.width / 2;
		if (a.y + a.height / 2 > bottommost) bottommost = a.y + a.height / 2;
	}
	// Change direction if at edge
	if (!moveDownPending && (leftmost < ALIEN_X_MARGIN || rightmost > GAME_WIDTH - ALIEN_X_MARGIN)) {
		moveDir *= -1;
		moveDownPending = true;
	}
	if (moveDownPending) {
		for (var i = 0; i < aliens.length; i++) {
			var a = aliens[i];
			if (!a.alive) continue;
			a.y += ALIEN_MOVE_DOWN;
		}
		moveDownPending = false;
	}
	// Aliens shoot randomly, but only bottom-most alive in each column can shoot
	var bottomAliens = {};
	for (var i = 0; i < aliens.length; i++) {
		var a = aliens[i];
		if (!a.alive) continue;
		// Track the bottom-most alive alien in each column
		if (!bottomAliens[a.col] || a.y > bottomAliens[a.col].y) {
			bottomAliens[a.col] = a;
		}
	}
	// Only allow a few (e.g. 2) random bottom aliens to shoot per tick
	var shootableAliens = [];
	for (var col in bottomAliens) {
		shootableAliens.push(bottomAliens[col]);
	}
	var maxShooters = 2;
	for (var s = 0; s < maxShooters && shootableAliens.length > 0; s++) {
		var idx = Math.floor(Math.random() * shootableAliens.length);
		var a = shootableAliens[idx];
		if (Math.random() < ALIEN_SHOOT_CHANCE + 0.001 * wave) {
			a.shoot();
		}
		shootableAliens.splice(idx, 1);
	}
	// Update player bullets
	for (var i = playerBullets.length - 1; i >= 0; i--) {
		var b = playerBullets[i];
		b.update();
		// Remove if off screen
		if (b.y < -b.height) {
			b.destroy();
			playerBullets.splice(i, 1);
			continue;
		}
		// Check collision with aliens
		for (var j = 0; j < aliens.length; j++) {
			var a = aliens[j];
			if (!a.alive) continue;
			if (b.intersects(a)) {
				a.alive = false;
				a.visible = false;
				b.destroy();
				playerBullets.splice(i, 1);
				LK.getSound('alienExplode').play();
				score += 10;
				updateGUI();
				break;
			}
		}
	}
	// Update alien bullets
	for (var i = alienBullets.length - 1; i >= 0; i--) {
		var b = alienBullets[i];
		b.update();
		// Remove if off screen
		if (b.y > GAME_HEIGHT + b.height) {
			b.destroy();
			alienBullets.splice(i, 1);
			continue;
		}
		// Check collision with player
		if (player && !player.invincible && b.intersects(player)) {
			b.destroy();
			alienBullets.splice(i, 1);
			// Lose life
			lives--;
			updateGUI();
			LK.getSound('hit').play();
			if (lives <= 0) {
				triggerGameOver();
				return;
			} else {
				player.setInvincible(90); // 1.5s invincibility
			}
		}
	}
	// Update powerups
	for (var i = powerups.length - 1; i >= 0; i--) {
		var p = powerups[i];
		p.update();
		if (p.y > GAME_HEIGHT + p.height) {
			p.destroy();
			powerups.splice(i, 1);
			continue;
		}
		if (p.intersects(player)) {
			LK.getSound('powerup').play();
			// Only restore up to 3 hearts
			if (lives < 3) {
				lives = 3;
				updateGUI();
			}
			p.destroy();
			powerups.splice(i, 1);
		}
	}
	// Powerup spawn
	if (powerups.length === 0 && Math.random() < POWERUP_CHANCE) {
		spawnPowerup();
	}
	// Check if aliens reach player
	for (var i = 0; i < aliens.length; i++) {
		var a = aliens[i];
		if (!a.alive) continue;
		if (player && a.y + a.height / 2 >= player.y - player.height / 2) {
			triggerGameOver();
			return;
		}
	}
	// Next wave if all aliens dead
	var anyAlive = false;
	for (var i = 0; i < aliens.length; i++) {
		if (aliens[i].alive) {
			anyAlive = true;
			break;
		}
	}
	if (!anyAlive) {
		wave++;
		if (wave > 10) {
			triggerYouWin();
			return;
		}
		startWave();
	}
};
// Clean up on game over or reset
game.on('destroy', function () {
	LK.stopMusic();
});