User prompt
reduce the number of enemies on screen
User prompt
player tap for shoot
User prompt
reduce enemy ship
User prompt
reduce enemy
User prompt
fix player color
User prompt
make smooth control ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
enemy move to left side move and shoot
User prompt
multiple direction shooter bullet from enemy
User prompt
enemy targeting player
User prompt
enemy shoot multi direction
User prompt
make enemy attack player
User prompt
fix enemy
User prompt
fix boss problem
Code edit (1 edits merged)
Please save this source code
User prompt
Cosmic Defender
Initial prompt
side scrolling shooter
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Asteroid = Container.expand(function () {
var self = Container.call(this);
var asteroid = self.attachAsset('asteroid', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -5;
self.rotationSpeed = (Math.random() - 0.5) * 0.05;
self.size = 'medium';
self.health = 2;
self.setSize = function (size) {
self.size = size;
switch (size) {
case 'small':
asteroid.scaleX = 0.7;
asteroid.scaleY = 0.7;
self.health = 1;
self.speed = -6;
break;
case 'medium':
// Default size
break;
case 'large':
asteroid.scaleX = 1.5;
asteroid.scaleY = 1.5;
self.health = 3;
self.speed = -3;
break;
}
};
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0x555555, 200);
return self.health <= 0;
};
self.update = function () {
self.x += self.speed;
self.rotation += self.rotationSpeed;
// Remove if out of bounds
if (self.x < -100) {
self.shouldRemove = true;
}
};
return self;
});
var Boss = Container.expand(function () {
var self = Container.call(this);
var bossGraphic = self.attachAsset('boss', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -1;
self.health = 50;
self.maxHealth = 50;
self.phase = 1;
self.attackTimer = 0;
self.attackCooldown = 60;
self.movePattern = 'entrance';
self.targetY = 0;
self.points = 2000;
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xff0000, 100);
// Change phase at 50% health
if (self.health <= self.maxHealth / 2 && self.phase === 1) {
self.phase = 2;
self.attackCooldown = 40;
bossGraphic.tint = 0xe74c3c; // Red tint for phase 2
}
return self.health <= 0;
};
self.update = function () {
if (self.movePattern === 'entrance') {
self.x += self.speed;
if (self.x <= 1700) {
self.movePattern = 'vertical';
self.targetY = Math.random() * 1500 + 500;
}
} else if (self.movePattern === 'vertical') {
// Move toward target Y position
if (Math.abs(self.y - self.targetY) > 5) {
self.y += self.targetY > self.y ? 4 : -4;
} else {
// Pick a new target
self.targetY = Math.random() * 1500 + 500;
}
}
// Boss attack timer
self.attackTimer++;
if (self.attackTimer >= self.attackCooldown) {
self.attackTimer = 0;
self.readyToAttack = true;
}
};
return self;
});
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphic = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -3;
self.health = 2;
self.type = 'normal';
self.fireRate = 120;
self.lastShot = Math.floor(Math.random() * 60);
self.points = 100;
self.movePattern = 'straight';
self.amplitude = 0;
self.frequency = 0;
self.initialY = 0;
self.angle = 0;
self.setType = function (type) {
self.type = type;
switch (type) {
case 'fast':
self.speed = -5;
self.health = 1;
enemyGraphic.tint = 0x2ecc71; // Green
self.points = 150;
self.fireRate = 0; // Doesn't shoot
break;
case 'tank':
self.speed = -2;
self.health = 4;
enemyGraphic.tint = 0xe74c3c; // Red
enemyGraphic.scaleX = 1.3;
enemyGraphic.scaleY = 1.3;
self.points = 200;
self.fireRate = 100;
break;
case 'zigzag':
self.movePattern = 'zigzag';
self.amplitude = 100;
self.frequency = 0.02;
enemyGraphic.tint = 0xf1c40f; // Yellow
self.points = 150;
break;
}
};
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xff0000, 200);
return self.health <= 0;
};
self.update = function () {
if (self.movePattern === 'straight') {
self.x += self.speed;
} else if (self.movePattern === 'zigzag') {
self.x += self.speed;
self.y = self.initialY + Math.sin(self.angle) * self.amplitude;
self.angle += self.frequency;
}
// Remove if out of bounds
if (self.x < -100) {
self.shouldRemove = true;
}
};
return self;
});
var EnemyBullet = Container.expand(function () {
var self = Container.call(this);
var bullet = self.attachAsset('enemyBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -10;
self.angle = 0;
self.setAngle = function (angle) {
self.angle = angle;
};
self.update = function () {
self.x += Math.cos(self.angle) * self.speed;
self.y += Math.sin(self.angle) * self.speed;
// Remove if out of bounds
if (self.x < -50 || self.x > 2048 + 50 || self.y < -50 || self.y > 2732 + 50) {
self.shouldRemove = true;
}
};
return self;
});
var Explosion = Container.expand(function () {
var self = Container.call(this);
var explosion = self.attachAsset('explosion', {
anchorX: 0.5,
anchorY: 0.5
});
self.lifetime = 20;
self.update = function () {
self.lifetime--;
// Scale up and fade out
explosion.scaleX += 0.1;
explosion.scaleY += 0.1;
explosion.alpha = self.lifetime / 20;
if (self.lifetime <= 0) {
self.shouldRemove = true;
}
};
return self;
});
var PlayerBullet = Container.expand(function () {
var self = Container.call(this);
var bullet = self.attachAsset('playerBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 20;
self.damage = 1;
self.powered = false;
self.setPowered = function () {
self.powered = true;
self.damage = 2;
bullet.scaleX = 1.5;
bullet.scaleY = 1.5;
bullet.tint = 0xff9500;
};
self.update = function () {
self.x += self.speed;
// Remove if out of bounds
if (self.x > 2048 + 50) {
self.shouldRemove = true;
}
};
return self;
});
var PlayerShip = Container.expand(function () {
var self = Container.call(this);
var ship = self.attachAsset('playerShip', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 10;
self.health = 3;
self.maxHealth = 3;
self.fireRate = 15;
self.lastShot = 0;
self.invulnerable = false;
self.powerUpActive = false;
self.powerUpType = null;
self.powerUpTimer = 0;
self.takeDamage = function () {
if (self.invulnerable) {
return;
}
self.health -= 1;
LK.getSound('damage').play();
// Flash red when damaged
LK.effects.flashObject(self, 0xff0000, 500);
// Make player invulnerable for a short period
self.invulnerable = true;
self.alpha = 0.5;
LK.setTimeout(function () {
self.invulnerable = false;
self.alpha = 1;
}, 2000);
};
self.activatePowerUp = function (type) {
self.powerUpActive = true;
self.powerUpType = type;
self.powerUpTimer = 300; // 5 seconds at 60fps
LK.getSound('powerUp').play();
// Apply power-up effect
switch (type) {
case 'weapon':
ship.tint = 0xf1c40f; // Yellow
break;
case 'shield':
ship.tint = 0x2ecc71; // Green
self.invulnerable = true;
break;
case 'speed':
ship.tint = 0x3498db; // Blue
self.speed = 15;
break;
}
};
self.update = function () {
// Handle power-up timer
if (self.powerUpActive) {
self.powerUpTimer--;
if (self.powerUpTimer <= 0) {
// Reset power-up effects
self.powerUpActive = false;
ship.tint = 0xffffff;
self.speed = 10;
if (self.powerUpType === 'shield') {
self.invulnerable = false;
}
}
}
};
return self;
});
var PowerUp = Container.expand(function () {
var self = Container.call(this);
var powerUp = self.attachAsset('powerUp', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -3;
self.type = 'weapon';
self.blinkTimer = 0;
self.setType = function (type) {
self.type = type;
switch (type) {
case 'weapon':
powerUp.tint = 0xf1c40f; // Yellow
break;
case 'shield':
powerUp.tint = 0x2ecc71; // Green
break;
case 'speed':
powerUp.tint = 0x3498db; // Blue
break;
}
};
self.update = function () {
self.x += self.speed;
// Make power-up blink
self.blinkTimer++;
if (self.blinkTimer % 20 === 0) {
powerUp.alpha = powerUp.alpha === 1 ? 0.5 : 1;
}
// Remove if out of bounds
if (self.x < -100) {
self.shouldRemove = true;
}
};
return self;
});
var Star = Container.expand(function () {
var self = Container.call(this);
var star = self.attachAsset('starBackground', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -1;
self.setSpeed = function (speed) {
self.speed = speed;
// Adjust star size based on speed (parallax effect)
var scale = Math.max(0.5, Math.min(2, Math.abs(speed) / 2));
star.scaleX = scale;
star.scaleY = scale;
// Adjust brightness based on speed
var brightness = Math.max(0.3, Math.min(1, Math.abs(speed) / 5));
star.alpha = brightness;
};
self.update = function () {
self.x += self.speed;
// Wrap around when off-screen
if (self.x < -50) {
self.x = 2048 + 50;
self.y = Math.random() * 2732;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000022
});
/****
* Game Code
****/
// Game state variables
var player;
var playerBullets = [];
var enemies = [];
var bosses = [];
var enemyBullets = [];
var asteroids = [];
var powerUps = [];
var explosions = [];
var stars = [];
// Game settings
var level = 1;
var score = 0;
var enemySpawnRate = 120;
var asteroidSpawnRate = 180;
var bossSpawned = false;
var gameActive = true;
var levelCompleted = false;
var spawnBossAt = 10; // Spawn boss after this many enemies killed
var enemiesKilled = 0;
// UI elements
var scoreTxt;
var healthTxt;
var levelTxt;
// Initialize game
function initGame() {
// Create player
player = new PlayerShip();
player.x = 200;
player.y = 2732 / 2;
game.addChild(player);
// Create stars for background
for (var i = 0; i < 100; i++) {
var star = new Star();
star.x = Math.random() * 2048;
star.y = Math.random() * 2732;
star.setSpeed(-(Math.random() * 4 + 1));
stars.push(star);
game.addChild(star);
}
// Setup UI
setupUI();
// Play background music
LK.playMusic('gameMusic');
}
function setupUI() {
// Score text
scoreTxt = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(scoreTxt);
// Health text
healthTxt = new Text2('Health: 3', {
size: 60,
fill: 0xFFFFFF
});
healthTxt.anchor.set(0, 0);
LK.gui.top.addChild(healthTxt);
// Level text
levelTxt = new Text2('Level: 1', {
size: 60,
fill: 0xFFFFFF
});
levelTxt.anchor.set(0, 0);
LK.gui.topLeft.addChild(levelTxt);
// Position adjustments to avoid overlapping with menu icon
levelTxt.x = 120; // Move away from the top-left corner
}
// Update UI elements
function updateUI() {
scoreTxt.setText('Score: ' + score);
healthTxt.setText('Health: ' + player.health);
levelTxt.setText('Level: ' + level);
// Set score in LK system for leaderboards
LK.setScore(score);
}
// Player shooting
function playerShoot() {
if (LK.ticks - player.lastShot >= player.fireRate) {
var bullet = new PlayerBullet();
bullet.x = player.x + 50;
bullet.y = player.y;
// Apply power-up effect if active
if (player.powerUpActive && player.powerUpType === 'weapon') {
bullet.setPowered();
}
playerBullets.push(bullet);
game.addChild(bullet);
// Play sound
LK.getSound('playerShoot').play();
player.lastShot = LK.ticks;
}
}
// Enemy shooting
function enemyShoot(enemy) {
if (enemy.fireRate > 0 && LK.ticks - enemy.lastShot >= enemy.fireRate) {
var bullet = new EnemyBullet();
bullet.x = enemy.x - 20;
bullet.y = enemy.y;
// Aim at player
var dx = player.x - enemy.x;
var dy = player.y - enemy.y;
var angle = Math.atan2(dy, dx);
bullet.setAngle(angle);
enemyBullets.push(bullet);
game.addChild(bullet);
// Play sound
LK.getSound('enemyShoot').play();
enemy.lastShot = LK.ticks;
}
}
// Boss attack patterns
function bossAttack(boss) {
if (boss.readyToAttack) {
boss.readyToAttack = false;
if (boss.phase === 1) {
// Phase 1: Spread shot
for (var i = -2; i <= 2; i++) {
var bullet = new EnemyBullet();
bullet.x = boss.x - 50;
bullet.y = boss.y;
var angle = Math.atan2(player.y - boss.y, player.x - boss.x) + i * 0.2;
bullet.setAngle(angle);
enemyBullets.push(bullet);
game.addChild(bullet);
}
} else {
// Phase 2: Rapid fire + homing shots
for (var i = 0; i < 3; i++) {
LK.setTimeout(function () {
if (!boss.shouldRemove && boss.health > 0) {
var bullet = new EnemyBullet();
bullet.x = boss.x - 50;
bullet.y = boss.y;
var angle = Math.atan2(player.y - boss.y, player.x - boss.x);
bullet.setAngle(angle);
enemyBullets.push(bullet);
game.addChild(bullet);
LK.getSound('enemyShoot').play();
}
}, i * 200);
}
}
LK.getSound('enemyShoot').play();
}
}
// Spawn enemies
function spawnEnemy() {
if (!gameActive || levelCompleted || bossSpawned) {
return;
}
if (LK.ticks % enemySpawnRate === 0) {
var enemy = new Enemy();
enemy.x = 2048 + 100;
enemy.y = Math.random() * (2732 - 300) + 150;
enemy.initialY = enemy.y;
// Different enemy types based on random chance and level
var typeRoll = Math.random();
if (level >= 3 && typeRoll < 0.2) {
enemy.setType('tank');
} else if (level >= 2 && typeRoll < 0.4) {
enemy.setType('zigzag');
} else if (typeRoll < 0.6) {
enemy.setType('fast');
}
enemies.push(enemy);
game.addChild(enemy);
}
}
// Spawn asteroids
function spawnAsteroid() {
if (!gameActive || levelCompleted) {
return;
}
if (LK.ticks % asteroidSpawnRate === 0) {
var asteroid = new Asteroid();
asteroid.x = 2048 + 100;
asteroid.y = Math.random() * (2732 - 200) + 100;
// Random asteroid size
var sizeRoll = Math.random();
if (sizeRoll < 0.3) {
asteroid.setSize('small');
} else if (sizeRoll < 0.8) {
asteroid.setSize('medium');
} else {
asteroid.setSize('large');
}
asteroids.push(asteroid);
game.addChild(asteroid);
}
}
// Spawn boss
function spawnBoss() {
if (bossSpawned || !gameActive || levelCompleted) {
return;
}
if (enemiesKilled >= spawnBossAt) {
var boss = new Boss();
boss.x = 2048 + 200;
boss.y = 2732 / 2;
// Adjust boss health based on level
boss.health = 50 + (level - 1) * 25;
boss.maxHealth = boss.health;
bosses.push(boss);
game.addChild(boss);
bossSpawned = true;
}
}
// Spawn power-up
function spawnPowerUp() {
if (!gameActive || levelCompleted) {
return;
}
// Random chance to spawn power-up (1% chance each tick)
if (Math.random() < 0.01) {
var powerUp = new PowerUp();
powerUp.x = 2048 + 100;
powerUp.y = Math.random() * (2732 - 200) + 100;
// Random power-up type
var typeRoll = Math.random();
if (typeRoll < 0.33) {
powerUp.setType('weapon');
} else if (typeRoll < 0.66) {
powerUp.setType('shield');
} else {
powerUp.setType('speed');
}
powerUps.push(powerUp);
game.addChild(powerUp);
}
}
// Create explosion
function createExplosion(x, y, scale) {
var explosion = new Explosion();
explosion.x = x;
explosion.y = y;
if (scale) {
explosion.scaleX = scale;
explosion.scaleY = scale;
}
explosions.push(explosion);
game.addChild(explosion);
LK.getSound('explosion').play();
}
// Check collisions
function checkCollisions() {
// Player bullets vs enemies
for (var i = playerBullets.length - 1; i >= 0; i--) {
var bullet = playerBullets[i];
// Check against enemies
for (var j = enemies.length - 1; j >= 0; j--) {
var enemy = enemies[j];
if (bullet.intersects(enemy)) {
if (enemy.takeDamage(bullet.damage)) {
// Enemy destroyed
createExplosion(enemy.x, enemy.y);
// Add score
score += enemy.points;
enemiesKilled++;
// Remove enemy
enemy.destroy();
enemies.splice(j, 1);
}
// Remove bullet
bullet.destroy();
playerBullets.splice(i, 1);
break;
}
}
// Check against bosses if bullet still exists
if (playerBullets[i]) {
for (var j = bosses.length - 1; j >= 0; j--) {
var boss = bosses[j];
if (bullet.intersects(boss)) {
if (boss.takeDamage(bullet.damage)) {
// Boss destroyed
createExplosion(boss.x, boss.y, 2);
// Add score
score += boss.points;
// Level completed
levelCompleted = true;
// Remove boss
boss.destroy();
bosses.splice(j, 1);
// Advance to next level after delay
LK.setTimeout(function () {
levelUp();
}, 3000);
}
// Remove bullet
bullet.destroy();
playerBullets.splice(i, 1);
break;
}
}
}
// Check against asteroids if bullet still exists
if (playerBullets[i]) {
for (var j = asteroids.length - 1; j >= 0; j--) {
var asteroid = asteroids[j];
if (bullet.intersects(asteroid)) {
if (asteroid.takeDamage(bullet.damage)) {
// Asteroid destroyed
createExplosion(asteroid.x, asteroid.y);
// Add score
score += 50;
// Remove asteroid
asteroid.destroy();
asteroids.splice(j, 1);
}
// Remove bullet
bullet.destroy();
playerBullets.splice(i, 1);
break;
}
}
}
}
// Enemy bullets vs player
for (var i = enemyBullets.length - 1; i >= 0; i--) {
var bullet = enemyBullets[i];
if (bullet.intersects(player)) {
// Player hit
player.takeDamage();
// Remove bullet
bullet.destroy();
enemyBullets.splice(i, 1);
// Check player health
if (player.health <= 0) {
gameOver();
}
}
}
// Enemies vs player
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
if (enemy.intersects(player)) {
// Player collided with enemy
player.takeDamage();
// Destroy enemy
createExplosion(enemy.x, enemy.y);
enemy.destroy();
enemies.splice(i, 1);
// Check player health
if (player.health <= 0) {
gameOver();
}
}
}
// Asteroids vs player
for (var i = asteroids.length - 1; i >= 0; i--) {
var asteroid = asteroids[i];
if (asteroid.intersects(player)) {
// Player collided with asteroid
player.takeDamage();
// Destroy asteroid
createExplosion(asteroid.x, asteroid.y);
asteroid.destroy();
asteroids.splice(i, 1);
// Check player health
if (player.health <= 0) {
gameOver();
}
}
}
// PowerUps vs player
for (var i = powerUps.length - 1; i >= 0; i--) {
var powerUp = powerUps[i];
if (powerUp.intersects(player)) {
// Player collected power-up
player.activatePowerUp(powerUp.type);
// Remove power-up
powerUp.destroy();
powerUps.splice(i, 1);
}
}
}
// Level up function
function levelUp() {
level++;
enemiesKilled = 0;
bossSpawned = false;
levelCompleted = false;
// Increase difficulty
enemySpawnRate = Math.max(60, enemySpawnRate - 10);
asteroidSpawnRate = Math.max(90, asteroidSpawnRate - 15);
spawnBossAt += 5;
// Update UI
updateUI();
// Fully heal player for next level
player.health = player.maxHealth;
// Clear all enemies and projectiles
clearEntities();
}
// Clear all entities except player and stars
function clearEntities() {
// Clear enemies
for (var i = 0; i < enemies.length; i++) {
enemies[i].destroy();
}
enemies = [];
// Clear bosses
for (var i = 0; i < bosses.length; i++) {
bosses[i].destroy();
}
bosses = [];
// Clear enemy bullets
for (var i = 0; i < enemyBullets.length; i++) {
enemyBullets[i].destroy();
}
enemyBullets = [];
// Clear player bullets
for (var i = 0; i < playerBullets.length; i++) {
playerBullets[i].destroy();
}
playerBullets = [];
// Clear asteroids
for (var i = 0; i < asteroids.length; i++) {
asteroids[i].destroy();
}
asteroids = [];
// Clear power-ups
for (var i = 0; i < powerUps.length; i++) {
powerUps[i].destroy();
}
powerUps = [];
// Clear explosions
for (var i = 0; i < explosions.length; i++) {
explosions[i].destroy();
}
explosions = [];
}
// Game over
function gameOver() {
gameActive = false;
// Create explosion at player position
createExplosion(player.x, player.y, 1.5);
// Hide player
player.visible = false;
// Show game over screen
LK.showGameOver();
}
// Handle player movement
function handleMove(x, y) {
if (!gameActive) {
return;
}
// Move player based on touch position
if (x < 300) {
x = 300;
} // Keep player from going too far left
if (x > 2048 - 100) {
x = 2048 - 100;
} // Keep player from going too far right
player.x = x;
player.y = y;
}
// Touch/mouse controls
game.down = function (x, y) {
if (!gameActive) {
return;
}
handleMove(x, y);
};
game.move = function (x, y) {
if (!gameActive) {
return;
}
handleMove(x, y);
};
// Main game loop
game.update = function () {
if (!gameActive && !levelCompleted) {
return;
}
// Spawn game entities
spawnEnemy();
spawnAsteroid();
spawnPowerUp();
spawnBoss();
// Auto-shoot
if (gameActive) {
playerShoot();
}
// Update all game entities
// Update player bullets
for (var i = playerBullets.length - 1; i >= 0; i--) {
var bullet = playerBullets[i];
// Check if bullet should be removed
if (bullet.shouldRemove) {
bullet.destroy();
playerBullets.splice(i, 1);
}
}
// Update enemies and enemy shooting
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
// Check if enemy should shoot
enemyShoot(enemy);
// Check if enemy should be removed
if (enemy.shouldRemove) {
enemy.destroy();
enemies.splice(i, 1);
}
}
// Update bosses and boss attacks
for (var i = bosses.length - 1; i >= 0; i--) {
var boss = bosses[i];
// Boss attack
bossAttack(boss);
// Check if boss should be removed
if (boss.shouldRemove) {
boss.destroy();
bosses.splice(i, 1);
}
}
// Update enemy bullets
for (var i = enemyBullets.length - 1; i >= 0; i--) {
var bullet = enemyBullets[i];
// Check if bullet should be removed
if (bullet.shouldRemove) {
bullet.destroy();
enemyBullets.splice(i, 1);
}
}
// Update asteroids
for (var i = asteroids.length - 1; i >= 0; i--) {
var asteroid = asteroids[i];
// Check if asteroid should be removed
if (asteroid.shouldRemove) {
asteroid.destroy();
asteroids.splice(i, 1);
}
}
// Update power-ups
for (var i = powerUps.length - 1; i >= 0; i--) {
var powerUp = powerUps[i];
// Check if power-up should be removed
if (powerUp.shouldRemove) {
powerUp.destroy();
powerUps.splice(i, 1);
}
}
// Update explosions
for (var i = explosions.length - 1; i >= 0; i--) {
var explosion = explosions[i];
// Check if explosion should be removed
if (explosion.shouldRemove) {
explosion.destroy();
explosions.splice(i, 1);
}
}
// Check for collisions
checkCollisions();
// Update UI
updateUI();
};
// Initialize the game
initGame(); ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,939 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+var storage = LK.import("@upit/storage.v1");
+
+/****
+* Classes
+****/
+var Asteroid = Container.expand(function () {
+ var self = Container.call(this);
+ var asteroid = self.attachAsset('asteroid', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = -5;
+ self.rotationSpeed = (Math.random() - 0.5) * 0.05;
+ self.size = 'medium';
+ self.health = 2;
+ self.setSize = function (size) {
+ self.size = size;
+ switch (size) {
+ case 'small':
+ asteroid.scaleX = 0.7;
+ asteroid.scaleY = 0.7;
+ self.health = 1;
+ self.speed = -6;
+ break;
+ case 'medium':
+ // Default size
+ break;
+ case 'large':
+ asteroid.scaleX = 1.5;
+ asteroid.scaleY = 1.5;
+ self.health = 3;
+ self.speed = -3;
+ break;
+ }
+ };
+ self.takeDamage = function (damage) {
+ self.health -= damage;
+ LK.effects.flashObject(self, 0x555555, 200);
+ return self.health <= 0;
+ };
+ self.update = function () {
+ self.x += self.speed;
+ self.rotation += self.rotationSpeed;
+ // Remove if out of bounds
+ if (self.x < -100) {
+ self.shouldRemove = true;
+ }
+ };
+ return self;
+});
+var Boss = Container.expand(function () {
+ var self = Container.call(this);
+ var bossGraphic = self.attachAsset('boss', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = -1;
+ self.health = 50;
+ self.maxHealth = 50;
+ self.phase = 1;
+ self.attackTimer = 0;
+ self.attackCooldown = 60;
+ self.movePattern = 'entrance';
+ self.targetY = 0;
+ self.points = 2000;
+ self.takeDamage = function (damage) {
+ self.health -= damage;
+ LK.effects.flashObject(self, 0xff0000, 100);
+ // Change phase at 50% health
+ if (self.health <= self.maxHealth / 2 && self.phase === 1) {
+ self.phase = 2;
+ self.attackCooldown = 40;
+ bossGraphic.tint = 0xe74c3c; // Red tint for phase 2
+ }
+ return self.health <= 0;
+ };
+ self.update = function () {
+ if (self.movePattern === 'entrance') {
+ self.x += self.speed;
+ if (self.x <= 1700) {
+ self.movePattern = 'vertical';
+ self.targetY = Math.random() * 1500 + 500;
+ }
+ } else if (self.movePattern === 'vertical') {
+ // Move toward target Y position
+ if (Math.abs(self.y - self.targetY) > 5) {
+ self.y += self.targetY > self.y ? 4 : -4;
+ } else {
+ // Pick a new target
+ self.targetY = Math.random() * 1500 + 500;
+ }
+ }
+ // Boss attack timer
+ self.attackTimer++;
+ if (self.attackTimer >= self.attackCooldown) {
+ self.attackTimer = 0;
+ self.readyToAttack = true;
+ }
+ };
+ return self;
+});
+var Enemy = Container.expand(function () {
+ var self = Container.call(this);
+ var enemyGraphic = self.attachAsset('enemy', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = -3;
+ self.health = 2;
+ self.type = 'normal';
+ self.fireRate = 120;
+ self.lastShot = Math.floor(Math.random() * 60);
+ self.points = 100;
+ self.movePattern = 'straight';
+ self.amplitude = 0;
+ self.frequency = 0;
+ self.initialY = 0;
+ self.angle = 0;
+ self.setType = function (type) {
+ self.type = type;
+ switch (type) {
+ case 'fast':
+ self.speed = -5;
+ self.health = 1;
+ enemyGraphic.tint = 0x2ecc71; // Green
+ self.points = 150;
+ self.fireRate = 0; // Doesn't shoot
+ break;
+ case 'tank':
+ self.speed = -2;
+ self.health = 4;
+ enemyGraphic.tint = 0xe74c3c; // Red
+ enemyGraphic.scaleX = 1.3;
+ enemyGraphic.scaleY = 1.3;
+ self.points = 200;
+ self.fireRate = 100;
+ break;
+ case 'zigzag':
+ self.movePattern = 'zigzag';
+ self.amplitude = 100;
+ self.frequency = 0.02;
+ enemyGraphic.tint = 0xf1c40f; // Yellow
+ self.points = 150;
+ break;
+ }
+ };
+ self.takeDamage = function (damage) {
+ self.health -= damage;
+ LK.effects.flashObject(self, 0xff0000, 200);
+ return self.health <= 0;
+ };
+ self.update = function () {
+ if (self.movePattern === 'straight') {
+ self.x += self.speed;
+ } else if (self.movePattern === 'zigzag') {
+ self.x += self.speed;
+ self.y = self.initialY + Math.sin(self.angle) * self.amplitude;
+ self.angle += self.frequency;
+ }
+ // Remove if out of bounds
+ if (self.x < -100) {
+ self.shouldRemove = true;
+ }
+ };
+ return self;
+});
+var EnemyBullet = Container.expand(function () {
+ var self = Container.call(this);
+ var bullet = self.attachAsset('enemyBullet', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = -10;
+ self.angle = 0;
+ self.setAngle = function (angle) {
+ self.angle = angle;
+ };
+ self.update = function () {
+ self.x += Math.cos(self.angle) * self.speed;
+ self.y += Math.sin(self.angle) * self.speed;
+ // Remove if out of bounds
+ if (self.x < -50 || self.x > 2048 + 50 || self.y < -50 || self.y > 2732 + 50) {
+ self.shouldRemove = true;
+ }
+ };
+ return self;
+});
+var Explosion = Container.expand(function () {
+ var self = Container.call(this);
+ var explosion = self.attachAsset('explosion', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.lifetime = 20;
+ self.update = function () {
+ self.lifetime--;
+ // Scale up and fade out
+ explosion.scaleX += 0.1;
+ explosion.scaleY += 0.1;
+ explosion.alpha = self.lifetime / 20;
+ if (self.lifetime <= 0) {
+ self.shouldRemove = true;
+ }
+ };
+ return self;
+});
+var PlayerBullet = Container.expand(function () {
+ var self = Container.call(this);
+ var bullet = self.attachAsset('playerBullet', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 20;
+ self.damage = 1;
+ self.powered = false;
+ self.setPowered = function () {
+ self.powered = true;
+ self.damage = 2;
+ bullet.scaleX = 1.5;
+ bullet.scaleY = 1.5;
+ bullet.tint = 0xff9500;
+ };
+ self.update = function () {
+ self.x += self.speed;
+ // Remove if out of bounds
+ if (self.x > 2048 + 50) {
+ self.shouldRemove = true;
+ }
+ };
+ return self;
+});
+var PlayerShip = Container.expand(function () {
+ var self = Container.call(this);
+ var ship = self.attachAsset('playerShip', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 10;
+ self.health = 3;
+ self.maxHealth = 3;
+ self.fireRate = 15;
+ self.lastShot = 0;
+ self.invulnerable = false;
+ self.powerUpActive = false;
+ self.powerUpType = null;
+ self.powerUpTimer = 0;
+ self.takeDamage = function () {
+ if (self.invulnerable) {
+ return;
+ }
+ self.health -= 1;
+ LK.getSound('damage').play();
+ // Flash red when damaged
+ LK.effects.flashObject(self, 0xff0000, 500);
+ // Make player invulnerable for a short period
+ self.invulnerable = true;
+ self.alpha = 0.5;
+ LK.setTimeout(function () {
+ self.invulnerable = false;
+ self.alpha = 1;
+ }, 2000);
+ };
+ self.activatePowerUp = function (type) {
+ self.powerUpActive = true;
+ self.powerUpType = type;
+ self.powerUpTimer = 300; // 5 seconds at 60fps
+ LK.getSound('powerUp').play();
+ // Apply power-up effect
+ switch (type) {
+ case 'weapon':
+ ship.tint = 0xf1c40f; // Yellow
+ break;
+ case 'shield':
+ ship.tint = 0x2ecc71; // Green
+ self.invulnerable = true;
+ break;
+ case 'speed':
+ ship.tint = 0x3498db; // Blue
+ self.speed = 15;
+ break;
+ }
+ };
+ self.update = function () {
+ // Handle power-up timer
+ if (self.powerUpActive) {
+ self.powerUpTimer--;
+ if (self.powerUpTimer <= 0) {
+ // Reset power-up effects
+ self.powerUpActive = false;
+ ship.tint = 0xffffff;
+ self.speed = 10;
+ if (self.powerUpType === 'shield') {
+ self.invulnerable = false;
+ }
+ }
+ }
+ };
+ return self;
+});
+var PowerUp = Container.expand(function () {
+ var self = Container.call(this);
+ var powerUp = self.attachAsset('powerUp', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = -3;
+ self.type = 'weapon';
+ self.blinkTimer = 0;
+ self.setType = function (type) {
+ self.type = type;
+ switch (type) {
+ case 'weapon':
+ powerUp.tint = 0xf1c40f; // Yellow
+ break;
+ case 'shield':
+ powerUp.tint = 0x2ecc71; // Green
+ break;
+ case 'speed':
+ powerUp.tint = 0x3498db; // Blue
+ break;
+ }
+ };
+ self.update = function () {
+ self.x += self.speed;
+ // Make power-up blink
+ self.blinkTimer++;
+ if (self.blinkTimer % 20 === 0) {
+ powerUp.alpha = powerUp.alpha === 1 ? 0.5 : 1;
+ }
+ // Remove if out of bounds
+ if (self.x < -100) {
+ self.shouldRemove = true;
+ }
+ };
+ return self;
+});
+var Star = Container.expand(function () {
+ var self = Container.call(this);
+ var star = self.attachAsset('starBackground', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = -1;
+ self.setSpeed = function (speed) {
+ self.speed = speed;
+ // Adjust star size based on speed (parallax effect)
+ var scale = Math.max(0.5, Math.min(2, Math.abs(speed) / 2));
+ star.scaleX = scale;
+ star.scaleY = scale;
+ // Adjust brightness based on speed
+ var brightness = Math.max(0.3, Math.min(1, Math.abs(speed) / 5));
+ star.alpha = brightness;
+ };
+ self.update = function () {
+ self.x += self.speed;
+ // Wrap around when off-screen
+ if (self.x < -50) {
+ self.x = 2048 + 50;
+ self.y = Math.random() * 2732;
+ }
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x000022
+});
+
+/****
+* Game Code
+****/
+// Game state variables
+var player;
+var playerBullets = [];
+var enemies = [];
+var bosses = [];
+var enemyBullets = [];
+var asteroids = [];
+var powerUps = [];
+var explosions = [];
+var stars = [];
+// Game settings
+var level = 1;
+var score = 0;
+var enemySpawnRate = 120;
+var asteroidSpawnRate = 180;
+var bossSpawned = false;
+var gameActive = true;
+var levelCompleted = false;
+var spawnBossAt = 10; // Spawn boss after this many enemies killed
+var enemiesKilled = 0;
+// UI elements
+var scoreTxt;
+var healthTxt;
+var levelTxt;
+// Initialize game
+function initGame() {
+ // Create player
+ player = new PlayerShip();
+ player.x = 200;
+ player.y = 2732 / 2;
+ game.addChild(player);
+ // Create stars for background
+ for (var i = 0; i < 100; i++) {
+ var star = new Star();
+ star.x = Math.random() * 2048;
+ star.y = Math.random() * 2732;
+ star.setSpeed(-(Math.random() * 4 + 1));
+ stars.push(star);
+ game.addChild(star);
+ }
+ // Setup UI
+ setupUI();
+ // Play background music
+ LK.playMusic('gameMusic');
+}
+function setupUI() {
+ // Score text
+ scoreTxt = new Text2('Score: 0', {
+ size: 60,
+ fill: 0xFFFFFF
+ });
+ scoreTxt.anchor.set(0, 0);
+ LK.gui.topRight.addChild(scoreTxt);
+ // Health text
+ healthTxt = new Text2('Health: 3', {
+ size: 60,
+ fill: 0xFFFFFF
+ });
+ healthTxt.anchor.set(0, 0);
+ LK.gui.top.addChild(healthTxt);
+ // Level text
+ levelTxt = new Text2('Level: 1', {
+ size: 60,
+ fill: 0xFFFFFF
+ });
+ levelTxt.anchor.set(0, 0);
+ LK.gui.topLeft.addChild(levelTxt);
+ // Position adjustments to avoid overlapping with menu icon
+ levelTxt.x = 120; // Move away from the top-left corner
+}
+// Update UI elements
+function updateUI() {
+ scoreTxt.setText('Score: ' + score);
+ healthTxt.setText('Health: ' + player.health);
+ levelTxt.setText('Level: ' + level);
+ // Set score in LK system for leaderboards
+ LK.setScore(score);
+}
+// Player shooting
+function playerShoot() {
+ if (LK.ticks - player.lastShot >= player.fireRate) {
+ var bullet = new PlayerBullet();
+ bullet.x = player.x + 50;
+ bullet.y = player.y;
+ // Apply power-up effect if active
+ if (player.powerUpActive && player.powerUpType === 'weapon') {
+ bullet.setPowered();
+ }
+ playerBullets.push(bullet);
+ game.addChild(bullet);
+ // Play sound
+ LK.getSound('playerShoot').play();
+ player.lastShot = LK.ticks;
+ }
+}
+// Enemy shooting
+function enemyShoot(enemy) {
+ if (enemy.fireRate > 0 && LK.ticks - enemy.lastShot >= enemy.fireRate) {
+ var bullet = new EnemyBullet();
+ bullet.x = enemy.x - 20;
+ bullet.y = enemy.y;
+ // Aim at player
+ var dx = player.x - enemy.x;
+ var dy = player.y - enemy.y;
+ var angle = Math.atan2(dy, dx);
+ bullet.setAngle(angle);
+ enemyBullets.push(bullet);
+ game.addChild(bullet);
+ // Play sound
+ LK.getSound('enemyShoot').play();
+ enemy.lastShot = LK.ticks;
+ }
+}
+// Boss attack patterns
+function bossAttack(boss) {
+ if (boss.readyToAttack) {
+ boss.readyToAttack = false;
+ if (boss.phase === 1) {
+ // Phase 1: Spread shot
+ for (var i = -2; i <= 2; i++) {
+ var bullet = new EnemyBullet();
+ bullet.x = boss.x - 50;
+ bullet.y = boss.y;
+ var angle = Math.atan2(player.y - boss.y, player.x - boss.x) + i * 0.2;
+ bullet.setAngle(angle);
+ enemyBullets.push(bullet);
+ game.addChild(bullet);
+ }
+ } else {
+ // Phase 2: Rapid fire + homing shots
+ for (var i = 0; i < 3; i++) {
+ LK.setTimeout(function () {
+ if (!boss.shouldRemove && boss.health > 0) {
+ var bullet = new EnemyBullet();
+ bullet.x = boss.x - 50;
+ bullet.y = boss.y;
+ var angle = Math.atan2(player.y - boss.y, player.x - boss.x);
+ bullet.setAngle(angle);
+ enemyBullets.push(bullet);
+ game.addChild(bullet);
+ LK.getSound('enemyShoot').play();
+ }
+ }, i * 200);
+ }
+ }
+ LK.getSound('enemyShoot').play();
+ }
+}
+// Spawn enemies
+function spawnEnemy() {
+ if (!gameActive || levelCompleted || bossSpawned) {
+ return;
+ }
+ if (LK.ticks % enemySpawnRate === 0) {
+ var enemy = new Enemy();
+ enemy.x = 2048 + 100;
+ enemy.y = Math.random() * (2732 - 300) + 150;
+ enemy.initialY = enemy.y;
+ // Different enemy types based on random chance and level
+ var typeRoll = Math.random();
+ if (level >= 3 && typeRoll < 0.2) {
+ enemy.setType('tank');
+ } else if (level >= 2 && typeRoll < 0.4) {
+ enemy.setType('zigzag');
+ } else if (typeRoll < 0.6) {
+ enemy.setType('fast');
+ }
+ enemies.push(enemy);
+ game.addChild(enemy);
+ }
+}
+// Spawn asteroids
+function spawnAsteroid() {
+ if (!gameActive || levelCompleted) {
+ return;
+ }
+ if (LK.ticks % asteroidSpawnRate === 0) {
+ var asteroid = new Asteroid();
+ asteroid.x = 2048 + 100;
+ asteroid.y = Math.random() * (2732 - 200) + 100;
+ // Random asteroid size
+ var sizeRoll = Math.random();
+ if (sizeRoll < 0.3) {
+ asteroid.setSize('small');
+ } else if (sizeRoll < 0.8) {
+ asteroid.setSize('medium');
+ } else {
+ asteroid.setSize('large');
+ }
+ asteroids.push(asteroid);
+ game.addChild(asteroid);
+ }
+}
+// Spawn boss
+function spawnBoss() {
+ if (bossSpawned || !gameActive || levelCompleted) {
+ return;
+ }
+ if (enemiesKilled >= spawnBossAt) {
+ var boss = new Boss();
+ boss.x = 2048 + 200;
+ boss.y = 2732 / 2;
+ // Adjust boss health based on level
+ boss.health = 50 + (level - 1) * 25;
+ boss.maxHealth = boss.health;
+ bosses.push(boss);
+ game.addChild(boss);
+ bossSpawned = true;
+ }
+}
+// Spawn power-up
+function spawnPowerUp() {
+ if (!gameActive || levelCompleted) {
+ return;
+ }
+ // Random chance to spawn power-up (1% chance each tick)
+ if (Math.random() < 0.01) {
+ var powerUp = new PowerUp();
+ powerUp.x = 2048 + 100;
+ powerUp.y = Math.random() * (2732 - 200) + 100;
+ // Random power-up type
+ var typeRoll = Math.random();
+ if (typeRoll < 0.33) {
+ powerUp.setType('weapon');
+ } else if (typeRoll < 0.66) {
+ powerUp.setType('shield');
+ } else {
+ powerUp.setType('speed');
+ }
+ powerUps.push(powerUp);
+ game.addChild(powerUp);
+ }
+}
+// Create explosion
+function createExplosion(x, y, scale) {
+ var explosion = new Explosion();
+ explosion.x = x;
+ explosion.y = y;
+ if (scale) {
+ explosion.scaleX = scale;
+ explosion.scaleY = scale;
+ }
+ explosions.push(explosion);
+ game.addChild(explosion);
+ LK.getSound('explosion').play();
+}
+// Check collisions
+function checkCollisions() {
+ // Player bullets vs enemies
+ for (var i = playerBullets.length - 1; i >= 0; i--) {
+ var bullet = playerBullets[i];
+ // Check against enemies
+ for (var j = enemies.length - 1; j >= 0; j--) {
+ var enemy = enemies[j];
+ if (bullet.intersects(enemy)) {
+ if (enemy.takeDamage(bullet.damage)) {
+ // Enemy destroyed
+ createExplosion(enemy.x, enemy.y);
+ // Add score
+ score += enemy.points;
+ enemiesKilled++;
+ // Remove enemy
+ enemy.destroy();
+ enemies.splice(j, 1);
+ }
+ // Remove bullet
+ bullet.destroy();
+ playerBullets.splice(i, 1);
+ break;
+ }
+ }
+ // Check against bosses if bullet still exists
+ if (playerBullets[i]) {
+ for (var j = bosses.length - 1; j >= 0; j--) {
+ var boss = bosses[j];
+ if (bullet.intersects(boss)) {
+ if (boss.takeDamage(bullet.damage)) {
+ // Boss destroyed
+ createExplosion(boss.x, boss.y, 2);
+ // Add score
+ score += boss.points;
+ // Level completed
+ levelCompleted = true;
+ // Remove boss
+ boss.destroy();
+ bosses.splice(j, 1);
+ // Advance to next level after delay
+ LK.setTimeout(function () {
+ levelUp();
+ }, 3000);
+ }
+ // Remove bullet
+ bullet.destroy();
+ playerBullets.splice(i, 1);
+ break;
+ }
+ }
+ }
+ // Check against asteroids if bullet still exists
+ if (playerBullets[i]) {
+ for (var j = asteroids.length - 1; j >= 0; j--) {
+ var asteroid = asteroids[j];
+ if (bullet.intersects(asteroid)) {
+ if (asteroid.takeDamage(bullet.damage)) {
+ // Asteroid destroyed
+ createExplosion(asteroid.x, asteroid.y);
+ // Add score
+ score += 50;
+ // Remove asteroid
+ asteroid.destroy();
+ asteroids.splice(j, 1);
+ }
+ // Remove bullet
+ bullet.destroy();
+ playerBullets.splice(i, 1);
+ break;
+ }
+ }
+ }
+ }
+ // Enemy bullets vs player
+ for (var i = enemyBullets.length - 1; i >= 0; i--) {
+ var bullet = enemyBullets[i];
+ if (bullet.intersects(player)) {
+ // Player hit
+ player.takeDamage();
+ // Remove bullet
+ bullet.destroy();
+ enemyBullets.splice(i, 1);
+ // Check player health
+ if (player.health <= 0) {
+ gameOver();
+ }
+ }
+ }
+ // Enemies vs player
+ for (var i = enemies.length - 1; i >= 0; i--) {
+ var enemy = enemies[i];
+ if (enemy.intersects(player)) {
+ // Player collided with enemy
+ player.takeDamage();
+ // Destroy enemy
+ createExplosion(enemy.x, enemy.y);
+ enemy.destroy();
+ enemies.splice(i, 1);
+ // Check player health
+ if (player.health <= 0) {
+ gameOver();
+ }
+ }
+ }
+ // Asteroids vs player
+ for (var i = asteroids.length - 1; i >= 0; i--) {
+ var asteroid = asteroids[i];
+ if (asteroid.intersects(player)) {
+ // Player collided with asteroid
+ player.takeDamage();
+ // Destroy asteroid
+ createExplosion(asteroid.x, asteroid.y);
+ asteroid.destroy();
+ asteroids.splice(i, 1);
+ // Check player health
+ if (player.health <= 0) {
+ gameOver();
+ }
+ }
+ }
+ // PowerUps vs player
+ for (var i = powerUps.length - 1; i >= 0; i--) {
+ var powerUp = powerUps[i];
+ if (powerUp.intersects(player)) {
+ // Player collected power-up
+ player.activatePowerUp(powerUp.type);
+ // Remove power-up
+ powerUp.destroy();
+ powerUps.splice(i, 1);
+ }
+ }
+}
+// Level up function
+function levelUp() {
+ level++;
+ enemiesKilled = 0;
+ bossSpawned = false;
+ levelCompleted = false;
+ // Increase difficulty
+ enemySpawnRate = Math.max(60, enemySpawnRate - 10);
+ asteroidSpawnRate = Math.max(90, asteroidSpawnRate - 15);
+ spawnBossAt += 5;
+ // Update UI
+ updateUI();
+ // Fully heal player for next level
+ player.health = player.maxHealth;
+ // Clear all enemies and projectiles
+ clearEntities();
+}
+// Clear all entities except player and stars
+function clearEntities() {
+ // Clear enemies
+ for (var i = 0; i < enemies.length; i++) {
+ enemies[i].destroy();
+ }
+ enemies = [];
+ // Clear bosses
+ for (var i = 0; i < bosses.length; i++) {
+ bosses[i].destroy();
+ }
+ bosses = [];
+ // Clear enemy bullets
+ for (var i = 0; i < enemyBullets.length; i++) {
+ enemyBullets[i].destroy();
+ }
+ enemyBullets = [];
+ // Clear player bullets
+ for (var i = 0; i < playerBullets.length; i++) {
+ playerBullets[i].destroy();
+ }
+ playerBullets = [];
+ // Clear asteroids
+ for (var i = 0; i < asteroids.length; i++) {
+ asteroids[i].destroy();
+ }
+ asteroids = [];
+ // Clear power-ups
+ for (var i = 0; i < powerUps.length; i++) {
+ powerUps[i].destroy();
+ }
+ powerUps = [];
+ // Clear explosions
+ for (var i = 0; i < explosions.length; i++) {
+ explosions[i].destroy();
+ }
+ explosions = [];
+}
+// Game over
+function gameOver() {
+ gameActive = false;
+ // Create explosion at player position
+ createExplosion(player.x, player.y, 1.5);
+ // Hide player
+ player.visible = false;
+ // Show game over screen
+ LK.showGameOver();
+}
+// Handle player movement
+function handleMove(x, y) {
+ if (!gameActive) {
+ return;
+ }
+ // Move player based on touch position
+ if (x < 300) {
+ x = 300;
+ } // Keep player from going too far left
+ if (x > 2048 - 100) {
+ x = 2048 - 100;
+ } // Keep player from going too far right
+ player.x = x;
+ player.y = y;
+}
+// Touch/mouse controls
+game.down = function (x, y) {
+ if (!gameActive) {
+ return;
+ }
+ handleMove(x, y);
+};
+game.move = function (x, y) {
+ if (!gameActive) {
+ return;
+ }
+ handleMove(x, y);
+};
+// Main game loop
+game.update = function () {
+ if (!gameActive && !levelCompleted) {
+ return;
+ }
+ // Spawn game entities
+ spawnEnemy();
+ spawnAsteroid();
+ spawnPowerUp();
+ spawnBoss();
+ // Auto-shoot
+ if (gameActive) {
+ playerShoot();
+ }
+ // Update all game entities
+ // Update player bullets
+ for (var i = playerBullets.length - 1; i >= 0; i--) {
+ var bullet = playerBullets[i];
+ // Check if bullet should be removed
+ if (bullet.shouldRemove) {
+ bullet.destroy();
+ playerBullets.splice(i, 1);
+ }
+ }
+ // Update enemies and enemy shooting
+ for (var i = enemies.length - 1; i >= 0; i--) {
+ var enemy = enemies[i];
+ // Check if enemy should shoot
+ enemyShoot(enemy);
+ // Check if enemy should be removed
+ if (enemy.shouldRemove) {
+ enemy.destroy();
+ enemies.splice(i, 1);
+ }
+ }
+ // Update bosses and boss attacks
+ for (var i = bosses.length - 1; i >= 0; i--) {
+ var boss = bosses[i];
+ // Boss attack
+ bossAttack(boss);
+ // Check if boss should be removed
+ if (boss.shouldRemove) {
+ boss.destroy();
+ bosses.splice(i, 1);
+ }
+ }
+ // Update enemy bullets
+ for (var i = enemyBullets.length - 1; i >= 0; i--) {
+ var bullet = enemyBullets[i];
+ // Check if bullet should be removed
+ if (bullet.shouldRemove) {
+ bullet.destroy();
+ enemyBullets.splice(i, 1);
+ }
+ }
+ // Update asteroids
+ for (var i = asteroids.length - 1; i >= 0; i--) {
+ var asteroid = asteroids[i];
+ // Check if asteroid should be removed
+ if (asteroid.shouldRemove) {
+ asteroid.destroy();
+ asteroids.splice(i, 1);
+ }
+ }
+ // Update power-ups
+ for (var i = powerUps.length - 1; i >= 0; i--) {
+ var powerUp = powerUps[i];
+ // Check if power-up should be removed
+ if (powerUp.shouldRemove) {
+ powerUp.destroy();
+ powerUps.splice(i, 1);
+ }
+ }
+ // Update explosions
+ for (var i = explosions.length - 1; i >= 0; i--) {
+ var explosion = explosions[i];
+ // Check if explosion should be removed
+ if (explosion.shouldRemove) {
+ explosion.destroy();
+ explosions.splice(i, 1);
+ }
+ }
+ // Check for collisions
+ checkCollisions();
+ // Update UI
+ updateUI();
+};
+// Initialize the game
+initGame();
\ No newline at end of file
unreal engine image side right body view angle space battle ship thunder style. In-Game asset. 2d. High contrast. No shadows
unreal engine image side right body view angle space battle ship samurai vibe In-Game asset. 2d. High contrast. No shadows
unreal engine image side right body view angle space bright black asteroid In-Game asset. 2d. High contrast. No shadows
3d unreal engine image space bright red explosion In-Game asset. 2d. High contrast. No shadows
unreal engine image side right body view angle space battle ship evil samurai vibe In-Game asset. 2d. High contrast. No shadows
space pearl. In-Game asset. 2d. High contrast. No shadows