User prompt
Write game description
User prompt
The enemy will fire 2 bullets every 6 seconds.
User prompt
The enemy will fire 2 bullets every 3 seconds.
User prompt
Enemy low attack for player
User prompt
Low attack for enemy
User prompt
Heath bar for player
Code edit (1 edits merged)
Please save this source code
User prompt
Ultimate Arena: Survival Showdown
Initial prompt
Best game
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
highScore: 0,
level: 1
});
/****
* Classes
****/
var Boss = Container.expand(function () {
var self = Container.call(this);
var bossGraphics = self.attachAsset('boss', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
self.health = 300;
self.maxHealth = 300;
self.pointValue = 100;
self.phase = 1;
self.shootCooldown = 0;
self.shootDelay = 60; // 1 second at 60 fps
self.movementCounter = 0;
self.speed = 1;
self.takeDamage = function (amount) {
self.health -= amount;
LK.effects.flashObject(self, 0xff0000, 200);
// Phase transitions
if (self.health < self.maxHealth * 0.7 && self.phase === 1) {
self.phase = 2;
self.shootDelay = 45; // Faster attacks in phase 2
} else if (self.health < self.maxHealth * 0.3 && self.phase === 2) {
self.phase = 3;
self.shootDelay = 30; // Even faster attacks in phase 3
bossGraphics.tint = 0xff5555; // Visual indicator for final phase
}
};
self.update = function () {
// Boss movement pattern
if (self.phase === 1) {
self.x += Math.sin(self.movementCounter * 0.02) * 2;
if (self.y < 400) {
self.y += 0.5;
}
} else if (self.phase === 2) {
self.x += Math.sin(self.movementCounter * 0.03) * 3;
self.y += Math.sin(self.movementCounter * 0.01) * 1;
} else {
self.x += Math.sin(self.movementCounter * 0.04) * 5;
self.y += Math.sin(self.movementCounter * 0.02) * 2;
}
self.movementCounter++;
// Update shoot cooldown
if (self.shootCooldown > 0) {
self.shootCooldown--;
}
};
return self;
});
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 12;
self.damage = 10;
self.direction = {
x: 0,
y: -1
};
self.update = function () {
self.x += self.direction.x * self.speed;
self.y += self.direction.y * self.speed;
};
return self;
});
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 30;
self.speed = 2;
self.pointValue = 10;
self.movementPattern = 'direct'; // direct, zigzag, circle
self.movementCounter = 0;
self.shootCooldown = 0;
self.shootDelay = 360; // 6 seconds at 60 fps
self.takeDamage = function (amount) {
self.health -= amount;
LK.effects.flashObject(self, 0xff0000, 200);
};
self.update = function () {
// Movement patterns
switch (self.movementPattern) {
case 'direct':
self.y += self.speed;
break;
case 'zigzag':
self.y += self.speed;
self.x += Math.sin(self.movementCounter * 0.05) * 3;
self.movementCounter++;
break;
case 'circle':
self.y += self.speed * 0.7;
self.x += Math.sin(self.movementCounter * 0.03) * 4;
self.movementCounter++;
break;
}
// Update shoot cooldown
if (self.shootCooldown > 0) {
self.shootCooldown--;
}
};
return self;
});
var EnemyBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('enemyBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.damage = 5;
self.direction = {
x: 0,
y: 1
};
self.update = function () {
self.x += self.direction.x * self.speed;
self.y += self.direction.y * self.speed;
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
self.health = 100;
self.maxHealth = 100;
self.shootCooldown = 0;
self.shootDelay = 15;
self.speed = 10;
self.powerUpActive = false;
self.powerUpTimer = 0;
self.powerUpDuration = 300; // 5 seconds at 60 fps
self.takeDamage = function (amount) {
self.health -= amount;
if (self.health <= 0) {
self.health = 0;
}
LK.getSound('playerDamage').play();
LK.effects.flashObject(self, 0xff0000, 500);
tween(playerGraphics, {
alpha: 0.3
}, {
duration: 100,
onFinish: function onFinish() {
tween(playerGraphics, {
alpha: 1
}, {
duration: 100
});
}
});
};
self.activatePowerUp = function () {
self.powerUpActive = true;
self.powerUpTimer = self.powerUpDuration;
playerGraphics.tint = 0x2ecc71;
self.shootDelay = 7; // Faster shooting with power-up
};
self.update = function () {
// Update power-up status
if (self.powerUpActive) {
self.powerUpTimer--;
if (self.powerUpTimer <= 0) {
self.powerUpActive = false;
playerGraphics.tint = 0xffffff; // Reset tint
self.shootDelay = 15; // Reset shooting speed
}
}
// Update shoot cooldown
if (self.shootCooldown > 0) {
self.shootCooldown--;
}
};
return self;
});
var PowerUp = Container.expand(function () {
var self = Container.call(this);
var powerUpGraphics = self.attachAsset('powerUp', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 3;
self.rotationSpeed = 0.05;
self.update = function () {
self.y += self.speed;
self.rotation += self.rotationSpeed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
/****
* Game Description
*
* Welcome to the Ultimate Space Battle! In this thrilling game, you are the pilot of a powerful spaceship tasked with defending the galaxy from waves of enemy ships and formidable bosses.
* Navigate through the arena, dodge enemy fire, and strategically shoot down foes to earn points.
* Collect power-ups to enhance your ship's capabilities and survive the relentless onslaught.
* Every fifth wave brings a challenging boss fight, testing your skills and reflexes.
* Aim for the highest score and see if you can beat your personal best!
****/
game.setBackgroundColor(0x2c3e50);
// Game variables
var player;
var bullets = [];
var enemyBullets = [];
var enemies = [];
var powerUps = [];
var boss = null;
var isBossFight = false;
var gameLevel = storage.level || 1;
var score = 0;
var wave = 1;
var waveSize = 5 + (gameLevel - 1) * 2;
var waveDelay = 180; // 3 seconds at 60fps
var waveTimer = waveDelay;
var lastMouseX = 0;
var lastMouseY = 0;
// Create arena background
var arena = LK.getAsset('arena', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.3
});
arena.x = 2048 / 2;
arena.y = 2732 / 2;
game.addChild(arena);
// Create player
player = new Player();
player.x = 2048 / 2;
player.y = 2732 - 300;
game.addChild(player);
// UI Elements
var scoreTxt = new Text2('SCORE: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(scoreTxt);
var waveTxt = new Text2('WAVE: 1', {
size: 80,
fill: 0xFFFFFF
});
waveTxt.anchor.set(1, 0);
LK.gui.topLeft.addChild(waveTxt);
waveTxt.x = 150; // Move away from the corner
// Player Health Bar
var healthBar = new Container();
var healthBarBg = LK.getAsset('bullet', {
anchorX: 0,
anchorY: 0.5,
scaleX: 20,
scaleY: 0.8
});
healthBarBg.tint = 0x333333;
var healthBarFill = LK.getAsset('bullet', {
anchorX: 0,
anchorY: 0.5,
scaleX: 20,
scaleY: 0.8
});
healthBarFill.tint = 0x2ecc71;
healthBar.addChild(healthBarBg);
healthBar.addChild(healthBarFill);
healthBar.y = 100;
LK.gui.bottom.addChild(healthBar);
var healthBar = new Container();
var healthBarBg = LK.getAsset('bullet', {
anchorX: 0,
anchorY: 0.5,
scaleX: 20,
scaleY: 0.8
});
healthBarBg.tint = 0x333333;
var healthBarFill = LK.getAsset('bullet', {
anchorX: 0,
anchorY: 0.5,
scaleX: 20,
scaleY: 0.8
});
healthBarFill.tint = 0x2ecc71;
healthBar.addChild(healthBarBg);
healthBar.addChild(healthBarFill);
healthBar.y = 100;
LK.gui.bottom.addChild(healthBar);
// Boss health bar (only visible during boss fights)
var bossHealthBar = new Container();
var bossHealthBarBg = LK.getAsset('bullet', {
anchorX: 0,
anchorY: 0.5,
scaleX: 30,
scaleY: 1
});
bossHealthBarBg.tint = 0x333333;
var bossHealthBarFill = LK.getAsset('bullet', {
anchorX: 0,
anchorY: 0.5,
scaleX: 30,
scaleY: 1
});
bossHealthBarFill.tint = 0xe74c3c;
var bossLabel = new Text2('BOSS', {
size: 60,
fill: 0xFF0000
});
bossLabel.anchor.set(0.5, 0.5);
bossLabel.y = -40;
bossHealthBar.addChild(bossHealthBarBg);
bossHealthBar.addChild(bossHealthBarFill);
bossHealthBar.addChild(bossLabel);
bossHealthBar.visible = false;
bossHealthBar.y = 250;
LK.gui.top.addChild(bossHealthBar);
// Game functions
function spawnWave() {
var currentWaveSize = isBossFight ? 0 : waveSize;
if (isBossFight) {
// Spawn boss
boss = new Boss();
boss.x = 2048 / 2;
boss.y = 300;
game.addChild(boss);
// Show boss health bar
bossHealthBar.visible = true;
// Boss intro effect
tween(boss, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 500,
onFinish: function onFinish() {
tween(boss, {
scaleX: 1,
scaleY: 1
}, {
duration: 300
});
}
});
} else {
// Spawn regular enemies
for (var i = 0; i < currentWaveSize; i++) {
var enemy = new Enemy();
enemy.x = 200 + Math.random() * (2048 - 400);
enemy.y = -100 - Math.random() * 300;
// Assign random movement pattern
var patterns = ['direct', 'zigzag', 'circle'];
enemy.movementPattern = patterns[Math.floor(Math.random() * patterns.length)];
// Increase enemy difficulty with wave
enemy.health += Math.floor(wave * 0.5);
enemy.pointValue += Math.floor(wave * 0.2);
if (wave > 3) {
enemy.shootDelay = Math.max(60, 120 - wave * 5); // Enemies shoot faster in later waves
}
game.addChild(enemy);
enemies.push(enemy);
}
}
wave++;
waveSize = 5 + Math.floor((wave - 1) * 1.5);
waveTimer = waveDelay;
// Update wave text
waveTxt.setText('WAVE: ' + wave);
}
function spawnPowerUp() {
if (Math.random() < 0.3) {
// 30% chance to spawn power-up
var powerUp = new PowerUp();
powerUp.x = 200 + Math.random() * (2048 - 400);
powerUp.y = -50;
game.addChild(powerUp);
powerUps.push(powerUp);
}
}
function playerShoot() {
if (player.shootCooldown <= 0) {
// Create bullet
var bullet = new Bullet();
bullet.x = player.x;
bullet.y = player.y - 50;
if (player.powerUpActive) {
// Triple shot when powered up
var bulletLeft = new Bullet();
bulletLeft.x = player.x - 40;
bulletLeft.y = player.y - 30;
bulletLeft.direction = {
x: -0.2,
y: -0.8
};
var bulletRight = new Bullet();
bulletRight.x = player.x + 40;
bulletRight.y = player.y - 30;
bulletRight.direction = {
x: 0.2,
y: -0.8
};
game.addChild(bulletLeft);
game.addChild(bulletRight);
bullets.push(bulletLeft);
bullets.push(bulletRight);
}
game.addChild(bullet);
bullets.push(bullet);
// Set cooldown
player.shootCooldown = player.shootDelay;
// Play sound
LK.getSound('shoot').play();
}
}
function enemyShoot(enemy) {
if (enemy.shootCooldown <= 0) {
// Fire two bullets
for (var i = 0; i < 2; i++) {
var bullet = new EnemyBullet();
bullet.x = enemy.x;
bullet.y = enemy.y + 50;
// Aim at player
var dx = player.x - enemy.x;
var dy = player.y - enemy.y;
var distance = Math.sqrt(dx * dx + dy * dy);
bullet.direction = {
x: dx / distance,
y: dy / distance
};
game.addChild(bullet);
enemyBullets.push(bullet);
}
// Set cooldown
enemy.shootCooldown = enemy.shootDelay;
}
}
function bossShoot() {
if (boss && boss.shootCooldown <= 0) {
// Pattern depends on boss phase
if (boss.phase === 1) {
// Simple triple shot
for (var i = -1; i <= 1; i++) {
var bullet = new EnemyBullet();
bullet.x = boss.x + i * 60;
bullet.y = boss.y + 60;
game.addChild(bullet);
enemyBullets.push(bullet);
}
} else if (boss.phase === 2) {
// Spread shot
for (var i = -2; i <= 2; i++) {
var bullet = new EnemyBullet();
bullet.x = boss.x + i * 50;
bullet.y = boss.y + 60;
bullet.direction = {
x: i * 0.2,
y: 1
};
game.addChild(bullet);
enemyBullets.push(bullet);
}
} else {
// Circular burst
for (var i = 0; i < 8; i++) {
var angle = Math.PI * 2 / 8 * i;
var bullet = new EnemyBullet();
bullet.x = boss.x;
bullet.y = boss.y;
bullet.direction = {
x: Math.sin(angle),
y: Math.cos(angle)
};
game.addChild(bullet);
enemyBullets.push(bullet);
}
// Also shoot directly at player
var targetBullet = new EnemyBullet();
targetBullet.x = boss.x;
targetBullet.y = boss.y;
var dx = player.x - boss.x;
var dy = player.y - boss.y;
var distance = Math.sqrt(dx * dx + dy * dy);
targetBullet.direction = {
x: dx / distance,
y: dy / distance
};
game.addChild(targetBullet);
enemyBullets.push(targetBullet);
}
// Set cooldown
boss.shootCooldown = boss.shootDelay;
}
}
// Handle player movement
game.move = function (x, y, obj) {
lastMouseX = x;
lastMouseY = y;
};
game.down = function (x, y, obj) {
lastMouseX = x;
lastMouseY = y;
playerShoot();
};
game.up = function (x, y, obj) {
// Nothing needed here
};
// Main game update
game.update = function () {
// Play music if not already playing
if (LK.ticks === 1) {
LK.playMusic('battleMusic');
}
// Move player toward touch/mouse position, but with smoothing
if (lastMouseX !== 0 && lastMouseY !== 0) {
var dx = lastMouseX - player.x;
var dy = lastMouseY - player.y;
// Apply movement with speed limit
player.x += Math.min(Math.max(dx, -player.speed), player.speed);
player.y += Math.min(Math.max(dy, -player.speed), player.speed);
// Keep player in bounds
player.x = Math.max(100, Math.min(2048 - 100, player.x));
player.y = Math.max(100, Math.min(2732 - 100, player.y));
}
// Automatic shooting
if (LK.ticks % player.shootDelay === 0) {
playerShoot();
}
// Update player
player.update();
// Update player health bar
healthBarFill.scaleX = 20 * (player.health / player.maxHealth);
healthBarFill.tint = player.health > player.maxHealth * 0.6 ? 0x2ecc71 : player.health > player.maxHealth * 0.3 ? 0xf39c12 : 0xe74c3c;
// Boss health bar update
if (boss && bossHealthBar.visible) {
bossHealthBarFill.scaleX = 30 * (boss.health / boss.maxHealth);
}
// Wave management
if (enemies.length === 0 && !isBossFight && boss === null) {
waveTimer--;
if (waveTimer <= 0) {
// Every 5 waves is a boss
if (wave % 5 === 0) {
isBossFight = true;
}
spawnWave();
// Chance to spawn power-up on new wave
spawnPowerUp();
}
}
// Update bullets
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
bullet.update();
// Check if bullet is off screen
if (bullet.y < -50 || bullet.y > 2732 + 50 || bullet.x < -50 || bullet.x > 2048 + 50) {
bullet.destroy();
bullets.splice(i, 1);
continue;
}
// Check for collisions with enemies
for (var j = enemies.length - 1; j >= 0; j--) {
var enemy = enemies[j];
if (bullet.intersects(enemy)) {
enemy.takeDamage(bullet.damage);
bullet.destroy();
bullets.splice(i, 1);
// Check if enemy is dead
if (enemy.health <= 0) {
score += enemy.pointValue;
scoreTxt.setText('SCORE: ' + score);
// Play enemy death sound
LK.getSound('enemyDeath').play();
// Spawn power-up chance on enemy death
if (Math.random() < 0.1) {
// 10% chance
var powerUp = new PowerUp();
powerUp.x = enemy.x;
powerUp.y = enemy.y;
game.addChild(powerUp);
powerUps.push(powerUp);
}
// Remove enemy
enemy.destroy();
enemies.splice(j, 1);
}
// Skip checking other enemies since this bullet is destroyed
break;
}
}
// Check for collision with boss
if (!bullet.destroyed && boss && bullet.intersects(boss)) {
boss.takeDamage(bullet.damage);
bullet.destroy();
bullets.splice(i, 1);
// Check if boss is dead
if (boss.health <= 0) {
score += boss.pointValue;
scoreTxt.setText('SCORE: ' + score);
// Play enemy death sound at higher volume
var deathSound = LK.getSound('enemyDeath');
deathSound.volume = 0.8;
deathSound.play();
// Boss death effect
LK.effects.flashScreen(0xffffff, 500);
// Remove boss
boss.destroy();
boss = null;
isBossFight = false;
bossHealthBar.visible = false;
// Level up!
gameLevel++;
storage.level = gameLevel;
// If high score is beaten, save it
if (score > storage.highScore) {
storage.highScore = score;
}
}
}
}
// Update enemy bullets
for (var i = enemyBullets.length - 1; i >= 0; i--) {
var bullet = enemyBullets[i];
bullet.update();
// Check if bullet is off screen
if (bullet.y < -50 || bullet.y > 2732 + 50 || bullet.x < -50 || bullet.x > 2048 + 50) {
bullet.destroy();
enemyBullets.splice(i, 1);
continue;
}
// Check for collision with player
if (bullet.intersects(player)) {
player.takeDamage(bullet.damage);
bullet.destroy();
enemyBullets.splice(i, 1);
// Check if player is dead
if (player.health <= 0) {
// Game over!
LK.effects.flashScreen(0xff0000, 1000);
// If high score is beaten, save it
if (score > storage.highScore) {
storage.highScore = score;
}
LK.showGameOver();
return;
}
}
}
// Update enemies
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
enemy.update();
// Check if enemy is off bottom of screen
if (enemy.y > 2732 + 100) {
enemy.destroy();
enemies.splice(i, 1);
continue;
}
// Enemy shooting
if (enemy.shootCooldown <= 0 && enemy.y > 0) {
enemyShoot(enemy);
}
// Check for collision with player
if (enemy.intersects(player)) {
player.takeDamage(20);
enemy.takeDamage(30);
// Check if enemy is dead from collision
if (enemy.health <= 0) {
score += enemy.pointValue;
scoreTxt.setText('SCORE: ' + score);
// Play enemy death sound
LK.getSound('enemyDeath').play();
// Remove enemy
enemy.destroy();
enemies.splice(i, 1);
}
// Check if player is dead
if (player.health <= 0) {
// Game over!
LK.effects.flashScreen(0xff0000, 1000);
// If high score is beaten, save it
if (score > storage.highScore) {
storage.highScore = score;
}
LK.showGameOver();
return;
}
}
}
// Update power-ups
for (var i = powerUps.length - 1; i >= 0; i--) {
var powerUp = powerUps[i];
powerUp.update();
// Check if power-up is off bottom of screen
if (powerUp.y > 2732 + 50) {
powerUp.destroy();
powerUps.splice(i, 1);
continue;
}
// Check for collision with player
if (powerUp.intersects(player)) {
// Activate power-up
player.activatePowerUp();
// Play power-up sound
LK.getSound('powerup').play();
// Remove power-up
powerUp.destroy();
powerUps.splice(i, 1);
}
}
// Update boss
if (boss) {
boss.update();
// Boss shooting
bossShoot();
}
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
highScore: 0,
level: 1
});
/****
* Classes
****/
var Boss = Container.expand(function () {
var self = Container.call(this);
var bossGraphics = self.attachAsset('boss', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
self.health = 300;
self.maxHealth = 300;
self.pointValue = 100;
self.phase = 1;
self.shootCooldown = 0;
self.shootDelay = 60; // 1 second at 60 fps
self.movementCounter = 0;
self.speed = 1;
self.takeDamage = function (amount) {
self.health -= amount;
LK.effects.flashObject(self, 0xff0000, 200);
// Phase transitions
if (self.health < self.maxHealth * 0.7 && self.phase === 1) {
self.phase = 2;
self.shootDelay = 45; // Faster attacks in phase 2
} else if (self.health < self.maxHealth * 0.3 && self.phase === 2) {
self.phase = 3;
self.shootDelay = 30; // Even faster attacks in phase 3
bossGraphics.tint = 0xff5555; // Visual indicator for final phase
}
};
self.update = function () {
// Boss movement pattern
if (self.phase === 1) {
self.x += Math.sin(self.movementCounter * 0.02) * 2;
if (self.y < 400) {
self.y += 0.5;
}
} else if (self.phase === 2) {
self.x += Math.sin(self.movementCounter * 0.03) * 3;
self.y += Math.sin(self.movementCounter * 0.01) * 1;
} else {
self.x += Math.sin(self.movementCounter * 0.04) * 5;
self.y += Math.sin(self.movementCounter * 0.02) * 2;
}
self.movementCounter++;
// Update shoot cooldown
if (self.shootCooldown > 0) {
self.shootCooldown--;
}
};
return self;
});
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 12;
self.damage = 10;
self.direction = {
x: 0,
y: -1
};
self.update = function () {
self.x += self.direction.x * self.speed;
self.y += self.direction.y * self.speed;
};
return self;
});
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 30;
self.speed = 2;
self.pointValue = 10;
self.movementPattern = 'direct'; // direct, zigzag, circle
self.movementCounter = 0;
self.shootCooldown = 0;
self.shootDelay = 360; // 6 seconds at 60 fps
self.takeDamage = function (amount) {
self.health -= amount;
LK.effects.flashObject(self, 0xff0000, 200);
};
self.update = function () {
// Movement patterns
switch (self.movementPattern) {
case 'direct':
self.y += self.speed;
break;
case 'zigzag':
self.y += self.speed;
self.x += Math.sin(self.movementCounter * 0.05) * 3;
self.movementCounter++;
break;
case 'circle':
self.y += self.speed * 0.7;
self.x += Math.sin(self.movementCounter * 0.03) * 4;
self.movementCounter++;
break;
}
// Update shoot cooldown
if (self.shootCooldown > 0) {
self.shootCooldown--;
}
};
return self;
});
var EnemyBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('enemyBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.damage = 5;
self.direction = {
x: 0,
y: 1
};
self.update = function () {
self.x += self.direction.x * self.speed;
self.y += self.direction.y * self.speed;
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
self.health = 100;
self.maxHealth = 100;
self.shootCooldown = 0;
self.shootDelay = 15;
self.speed = 10;
self.powerUpActive = false;
self.powerUpTimer = 0;
self.powerUpDuration = 300; // 5 seconds at 60 fps
self.takeDamage = function (amount) {
self.health -= amount;
if (self.health <= 0) {
self.health = 0;
}
LK.getSound('playerDamage').play();
LK.effects.flashObject(self, 0xff0000, 500);
tween(playerGraphics, {
alpha: 0.3
}, {
duration: 100,
onFinish: function onFinish() {
tween(playerGraphics, {
alpha: 1
}, {
duration: 100
});
}
});
};
self.activatePowerUp = function () {
self.powerUpActive = true;
self.powerUpTimer = self.powerUpDuration;
playerGraphics.tint = 0x2ecc71;
self.shootDelay = 7; // Faster shooting with power-up
};
self.update = function () {
// Update power-up status
if (self.powerUpActive) {
self.powerUpTimer--;
if (self.powerUpTimer <= 0) {
self.powerUpActive = false;
playerGraphics.tint = 0xffffff; // Reset tint
self.shootDelay = 15; // Reset shooting speed
}
}
// Update shoot cooldown
if (self.shootCooldown > 0) {
self.shootCooldown--;
}
};
return self;
});
var PowerUp = Container.expand(function () {
var self = Container.call(this);
var powerUpGraphics = self.attachAsset('powerUp', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 3;
self.rotationSpeed = 0.05;
self.update = function () {
self.y += self.speed;
self.rotation += self.rotationSpeed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
/****
* Game Description
*
* Welcome to the Ultimate Space Battle! In this thrilling game, you are the pilot of a powerful spaceship tasked with defending the galaxy from waves of enemy ships and formidable bosses.
* Navigate through the arena, dodge enemy fire, and strategically shoot down foes to earn points.
* Collect power-ups to enhance your ship's capabilities and survive the relentless onslaught.
* Every fifth wave brings a challenging boss fight, testing your skills and reflexes.
* Aim for the highest score and see if you can beat your personal best!
****/
game.setBackgroundColor(0x2c3e50);
// Game variables
var player;
var bullets = [];
var enemyBullets = [];
var enemies = [];
var powerUps = [];
var boss = null;
var isBossFight = false;
var gameLevel = storage.level || 1;
var score = 0;
var wave = 1;
var waveSize = 5 + (gameLevel - 1) * 2;
var waveDelay = 180; // 3 seconds at 60fps
var waveTimer = waveDelay;
var lastMouseX = 0;
var lastMouseY = 0;
// Create arena background
var arena = LK.getAsset('arena', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.3
});
arena.x = 2048 / 2;
arena.y = 2732 / 2;
game.addChild(arena);
// Create player
player = new Player();
player.x = 2048 / 2;
player.y = 2732 - 300;
game.addChild(player);
// UI Elements
var scoreTxt = new Text2('SCORE: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(scoreTxt);
var waveTxt = new Text2('WAVE: 1', {
size: 80,
fill: 0xFFFFFF
});
waveTxt.anchor.set(1, 0);
LK.gui.topLeft.addChild(waveTxt);
waveTxt.x = 150; // Move away from the corner
// Player Health Bar
var healthBar = new Container();
var healthBarBg = LK.getAsset('bullet', {
anchorX: 0,
anchorY: 0.5,
scaleX: 20,
scaleY: 0.8
});
healthBarBg.tint = 0x333333;
var healthBarFill = LK.getAsset('bullet', {
anchorX: 0,
anchorY: 0.5,
scaleX: 20,
scaleY: 0.8
});
healthBarFill.tint = 0x2ecc71;
healthBar.addChild(healthBarBg);
healthBar.addChild(healthBarFill);
healthBar.y = 100;
LK.gui.bottom.addChild(healthBar);
var healthBar = new Container();
var healthBarBg = LK.getAsset('bullet', {
anchorX: 0,
anchorY: 0.5,
scaleX: 20,
scaleY: 0.8
});
healthBarBg.tint = 0x333333;
var healthBarFill = LK.getAsset('bullet', {
anchorX: 0,
anchorY: 0.5,
scaleX: 20,
scaleY: 0.8
});
healthBarFill.tint = 0x2ecc71;
healthBar.addChild(healthBarBg);
healthBar.addChild(healthBarFill);
healthBar.y = 100;
LK.gui.bottom.addChild(healthBar);
// Boss health bar (only visible during boss fights)
var bossHealthBar = new Container();
var bossHealthBarBg = LK.getAsset('bullet', {
anchorX: 0,
anchorY: 0.5,
scaleX: 30,
scaleY: 1
});
bossHealthBarBg.tint = 0x333333;
var bossHealthBarFill = LK.getAsset('bullet', {
anchorX: 0,
anchorY: 0.5,
scaleX: 30,
scaleY: 1
});
bossHealthBarFill.tint = 0xe74c3c;
var bossLabel = new Text2('BOSS', {
size: 60,
fill: 0xFF0000
});
bossLabel.anchor.set(0.5, 0.5);
bossLabel.y = -40;
bossHealthBar.addChild(bossHealthBarBg);
bossHealthBar.addChild(bossHealthBarFill);
bossHealthBar.addChild(bossLabel);
bossHealthBar.visible = false;
bossHealthBar.y = 250;
LK.gui.top.addChild(bossHealthBar);
// Game functions
function spawnWave() {
var currentWaveSize = isBossFight ? 0 : waveSize;
if (isBossFight) {
// Spawn boss
boss = new Boss();
boss.x = 2048 / 2;
boss.y = 300;
game.addChild(boss);
// Show boss health bar
bossHealthBar.visible = true;
// Boss intro effect
tween(boss, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 500,
onFinish: function onFinish() {
tween(boss, {
scaleX: 1,
scaleY: 1
}, {
duration: 300
});
}
});
} else {
// Spawn regular enemies
for (var i = 0; i < currentWaveSize; i++) {
var enemy = new Enemy();
enemy.x = 200 + Math.random() * (2048 - 400);
enemy.y = -100 - Math.random() * 300;
// Assign random movement pattern
var patterns = ['direct', 'zigzag', 'circle'];
enemy.movementPattern = patterns[Math.floor(Math.random() * patterns.length)];
// Increase enemy difficulty with wave
enemy.health += Math.floor(wave * 0.5);
enemy.pointValue += Math.floor(wave * 0.2);
if (wave > 3) {
enemy.shootDelay = Math.max(60, 120 - wave * 5); // Enemies shoot faster in later waves
}
game.addChild(enemy);
enemies.push(enemy);
}
}
wave++;
waveSize = 5 + Math.floor((wave - 1) * 1.5);
waveTimer = waveDelay;
// Update wave text
waveTxt.setText('WAVE: ' + wave);
}
function spawnPowerUp() {
if (Math.random() < 0.3) {
// 30% chance to spawn power-up
var powerUp = new PowerUp();
powerUp.x = 200 + Math.random() * (2048 - 400);
powerUp.y = -50;
game.addChild(powerUp);
powerUps.push(powerUp);
}
}
function playerShoot() {
if (player.shootCooldown <= 0) {
// Create bullet
var bullet = new Bullet();
bullet.x = player.x;
bullet.y = player.y - 50;
if (player.powerUpActive) {
// Triple shot when powered up
var bulletLeft = new Bullet();
bulletLeft.x = player.x - 40;
bulletLeft.y = player.y - 30;
bulletLeft.direction = {
x: -0.2,
y: -0.8
};
var bulletRight = new Bullet();
bulletRight.x = player.x + 40;
bulletRight.y = player.y - 30;
bulletRight.direction = {
x: 0.2,
y: -0.8
};
game.addChild(bulletLeft);
game.addChild(bulletRight);
bullets.push(bulletLeft);
bullets.push(bulletRight);
}
game.addChild(bullet);
bullets.push(bullet);
// Set cooldown
player.shootCooldown = player.shootDelay;
// Play sound
LK.getSound('shoot').play();
}
}
function enemyShoot(enemy) {
if (enemy.shootCooldown <= 0) {
// Fire two bullets
for (var i = 0; i < 2; i++) {
var bullet = new EnemyBullet();
bullet.x = enemy.x;
bullet.y = enemy.y + 50;
// Aim at player
var dx = player.x - enemy.x;
var dy = player.y - enemy.y;
var distance = Math.sqrt(dx * dx + dy * dy);
bullet.direction = {
x: dx / distance,
y: dy / distance
};
game.addChild(bullet);
enemyBullets.push(bullet);
}
// Set cooldown
enemy.shootCooldown = enemy.shootDelay;
}
}
function bossShoot() {
if (boss && boss.shootCooldown <= 0) {
// Pattern depends on boss phase
if (boss.phase === 1) {
// Simple triple shot
for (var i = -1; i <= 1; i++) {
var bullet = new EnemyBullet();
bullet.x = boss.x + i * 60;
bullet.y = boss.y + 60;
game.addChild(bullet);
enemyBullets.push(bullet);
}
} else if (boss.phase === 2) {
// Spread shot
for (var i = -2; i <= 2; i++) {
var bullet = new EnemyBullet();
bullet.x = boss.x + i * 50;
bullet.y = boss.y + 60;
bullet.direction = {
x: i * 0.2,
y: 1
};
game.addChild(bullet);
enemyBullets.push(bullet);
}
} else {
// Circular burst
for (var i = 0; i < 8; i++) {
var angle = Math.PI * 2 / 8 * i;
var bullet = new EnemyBullet();
bullet.x = boss.x;
bullet.y = boss.y;
bullet.direction = {
x: Math.sin(angle),
y: Math.cos(angle)
};
game.addChild(bullet);
enemyBullets.push(bullet);
}
// Also shoot directly at player
var targetBullet = new EnemyBullet();
targetBullet.x = boss.x;
targetBullet.y = boss.y;
var dx = player.x - boss.x;
var dy = player.y - boss.y;
var distance = Math.sqrt(dx * dx + dy * dy);
targetBullet.direction = {
x: dx / distance,
y: dy / distance
};
game.addChild(targetBullet);
enemyBullets.push(targetBullet);
}
// Set cooldown
boss.shootCooldown = boss.shootDelay;
}
}
// Handle player movement
game.move = function (x, y, obj) {
lastMouseX = x;
lastMouseY = y;
};
game.down = function (x, y, obj) {
lastMouseX = x;
lastMouseY = y;
playerShoot();
};
game.up = function (x, y, obj) {
// Nothing needed here
};
// Main game update
game.update = function () {
// Play music if not already playing
if (LK.ticks === 1) {
LK.playMusic('battleMusic');
}
// Move player toward touch/mouse position, but with smoothing
if (lastMouseX !== 0 && lastMouseY !== 0) {
var dx = lastMouseX - player.x;
var dy = lastMouseY - player.y;
// Apply movement with speed limit
player.x += Math.min(Math.max(dx, -player.speed), player.speed);
player.y += Math.min(Math.max(dy, -player.speed), player.speed);
// Keep player in bounds
player.x = Math.max(100, Math.min(2048 - 100, player.x));
player.y = Math.max(100, Math.min(2732 - 100, player.y));
}
// Automatic shooting
if (LK.ticks % player.shootDelay === 0) {
playerShoot();
}
// Update player
player.update();
// Update player health bar
healthBarFill.scaleX = 20 * (player.health / player.maxHealth);
healthBarFill.tint = player.health > player.maxHealth * 0.6 ? 0x2ecc71 : player.health > player.maxHealth * 0.3 ? 0xf39c12 : 0xe74c3c;
// Boss health bar update
if (boss && bossHealthBar.visible) {
bossHealthBarFill.scaleX = 30 * (boss.health / boss.maxHealth);
}
// Wave management
if (enemies.length === 0 && !isBossFight && boss === null) {
waveTimer--;
if (waveTimer <= 0) {
// Every 5 waves is a boss
if (wave % 5 === 0) {
isBossFight = true;
}
spawnWave();
// Chance to spawn power-up on new wave
spawnPowerUp();
}
}
// Update bullets
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
bullet.update();
// Check if bullet is off screen
if (bullet.y < -50 || bullet.y > 2732 + 50 || bullet.x < -50 || bullet.x > 2048 + 50) {
bullet.destroy();
bullets.splice(i, 1);
continue;
}
// Check for collisions with enemies
for (var j = enemies.length - 1; j >= 0; j--) {
var enemy = enemies[j];
if (bullet.intersects(enemy)) {
enemy.takeDamage(bullet.damage);
bullet.destroy();
bullets.splice(i, 1);
// Check if enemy is dead
if (enemy.health <= 0) {
score += enemy.pointValue;
scoreTxt.setText('SCORE: ' + score);
// Play enemy death sound
LK.getSound('enemyDeath').play();
// Spawn power-up chance on enemy death
if (Math.random() < 0.1) {
// 10% chance
var powerUp = new PowerUp();
powerUp.x = enemy.x;
powerUp.y = enemy.y;
game.addChild(powerUp);
powerUps.push(powerUp);
}
// Remove enemy
enemy.destroy();
enemies.splice(j, 1);
}
// Skip checking other enemies since this bullet is destroyed
break;
}
}
// Check for collision with boss
if (!bullet.destroyed && boss && bullet.intersects(boss)) {
boss.takeDamage(bullet.damage);
bullet.destroy();
bullets.splice(i, 1);
// Check if boss is dead
if (boss.health <= 0) {
score += boss.pointValue;
scoreTxt.setText('SCORE: ' + score);
// Play enemy death sound at higher volume
var deathSound = LK.getSound('enemyDeath');
deathSound.volume = 0.8;
deathSound.play();
// Boss death effect
LK.effects.flashScreen(0xffffff, 500);
// Remove boss
boss.destroy();
boss = null;
isBossFight = false;
bossHealthBar.visible = false;
// Level up!
gameLevel++;
storage.level = gameLevel;
// If high score is beaten, save it
if (score > storage.highScore) {
storage.highScore = score;
}
}
}
}
// Update enemy bullets
for (var i = enemyBullets.length - 1; i >= 0; i--) {
var bullet = enemyBullets[i];
bullet.update();
// Check if bullet is off screen
if (bullet.y < -50 || bullet.y > 2732 + 50 || bullet.x < -50 || bullet.x > 2048 + 50) {
bullet.destroy();
enemyBullets.splice(i, 1);
continue;
}
// Check for collision with player
if (bullet.intersects(player)) {
player.takeDamage(bullet.damage);
bullet.destroy();
enemyBullets.splice(i, 1);
// Check if player is dead
if (player.health <= 0) {
// Game over!
LK.effects.flashScreen(0xff0000, 1000);
// If high score is beaten, save it
if (score > storage.highScore) {
storage.highScore = score;
}
LK.showGameOver();
return;
}
}
}
// Update enemies
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
enemy.update();
// Check if enemy is off bottom of screen
if (enemy.y > 2732 + 100) {
enemy.destroy();
enemies.splice(i, 1);
continue;
}
// Enemy shooting
if (enemy.shootCooldown <= 0 && enemy.y > 0) {
enemyShoot(enemy);
}
// Check for collision with player
if (enemy.intersects(player)) {
player.takeDamage(20);
enemy.takeDamage(30);
// Check if enemy is dead from collision
if (enemy.health <= 0) {
score += enemy.pointValue;
scoreTxt.setText('SCORE: ' + score);
// Play enemy death sound
LK.getSound('enemyDeath').play();
// Remove enemy
enemy.destroy();
enemies.splice(i, 1);
}
// Check if player is dead
if (player.health <= 0) {
// Game over!
LK.effects.flashScreen(0xff0000, 1000);
// If high score is beaten, save it
if (score > storage.highScore) {
storage.highScore = score;
}
LK.showGameOver();
return;
}
}
}
// Update power-ups
for (var i = powerUps.length - 1; i >= 0; i--) {
var powerUp = powerUps[i];
powerUp.update();
// Check if power-up is off bottom of screen
if (powerUp.y > 2732 + 50) {
powerUp.destroy();
powerUps.splice(i, 1);
continue;
}
// Check for collision with player
if (powerUp.intersects(player)) {
// Activate power-up
player.activatePowerUp();
// Play power-up sound
LK.getSound('powerup').play();
// Remove power-up
powerUp.destroy();
powerUps.splice(i, 1);
}
}
// Update boss
if (boss) {
boss.update();
// Boss shooting
bossShoot();
}
};
Arena. Single Game Texture. High contrast. Arena
Boss. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Power up bullet. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Enemy plane. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows