/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/**** 
* Classes
****/ 
var Bullet = Container.expand(function () {
	var self = Container.call(this);
	var bulletGraphic = self.attachAsset('bullet', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 15;
	self.damage = 10;
	self.isPlayerBullet = true;
	self.update = function () {
		self.y -= self.speed;
		// Check if bullet is off screen
		if (self.y < -50 || self.y > 2732 + 50 || self.x < -50 || self.x > 2048 + 50) {
			return true; // Signal for removal
		}
		return false;
	};
	return self;
});
var EnemyBullet = Bullet.expand(function () {
	var self = Bullet.call(this);
	// Replace the bullet graphic with enemy bullet
	self.removeChildren();
	var bulletGraphic = self.attachAsset('enemyBullet', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 8;
	self.damage = 15;
	self.isPlayerBullet = false;
	self.update = function () {
		self.y += self.speed;
		// Check if bullet is off screen
		if (self.y < -50 || self.y > 2732 + 50 || self.x < -50 || self.x > 2048 + 50) {
			return true; // Signal for removal
		}
		return false;
	};
	return self;
});
var Enemy = Container.expand(function () {
	var self = Container.call(this);
	var enemyGraphic = self.attachAsset('enemy', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.health = 30;
	self.points = 200;
	self.speed = 3;
	self.direction = 1;
	self.shootDelay = 60;
	self.lastShot = 0;
	self.update = function () {
		self.x += self.speed * self.direction;
		// Boundary check and reverse direction
		if (self.x > 2048 - 100 || self.x < 100) {
			self.direction *= -1;
		}
		// Shooting logic
		self.lastShot++;
		if (self.lastShot >= self.shootDelay) {
			self.lastShot = 0;
			return true; // Signal to shoot
		}
		return false; // No shooting this update
	};
	self.hit = function (damage) {
		self.health -= damage;
		LK.effects.flashObject(enemyGraphic, 0xff0000, 200);
		LK.getSound('hit').play();
		if (self.health <= 0) {
			LK.getSound('explosion').play();
			return true; // Enemy destroyed
		}
		return false; // Enemy still alive
	};
	return self;
});
var Explosion = Container.expand(function () {
	var self = Container.call(this);
	var explosionGraphic = self.attachAsset('explosion', {
		anchorX: 0.5,
		anchorY: 0.5,
		alpha: 0.8
	});
	self.lifetime = 0;
	self.duration = 30; // Frames
	self.update = function () {
		self.lifetime++;
		// Scale explosion up then down
		if (self.lifetime < self.duration / 2) {
			explosionGraphic.scale.set(1 + self.lifetime / (self.duration / 2));
		} else {
			explosionGraphic.scale.set(2 - (self.lifetime - self.duration / 2) / (self.duration / 2));
		}
		// Fade out
		explosionGraphic.alpha = 0.8 * (1 - self.lifetime / self.duration);
		if (self.lifetime >= self.duration) {
			return true; // Signal for removal
		}
		return false;
	};
	return self;
});
var Obstacle = Container.expand(function () {
	var self = Container.call(this);
	var obstacleGraphic = self.attachAsset('obstacle', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.health = 100;
	self.hit = function (damage) {
		self.health -= damage;
		LK.effects.flashObject(obstacleGraphic, 0x666666, 200);
		if (self.health <= 0) {
			return true; // Obstacle destroyed
		}
		return false; // Obstacle still intact
	};
	return self;
});
var Player = Container.expand(function () {
	var self = Container.call(this);
	var playerGraphic = self.attachAsset('player', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 10;
	self.health = 100;
	self.powerLevel = 1;
	self.invincible = false;
	self.lastShot = 0;
	self.shootDelay = 15;
	self.flash = function () {
		if (self.invincible) {
			return;
		}
		self.invincible = true;
		LK.effects.flashObject(playerGraphic, 0xffffff, 500);
		LK.setTimeout(function () {
			self.invincible = false;
		}, 1500);
	};
	self.takeDamage = function (amount) {
		if (self.invincible) {
			return false;
		}
		self.health -= amount;
		self.flash();
		if (self.health <= 0) {
			return true; // Player died
		}
		return false; // Player still alive
	};
	self.increasePower = function () {
		if (self.powerLevel < 3) {
			self.powerLevel++;
			self.shootDelay = Math.max(5, self.shootDelay - 3);
			return true;
		}
		return false;
	};
	return self;
});
var PowerUp = Container.expand(function () {
	var self = Container.call(this);
	var powerupGraphic = self.attachAsset('powerup', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.type = "weapon"; // Default powerup type
	self.speed = 2;
	self.update = function () {
		self.y += self.speed;
		// Check if powerup is off screen
		if (self.y > 2732 + 50) {
			return true; // Signal for removal
		}
		return false;
	};
	// Make the powerup pulse
	function pulse() {
		tween(powerupGraphic, {
			alpha: 0.6
		}, {
			duration: 500,
			easing: tween.easeInOut,
			onFinish: function onFinish() {
				tween(powerupGraphic, {
					alpha: 1
				}, {
					duration: 500,
					easing: tween.easeInOut,
					onFinish: pulse
				});
			}
		});
	}
	pulse();
	return self;
});
var Target = Container.expand(function () {
	var self = Container.call(this);
	var targetGraphic = self.attachAsset('target', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.health = 20;
	self.points = 100;
	self.speed = 0;
	self.direction = 1; // 1 for right, -1 for left
	self.update = function () {
		if (self.speed > 0) {
			self.x += self.speed * self.direction;
			// Boundary check and reverse direction
			if (self.x > 2048 - 100 || self.x < 100) {
				self.direction *= -1;
			}
		}
		return false; // Not to be removed yet
	};
	self.hit = function (damage) {
		self.health -= damage;
		LK.effects.flashObject(targetGraphic, 0xff0000, 200);
		LK.getSound('hit').play();
		if (self.health <= 0) {
			LK.getSound('explosion').play();
			return true; // Target destroyed
		}
		return false; // Target still alive
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x000033
});
/**** 
* Game Code
****/ 
// Game state
var gameActive = true;
var waveNumber = 1;
var timeLeft = 60;
var scoreMultiplier = 1;
var combo = 0;
var comboTimer = 0;
var lastFrameTime = Date.now();
// Game elements
var player;
var bullets = [];
var enemyBullets = [];
var targets = [];
var enemies = [];
var obstacles = [];
var powerups = [];
var explosions = [];
// UI elements
var scoreTxt;
var multiplierTxt;
var waveTxt;
var timeTxt;
var healthBar;
var healthBarBg;
// Game controls
var touchX = null;
var touchY = null;
var isTouching = false;
// Initialize UI
function initUI() {
	// Score display
	scoreTxt = new Text2('0', {
		size: 70,
		fill: 0xFFFFFF
	});
	scoreTxt.anchor.set(0.5, 0);
	LK.gui.top.addChild(scoreTxt);
	// Wave display
	waveTxt = new Text2('WAVE 1', {
		size: 50,
		fill: 0xFFCC00
	});
	waveTxt.anchor.set(0, 0);
	waveTxt.x = 150;
	waveTxt.y = 20;
	LK.gui.topLeft.addChild(waveTxt);
	// Time display
	timeTxt = new Text2('60s', {
		size: 50,
		fill: 0xFFFFFF
	});
	timeTxt.anchor.set(1, 0);
	timeTxt.x = -20;
	timeTxt.y = 20;
	LK.gui.topRight.addChild(timeTxt);
	// Multiplier display
	multiplierTxt = new Text2('x1', {
		size: 50,
		fill: 0x00FFFF
	});
	multiplierTxt.anchor.set(0.5, 0);
	multiplierTxt.y = 80;
	LK.gui.top.addChild(multiplierTxt);
	// Health bar background
	healthBarBg = LK.getAsset('obstacle', {
		width: 300,
		height: 30,
		anchorX: 0,
		anchorY: 0,
		x: 20,
		y: 80,
		tint: 0x333333
	});
	LK.gui.topLeft.addChild(healthBarBg);
	// Health bar
	healthBar = LK.getAsset('player', {
		width: 300,
		height: 30,
		anchorX: 0,
		anchorY: 0,
		x: 20,
		y: 80,
		tint: 0x00ff00
	});
	LK.gui.topLeft.addChild(healthBar);
}
// Start the game
function startGame() {
	// Initialize player
	player = new Player();
	player.x = 2048 / 2;
	player.y = 2732 - 200;
	game.addChild(player);
	// Initialize UI
	initUI();
	// Setup first wave
	setupWave(waveNumber);
	// Start timer
	gameTimer = LK.setInterval(function () {
		timeLeft--;
		timeTxt.setText(timeLeft + 's');
		if (timeLeft <= 0) {
			endWave();
		}
	}, 1000);
	// Play background music
	LK.playMusic('gameplay');
	// Update score display
	updateScore();
}
// Set up a new wave
function setupWave(wave) {
	// Clear any existing entities
	clearEntities();
	// Set wave text
	waveTxt.setText('WAVE ' + wave);
	// Create targets based on wave number
	var numTargets = 5 + wave * 2;
	for (var i = 0; i < numTargets; i++) {
		var target = new Target();
		target.x = 200 + i * 200 % (2048 - 400);
		target.y = 200 + Math.floor(i / 9) * 150;
		target.speed = 1 + wave * 0.5;
		target.health = 20 + wave * 10;
		target.points = 100 + wave * 20;
		if (i % 3 === 0) {
			target.direction = -1;
		}
		targets.push(target);
		game.addChild(target);
	}
	// Add enemies for higher waves
	if (wave > 1) {
		var numEnemies = Math.min(wave, 5);
		for (var j = 0; j < numEnemies; j++) {
			var enemy = new Enemy();
			enemy.x = 300 + j * 350;
			enemy.y = 400;
			enemy.speed = 2 + wave * 0.3;
			enemy.health = 30 + wave * 15;
			enemy.shootDelay = Math.max(30, 60 - wave * 5);
			enemies.push(enemy);
			game.addChild(enemy);
		}
	}
	// Add obstacles
	var numObstacles = Math.min(3, Math.floor(wave / 2));
	for (var k = 0; k < numObstacles; k++) {
		var obstacle = new Obstacle();
		obstacle.x = 400 + k * 600;
		obstacle.y = 700;
		obstacles.push(obstacle);
		game.addChild(obstacle);
	}
	// Reset timer
	timeLeft = 60;
	timeTxt.setText(timeLeft + 's');
}
// End the current wave
function endWave() {
	waveNumber++;
	// If player completed all waves, show win
	if (waveNumber > 5) {
		LK.showYouWin();
		return;
	}
	// Award bonus points for completing wave
	var timeBonus = timeLeft * 10;
	LK.setScore(LK.getScore() + timeBonus);
	updateScore();
	// Set up new wave
	setupWave(waveNumber);
}
// Clear all entities except player
function clearEntities() {
	// Clear bullets
	for (var i = bullets.length - 1; i >= 0; i--) {
		bullets[i].destroy();
	}
	bullets = [];
	// Clear enemy bullets
	for (var j = enemyBullets.length - 1; j >= 0; j--) {
		enemyBullets[j].destroy();
	}
	enemyBullets = [];
	// Clear targets
	for (var k = targets.length - 1; k >= 0; k--) {
		targets[k].destroy();
	}
	targets = [];
	// Clear enemies
	for (var l = enemies.length - 1; l >= 0; l--) {
		enemies[l].destroy();
	}
	enemies = [];
	// Clear obstacles
	for (var m = obstacles.length - 1; m >= 0; m--) {
		obstacles[m].destroy();
	}
	obstacles = [];
	// Clear powerups
	for (var n = powerups.length - 1; n >= 0; n--) {
		powerups[n].destroy();
	}
	powerups = [];
	// Clear explosions
	for (var o = explosions.length - 1; o >= 0; o--) {
		explosions[o].destroy();
	}
	explosions = [];
}
// Update score display
function updateScore() {
	scoreTxt.setText(LK.getScore().toString());
	multiplierTxt.setText('x' + scoreMultiplier);
	// Update health bar
	if (player) {
		var healthPercent = player.health / 100;
		healthBar.width = 300 * healthPercent;
		// Change health bar color based on health
		if (healthPercent > 0.6) {
			healthBar.tint = 0x00ff00;
		} else if (healthPercent > 0.3) {
			healthBar.tint = 0xffff00;
		} else {
			healthBar.tint = 0xff0000;
		}
	}
}
// Create a player bullet
function firePlayerBullet() {
	var bullet = new Bullet();
	bullet.x = player.x;
	bullet.y = player.y - 40;
	bullet.damage = 10 + (player.powerLevel - 1) * 5;
	bullets.push(bullet);
	game.addChild(bullet);
	// If power level > 1, fire additional bullets
	if (player.powerLevel >= 2) {
		var bulletLeft = new Bullet();
		bulletLeft.x = player.x - 20;
		bulletLeft.y = player.y - 30;
		bullets.push(bulletLeft);
		game.addChild(bulletLeft);
		if (player.powerLevel >= 3) {
			var bulletRight = new Bullet();
			bulletRight.x = player.x + 20;
			bulletRight.y = player.y - 30;
			bullets.push(bulletRight);
			game.addChild(bulletRight);
		}
	}
	LK.getSound('shoot').play();
}
// Create an enemy bullet
function fireEnemyBullet(enemy) {
	var bullet = new EnemyBullet();
	bullet.x = enemy.x;
	bullet.y = enemy.y + 40;
	enemyBullets.push(bullet);
	game.addChild(bullet);
}
// Create an explosion
function createExplosion(x, y, scale) {
	var explosion = new Explosion();
	explosion.x = x;
	explosion.y = y;
	if (scale) {
		explosion.scale.set(scale);
	}
	explosions.push(explosion);
	game.addChild(explosion);
}
// Create a power-up
function spawnPowerUp(x, y) {
	// Only spawn with 30% chance
	if (Math.random() > 0.3) {
		return;
	}
	var powerup = new PowerUp();
	powerup.x = x;
	powerup.y = y;
	powerups.push(powerup);
	game.addChild(powerup);
}
// Handle touch/mouse movement
function handleMove(x, y) {
	if (isTouching && player) {
		player.x = x;
		player.y = y;
		// Clamp player position to screen bounds
		player.x = Math.max(50, Math.min(2048 - 50, player.x));
		player.y = Math.max(400, Math.min(2732 - 50, player.y));
	}
}
// Game touch/mouse handlers
game.down = function (x, y, obj) {
	touchX = x;
	touchY = y;
	isTouching = true;
	handleMove(x, y);
};
game.move = function (x, y, obj) {
	touchX = x;
	touchY = y;
	handleMove(x, y);
};
game.up = function (x, y, obj) {
	isTouching = false;
};
// Update game each frame
game.update = function () {
	if (!gameActive) {
		return;
	}
	// Calculate delta time for smoother animations
	var currentTime = Date.now();
	var deltaTime = (currentTime - lastFrameTime) / 16.67; // Normalize to 60fps
	lastFrameTime = currentTime;
	// Handle combo system
	if (combo > 0) {
		comboTimer++;
		if (comboTimer > 60) {
			// 1 second to maintain combo
			combo = 0;
			comboTimer = 0;
			scoreMultiplier = 1;
			updateScore();
		}
	}
	// Player shooting
	if (player) {
		player.lastShot++;
		if (player.lastShot >= player.shootDelay) {
			player.lastShot = 0;
			firePlayerBullet();
		}
	}
	// Update bullets
	for (var i = bullets.length - 1; i >= 0; i--) {
		if (bullets[i].update()) {
			bullets[i].destroy();
			bullets.splice(i, 1);
			continue;
		}
		// Check bullet collisions with targets
		for (var t = targets.length - 1; t >= 0; t--) {
			if (bullets[i] && bullets[i].intersects(targets[t])) {
				if (targets[t].hit(bullets[i].damage)) {
					// Target destroyed
					combo++;
					comboTimer = 0;
					scoreMultiplier = Math.min(5, 1 + Math.floor(combo / 3));
					LK.setScore(LK.getScore() + targets[t].points * scoreMultiplier);
					updateScore();
					createExplosion(targets[t].x, targets[t].y, 1);
					spawnPowerUp(targets[t].x, targets[t].y);
					targets[t].destroy();
					targets.splice(t, 1);
				}
				bullets[i].destroy();
				bullets.splice(i, 1);
				break;
			}
		}
		// Check bullet collisions with enemies
		if (bullets[i]) {
			for (var e = enemies.length - 1; e >= 0; e--) {
				if (bullets[i] && bullets[i].intersects(enemies[e])) {
					if (enemies[e].hit(bullets[i].damage)) {
						// Enemy destroyed
						combo++;
						comboTimer = 0;
						scoreMultiplier = Math.min(5, 1 + Math.floor(combo / 3));
						LK.setScore(LK.getScore() + enemies[e].points * scoreMultiplier);
						updateScore();
						createExplosion(enemies[e].x, enemies[e].y, 1.5);
						spawnPowerUp(enemies[e].x, enemies[e].y);
						enemies[e].destroy();
						enemies.splice(e, 1);
					}
					bullets[i].destroy();
					bullets.splice(i, 1);
					break;
				}
			}
		}
		// Check bullet collisions with obstacles
		if (bullets[i]) {
			for (var o = obstacles.length - 1; o >= 0; o--) {
				if (bullets[i] && bullets[i].intersects(obstacles[o])) {
					if (obstacles[o].hit(bullets[i].damage)) {
						// Obstacle destroyed
						createExplosion(obstacles[o].x, obstacles[o].y, 2);
						obstacles[o].destroy();
						obstacles.splice(o, 1);
					}
					bullets[i].destroy();
					bullets.splice(i, 1);
					break;
				}
			}
		}
	}
	// Update enemy bullets
	for (var j = enemyBullets.length - 1; j >= 0; j--) {
		if (enemyBullets[j].update()) {
			enemyBullets[j].destroy();
			enemyBullets.splice(j, 1);
			continue;
		}
		// Check enemy bullet collisions with player
		if (player && enemyBullets[j].intersects(player)) {
			if (player.takeDamage(enemyBullets[j].damage)) {
				// Player destroyed
				createExplosion(player.x, player.y, 2);
				player.destroy();
				player = null;
				LK.showGameOver();
				gameActive = false;
			}
			updateScore();
			enemyBullets[j].destroy();
			enemyBullets.splice(j, 1);
		}
		// Check enemy bullet collisions with obstacles
		if (enemyBullets[j]) {
			for (var p = obstacles.length - 1; p >= 0; p--) {
				if (enemyBullets[j] && enemyBullets[j].intersects(obstacles[p])) {
					if (obstacles[p].hit(enemyBullets[j].damage)) {
						// Obstacle destroyed
						createExplosion(obstacles[p].x, obstacles[p].y, 2);
						obstacles[p].destroy();
						obstacles.splice(p, 1);
					}
					enemyBullets[j].destroy();
					enemyBullets.splice(j, 1);
					break;
				}
			}
		}
	}
	// Update targets
	for (var k = targets.length - 1; k >= 0; k--) {
		targets[k].update();
	}
	// Update enemies
	for (var l = enemies.length - 1; l >= 0; l--) {
		if (enemies[l].update()) {
			fireEnemyBullet(enemies[l]);
		}
	}
	// Update powerups
	for (var m = powerups.length - 1; m >= 0; m--) {
		if (powerups[m].update()) {
			powerups[m].destroy();
			powerups.splice(m, 1);
			continue;
		}
		// Check powerup collision with player
		if (player && powerups[m].intersects(player)) {
			if (player.increasePower()) {
				LK.getSound('powerup').play();
				LK.effects.flashObject(player, 0x00ff00, 500);
			} else {
				// Already max power, give points instead
				LK.setScore(LK.getScore() + 500);
				updateScore();
			}
			powerups[m].destroy();
			powerups.splice(m, 1);
		}
	}
	// Update explosions
	for (var n = explosions.length - 1; n >= 0; n--) {
		if (explosions[n].update()) {
			explosions[n].destroy();
			explosions.splice(n, 1);
		}
	}
	// Check if all targets destroyed
	if (targets.length === 0 && enemies.length === 0) {
		endWave();
	}
};
// Start the game
startGame(); /**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/**** 
* Classes
****/ 
var Bullet = Container.expand(function () {
	var self = Container.call(this);
	var bulletGraphic = self.attachAsset('bullet', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 15;
	self.damage = 10;
	self.isPlayerBullet = true;
	self.update = function () {
		self.y -= self.speed;
		// Check if bullet is off screen
		if (self.y < -50 || self.y > 2732 + 50 || self.x < -50 || self.x > 2048 + 50) {
			return true; // Signal for removal
		}
		return false;
	};
	return self;
});
var EnemyBullet = Bullet.expand(function () {
	var self = Bullet.call(this);
	// Replace the bullet graphic with enemy bullet
	self.removeChildren();
	var bulletGraphic = self.attachAsset('enemyBullet', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 8;
	self.damage = 15;
	self.isPlayerBullet = false;
	self.update = function () {
		self.y += self.speed;
		// Check if bullet is off screen
		if (self.y < -50 || self.y > 2732 + 50 || self.x < -50 || self.x > 2048 + 50) {
			return true; // Signal for removal
		}
		return false;
	};
	return self;
});
var Enemy = Container.expand(function () {
	var self = Container.call(this);
	var enemyGraphic = self.attachAsset('enemy', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.health = 30;
	self.points = 200;
	self.speed = 3;
	self.direction = 1;
	self.shootDelay = 60;
	self.lastShot = 0;
	self.update = function () {
		self.x += self.speed * self.direction;
		// Boundary check and reverse direction
		if (self.x > 2048 - 100 || self.x < 100) {
			self.direction *= -1;
		}
		// Shooting logic
		self.lastShot++;
		if (self.lastShot >= self.shootDelay) {
			self.lastShot = 0;
			return true; // Signal to shoot
		}
		return false; // No shooting this update
	};
	self.hit = function (damage) {
		self.health -= damage;
		LK.effects.flashObject(enemyGraphic, 0xff0000, 200);
		LK.getSound('hit').play();
		if (self.health <= 0) {
			LK.getSound('explosion').play();
			return true; // Enemy destroyed
		}
		return false; // Enemy still alive
	};
	return self;
});
var Explosion = Container.expand(function () {
	var self = Container.call(this);
	var explosionGraphic = self.attachAsset('explosion', {
		anchorX: 0.5,
		anchorY: 0.5,
		alpha: 0.8
	});
	self.lifetime = 0;
	self.duration = 30; // Frames
	self.update = function () {
		self.lifetime++;
		// Scale explosion up then down
		if (self.lifetime < self.duration / 2) {
			explosionGraphic.scale.set(1 + self.lifetime / (self.duration / 2));
		} else {
			explosionGraphic.scale.set(2 - (self.lifetime - self.duration / 2) / (self.duration / 2));
		}
		// Fade out
		explosionGraphic.alpha = 0.8 * (1 - self.lifetime / self.duration);
		if (self.lifetime >= self.duration) {
			return true; // Signal for removal
		}
		return false;
	};
	return self;
});
var Obstacle = Container.expand(function () {
	var self = Container.call(this);
	var obstacleGraphic = self.attachAsset('obstacle', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.health = 100;
	self.hit = function (damage) {
		self.health -= damage;
		LK.effects.flashObject(obstacleGraphic, 0x666666, 200);
		if (self.health <= 0) {
			return true; // Obstacle destroyed
		}
		return false; // Obstacle still intact
	};
	return self;
});
var Player = Container.expand(function () {
	var self = Container.call(this);
	var playerGraphic = self.attachAsset('player', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 10;
	self.health = 100;
	self.powerLevel = 1;
	self.invincible = false;
	self.lastShot = 0;
	self.shootDelay = 15;
	self.flash = function () {
		if (self.invincible) {
			return;
		}
		self.invincible = true;
		LK.effects.flashObject(playerGraphic, 0xffffff, 500);
		LK.setTimeout(function () {
			self.invincible = false;
		}, 1500);
	};
	self.takeDamage = function (amount) {
		if (self.invincible) {
			return false;
		}
		self.health -= amount;
		self.flash();
		if (self.health <= 0) {
			return true; // Player died
		}
		return false; // Player still alive
	};
	self.increasePower = function () {
		if (self.powerLevel < 3) {
			self.powerLevel++;
			self.shootDelay = Math.max(5, self.shootDelay - 3);
			return true;
		}
		return false;
	};
	return self;
});
var PowerUp = Container.expand(function () {
	var self = Container.call(this);
	var powerupGraphic = self.attachAsset('powerup', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.type = "weapon"; // Default powerup type
	self.speed = 2;
	self.update = function () {
		self.y += self.speed;
		// Check if powerup is off screen
		if (self.y > 2732 + 50) {
			return true; // Signal for removal
		}
		return false;
	};
	// Make the powerup pulse
	function pulse() {
		tween(powerupGraphic, {
			alpha: 0.6
		}, {
			duration: 500,
			easing: tween.easeInOut,
			onFinish: function onFinish() {
				tween(powerupGraphic, {
					alpha: 1
				}, {
					duration: 500,
					easing: tween.easeInOut,
					onFinish: pulse
				});
			}
		});
	}
	pulse();
	return self;
});
var Target = Container.expand(function () {
	var self = Container.call(this);
	var targetGraphic = self.attachAsset('target', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.health = 20;
	self.points = 100;
	self.speed = 0;
	self.direction = 1; // 1 for right, -1 for left
	self.update = function () {
		if (self.speed > 0) {
			self.x += self.speed * self.direction;
			// Boundary check and reverse direction
			if (self.x > 2048 - 100 || self.x < 100) {
				self.direction *= -1;
			}
		}
		return false; // Not to be removed yet
	};
	self.hit = function (damage) {
		self.health -= damage;
		LK.effects.flashObject(targetGraphic, 0xff0000, 200);
		LK.getSound('hit').play();
		if (self.health <= 0) {
			LK.getSound('explosion').play();
			return true; // Target destroyed
		}
		return false; // Target still alive
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x000033
});
/**** 
* Game Code
****/ 
// Game state
var gameActive = true;
var waveNumber = 1;
var timeLeft = 60;
var scoreMultiplier = 1;
var combo = 0;
var comboTimer = 0;
var lastFrameTime = Date.now();
// Game elements
var player;
var bullets = [];
var enemyBullets = [];
var targets = [];
var enemies = [];
var obstacles = [];
var powerups = [];
var explosions = [];
// UI elements
var scoreTxt;
var multiplierTxt;
var waveTxt;
var timeTxt;
var healthBar;
var healthBarBg;
// Game controls
var touchX = null;
var touchY = null;
var isTouching = false;
// Initialize UI
function initUI() {
	// Score display
	scoreTxt = new Text2('0', {
		size: 70,
		fill: 0xFFFFFF
	});
	scoreTxt.anchor.set(0.5, 0);
	LK.gui.top.addChild(scoreTxt);
	// Wave display
	waveTxt = new Text2('WAVE 1', {
		size: 50,
		fill: 0xFFCC00
	});
	waveTxt.anchor.set(0, 0);
	waveTxt.x = 150;
	waveTxt.y = 20;
	LK.gui.topLeft.addChild(waveTxt);
	// Time display
	timeTxt = new Text2('60s', {
		size: 50,
		fill: 0xFFFFFF
	});
	timeTxt.anchor.set(1, 0);
	timeTxt.x = -20;
	timeTxt.y = 20;
	LK.gui.topRight.addChild(timeTxt);
	// Multiplier display
	multiplierTxt = new Text2('x1', {
		size: 50,
		fill: 0x00FFFF
	});
	multiplierTxt.anchor.set(0.5, 0);
	multiplierTxt.y = 80;
	LK.gui.top.addChild(multiplierTxt);
	// Health bar background
	healthBarBg = LK.getAsset('obstacle', {
		width: 300,
		height: 30,
		anchorX: 0,
		anchorY: 0,
		x: 20,
		y: 80,
		tint: 0x333333
	});
	LK.gui.topLeft.addChild(healthBarBg);
	// Health bar
	healthBar = LK.getAsset('player', {
		width: 300,
		height: 30,
		anchorX: 0,
		anchorY: 0,
		x: 20,
		y: 80,
		tint: 0x00ff00
	});
	LK.gui.topLeft.addChild(healthBar);
}
// Start the game
function startGame() {
	// Initialize player
	player = new Player();
	player.x = 2048 / 2;
	player.y = 2732 - 200;
	game.addChild(player);
	// Initialize UI
	initUI();
	// Setup first wave
	setupWave(waveNumber);
	// Start timer
	gameTimer = LK.setInterval(function () {
		timeLeft--;
		timeTxt.setText(timeLeft + 's');
		if (timeLeft <= 0) {
			endWave();
		}
	}, 1000);
	// Play background music
	LK.playMusic('gameplay');
	// Update score display
	updateScore();
}
// Set up a new wave
function setupWave(wave) {
	// Clear any existing entities
	clearEntities();
	// Set wave text
	waveTxt.setText('WAVE ' + wave);
	// Create targets based on wave number
	var numTargets = 5 + wave * 2;
	for (var i = 0; i < numTargets; i++) {
		var target = new Target();
		target.x = 200 + i * 200 % (2048 - 400);
		target.y = 200 + Math.floor(i / 9) * 150;
		target.speed = 1 + wave * 0.5;
		target.health = 20 + wave * 10;
		target.points = 100 + wave * 20;
		if (i % 3 === 0) {
			target.direction = -1;
		}
		targets.push(target);
		game.addChild(target);
	}
	// Add enemies for higher waves
	if (wave > 1) {
		var numEnemies = Math.min(wave, 5);
		for (var j = 0; j < numEnemies; j++) {
			var enemy = new Enemy();
			enemy.x = 300 + j * 350;
			enemy.y = 400;
			enemy.speed = 2 + wave * 0.3;
			enemy.health = 30 + wave * 15;
			enemy.shootDelay = Math.max(30, 60 - wave * 5);
			enemies.push(enemy);
			game.addChild(enemy);
		}
	}
	// Add obstacles
	var numObstacles = Math.min(3, Math.floor(wave / 2));
	for (var k = 0; k < numObstacles; k++) {
		var obstacle = new Obstacle();
		obstacle.x = 400 + k * 600;
		obstacle.y = 700;
		obstacles.push(obstacle);
		game.addChild(obstacle);
	}
	// Reset timer
	timeLeft = 60;
	timeTxt.setText(timeLeft + 's');
}
// End the current wave
function endWave() {
	waveNumber++;
	// If player completed all waves, show win
	if (waveNumber > 5) {
		LK.showYouWin();
		return;
	}
	// Award bonus points for completing wave
	var timeBonus = timeLeft * 10;
	LK.setScore(LK.getScore() + timeBonus);
	updateScore();
	// Set up new wave
	setupWave(waveNumber);
}
// Clear all entities except player
function clearEntities() {
	// Clear bullets
	for (var i = bullets.length - 1; i >= 0; i--) {
		bullets[i].destroy();
	}
	bullets = [];
	// Clear enemy bullets
	for (var j = enemyBullets.length - 1; j >= 0; j--) {
		enemyBullets[j].destroy();
	}
	enemyBullets = [];
	// Clear targets
	for (var k = targets.length - 1; k >= 0; k--) {
		targets[k].destroy();
	}
	targets = [];
	// Clear enemies
	for (var l = enemies.length - 1; l >= 0; l--) {
		enemies[l].destroy();
	}
	enemies = [];
	// Clear obstacles
	for (var m = obstacles.length - 1; m >= 0; m--) {
		obstacles[m].destroy();
	}
	obstacles = [];
	// Clear powerups
	for (var n = powerups.length - 1; n >= 0; n--) {
		powerups[n].destroy();
	}
	powerups = [];
	// Clear explosions
	for (var o = explosions.length - 1; o >= 0; o--) {
		explosions[o].destroy();
	}
	explosions = [];
}
// Update score display
function updateScore() {
	scoreTxt.setText(LK.getScore().toString());
	multiplierTxt.setText('x' + scoreMultiplier);
	// Update health bar
	if (player) {
		var healthPercent = player.health / 100;
		healthBar.width = 300 * healthPercent;
		// Change health bar color based on health
		if (healthPercent > 0.6) {
			healthBar.tint = 0x00ff00;
		} else if (healthPercent > 0.3) {
			healthBar.tint = 0xffff00;
		} else {
			healthBar.tint = 0xff0000;
		}
	}
}
// Create a player bullet
function firePlayerBullet() {
	var bullet = new Bullet();
	bullet.x = player.x;
	bullet.y = player.y - 40;
	bullet.damage = 10 + (player.powerLevel - 1) * 5;
	bullets.push(bullet);
	game.addChild(bullet);
	// If power level > 1, fire additional bullets
	if (player.powerLevel >= 2) {
		var bulletLeft = new Bullet();
		bulletLeft.x = player.x - 20;
		bulletLeft.y = player.y - 30;
		bullets.push(bulletLeft);
		game.addChild(bulletLeft);
		if (player.powerLevel >= 3) {
			var bulletRight = new Bullet();
			bulletRight.x = player.x + 20;
			bulletRight.y = player.y - 30;
			bullets.push(bulletRight);
			game.addChild(bulletRight);
		}
	}
	LK.getSound('shoot').play();
}
// Create an enemy bullet
function fireEnemyBullet(enemy) {
	var bullet = new EnemyBullet();
	bullet.x = enemy.x;
	bullet.y = enemy.y + 40;
	enemyBullets.push(bullet);
	game.addChild(bullet);
}
// Create an explosion
function createExplosion(x, y, scale) {
	var explosion = new Explosion();
	explosion.x = x;
	explosion.y = y;
	if (scale) {
		explosion.scale.set(scale);
	}
	explosions.push(explosion);
	game.addChild(explosion);
}
// Create a power-up
function spawnPowerUp(x, y) {
	// Only spawn with 30% chance
	if (Math.random() > 0.3) {
		return;
	}
	var powerup = new PowerUp();
	powerup.x = x;
	powerup.y = y;
	powerups.push(powerup);
	game.addChild(powerup);
}
// Handle touch/mouse movement
function handleMove(x, y) {
	if (isTouching && player) {
		player.x = x;
		player.y = y;
		// Clamp player position to screen bounds
		player.x = Math.max(50, Math.min(2048 - 50, player.x));
		player.y = Math.max(400, Math.min(2732 - 50, player.y));
	}
}
// Game touch/mouse handlers
game.down = function (x, y, obj) {
	touchX = x;
	touchY = y;
	isTouching = true;
	handleMove(x, y);
};
game.move = function (x, y, obj) {
	touchX = x;
	touchY = y;
	handleMove(x, y);
};
game.up = function (x, y, obj) {
	isTouching = false;
};
// Update game each frame
game.update = function () {
	if (!gameActive) {
		return;
	}
	// Calculate delta time for smoother animations
	var currentTime = Date.now();
	var deltaTime = (currentTime - lastFrameTime) / 16.67; // Normalize to 60fps
	lastFrameTime = currentTime;
	// Handle combo system
	if (combo > 0) {
		comboTimer++;
		if (comboTimer > 60) {
			// 1 second to maintain combo
			combo = 0;
			comboTimer = 0;
			scoreMultiplier = 1;
			updateScore();
		}
	}
	// Player shooting
	if (player) {
		player.lastShot++;
		if (player.lastShot >= player.shootDelay) {
			player.lastShot = 0;
			firePlayerBullet();
		}
	}
	// Update bullets
	for (var i = bullets.length - 1; i >= 0; i--) {
		if (bullets[i].update()) {
			bullets[i].destroy();
			bullets.splice(i, 1);
			continue;
		}
		// Check bullet collisions with targets
		for (var t = targets.length - 1; t >= 0; t--) {
			if (bullets[i] && bullets[i].intersects(targets[t])) {
				if (targets[t].hit(bullets[i].damage)) {
					// Target destroyed
					combo++;
					comboTimer = 0;
					scoreMultiplier = Math.min(5, 1 + Math.floor(combo / 3));
					LK.setScore(LK.getScore() + targets[t].points * scoreMultiplier);
					updateScore();
					createExplosion(targets[t].x, targets[t].y, 1);
					spawnPowerUp(targets[t].x, targets[t].y);
					targets[t].destroy();
					targets.splice(t, 1);
				}
				bullets[i].destroy();
				bullets.splice(i, 1);
				break;
			}
		}
		// Check bullet collisions with enemies
		if (bullets[i]) {
			for (var e = enemies.length - 1; e >= 0; e--) {
				if (bullets[i] && bullets[i].intersects(enemies[e])) {
					if (enemies[e].hit(bullets[i].damage)) {
						// Enemy destroyed
						combo++;
						comboTimer = 0;
						scoreMultiplier = Math.min(5, 1 + Math.floor(combo / 3));
						LK.setScore(LK.getScore() + enemies[e].points * scoreMultiplier);
						updateScore();
						createExplosion(enemies[e].x, enemies[e].y, 1.5);
						spawnPowerUp(enemies[e].x, enemies[e].y);
						enemies[e].destroy();
						enemies.splice(e, 1);
					}
					bullets[i].destroy();
					bullets.splice(i, 1);
					break;
				}
			}
		}
		// Check bullet collisions with obstacles
		if (bullets[i]) {
			for (var o = obstacles.length - 1; o >= 0; o--) {
				if (bullets[i] && bullets[i].intersects(obstacles[o])) {
					if (obstacles[o].hit(bullets[i].damage)) {
						// Obstacle destroyed
						createExplosion(obstacles[o].x, obstacles[o].y, 2);
						obstacles[o].destroy();
						obstacles.splice(o, 1);
					}
					bullets[i].destroy();
					bullets.splice(i, 1);
					break;
				}
			}
		}
	}
	// Update enemy bullets
	for (var j = enemyBullets.length - 1; j >= 0; j--) {
		if (enemyBullets[j].update()) {
			enemyBullets[j].destroy();
			enemyBullets.splice(j, 1);
			continue;
		}
		// Check enemy bullet collisions with player
		if (player && enemyBullets[j].intersects(player)) {
			if (player.takeDamage(enemyBullets[j].damage)) {
				// Player destroyed
				createExplosion(player.x, player.y, 2);
				player.destroy();
				player = null;
				LK.showGameOver();
				gameActive = false;
			}
			updateScore();
			enemyBullets[j].destroy();
			enemyBullets.splice(j, 1);
		}
		// Check enemy bullet collisions with obstacles
		if (enemyBullets[j]) {
			for (var p = obstacles.length - 1; p >= 0; p--) {
				if (enemyBullets[j] && enemyBullets[j].intersects(obstacles[p])) {
					if (obstacles[p].hit(enemyBullets[j].damage)) {
						// Obstacle destroyed
						createExplosion(obstacles[p].x, obstacles[p].y, 2);
						obstacles[p].destroy();
						obstacles.splice(p, 1);
					}
					enemyBullets[j].destroy();
					enemyBullets.splice(j, 1);
					break;
				}
			}
		}
	}
	// Update targets
	for (var k = targets.length - 1; k >= 0; k--) {
		targets[k].update();
	}
	// Update enemies
	for (var l = enemies.length - 1; l >= 0; l--) {
		if (enemies[l].update()) {
			fireEnemyBullet(enemies[l]);
		}
	}
	// Update powerups
	for (var m = powerups.length - 1; m >= 0; m--) {
		if (powerups[m].update()) {
			powerups[m].destroy();
			powerups.splice(m, 1);
			continue;
		}
		// Check powerup collision with player
		if (player && powerups[m].intersects(player)) {
			if (player.increasePower()) {
				LK.getSound('powerup').play();
				LK.effects.flashObject(player, 0x00ff00, 500);
			} else {
				// Already max power, give points instead
				LK.setScore(LK.getScore() + 500);
				updateScore();
			}
			powerups[m].destroy();
			powerups.splice(m, 1);
		}
	}
	// Update explosions
	for (var n = explosions.length - 1; n >= 0; n--) {
		if (explosions[n].update()) {
			explosions[n].destroy();
			explosions.splice(n, 1);
		}
	}
	// Check if all targets destroyed
	if (targets.length === 0 && enemies.length === 0) {
		endWave();
	}
};
// Start the game
startGame();