/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var facekit = LK.import("@upit/facekit.v1");
/**** 
* Classes
****/ 
// Enemy class
var Enemy = Container.expand(function () {
	var self = Container.call(this);
	var enemyAsset = self.attachAsset('enemy', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 12 + Math.random() * 8; // Downward, randomize a bit
	self.update = function () {
		self.y += self.speed;
	};
	return self;
});
// Bullet class
var HeroBullet = Container.expand(function () {
	var self = Container.call(this);
	var bulletAsset = self.attachAsset('heroBullet', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = -40; // Fast upward
	self.update = function () {
		self.y += self.speed;
	};
	return self;
});
// Hero Ship class
var HeroShip = Container.expand(function () {
	var self = Container.call(this);
	var shipAsset = self.attachAsset('heroShip', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// For possible future effects
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x000000
});
/**** 
* Game Code
****/ 
// Start music 'Adrenaline' at game start
LK.playMusic('Adrenaline');
// Score display 
// Hero ship: ellipse, blue
// Bullet: small yellow box
// Enemy: red ellipse
// Sound for shooting
var scoreTxt = new Text2('0', {
	size: 120,
	fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Create hero ship
var heroShip = new HeroShip();
game.addChild(heroShip);
// Start at center bottom
heroShip.x = 2048 / 2;
heroShip.y = 2732 - 350;
// Bullets and enemies arrays
var heroBullets = [];
var enemies = [];
// Bullet cooldown
var bulletCooldown = 0;
var bulletCooldownFrames = 12; // ~0.2s at 60fps
// Enemy spawn timer
var enemySpawnFrames = 36; // ~0.6s at 60fps
// For mouth open detection
var lastMouthOpen = false;
// For game over state
var isGameOver = false;
// Main update loop
game.update = function () {
	// Move hero ship to facekit mouth position (if available)
	if (facekit.mouthCenter && typeof facekit.mouthCenter.x === 'number' && typeof facekit.mouthCenter.y === 'number') {
		// Clamp to game area, keep ship fully visible
		var shipW = heroShip.width || 140;
		var shipH = heroShip.height || 140;
		var targetX = Math.max(shipW / 2, Math.min(2048 - shipW / 2, facekit.mouthCenter.x));
		var targetY = Math.max(shipH / 2 + 100, Math.min(2732 - shipH / 2, facekit.mouthCenter.y));
		// Tween for smoothness
		tween(heroShip, {
			x: targetX,
			y: targetY
		}, {
			duration: 80,
			easing: tween.easeOut
		});
	}
	// Handle shooting (mouth open)
	var mouthOpen = !!facekit.mouthOpen;
	if (mouthOpen && !lastMouthOpen && bulletCooldown <= 0) {
		// Fire bullet
		var bullet = new HeroBullet();
		bullet.x = heroShip.x;
		bullet.y = heroShip.y - (heroShip.height ? heroShip.height / 2 : 70) - 30;
		heroBullets.push(bullet);
		game.addChild(bullet);
		bulletCooldown = bulletCooldownFrames;
		// Play shoot sound
		LK.getSound('shoot').play();
	}
	lastMouthOpen = mouthOpen;
	if (bulletCooldown > 0) bulletCooldown--;
	// Update bullets
	for (var i = heroBullets.length - 1; i >= 0; i--) {
		var b = heroBullets[i];
		b.update();
		// Remove if off screen
		if (b.y < -100) {
			b.destroy();
			heroBullets.splice(i, 1);
			continue;
		}
	}
	// Spawn enemies
	if (LK.ticks % enemySpawnFrames === 0) {
		var enemy = new Enemy();
		// Random X, avoid edges
		var ew = enemy.width || 120;
		enemy.x = ew / 2 + 80 + Math.random() * (2048 - ew - 160);
		enemy.y = -ew / 2 - 40;
		enemies.push(enemy);
		game.addChild(enemy);
	}
	// Update enemies
	for (var j = enemies.length - 1; j >= 0; j--) {
		var e = enemies[j];
		e.update();
		// Remove if off screen
		if (e.y > 2732 + 100) {
			e.destroy();
			enemies.splice(j, 1);
			continue;
		}
	}
	// Bullet-enemy collisions
	for (var k = enemies.length - 1; k >= 0; k--) {
		var enemyObj = enemies[k];
		for (var l = heroBullets.length - 1; l >= 0; l--) {
			var bulletObj = heroBullets[l];
			if (enemyObj.intersects(bulletObj)) {
				// Destroy both
				enemyObj.destroy();
				bulletObj.destroy();
				enemies.splice(k, 1);
				heroBullets.splice(l, 1);
				// Score up
				LK.setScore(LK.getScore() + 1);
				scoreTxt.setText(LK.getScore());
				break;
			}
		}
	}
	// Enemy-hero collision (game over)
	for (var m = 0; m < enemies.length; m++) {
		var enemyObj2 = enemies[m];
		if (enemyObj2.intersects(heroShip)) {
			if (!isGameOver) {
				isGameOver = true;
				LK.effects.flashScreen(0xff0000, 1000);
				LK.showGameOver();
			}
			break;
		}
	}
};
// No touch controls needed; all control is via facekit
// Reset state on game over (handled by LK, but clear local state)
game.onDestroy = function () {
	heroBullets = [];
	enemies = [];
	isGameOver = false;
	lastMouthOpen = false;
	bulletCooldown = 0;
	scoreTxt.setText('0');
}; /**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var facekit = LK.import("@upit/facekit.v1");
/**** 
* Classes
****/ 
// Enemy class
var Enemy = Container.expand(function () {
	var self = Container.call(this);
	var enemyAsset = self.attachAsset('enemy', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 12 + Math.random() * 8; // Downward, randomize a bit
	self.update = function () {
		self.y += self.speed;
	};
	return self;
});
// Bullet class
var HeroBullet = Container.expand(function () {
	var self = Container.call(this);
	var bulletAsset = self.attachAsset('heroBullet', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = -40; // Fast upward
	self.update = function () {
		self.y += self.speed;
	};
	return self;
});
// Hero Ship class
var HeroShip = Container.expand(function () {
	var self = Container.call(this);
	var shipAsset = self.attachAsset('heroShip', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// For possible future effects
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x000000
});
/**** 
* Game Code
****/ 
// Start music 'Adrenaline' at game start
LK.playMusic('Adrenaline');
// Score display 
// Hero ship: ellipse, blue
// Bullet: small yellow box
// Enemy: red ellipse
// Sound for shooting
var scoreTxt = new Text2('0', {
	size: 120,
	fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Create hero ship
var heroShip = new HeroShip();
game.addChild(heroShip);
// Start at center bottom
heroShip.x = 2048 / 2;
heroShip.y = 2732 - 350;
// Bullets and enemies arrays
var heroBullets = [];
var enemies = [];
// Bullet cooldown
var bulletCooldown = 0;
var bulletCooldownFrames = 12; // ~0.2s at 60fps
// Enemy spawn timer
var enemySpawnFrames = 36; // ~0.6s at 60fps
// For mouth open detection
var lastMouthOpen = false;
// For game over state
var isGameOver = false;
// Main update loop
game.update = function () {
	// Move hero ship to facekit mouth position (if available)
	if (facekit.mouthCenter && typeof facekit.mouthCenter.x === 'number' && typeof facekit.mouthCenter.y === 'number') {
		// Clamp to game area, keep ship fully visible
		var shipW = heroShip.width || 140;
		var shipH = heroShip.height || 140;
		var targetX = Math.max(shipW / 2, Math.min(2048 - shipW / 2, facekit.mouthCenter.x));
		var targetY = Math.max(shipH / 2 + 100, Math.min(2732 - shipH / 2, facekit.mouthCenter.y));
		// Tween for smoothness
		tween(heroShip, {
			x: targetX,
			y: targetY
		}, {
			duration: 80,
			easing: tween.easeOut
		});
	}
	// Handle shooting (mouth open)
	var mouthOpen = !!facekit.mouthOpen;
	if (mouthOpen && !lastMouthOpen && bulletCooldown <= 0) {
		// Fire bullet
		var bullet = new HeroBullet();
		bullet.x = heroShip.x;
		bullet.y = heroShip.y - (heroShip.height ? heroShip.height / 2 : 70) - 30;
		heroBullets.push(bullet);
		game.addChild(bullet);
		bulletCooldown = bulletCooldownFrames;
		// Play shoot sound
		LK.getSound('shoot').play();
	}
	lastMouthOpen = mouthOpen;
	if (bulletCooldown > 0) bulletCooldown--;
	// Update bullets
	for (var i = heroBullets.length - 1; i >= 0; i--) {
		var b = heroBullets[i];
		b.update();
		// Remove if off screen
		if (b.y < -100) {
			b.destroy();
			heroBullets.splice(i, 1);
			continue;
		}
	}
	// Spawn enemies
	if (LK.ticks % enemySpawnFrames === 0) {
		var enemy = new Enemy();
		// Random X, avoid edges
		var ew = enemy.width || 120;
		enemy.x = ew / 2 + 80 + Math.random() * (2048 - ew - 160);
		enemy.y = -ew / 2 - 40;
		enemies.push(enemy);
		game.addChild(enemy);
	}
	// Update enemies
	for (var j = enemies.length - 1; j >= 0; j--) {
		var e = enemies[j];
		e.update();
		// Remove if off screen
		if (e.y > 2732 + 100) {
			e.destroy();
			enemies.splice(j, 1);
			continue;
		}
	}
	// Bullet-enemy collisions
	for (var k = enemies.length - 1; k >= 0; k--) {
		var enemyObj = enemies[k];
		for (var l = heroBullets.length - 1; l >= 0; l--) {
			var bulletObj = heroBullets[l];
			if (enemyObj.intersects(bulletObj)) {
				// Destroy both
				enemyObj.destroy();
				bulletObj.destroy();
				enemies.splice(k, 1);
				heroBullets.splice(l, 1);
				// Score up
				LK.setScore(LK.getScore() + 1);
				scoreTxt.setText(LK.getScore());
				break;
			}
		}
	}
	// Enemy-hero collision (game over)
	for (var m = 0; m < enemies.length; m++) {
		var enemyObj2 = enemies[m];
		if (enemyObj2.intersects(heroShip)) {
			if (!isGameOver) {
				isGameOver = true;
				LK.effects.flashScreen(0xff0000, 1000);
				LK.showGameOver();
			}
			break;
		}
	}
};
// No touch controls needed; all control is via facekit
// Reset state on game over (handled by LK, but clear local state)
game.onDestroy = function () {
	heroBullets = [];
	enemies = [];
	isGameOver = false;
	lastMouthOpen = false;
	bulletCooldown = 0;
	scoreTxt.setText('0');
};