/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
	highScore: 0,
	totalWins: 0,
	totalMatches: 0
});
/**** 
* Classes
****/ 
var Entity = Container.expand(function () {
	var self = Container.call(this);
	self.speed = 0;
	self.health = 100;
	self.maxHealth = 100;
	self.size = 100;
	self.isDead = false;
	self.init = function (x, y, color) {
		self.x = x;
		self.y = y;
	};
	self.takeDamage = function (amount) {
		if (self.isDead) {
			return;
		}
		self.health -= amount;
		if (self.health <= 0) {
			self.health = 0;
			self.die();
		}
		// Flash red when taking damage
		LK.effects.flashObject(self, 0xff0000, 300);
	};
	self.die = function () {
		if (self.isDead) {
			return;
		}
		self.isDead = true;
		tween(self, {
			alpha: 0
		}, {
			duration: 500,
			onFinish: function onFinish() {
				self.destroy();
			}
		});
	};
	self.isOutOfBounds = function (bounds) {
		return self.x < bounds.x || self.x > bounds.x + bounds.width || self.y < bounds.y || self.y > bounds.y + bounds.height;
	};
	self.keepInBounds = function (bounds) {
		if (self.x < bounds.x) {
			self.x = bounds.x;
		} else if (self.x > bounds.x + bounds.width) {
			self.x = bounds.x + bounds.width;
		}
		if (self.y < bounds.y) {
			self.y = bounds.y;
		} else if (self.y > bounds.y + bounds.height) {
			self.y = bounds.y + bounds.height;
		}
	};
	return self;
});
var Player = Entity.expand(function () {
	var self = Entity.call(this);
	self.speed = 5;
	self.cooldown = 0;
	self.shootCooldownMax = 30; // half a second at 60fps
	self.score = 0;
	var playerGraphics = self.attachAsset('player', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Create health bar background
	var healthBarBg = self.attachAsset('healthBarBackground', {
		anchorX: 0.5,
		anchorY: 0,
		y: -80
	});
	// Create health bar
	var healthBar = self.attachAsset('healthBar', {
		anchorX: 0,
		anchorY: 0,
		y: -80,
		x: -100
	});
	self.init = function (x, y) {
		self.x = x;
		self.y = y;
		self.health = self.maxHealth;
		self.score = 0;
		self.isDead = false;
		self.alpha = 1;
		self.cooldown = 0;
		self.updateHealthBar();
	};
	self.updateHealthBar = function () {
		var healthPercentage = self.health / self.maxHealth;
		healthBar.width = 200 * healthPercentage;
	};
	self.takeDamage = function (amount) {
		Entity.prototype.takeDamage.call(self, amount);
		self.updateHealthBar();
	};
	self.update = function () {
		if (self.isDead) {
			return;
		}
		if (self.cooldown > 0) {
			self.cooldown--;
		}
		self.updateHealthBar();
	};
	self.shoot = function () {
		if (self.cooldown > 0 || self.isDead) {
			return null;
		}
		var projectile = new Projectile();
		projectile.init(self.x, self.y, 'up');
		self.cooldown = self.shootCooldownMax;
		LK.getSound('projectileShoot').play();
		return projectile;
	};
	self.addScore = function (points) {
		self.score += points;
		if (self.score > storage.highScore) {
			storage.highScore = self.score;
		}
	};
	return self;
});
var Enemy = Entity.expand(function () {
	var self = Entity.call(this);
	self.speed = 2;
	self.attackCooldown = 0;
	self.attackRate = 120; // 2 seconds at 60fps
	self.scoreValue = 10;
	self.targetPlayer = null;
	var enemyGraphics = self.attachAsset('enemy', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.init = function (x, y, targetPlayer) {
		self.x = x;
		self.y = y;
		self.health = 50;
		self.maxHealth = 50;
		self.isDead = false;
		self.alpha = 1;
		self.targetPlayer = targetPlayer;
		self.attackCooldown = Math.floor(Math.random() * self.attackRate);
	};
	self.update = function () {
		if (self.isDead || !self.targetPlayer) {
			return;
		}
		// Move toward player
		var dx = self.targetPlayer.x - self.x;
		var dy = self.targetPlayer.y - self.y;
		var distance = Math.sqrt(dx * dx + dy * dy);
		if (distance > 10) {
			self.x += dx / distance * self.speed;
			self.y += dy / distance * self.speed;
		}
		// Attack logic
		if (self.attackCooldown > 0) {
			self.attackCooldown--;
		} else if (distance < 150) {
			self.attackPlayer();
		}
	};
	self.attackPlayer = function () {
		if (self.isDead || self.targetPlayer.isDead) {
			return null;
		}
		// Attack directly by touching
		if (self.intersects(self.targetPlayer)) {
			self.targetPlayer.takeDamage(10);
			LK.getSound('hit').play();
		}
		// Sometimes shoot projectiles
		if (Math.random() < 0.3) {
			var projectile = new Projectile();
			var angle = Math.atan2(self.targetPlayer.y - self.y, self.targetPlayer.x - self.x);
			projectile.init(self.x, self.y, 'custom', angle);
			self.attackCooldown = self.attackRate;
			return projectile;
		}
		self.attackCooldown = self.attackRate / 2;
		return null;
	};
	return self;
});
var PowerUp = Container.expand(function () {
	var self = Container.call(this);
	self.type = 'health'; // Default type
	self.active = true;
	var powerUpGraphics = self.attachAsset('powerUp', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.init = function (x, y, type) {
		self.x = x;
		self.y = y;
		self.type = type || (Math.random() < 0.7 ? 'health' : 'speed');
		self.active = true;
		self.alpha = 1;
		// Different colors for different power-up types
		if (self.type === 'health') {
			powerUpGraphics.tint = 0x2ecc71; // Green
		} else if (self.type === 'speed') {
			powerUpGraphics.tint = 0x3498db; // Blue
		}
		// Add a pulsing animation
		self.pulse();
	};
	self.pulse = function () {
		tween(powerUpGraphics, {
			scaleX: 1.2,
			scaleY: 1.2
		}, {
			duration: 500,
			easing: tween.sinceOut,
			onFinish: function onFinish() {
				tween(powerUpGraphics, {
					scaleX: 1,
					scaleY: 1
				}, {
					duration: 500,
					easing: tween.sinceIn,
					onFinish: function onFinish() {
						if (self.active) {
							self.pulse();
						}
					}
				});
			}
		});
	};
	self.collect = function (player) {
		if (!self.active) {
			return;
		}
		self.active = false;
		LK.getSound('powerUpCollect').play();
		if (self.type === 'health') {
			player.health = Math.min(player.maxHealth, player.health + 25);
		} else if (self.type === 'speed') {
			var originalSpeed = player.speed;
			player.speed += 2;
			// Speed boost is temporary
			LK.setTimeout(function () {
				if (!player.isDead) {
					player.speed = originalSpeed;
				}
			}, 5000);
		}
		// Fade out and destroy
		tween(self, {
			alpha: 0
		}, {
			duration: 300,
			onFinish: function onFinish() {
				self.destroy();
			}
		});
	};
	return self;
});
var Projectile = Container.expand(function () {
	var self = Container.call(this);
	self.speed = 8;
	self.damage = 10;
	self.direction = 'up';
	self.angleRad = 0;
	var projectileGraphics = self.attachAsset('projectile', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.init = function (x, y, direction, angleRad) {
		self.x = x;
		self.y = y;
		self.direction = direction || 'up';
		self.angleRad = angleRad || 0;
	};
	self.update = function () {
		if (self.direction === 'up') {
			self.y -= self.speed;
		} else if (self.direction === 'down') {
			self.y += self.speed;
		} else if (self.direction === 'custom' && self.angleRad !== undefined) {
			self.x += Math.cos(self.angleRad) * self.speed;
			self.y += Math.sin(self.angleRad) * self.speed;
		}
	};
	return self;
});
var Trap = Container.expand(function () {
	var self = Container.call(this);
	self.damage = 15;
	self.active = true;
	var trapGraphics = self.attachAsset('trap', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.init = function (x, y, damage) {
		self.x = x;
		self.y = y;
		self.damage = damage || 15;
		self.active = true;
		self.alpha = 1;
		// Add a rotating animation
		self.rotate();
	};
	self.rotate = function () {
		tween(trapGraphics, {
			rotation: Math.PI * 2
		}, {
			duration: 3000,
			onFinish: function onFinish() {
				trapGraphics.rotation = 0;
				if (self.active) {
					self.rotate();
				}
			}
		});
	};
	self.trigger = function (entity) {
		if (!self.active) {
			return;
		}
		LK.getSound('trapHit').play();
		entity.takeDamage(self.damage);
		// Visual feedback
		LK.effects.flashObject(self, 0xff0000, 300);
		// Deactivate temporarily
		self.active = false;
		trapGraphics.alpha = 0.5;
		// Reactivate after a delay
		LK.setTimeout(function () {
			if (self.parent) {
				// Check if still in the scene
				self.active = true;
				trapGraphics.alpha = 1;
			}
		}, 3000);
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x2c3e50
});
/**** 
* Game Code
****/ 
// Arena setup
var arena = LK.getAsset('arena', {
	anchorX: 0.5,
	anchorY: 0.5
});
arena.x = 2048 / 2;
arena.y = 2732 / 2;
game.addChild(arena);
// Game state variables
var player = null;
var enemies = [];
var powerUps = [];
var traps = [];
var projectiles = [];
var dragTarget = null;
var gameActive = false;
var waveNumber = 0;
var enemiesDefeated = 0;
var isGameStarting = false;
// Game boundaries
var bounds = {
	x: arena.x - arena.width / 2,
	y: arena.y - arena.height / 2,
	width: arena.width,
	height: arena.height
};
// UI elements
var scoreText = new Text2('0', {
	size: 60,
	fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
var waveText = new Text2('Wave 1', {
	size: 50,
	fill: 0xFFFFFF
});
waveText.anchor.set(0.5, 0);
waveText.y = 80;
LK.gui.top.addChild(waveText);
var highScoreText = new Text2('High Score: ' + storage.highScore, {
	size: 40,
	fill: 0xFFFFFF
});
highScoreText.anchor.set(1, 0);
highScoreText.x = -20;
highScoreText.y = 20;
LK.gui.topRight.addChild(highScoreText);
// Play music
LK.playMusic('battleMusic', {
	fade: {
		start: 0,
		end: 0.3,
		duration: 1000
	}
});
// Initialize the game
function startGame() {
	if (isGameStarting) {
		return;
	}
	isGameStarting = true;
	// Reset game state
	resetGameState();
	// Create player
	player = new Player();
	player.init(arena.x, arena.y + 300);
	game.addChild(player);
	// Create initial traps
	for (var i = 0; i < 5; i++) {
		createTrap();
	}
	// Create initial power-ups
	for (var i = 0; i < 3; i++) {
		createPowerUp();
	}
	// Start first wave
	startNextWave();
	// Update UI
	updateScoreDisplay();
	gameActive = true;
	isGameStarting = false;
}
function resetGameState() {
	// Remove existing entities
	if (player && !player.isDead) {
		player.die();
	}
	// Clean up arrays
	cleanupArrays();
	// Reset game variables
	waveNumber = 0;
	enemiesDefeated = 0;
	LK.setScore(0);
}
function cleanupArrays() {
	// Clean up enemies
	for (var i = enemies.length - 1; i >= 0; i--) {
		if (enemies[i].parent) {
			enemies[i].destroy();
		}
		enemies.splice(i, 1);
	}
	// Clean up power-ups
	for (var i = powerUps.length - 1; i >= 0; i--) {
		if (powerUps[i].parent) {
			powerUps[i].destroy();
		}
		powerUps.splice(i, 1);
	}
	// Clean up traps
	for (var i = traps.length - 1; i >= 0; i--) {
		if (traps[i].parent) {
			traps[i].destroy();
		}
		traps.splice(i, 1);
	}
	// Clean up projectiles
	for (var i = projectiles.length - 1; i >= 0; i--) {
		if (projectiles[i].parent) {
			projectiles[i].destroy();
		}
		projectiles.splice(i, 1);
	}
}
function startNextWave() {
	waveNumber++;
	waveText.setText('Wave ' + waveNumber);
	// Display wave announcement
	var waveAnnouncement = new Text2('Wave ' + waveNumber, {
		size: 120,
		fill: 0xFFFFFF
	});
	waveAnnouncement.anchor.set(0.5, 0.5);
	LK.gui.center.addChild(waveAnnouncement);
	// Fade in and out
	waveAnnouncement.alpha = 0;
	tween(waveAnnouncement, {
		alpha: 1
	}, {
		duration: 800,
		onFinish: function onFinish() {
			LK.setTimeout(function () {
				tween(waveAnnouncement, {
					alpha: 0
				}, {
					duration: 800,
					onFinish: function onFinish() {
						waveAnnouncement.destroy();
					}
				});
			}, 1000);
		}
	});
	// Spawn enemies for this wave
	var enemiesToSpawn = Math.min(3 + waveNumber, 10);
	for (var i = 0; i < enemiesToSpawn; i++) {
		LK.setTimeout(function () {
			if (gameActive && player && !player.isDead) {
				spawnEnemy();
			}
		}, i * 800);
	}
	// Add a new trap and powerup with each wave
	if (waveNumber > 1) {
		createTrap();
		if (waveNumber % 2 === 0) {
			createPowerUp();
		}
	}
}
function spawnEnemy() {
	if (!player || player.isDead) {
		return;
	}
	var enemy = new Enemy();
	var edge = Math.floor(Math.random() * 4);
	var x, y;
	// Spawn from edges of the arena
	switch (edge) {
		case 0:
			// Top
			x = bounds.x + Math.random() * bounds.width;
			y = bounds.y;
			break;
		case 1:
			// Right
			x = bounds.x + bounds.width;
			y = bounds.y + Math.random() * bounds.height;
			break;
		case 2:
			// Bottom
			x = bounds.x + Math.random() * bounds.width;
			y = bounds.y + bounds.height;
			break;
		case 3:
			// Left
			x = bounds.x;
			y = bounds.y + Math.random() * bounds.height;
			break;
	}
	enemy.init(x, y, player);
	game.addChild(enemy);
	enemies.push(enemy);
}
function createPowerUp() {
	var powerUp = new PowerUp();
	var x = bounds.x + 100 + Math.random() * (bounds.width - 200);
	var y = bounds.y + 100 + Math.random() * (bounds.height - 200);
	powerUp.init(x, y);
	game.addChild(powerUp);
	powerUps.push(powerUp);
}
function createTrap() {
	var trap = new Trap();
	var x = bounds.x + 100 + Math.random() * (bounds.width - 200);
	var y = bounds.y + 100 + Math.random() * (bounds.height - 200);
	trap.init(x, y);
	game.addChild(trap);
	traps.push(trap);
}
function updateScoreDisplay() {
	scoreText.setText('Score: ' + LK.getScore());
	highScoreText.setText('High Score: ' + storage.highScore);
}
function checkCollisions() {
	if (!player || player.isDead) {
		return;
	}
	// Player-Enemy collisions
	for (var i = enemies.length - 1; i >= 0; i--) {
		var enemy = enemies[i];
		if (enemy.isDead) {
			continue;
		}
		if (player.intersects(enemy)) {
			player.takeDamage(5);
			LK.getSound('hit').play();
		}
	}
	// Player-PowerUp collisions
	for (var i = powerUps.length - 1; i >= 0; i--) {
		var powerUp = powerUps[i];
		if (!powerUp.active) {
			continue;
		}
		if (player.intersects(powerUp)) {
			powerUp.collect(player);
			powerUps.splice(i, 1);
		}
	}
	// Player-Trap collisions
	for (var i = traps.length - 1; i >= 0; i--) {
		var trap = traps[i];
		if (!trap.active) {
			continue;
		}
		if (player.intersects(trap)) {
			trap.trigger(player);
		}
	}
	// Projectile-Enemy collisions
	for (var i = projectiles.length - 1; i >= 0; i--) {
		var projectile = projectiles[i];
		var hit = false;
		// Check if projectile is out of bounds
		if (projectile.isOutOfBounds(bounds)) {
			projectile.destroy();
			projectiles.splice(i, 1);
			continue;
		}
		// Check hits against enemies (only if shot by player)
		if (projectile.direction === 'up') {
			for (var j = enemies.length - 1; j >= 0; j--) {
				var enemy = enemies[j];
				if (enemy.isDead) {
					continue;
				}
				if (projectile.intersects(enemy)) {
					enemy.takeDamage(projectile.damage);
					LK.getSound('hit').play();
					if (enemy.health <= 0) {
						player.addScore(enemy.scoreValue);
						LK.setScore(player.score);
						updateScoreDisplay();
						enemies.splice(j, 1);
						enemiesDefeated++;
						// Check if wave is complete
						if (enemies.length === 0) {
							LK.setTimeout(startNextWave, 2000);
						}
					}
					hit = true;
					break;
				}
			}
		}
		// Check hits against player (only if shot by enemy)
		else if (projectile.direction === 'custom' && player && !player.isDead) {
			if (projectile.intersects(player)) {
				player.takeDamage(projectile.damage);
				LK.getSound('hit').play();
				hit = true;
			}
		}
		if (hit) {
			projectile.destroy();
			projectiles.splice(i, 1);
		}
	}
}
// Game input handlers
game.down = function (x, y, obj) {
	if (!gameActive) {
		startGame();
		return;
	}
	if (player && !player.isDead) {
		dragTarget = player;
		player.x = x;
		player.y = y;
		player.keepInBounds(bounds);
	}
};
game.up = function (x, y, obj) {
	dragTarget = null;
	// Shoot on release if game is active
	if (gameActive && player && !player.isDead) {
		var projectile = player.shoot();
		if (projectile) {
			game.addChild(projectile);
			projectiles.push(projectile);
		}
	}
};
game.move = function (x, y, obj) {
	if (dragTarget === player && player && !player.isDead) {
		player.x = x;
		player.y = y;
		player.keepInBounds(bounds);
	}
};
// Main game update loop
game.update = function () {
	if (!gameActive) {
		// Show start game message if not already started
		if (!isGameStarting && (!player || player.isDead)) {
			var _pulseMessage = function pulseMessage() {
				tween(startMessage, {
					scaleX: 1.1,
					scaleY: 1.1
				}, {
					duration: 800,
					easing: tween.sinceOut,
					onFinish: function onFinish() {
						tween(startMessage, {
							scaleX: 1,
							scaleY: 1
						}, {
							duration: 800,
							easing: tween.sinceIn,
							onFinish: function onFinish() {
								if (startMessage.parent) {
									_pulseMessage();
								}
							}
						});
					}
				});
			};
			var startMessage = new Text2('Tap to Start', {
				size: 80,
				fill: 0xFFFFFF
			});
			startMessage.anchor.set(0.5, 0.5);
			LK.gui.center.addChild(startMessage);
			// Pulse animation for the start message
			_pulseMessage();
			gameActive = true; // Set to true so message only shows once
		}
		return;
	}
	// If player is dead, show game over
	if (player && player.isDead) {
		storage.totalMatches++;
		LK.showGameOver();
		return;
	}
	// Update all game entities
	if (player) {
		player.update();
	}
	for (var i = 0; i < enemies.length; i++) {
		if (!enemies[i].isDead) {
			enemies[i].update();
			// Chance for enemy to shoot
			if (Math.random() < 0.005) {
				var enemyProjectile = enemies[i].attackPlayer();
				if (enemyProjectile) {
					game.addChild(enemyProjectile);
					projectiles.push(enemyProjectile);
				}
			}
		}
	}
	for (var i = 0; i < projectiles.length; i++) {
		projectiles[i].update();
	}
	// Check various collisions
	checkCollisions();
	// Spawn additional power-ups randomly
	if (Math.random() < 0.001 && powerUps.length < 5) {
		createPowerUp();
	}
	// Spawn additional traps randomly in later waves
	if (waveNumber > 2 && Math.random() < 0.0005 && traps.length < waveNumber + 3) {
		createTrap();
	}
};
// Initial screen
var titleText = new Text2('Arena Rivals', {
	size: 120,
	fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.y = -200;
LK.gui.center.addChild(titleText);
var instructionText = new Text2('Tap and drag to move\nRelease to shoot', {
	size: 60,
	fill: 0xFFFFFF
});
instructionText.anchor.set(0.5, 0.5);
instructionText.y = 100;
LK.gui.center.addChild(instructionText);
// Start game message
var startMessage = new Text2('Tap to Start', {
	size: 80,
	fill: 0xFFFFFF
});
startMessage.anchor.set(0.5, 0.5);
startMessage.y = 300;
LK.gui.center.addChild(startMessage);
// Pulse animation for the start message
function pulseStartMessage() {
	tween(startMessage, {
		scaleX: 1.1,
		scaleY: 1.1
	}, {
		duration: 800,
		easing: tween.sinceOut,
		onFinish: function onFinish() {
			tween(startMessage, {
				scaleX: 1,
				scaleY: 1
			}, {
				duration: 800,
				easing: tween.sinceIn,
				onFinish: pulseStartMessage
			});
		}
	});
}
pulseStartMessage(); /**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
	highScore: 0,
	totalWins: 0,
	totalMatches: 0
});
/**** 
* Classes
****/ 
var Entity = Container.expand(function () {
	var self = Container.call(this);
	self.speed = 0;
	self.health = 100;
	self.maxHealth = 100;
	self.size = 100;
	self.isDead = false;
	self.init = function (x, y, color) {
		self.x = x;
		self.y = y;
	};
	self.takeDamage = function (amount) {
		if (self.isDead) {
			return;
		}
		self.health -= amount;
		if (self.health <= 0) {
			self.health = 0;
			self.die();
		}
		// Flash red when taking damage
		LK.effects.flashObject(self, 0xff0000, 300);
	};
	self.die = function () {
		if (self.isDead) {
			return;
		}
		self.isDead = true;
		tween(self, {
			alpha: 0
		}, {
			duration: 500,
			onFinish: function onFinish() {
				self.destroy();
			}
		});
	};
	self.isOutOfBounds = function (bounds) {
		return self.x < bounds.x || self.x > bounds.x + bounds.width || self.y < bounds.y || self.y > bounds.y + bounds.height;
	};
	self.keepInBounds = function (bounds) {
		if (self.x < bounds.x) {
			self.x = bounds.x;
		} else if (self.x > bounds.x + bounds.width) {
			self.x = bounds.x + bounds.width;
		}
		if (self.y < bounds.y) {
			self.y = bounds.y;
		} else if (self.y > bounds.y + bounds.height) {
			self.y = bounds.y + bounds.height;
		}
	};
	return self;
});
var Player = Entity.expand(function () {
	var self = Entity.call(this);
	self.speed = 5;
	self.cooldown = 0;
	self.shootCooldownMax = 30; // half a second at 60fps
	self.score = 0;
	var playerGraphics = self.attachAsset('player', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Create health bar background
	var healthBarBg = self.attachAsset('healthBarBackground', {
		anchorX: 0.5,
		anchorY: 0,
		y: -80
	});
	// Create health bar
	var healthBar = self.attachAsset('healthBar', {
		anchorX: 0,
		anchorY: 0,
		y: -80,
		x: -100
	});
	self.init = function (x, y) {
		self.x = x;
		self.y = y;
		self.health = self.maxHealth;
		self.score = 0;
		self.isDead = false;
		self.alpha = 1;
		self.cooldown = 0;
		self.updateHealthBar();
	};
	self.updateHealthBar = function () {
		var healthPercentage = self.health / self.maxHealth;
		healthBar.width = 200 * healthPercentage;
	};
	self.takeDamage = function (amount) {
		Entity.prototype.takeDamage.call(self, amount);
		self.updateHealthBar();
	};
	self.update = function () {
		if (self.isDead) {
			return;
		}
		if (self.cooldown > 0) {
			self.cooldown--;
		}
		self.updateHealthBar();
	};
	self.shoot = function () {
		if (self.cooldown > 0 || self.isDead) {
			return null;
		}
		var projectile = new Projectile();
		projectile.init(self.x, self.y, 'up');
		self.cooldown = self.shootCooldownMax;
		LK.getSound('projectileShoot').play();
		return projectile;
	};
	self.addScore = function (points) {
		self.score += points;
		if (self.score > storage.highScore) {
			storage.highScore = self.score;
		}
	};
	return self;
});
var Enemy = Entity.expand(function () {
	var self = Entity.call(this);
	self.speed = 2;
	self.attackCooldown = 0;
	self.attackRate = 120; // 2 seconds at 60fps
	self.scoreValue = 10;
	self.targetPlayer = null;
	var enemyGraphics = self.attachAsset('enemy', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.init = function (x, y, targetPlayer) {
		self.x = x;
		self.y = y;
		self.health = 50;
		self.maxHealth = 50;
		self.isDead = false;
		self.alpha = 1;
		self.targetPlayer = targetPlayer;
		self.attackCooldown = Math.floor(Math.random() * self.attackRate);
	};
	self.update = function () {
		if (self.isDead || !self.targetPlayer) {
			return;
		}
		// Move toward player
		var dx = self.targetPlayer.x - self.x;
		var dy = self.targetPlayer.y - self.y;
		var distance = Math.sqrt(dx * dx + dy * dy);
		if (distance > 10) {
			self.x += dx / distance * self.speed;
			self.y += dy / distance * self.speed;
		}
		// Attack logic
		if (self.attackCooldown > 0) {
			self.attackCooldown--;
		} else if (distance < 150) {
			self.attackPlayer();
		}
	};
	self.attackPlayer = function () {
		if (self.isDead || self.targetPlayer.isDead) {
			return null;
		}
		// Attack directly by touching
		if (self.intersects(self.targetPlayer)) {
			self.targetPlayer.takeDamage(10);
			LK.getSound('hit').play();
		}
		// Sometimes shoot projectiles
		if (Math.random() < 0.3) {
			var projectile = new Projectile();
			var angle = Math.atan2(self.targetPlayer.y - self.y, self.targetPlayer.x - self.x);
			projectile.init(self.x, self.y, 'custom', angle);
			self.attackCooldown = self.attackRate;
			return projectile;
		}
		self.attackCooldown = self.attackRate / 2;
		return null;
	};
	return self;
});
var PowerUp = Container.expand(function () {
	var self = Container.call(this);
	self.type = 'health'; // Default type
	self.active = true;
	var powerUpGraphics = self.attachAsset('powerUp', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.init = function (x, y, type) {
		self.x = x;
		self.y = y;
		self.type = type || (Math.random() < 0.7 ? 'health' : 'speed');
		self.active = true;
		self.alpha = 1;
		// Different colors for different power-up types
		if (self.type === 'health') {
			powerUpGraphics.tint = 0x2ecc71; // Green
		} else if (self.type === 'speed') {
			powerUpGraphics.tint = 0x3498db; // Blue
		}
		// Add a pulsing animation
		self.pulse();
	};
	self.pulse = function () {
		tween(powerUpGraphics, {
			scaleX: 1.2,
			scaleY: 1.2
		}, {
			duration: 500,
			easing: tween.sinceOut,
			onFinish: function onFinish() {
				tween(powerUpGraphics, {
					scaleX: 1,
					scaleY: 1
				}, {
					duration: 500,
					easing: tween.sinceIn,
					onFinish: function onFinish() {
						if (self.active) {
							self.pulse();
						}
					}
				});
			}
		});
	};
	self.collect = function (player) {
		if (!self.active) {
			return;
		}
		self.active = false;
		LK.getSound('powerUpCollect').play();
		if (self.type === 'health') {
			player.health = Math.min(player.maxHealth, player.health + 25);
		} else if (self.type === 'speed') {
			var originalSpeed = player.speed;
			player.speed += 2;
			// Speed boost is temporary
			LK.setTimeout(function () {
				if (!player.isDead) {
					player.speed = originalSpeed;
				}
			}, 5000);
		}
		// Fade out and destroy
		tween(self, {
			alpha: 0
		}, {
			duration: 300,
			onFinish: function onFinish() {
				self.destroy();
			}
		});
	};
	return self;
});
var Projectile = Container.expand(function () {
	var self = Container.call(this);
	self.speed = 8;
	self.damage = 10;
	self.direction = 'up';
	self.angleRad = 0;
	var projectileGraphics = self.attachAsset('projectile', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.init = function (x, y, direction, angleRad) {
		self.x = x;
		self.y = y;
		self.direction = direction || 'up';
		self.angleRad = angleRad || 0;
	};
	self.update = function () {
		if (self.direction === 'up') {
			self.y -= self.speed;
		} else if (self.direction === 'down') {
			self.y += self.speed;
		} else if (self.direction === 'custom' && self.angleRad !== undefined) {
			self.x += Math.cos(self.angleRad) * self.speed;
			self.y += Math.sin(self.angleRad) * self.speed;
		}
	};
	return self;
});
var Trap = Container.expand(function () {
	var self = Container.call(this);
	self.damage = 15;
	self.active = true;
	var trapGraphics = self.attachAsset('trap', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.init = function (x, y, damage) {
		self.x = x;
		self.y = y;
		self.damage = damage || 15;
		self.active = true;
		self.alpha = 1;
		// Add a rotating animation
		self.rotate();
	};
	self.rotate = function () {
		tween(trapGraphics, {
			rotation: Math.PI * 2
		}, {
			duration: 3000,
			onFinish: function onFinish() {
				trapGraphics.rotation = 0;
				if (self.active) {
					self.rotate();
				}
			}
		});
	};
	self.trigger = function (entity) {
		if (!self.active) {
			return;
		}
		LK.getSound('trapHit').play();
		entity.takeDamage(self.damage);
		// Visual feedback
		LK.effects.flashObject(self, 0xff0000, 300);
		// Deactivate temporarily
		self.active = false;
		trapGraphics.alpha = 0.5;
		// Reactivate after a delay
		LK.setTimeout(function () {
			if (self.parent) {
				// Check if still in the scene
				self.active = true;
				trapGraphics.alpha = 1;
			}
		}, 3000);
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x2c3e50
});
/**** 
* Game Code
****/ 
// Arena setup
var arena = LK.getAsset('arena', {
	anchorX: 0.5,
	anchorY: 0.5
});
arena.x = 2048 / 2;
arena.y = 2732 / 2;
game.addChild(arena);
// Game state variables
var player = null;
var enemies = [];
var powerUps = [];
var traps = [];
var projectiles = [];
var dragTarget = null;
var gameActive = false;
var waveNumber = 0;
var enemiesDefeated = 0;
var isGameStarting = false;
// Game boundaries
var bounds = {
	x: arena.x - arena.width / 2,
	y: arena.y - arena.height / 2,
	width: arena.width,
	height: arena.height
};
// UI elements
var scoreText = new Text2('0', {
	size: 60,
	fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
var waveText = new Text2('Wave 1', {
	size: 50,
	fill: 0xFFFFFF
});
waveText.anchor.set(0.5, 0);
waveText.y = 80;
LK.gui.top.addChild(waveText);
var highScoreText = new Text2('High Score: ' + storage.highScore, {
	size: 40,
	fill: 0xFFFFFF
});
highScoreText.anchor.set(1, 0);
highScoreText.x = -20;
highScoreText.y = 20;
LK.gui.topRight.addChild(highScoreText);
// Play music
LK.playMusic('battleMusic', {
	fade: {
		start: 0,
		end: 0.3,
		duration: 1000
	}
});
// Initialize the game
function startGame() {
	if (isGameStarting) {
		return;
	}
	isGameStarting = true;
	// Reset game state
	resetGameState();
	// Create player
	player = new Player();
	player.init(arena.x, arena.y + 300);
	game.addChild(player);
	// Create initial traps
	for (var i = 0; i < 5; i++) {
		createTrap();
	}
	// Create initial power-ups
	for (var i = 0; i < 3; i++) {
		createPowerUp();
	}
	// Start first wave
	startNextWave();
	// Update UI
	updateScoreDisplay();
	gameActive = true;
	isGameStarting = false;
}
function resetGameState() {
	// Remove existing entities
	if (player && !player.isDead) {
		player.die();
	}
	// Clean up arrays
	cleanupArrays();
	// Reset game variables
	waveNumber = 0;
	enemiesDefeated = 0;
	LK.setScore(0);
}
function cleanupArrays() {
	// Clean up enemies
	for (var i = enemies.length - 1; i >= 0; i--) {
		if (enemies[i].parent) {
			enemies[i].destroy();
		}
		enemies.splice(i, 1);
	}
	// Clean up power-ups
	for (var i = powerUps.length - 1; i >= 0; i--) {
		if (powerUps[i].parent) {
			powerUps[i].destroy();
		}
		powerUps.splice(i, 1);
	}
	// Clean up traps
	for (var i = traps.length - 1; i >= 0; i--) {
		if (traps[i].parent) {
			traps[i].destroy();
		}
		traps.splice(i, 1);
	}
	// Clean up projectiles
	for (var i = projectiles.length - 1; i >= 0; i--) {
		if (projectiles[i].parent) {
			projectiles[i].destroy();
		}
		projectiles.splice(i, 1);
	}
}
function startNextWave() {
	waveNumber++;
	waveText.setText('Wave ' + waveNumber);
	// Display wave announcement
	var waveAnnouncement = new Text2('Wave ' + waveNumber, {
		size: 120,
		fill: 0xFFFFFF
	});
	waveAnnouncement.anchor.set(0.5, 0.5);
	LK.gui.center.addChild(waveAnnouncement);
	// Fade in and out
	waveAnnouncement.alpha = 0;
	tween(waveAnnouncement, {
		alpha: 1
	}, {
		duration: 800,
		onFinish: function onFinish() {
			LK.setTimeout(function () {
				tween(waveAnnouncement, {
					alpha: 0
				}, {
					duration: 800,
					onFinish: function onFinish() {
						waveAnnouncement.destroy();
					}
				});
			}, 1000);
		}
	});
	// Spawn enemies for this wave
	var enemiesToSpawn = Math.min(3 + waveNumber, 10);
	for (var i = 0; i < enemiesToSpawn; i++) {
		LK.setTimeout(function () {
			if (gameActive && player && !player.isDead) {
				spawnEnemy();
			}
		}, i * 800);
	}
	// Add a new trap and powerup with each wave
	if (waveNumber > 1) {
		createTrap();
		if (waveNumber % 2 === 0) {
			createPowerUp();
		}
	}
}
function spawnEnemy() {
	if (!player || player.isDead) {
		return;
	}
	var enemy = new Enemy();
	var edge = Math.floor(Math.random() * 4);
	var x, y;
	// Spawn from edges of the arena
	switch (edge) {
		case 0:
			// Top
			x = bounds.x + Math.random() * bounds.width;
			y = bounds.y;
			break;
		case 1:
			// Right
			x = bounds.x + bounds.width;
			y = bounds.y + Math.random() * bounds.height;
			break;
		case 2:
			// Bottom
			x = bounds.x + Math.random() * bounds.width;
			y = bounds.y + bounds.height;
			break;
		case 3:
			// Left
			x = bounds.x;
			y = bounds.y + Math.random() * bounds.height;
			break;
	}
	enemy.init(x, y, player);
	game.addChild(enemy);
	enemies.push(enemy);
}
function createPowerUp() {
	var powerUp = new PowerUp();
	var x = bounds.x + 100 + Math.random() * (bounds.width - 200);
	var y = bounds.y + 100 + Math.random() * (bounds.height - 200);
	powerUp.init(x, y);
	game.addChild(powerUp);
	powerUps.push(powerUp);
}
function createTrap() {
	var trap = new Trap();
	var x = bounds.x + 100 + Math.random() * (bounds.width - 200);
	var y = bounds.y + 100 + Math.random() * (bounds.height - 200);
	trap.init(x, y);
	game.addChild(trap);
	traps.push(trap);
}
function updateScoreDisplay() {
	scoreText.setText('Score: ' + LK.getScore());
	highScoreText.setText('High Score: ' + storage.highScore);
}
function checkCollisions() {
	if (!player || player.isDead) {
		return;
	}
	// Player-Enemy collisions
	for (var i = enemies.length - 1; i >= 0; i--) {
		var enemy = enemies[i];
		if (enemy.isDead) {
			continue;
		}
		if (player.intersects(enemy)) {
			player.takeDamage(5);
			LK.getSound('hit').play();
		}
	}
	// Player-PowerUp collisions
	for (var i = powerUps.length - 1; i >= 0; i--) {
		var powerUp = powerUps[i];
		if (!powerUp.active) {
			continue;
		}
		if (player.intersects(powerUp)) {
			powerUp.collect(player);
			powerUps.splice(i, 1);
		}
	}
	// Player-Trap collisions
	for (var i = traps.length - 1; i >= 0; i--) {
		var trap = traps[i];
		if (!trap.active) {
			continue;
		}
		if (player.intersects(trap)) {
			trap.trigger(player);
		}
	}
	// Projectile-Enemy collisions
	for (var i = projectiles.length - 1; i >= 0; i--) {
		var projectile = projectiles[i];
		var hit = false;
		// Check if projectile is out of bounds
		if (projectile.isOutOfBounds(bounds)) {
			projectile.destroy();
			projectiles.splice(i, 1);
			continue;
		}
		// Check hits against enemies (only if shot by player)
		if (projectile.direction === 'up') {
			for (var j = enemies.length - 1; j >= 0; j--) {
				var enemy = enemies[j];
				if (enemy.isDead) {
					continue;
				}
				if (projectile.intersects(enemy)) {
					enemy.takeDamage(projectile.damage);
					LK.getSound('hit').play();
					if (enemy.health <= 0) {
						player.addScore(enemy.scoreValue);
						LK.setScore(player.score);
						updateScoreDisplay();
						enemies.splice(j, 1);
						enemiesDefeated++;
						// Check if wave is complete
						if (enemies.length === 0) {
							LK.setTimeout(startNextWave, 2000);
						}
					}
					hit = true;
					break;
				}
			}
		}
		// Check hits against player (only if shot by enemy)
		else if (projectile.direction === 'custom' && player && !player.isDead) {
			if (projectile.intersects(player)) {
				player.takeDamage(projectile.damage);
				LK.getSound('hit').play();
				hit = true;
			}
		}
		if (hit) {
			projectile.destroy();
			projectiles.splice(i, 1);
		}
	}
}
// Game input handlers
game.down = function (x, y, obj) {
	if (!gameActive) {
		startGame();
		return;
	}
	if (player && !player.isDead) {
		dragTarget = player;
		player.x = x;
		player.y = y;
		player.keepInBounds(bounds);
	}
};
game.up = function (x, y, obj) {
	dragTarget = null;
	// Shoot on release if game is active
	if (gameActive && player && !player.isDead) {
		var projectile = player.shoot();
		if (projectile) {
			game.addChild(projectile);
			projectiles.push(projectile);
		}
	}
};
game.move = function (x, y, obj) {
	if (dragTarget === player && player && !player.isDead) {
		player.x = x;
		player.y = y;
		player.keepInBounds(bounds);
	}
};
// Main game update loop
game.update = function () {
	if (!gameActive) {
		// Show start game message if not already started
		if (!isGameStarting && (!player || player.isDead)) {
			var _pulseMessage = function pulseMessage() {
				tween(startMessage, {
					scaleX: 1.1,
					scaleY: 1.1
				}, {
					duration: 800,
					easing: tween.sinceOut,
					onFinish: function onFinish() {
						tween(startMessage, {
							scaleX: 1,
							scaleY: 1
						}, {
							duration: 800,
							easing: tween.sinceIn,
							onFinish: function onFinish() {
								if (startMessage.parent) {
									_pulseMessage();
								}
							}
						});
					}
				});
			};
			var startMessage = new Text2('Tap to Start', {
				size: 80,
				fill: 0xFFFFFF
			});
			startMessage.anchor.set(0.5, 0.5);
			LK.gui.center.addChild(startMessage);
			// Pulse animation for the start message
			_pulseMessage();
			gameActive = true; // Set to true so message only shows once
		}
		return;
	}
	// If player is dead, show game over
	if (player && player.isDead) {
		storage.totalMatches++;
		LK.showGameOver();
		return;
	}
	// Update all game entities
	if (player) {
		player.update();
	}
	for (var i = 0; i < enemies.length; i++) {
		if (!enemies[i].isDead) {
			enemies[i].update();
			// Chance for enemy to shoot
			if (Math.random() < 0.005) {
				var enemyProjectile = enemies[i].attackPlayer();
				if (enemyProjectile) {
					game.addChild(enemyProjectile);
					projectiles.push(enemyProjectile);
				}
			}
		}
	}
	for (var i = 0; i < projectiles.length; i++) {
		projectiles[i].update();
	}
	// Check various collisions
	checkCollisions();
	// Spawn additional power-ups randomly
	if (Math.random() < 0.001 && powerUps.length < 5) {
		createPowerUp();
	}
	// Spawn additional traps randomly in later waves
	if (waveNumber > 2 && Math.random() < 0.0005 && traps.length < waveNumber + 3) {
		createTrap();
	}
};
// Initial screen
var titleText = new Text2('Arena Rivals', {
	size: 120,
	fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.y = -200;
LK.gui.center.addChild(titleText);
var instructionText = new Text2('Tap and drag to move\nRelease to shoot', {
	size: 60,
	fill: 0xFFFFFF
});
instructionText.anchor.set(0.5, 0.5);
instructionText.y = 100;
LK.gui.center.addChild(instructionText);
// Start game message
var startMessage = new Text2('Tap to Start', {
	size: 80,
	fill: 0xFFFFFF
});
startMessage.anchor.set(0.5, 0.5);
startMessage.y = 300;
LK.gui.center.addChild(startMessage);
// Pulse animation for the start message
function pulseStartMessage() {
	tween(startMessage, {
		scaleX: 1.1,
		scaleY: 1.1
	}, {
		duration: 800,
		easing: tween.sinceOut,
		onFinish: function onFinish() {
			tween(startMessage, {
				scaleX: 1,
				scaleY: 1
			}, {
				duration: 800,
				easing: tween.sinceIn,
				onFinish: pulseStartMessage
			});
		}
	});
}
pulseStartMessage();