/**** 
* Classes
****/
// ExplosionBlock class
var ExplosionBlock = Container.expand(function () {
	var self = Container.call(this);
	var blockGraphics = self.createAsset('explosionBlock', 'Explosion Block', 0.5, 0.5);
	blockGraphics.scale.set(2);
	self.fadeOut = function () {
		var fadeDuration = 2000; // 2 seconds
		var fadeStep = self.alpha / (fadeDuration / (1000 / 60)); // Calculate fade step for 60FPS
		var fadeInterval = LK.setInterval(function () {
			self.alpha -= fadeStep;
			if (self.alpha <= 0) {
				LK.clearInterval(fadeInterval);
				self.destroy();
			}
		}, 1000 / 60);
	};
	self.fadeOut();
	blockGraphics.tint = 0xFFA500; // Orange color
	self.speed = 40;
	self.direction = {
		x: 0,
		y: 0
	};
	self.move = function () {
		self.x += self.direction.x * self.speed;
		self.y += self.direction.y * self.speed;
	};
	self.isOffScreen = function () {
		return self.x < -self.width || self.x > 2048 + self.width || self.y < -self.height || self.y > 2732 + self.height;
	};
});
// Enemy class
var Enemy = Container.expand(function () {
	var self = Container.call(this);
	var enemyGraphics = self.createAsset('enemy', 'Enemy Ship', 0.5, 0.5);
	enemyGraphics.scale.set(2);
	self.speed = 4;
	self.move = function () {
		self.y += self.speed;
	};
	self.isOffScreen = function () {
		return self.y > 2732 + self.height;
	};
});
// Hero class
var Hero = Container.expand(function () {
	var self = Container.call(this);
	var heroGraphics = self.createAsset('hero', 'Hero Ship', 0.5, 0.5);
	heroGraphics.scale.set(2);
	self.x = 2048 / 2;
	self.y = 2732 - 200;
});
// Bullet class
var Bullet = Container.expand(function () {
	var self = Container.call(this);
	var bulletGraphics = self.createAsset('bullet', 'Bullet', 0.5, 0.5);
	bulletGraphics.scale.set(2);
	self.speed = -20;
	self.move = function () {
		self.y += self.speed;
	};
	self.isOffScreen = function () {
		return self.y < -self.height;
	};
});
// EnemyBullet class
var EnemyBullet = Container.expand(function () {
	var self = Container.call(this);
	var bulletGraphics = self.createAsset('enemyBullet', 'Enemy Bullet', 0.5, 0.5);
	bulletGraphics.scale.set(2);
	self.speed = 10;
	self.move = function () {
		self.y += self.speed;
	};
	self.isOffScreen = function () {
		return self.y > 2732 + self.height;
	};
});
// HomingBullet class
var HomingBullet = Container.expand(function () {
	var self = Container.call(this);
	var bulletGraphics = self.createAsset('homingBullet', 'Homing Bullet', 0.5, 0.5);
	bulletGraphics.scale.set(2);
	self.speed = 2;
	self.target = null;
	self.creationTime = LK.ticks;
	self.move = function () {
		if (LK.ticks >= self.creationTime + 600) {
			self.destroy();
			return;
		}
		if (self.target) {
			var dx = self.target.x - self.x;
			var dy = self.target.y - self.y;
			var angle = Math.atan2(dy, dx);
			self.x += Math.cos(angle) * self.speed;
			self.y += Math.sin(angle) * self.speed;
			self.rotation = angle;
		} else {
			// Default movement towards the bottom of the screen if no target is set
			self.y += self.speed;
		}
		if (self.target && self.intersects(self.target)) {
			// Player hit by homing bullet
			LK.effects.flashScreen(0xff0000, 1000);
			LK.showGameOver();
			isGameOver = true;
			self.destroy();
			return;
		}
	};
	self.setTarget = function (target) {
		self.target = target;
	};
	self.isOffScreen = function () {
		return self.x < -self.width || self.x > 2048 + self.width || self.y < -self.height || self.y > 2732 + self.height;
	};
});
/**** 
* Initialize Game
****/
var game = new LK.Game({
	backgroundColor: 0x000000 // Init game with black background
});
/**** 
* Game Code
****/
// Initialize hero
var hero = game.addChild(new Hero());
// Initialize enemy and bullet arrays
var enemies = [];
var heroBullets = [];
var enemyBullets = [];
// Initialize homing bullet chance and increment
var homingBulletChance = 0.01; // 1% initial chance
var homingBulletIncrement = 0.01; // 1% increment every 3 seconds
var lastHomingBulletIncrementTime = LK.ticks;
// Game state
var isGameOver = false;
// Touch event handling
var dragNode = null;
function handleMove(obj) {
	var event = obj.event;
	var pos = event.getLocalPosition(game);
	if (dragNode) {
		dragNode.x = pos.x;
		dragNode.y = pos.y;
	}
}
game.on('down', function (obj) {
	dragNode = hero;
	handleMove(obj);
});
game.on('move', handleMove);
game.on('up', function (obj) {
	dragNode = null;
});
// Game tick event
LK.on('tick', function () {
	if (isGameOver) {
		LK.effects.flashScreen(0xff0000, 1000);
		LK.showGameOver();
		return;
	}
	// Move hero bullets
	for (var i = heroBullets.length - 1; i >= 0; i--) {
		heroBullets[i].move();
		if (heroBullets[i].isOffScreen()) {
			heroBullets[i].destroy();
			heroBullets.splice(i, 1);
		}
	}
	// Move enemies and enemy bullets
	for (var j = enemies.length - 1; j >= 0; j--) {
		enemies[j].move();
		if (enemies[j].isOffScreen()) {
			enemies[j].destroy();
			enemies.splice(j, 1);
		}
	}
	// Check if hero is hit by enemy bullets
	for (var m = enemyBullets.length - 1; m >= 0; m--) {
		enemyBullets[m].move();
		if (enemyBullets[m].intersects(hero)) {
			LK.effects.flashScreen(0xff0000, 1000);
			LK.showGameOver();
			isGameOver = true;
			return;
		}
		if (enemyBullets[m].isOffScreen()) {
			enemyBullets[m].destroy();
			enemyBullets.splice(m, 1);
		}
	}
	// Check for collisions
	for (var k = heroBullets.length - 1; k >= 0; k--) {
		for (var l = enemies.length - 1; l >= 0; l--) {
			if (heroBullets[k].intersects(enemies[l])) {
				heroBullets[k].destroy();
				heroBullets.splice(k, 1);
				// Create explosion blocks
				var directions = [{
					x: -1,
					y: 0
				},
				// Left
				{
					x: 1,
					y: 0
				},
				// Right
				{
					x: 0,
					y: -1
				},
				// Up
				{
					x: 0,
					y: 1
				} // Down
				];
				directions.forEach(function (dir) {
					var block = new ExplosionBlock();
					block.x = enemies[l].x;
					block.y = enemies[l].y;
					block.direction = dir;
					game.addChild(block);
				});
				// Destroy the enemy
				enemies[l].destroy();
				enemies.splice(l, 1);
				break;
			}
		}
	}
	// Fire hero bullets
	if (LK.ticks % 60 == 0) {
		var bullet = new Bullet();
		bullet.x = hero.x;
		bullet.y = hero.y;
		heroBullets.push(bullet);
		game.addChild(bullet);
	}
	// Enemies shoot bullets
	if (LK.ticks % 120 == 0) {
		enemies.forEach(function (enemy) {
			// Update homing bullet chance every 3 seconds (180 ticks)
			if (LK.ticks - lastHomingBulletIncrementTime >= 180) {
				homingBulletChance += homingBulletIncrement;
				lastHomingBulletIncrementTime = LK.ticks;
			}
			// Adjusted chance for HomingBullet
			if (Math.random() < homingBulletChance) {
				var homingBullet = new HomingBullet();
				homingBullet.x = enemy.x;
				homingBullet.y = enemy.y + enemy.height / 2;
				homingBullet.setTarget(hero);
				game.addChild(homingBullet);
			} else {
				var enemyBullet = new EnemyBullet();
				enemyBullet.x = enemy.x;
				enemyBullet.y = enemy.y + enemy.height / 2;
				enemyBullets.push(enemyBullet);
				game.addChild(enemyBullet);
			}
		});
	}
	// Spawn enemies and make them shoot bullets
	// Moved enemyBullets array declaration to the top of the game code to persist its state
	if (LK.ticks % 120 == 0) {
		var enemy = new Enemy();
		enemy.x = Math.random() * (2048 - enemy.width) + enemy.width / 2;
		enemy.y = -enemy.height;
		enemies.push(enemy);
		game.addChild(enemy);
	}
	// Enemies shoot bullets
	if (LK.ticks % 120 == 0) {
		enemies.forEach(function (enemy) {
			var enemyBullet = new EnemyBullet();
			enemyBullet.x = enemy.x;
			enemyBullet.y = enemy.y + enemy.height / 2;
			enemyBullets.push(enemyBullet);
			game.addChild(enemyBullet);
		});
	}
}); /**** 
* Classes
****/
// ExplosionBlock class
var ExplosionBlock = Container.expand(function () {
	var self = Container.call(this);
	var blockGraphics = self.createAsset('explosionBlock', 'Explosion Block', 0.5, 0.5);
	blockGraphics.scale.set(2);
	self.fadeOut = function () {
		var fadeDuration = 2000; // 2 seconds
		var fadeStep = self.alpha / (fadeDuration / (1000 / 60)); // Calculate fade step for 60FPS
		var fadeInterval = LK.setInterval(function () {
			self.alpha -= fadeStep;
			if (self.alpha <= 0) {
				LK.clearInterval(fadeInterval);
				self.destroy();
			}
		}, 1000 / 60);
	};
	self.fadeOut();
	blockGraphics.tint = 0xFFA500; // Orange color
	self.speed = 40;
	self.direction = {
		x: 0,
		y: 0
	};
	self.move = function () {
		self.x += self.direction.x * self.speed;
		self.y += self.direction.y * self.speed;
	};
	self.isOffScreen = function () {
		return self.x < -self.width || self.x > 2048 + self.width || self.y < -self.height || self.y > 2732 + self.height;
	};
});
// Enemy class
var Enemy = Container.expand(function () {
	var self = Container.call(this);
	var enemyGraphics = self.createAsset('enemy', 'Enemy Ship', 0.5, 0.5);
	enemyGraphics.scale.set(2);
	self.speed = 4;
	self.move = function () {
		self.y += self.speed;
	};
	self.isOffScreen = function () {
		return self.y > 2732 + self.height;
	};
});
// Hero class
var Hero = Container.expand(function () {
	var self = Container.call(this);
	var heroGraphics = self.createAsset('hero', 'Hero Ship', 0.5, 0.5);
	heroGraphics.scale.set(2);
	self.x = 2048 / 2;
	self.y = 2732 - 200;
});
// Bullet class
var Bullet = Container.expand(function () {
	var self = Container.call(this);
	var bulletGraphics = self.createAsset('bullet', 'Bullet', 0.5, 0.5);
	bulletGraphics.scale.set(2);
	self.speed = -20;
	self.move = function () {
		self.y += self.speed;
	};
	self.isOffScreen = function () {
		return self.y < -self.height;
	};
});
// EnemyBullet class
var EnemyBullet = Container.expand(function () {
	var self = Container.call(this);
	var bulletGraphics = self.createAsset('enemyBullet', 'Enemy Bullet', 0.5, 0.5);
	bulletGraphics.scale.set(2);
	self.speed = 10;
	self.move = function () {
		self.y += self.speed;
	};
	self.isOffScreen = function () {
		return self.y > 2732 + self.height;
	};
});
// HomingBullet class
var HomingBullet = Container.expand(function () {
	var self = Container.call(this);
	var bulletGraphics = self.createAsset('homingBullet', 'Homing Bullet', 0.5, 0.5);
	bulletGraphics.scale.set(2);
	self.speed = 2;
	self.target = null;
	self.creationTime = LK.ticks;
	self.move = function () {
		if (LK.ticks >= self.creationTime + 600) {
			self.destroy();
			return;
		}
		if (self.target) {
			var dx = self.target.x - self.x;
			var dy = self.target.y - self.y;
			var angle = Math.atan2(dy, dx);
			self.x += Math.cos(angle) * self.speed;
			self.y += Math.sin(angle) * self.speed;
			self.rotation = angle;
		} else {
			// Default movement towards the bottom of the screen if no target is set
			self.y += self.speed;
		}
		if (self.target && self.intersects(self.target)) {
			// Player hit by homing bullet
			LK.effects.flashScreen(0xff0000, 1000);
			LK.showGameOver();
			isGameOver = true;
			self.destroy();
			return;
		}
	};
	self.setTarget = function (target) {
		self.target = target;
	};
	self.isOffScreen = function () {
		return self.x < -self.width || self.x > 2048 + self.width || self.y < -self.height || self.y > 2732 + self.height;
	};
});
/**** 
* Initialize Game
****/
var game = new LK.Game({
	backgroundColor: 0x000000 // Init game with black background
});
/**** 
* Game Code
****/
// Initialize hero
var hero = game.addChild(new Hero());
// Initialize enemy and bullet arrays
var enemies = [];
var heroBullets = [];
var enemyBullets = [];
// Initialize homing bullet chance and increment
var homingBulletChance = 0.01; // 1% initial chance
var homingBulletIncrement = 0.01; // 1% increment every 3 seconds
var lastHomingBulletIncrementTime = LK.ticks;
// Game state
var isGameOver = false;
// Touch event handling
var dragNode = null;
function handleMove(obj) {
	var event = obj.event;
	var pos = event.getLocalPosition(game);
	if (dragNode) {
		dragNode.x = pos.x;
		dragNode.y = pos.y;
	}
}
game.on('down', function (obj) {
	dragNode = hero;
	handleMove(obj);
});
game.on('move', handleMove);
game.on('up', function (obj) {
	dragNode = null;
});
// Game tick event
LK.on('tick', function () {
	if (isGameOver) {
		LK.effects.flashScreen(0xff0000, 1000);
		LK.showGameOver();
		return;
	}
	// Move hero bullets
	for (var i = heroBullets.length - 1; i >= 0; i--) {
		heroBullets[i].move();
		if (heroBullets[i].isOffScreen()) {
			heroBullets[i].destroy();
			heroBullets.splice(i, 1);
		}
	}
	// Move enemies and enemy bullets
	for (var j = enemies.length - 1; j >= 0; j--) {
		enemies[j].move();
		if (enemies[j].isOffScreen()) {
			enemies[j].destroy();
			enemies.splice(j, 1);
		}
	}
	// Check if hero is hit by enemy bullets
	for (var m = enemyBullets.length - 1; m >= 0; m--) {
		enemyBullets[m].move();
		if (enemyBullets[m].intersects(hero)) {
			LK.effects.flashScreen(0xff0000, 1000);
			LK.showGameOver();
			isGameOver = true;
			return;
		}
		if (enemyBullets[m].isOffScreen()) {
			enemyBullets[m].destroy();
			enemyBullets.splice(m, 1);
		}
	}
	// Check for collisions
	for (var k = heroBullets.length - 1; k >= 0; k--) {
		for (var l = enemies.length - 1; l >= 0; l--) {
			if (heroBullets[k].intersects(enemies[l])) {
				heroBullets[k].destroy();
				heroBullets.splice(k, 1);
				// Create explosion blocks
				var directions = [{
					x: -1,
					y: 0
				},
				// Left
				{
					x: 1,
					y: 0
				},
				// Right
				{
					x: 0,
					y: -1
				},
				// Up
				{
					x: 0,
					y: 1
				} // Down
				];
				directions.forEach(function (dir) {
					var block = new ExplosionBlock();
					block.x = enemies[l].x;
					block.y = enemies[l].y;
					block.direction = dir;
					game.addChild(block);
				});
				// Destroy the enemy
				enemies[l].destroy();
				enemies.splice(l, 1);
				break;
			}
		}
	}
	// Fire hero bullets
	if (LK.ticks % 60 == 0) {
		var bullet = new Bullet();
		bullet.x = hero.x;
		bullet.y = hero.y;
		heroBullets.push(bullet);
		game.addChild(bullet);
	}
	// Enemies shoot bullets
	if (LK.ticks % 120 == 0) {
		enemies.forEach(function (enemy) {
			// Update homing bullet chance every 3 seconds (180 ticks)
			if (LK.ticks - lastHomingBulletIncrementTime >= 180) {
				homingBulletChance += homingBulletIncrement;
				lastHomingBulletIncrementTime = LK.ticks;
			}
			// Adjusted chance for HomingBullet
			if (Math.random() < homingBulletChance) {
				var homingBullet = new HomingBullet();
				homingBullet.x = enemy.x;
				homingBullet.y = enemy.y + enemy.height / 2;
				homingBullet.setTarget(hero);
				game.addChild(homingBullet);
			} else {
				var enemyBullet = new EnemyBullet();
				enemyBullet.x = enemy.x;
				enemyBullet.y = enemy.y + enemy.height / 2;
				enemyBullets.push(enemyBullet);
				game.addChild(enemyBullet);
			}
		});
	}
	// Spawn enemies and make them shoot bullets
	// Moved enemyBullets array declaration to the top of the game code to persist its state
	if (LK.ticks % 120 == 0) {
		var enemy = new Enemy();
		enemy.x = Math.random() * (2048 - enemy.width) + enemy.width / 2;
		enemy.y = -enemy.height;
		enemies.push(enemy);
		game.addChild(enemy);
	}
	// Enemies shoot bullets
	if (LK.ticks % 120 == 0) {
		enemies.forEach(function (enemy) {
			var enemyBullet = new EnemyBullet();
			enemyBullet.x = enemy.x;
			enemyBullet.y = enemy.y + enemy.height / 2;
			enemyBullets.push(enemyBullet);
			game.addChild(enemyBullet);
		});
	}
});
:quality(85)/https://cdn.frvr.ai/65a19e8a2d41d44247293aff.png%3F3) 
 Spaceship with 1 cannon facing upwards. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows. Pixelated.
:quality(85)/https://cdn.frvr.ai/65a19ee72d41d44247293b0d.png%3F3) 
 bullet launching upwards. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows. Pixelated.
:quality(85)/https://cdn.frvr.ai/65a19f332d41d44247293b17.png%3F3) 
 alien ship facing downwards. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows. Pixelated.
:quality(85)/https://cdn.frvr.ai/65a19f7a2d41d44247293b20.png%3F3) 
 slime ball being launched downwards. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows. Pixelated.
:quality(85)/https://cdn.frvr.ai/65a19fcb2d41d44247293b2e.png%3F3) 
 giant space explosion. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows. Pixelated.
:quality(85)/https://cdn.frvr.ai/65a1a49ee74c6fde7cf14ffa.png%3F3) 
 space trap. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows. Pixelated.