User prompt
start thiss ↪💡 Consider importing and using the following plugins: @upit/tween.v1, @upit/storage.v1
Code edit (1 edits merged)
Please save this source code
User prompt
Cosmic Ascent: Rogue Squadron
Initial prompt
Create a vertically-scrolling space shooter with roguelike elements where players pilot a customizable ship through waves of alien enemies, collecting power-ups and defeating massive bosses.
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Boss = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('boss', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 1;
self.health = 50;
self.maxHealth = 50;
self.shootTimer = 0;
self.shootInterval = 30;
self.moveTimer = 0;
self.moveDirection = 1;
self.update = function () {
// Boss movement pattern
self.x += self.moveDirection * 2;
if (self.x <= graphics.width / 2 || self.x >= 2048 - graphics.width / 2) {
self.moveDirection *= -1;
}
// Boss shooting pattern
self.shootTimer++;
if (self.shootTimer >= self.shootInterval) {
self.shootTimer = 0;
// Triple shot
for (var i = -1; i <= 1; i++) {
var bullet = new EnemyBullet();
bullet.x = self.x + i * 50;
bullet.y = self.y + graphics.height / 2;
enemyBullets.push(bullet);
game.addChild(bullet);
}
}
};
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xffffff, 300);
if (self.health <= 0) {
self.destroy();
return true;
}
return false;
};
return self;
});
var Enemy = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('enemy1', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 3;
self.health = 1;
self.maxHealth = 1;
self.shootTimer = 0;
self.shootInterval = 120;
self.movePattern = 'straight';
self.moveTimer = 0;
self.update = function () {
// Movement patterns
if (self.movePattern === 'straight') {
self.y += self.speed;
} else if (self.movePattern === 'zigzag') {
self.y += self.speed;
self.x += Math.sin(self.moveTimer * 0.1) * 2;
}
self.moveTimer++;
// Shooting
self.shootTimer++;
if (self.shootTimer >= self.shootInterval) {
self.shootTimer = 0;
if (self.y > 0 && self.y < 2732) {
var bullet = new EnemyBullet();
bullet.x = self.x;
bullet.y = self.y + graphics.height / 2;
enemyBullets.push(bullet);
game.addChild(bullet);
}
}
};
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xffffff, 200);
if (self.health <= 0) {
self.destroy();
return true;
}
return false;
};
return self;
});
var EnemyBullet = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('enemyBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.damage = 1;
self.update = function () {
self.y += self.speed;
};
return self;
});
var FastEnemy = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('enemy2', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 5;
self.health = 2;
self.maxHealth = 2;
self.shootInterval = 80;
self.movePattern = 'zigzag';
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 3;
self.maxHealth = 3;
self.shootTimer = 0;
self.shootInterval = 10;
self.rapidFire = false;
self.rapidFireTimer = 0;
self.multiShot = false;
self.multiShotTimer = 0;
self.invulnerable = false;
self.invulnerableTimer = 0;
self.update = function () {
// Power-up timers
if (self.rapidFire) {
self.rapidFireTimer--;
if (self.rapidFireTimer <= 0) {
self.rapidFire = false;
self.shootInterval = 10;
}
}
if (self.multiShot) {
self.multiShotTimer--;
if (self.multiShotTimer <= 0) {
self.multiShot = false;
}
}
if (self.invulnerable) {
self.invulnerableTimer--;
graphics.alpha = 0.5 + Math.sin(LK.ticks * 0.5) * 0.3;
if (self.invulnerableTimer <= 0) {
self.invulnerable = false;
graphics.alpha = 1;
}
}
// Auto-shooting
self.shootTimer++;
if (self.shootTimer >= self.shootInterval) {
self.shootTimer = 0;
self.shoot();
}
};
self.shoot = function () {
LK.getSound('shoot').play();
if (self.multiShot) {
// Triple shot
for (var i = -1; i <= 1; i++) {
var bullet = new PlayerBullet();
bullet.x = self.x + i * 30;
bullet.y = self.y - graphics.height / 2;
playerBullets.push(bullet);
game.addChild(bullet);
}
} else {
// Single shot
var bullet = new PlayerBullet();
bullet.x = self.x;
bullet.y = self.y - graphics.height / 2;
playerBullets.push(bullet);
game.addChild(bullet);
}
};
self.takeDamage = function () {
if (self.invulnerable) return false;
self.health--;
self.invulnerable = true;
self.invulnerableTimer = 120;
LK.effects.flashObject(self, 0xff0000, 500);
if (self.health <= 0) {
return true;
}
return false;
};
self.applyPowerUp = function (powerUpType) {
LK.getSound('powerup').play();
if (powerUpType === 'rapidfire') {
self.rapidFire = true;
self.rapidFireTimer = 600; // 10 seconds at 60fps
self.shootInterval = 5;
} else if (powerUpType === 'multishot') {
self.multiShot = true;
self.multiShotTimer = 600;
} else if (powerUpType === 'shield') {
if (self.health < self.maxHealth) {
self.health++;
}
}
};
return self;
});
var PlayerBullet = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('playerBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 15;
self.damage = 1;
self.update = function () {
self.y -= self.speed;
};
return self;
});
var PowerUp = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 4;
self.type = 'rapidfire'; // rapidfire, shield, multishot
self.moveTimer = 0;
self.update = function () {
self.y += self.speed;
self.moveTimer++;
graphics.rotation += 0.1;
// Pulsing effect
var scale = 1 + Math.sin(self.moveTimer * 0.2) * 0.2;
graphics.scaleX = scale;
graphics.scaleY = scale;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x001122
});
/****
* Game Code
****/
// Game state variables
var gameState = 'playing'; // playing, gameover
var currentWave = 1;
var enemiesInWave = 0;
var enemiesKilled = 0;
var waveTimer = 0;
var nextWaveDelay = 180; // 3 seconds
var bossWave = false;
var currentBoss = null;
// Game arrays
var playerBullets = [];
var enemyBullets = [];
var enemies = [];
var powerUps = [];
// Spawn timers
var enemySpawnTimer = 0;
var powerUpSpawnTimer = 0;
// Player stats
var playerLives = storage.playerLives || 3;
var totalScore = storage.totalScore || 0;
var highScore = storage.highScore || 0;
// Create player
var player = game.addChild(new Player());
player.x = 2048 / 2;
player.y = 2732 - 200;
// UI Elements
var scoreText = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(0, 0);
scoreText.x = 150;
scoreText.y = 50;
LK.gui.topLeft.addChild(scoreText);
var waveText = new Text2('Wave: 1', {
size: 60,
fill: 0xFFFFFF
});
waveText.anchor.set(0.5, 0);
LK.gui.top.addChild(waveText);
var healthText = new Text2('Lives: 3', {
size: 60,
fill: 0xFFFFFF
});
healthText.anchor.set(1, 0);
healthText.x = -50;
healthText.y = 50;
LK.gui.topRight.addChild(healthText);
// Touch controls
var dragActive = false;
game.down = function (x, y, obj) {
dragActive = true;
player.x = x;
player.y = y;
};
game.move = function (x, y, obj) {
if (dragActive && gameState === 'playing') {
player.x = Math.max(40, Math.min(2048 - 40, x));
player.y = Math.max(100, Math.min(2732 - 100, y));
}
};
game.up = function (x, y, obj) {
dragActive = false;
};
// Wave generation
function startWave() {
enemiesInWave = currentWave * 3 + Math.floor(currentWave / 2);
enemiesKilled = 0;
waveTimer = 0;
// Boss every 5th wave
if (currentWave % 5 === 0) {
bossWave = true;
spawnBoss();
} else {
bossWave = false;
}
waveText.setText('Wave: ' + currentWave);
}
function spawnBoss() {
currentBoss = new Boss();
currentBoss.x = 2048 / 2;
currentBoss.y = 200;
enemies.push(currentBoss);
game.addChild(currentBoss);
}
function spawnEnemy() {
var enemy;
// 30% chance for fast enemy after wave 3
if (currentWave > 3 && Math.random() < 0.3) {
enemy = new FastEnemy();
} else {
enemy = new Enemy();
}
enemy.x = Math.random() * (2048 - 100) + 50;
enemy.y = -50;
enemies.push(enemy);
game.addChild(enemy);
}
function spawnPowerUp() {
var powerUp = new PowerUp();
powerUp.x = Math.random() * (2048 - 80) + 40;
powerUp.y = -40;
var types = ['rapidfire', 'multishot', 'shield'];
powerUp.type = types[Math.floor(Math.random() * types.length)];
powerUps.push(powerUp);
game.addChild(powerUp);
}
// Start first wave
startWave();
// Main game update loop
game.update = function () {
if (gameState !== 'playing') return;
// Update wave timer
waveTimer++;
// Spawn enemies during wave
if (!bossWave && enemiesKilled < enemiesInWave) {
enemySpawnTimer++;
var spawnRate = Math.max(30, 120 - currentWave * 5);
if (enemySpawnTimer >= spawnRate) {
enemySpawnTimer = 0;
spawnEnemy();
}
}
// Spawn power-ups occasionally
powerUpSpawnTimer++;
if (powerUpSpawnTimer >= 900) {
// Every 15 seconds
powerUpSpawnTimer = 0;
if (Math.random() < 0.7) {
spawnPowerUp();
}
}
// Update and check player bullets
for (var i = playerBullets.length - 1; i >= 0; i--) {
var bullet = playerBullets[i];
if (bullet.lastY === undefined) bullet.lastY = bullet.y;
// Remove off-screen bullets
if (bullet.lastY >= -30 && bullet.y < -30) {
bullet.destroy();
playerBullets.splice(i, 1);
continue;
}
// Check collision with enemies
var hitEnemy = false;
for (var j = enemies.length - 1; j >= 0; j--) {
var enemy = enemies[j];
if (bullet.intersects(enemy)) {
if (enemy.takeDamage(bullet.damage)) {
// Enemy destroyed
LK.getSound('enemyHit').play();
LK.setScore(LK.getScore() + (enemy === currentBoss ? 500 : 100));
enemies.splice(j, 1);
enemiesKilled++;
if (enemy === currentBoss) {
currentBoss = null;
bossWave = false;
}
}
bullet.destroy();
playerBullets.splice(i, 1);
hitEnemy = true;
break;
}
}
if (!hitEnemy) {
bullet.lastY = bullet.y;
}
}
// Update and check enemy bullets
for (var i = enemyBullets.length - 1; i >= 0; i--) {
var bullet = enemyBullets[i];
if (bullet.lastY === undefined) bullet.lastY = bullet.y;
// Remove off-screen bullets
if (bullet.lastY <= 2760 && bullet.y > 2760) {
bullet.destroy();
enemyBullets.splice(i, 1);
continue;
}
// Check collision with player
if (bullet.intersects(player)) {
if (player.takeDamage()) {
// Player died
LK.getSound('explosion').play();
gameState = 'gameover';
// Update storage
storage.totalScore = totalScore + LK.getScore();
if (LK.getScore() > highScore) {
storage.highScore = LK.getScore();
}
LK.showGameOver();
return;
}
bullet.destroy();
enemyBullets.splice(i, 1);
} else {
bullet.lastY = bullet.y;
}
}
// Update and check enemies
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
if (enemy.lastY === undefined) enemy.lastY = enemy.y;
// Remove off-screen enemies (except boss)
if (enemy !== currentBoss && enemy.lastY <= 2760 && enemy.y > 2760) {
enemy.destroy();
enemies.splice(i, 1);
continue;
}
// Check collision with player
if (enemy.intersects(player)) {
if (player.takeDamage()) {
// Player died
LK.getSound('explosion').play();
gameState = 'gameover';
// Update storage
storage.totalScore = totalScore + LK.getScore();
if (LK.getScore() > highScore) {
storage.highScore = LK.getScore();
}
LK.showGameOver();
return;
}
}
enemy.lastY = enemy.y;
}
// Update and check power-ups
for (var i = powerUps.length - 1; i >= 0; i--) {
var powerUp = powerUps[i];
if (powerUp.lastY === undefined) powerUp.lastY = powerUp.y;
// Remove off-screen power-ups
if (powerUp.lastY <= 2760 && powerUp.y > 2760) {
powerUp.destroy();
powerUps.splice(i, 1);
continue;
}
// Check collision with player
if (powerUp.intersects(player)) {
player.applyPowerUp(powerUp.type);
powerUp.destroy();
powerUps.splice(i, 1);
} else {
powerUp.lastY = powerUp.y;
}
}
// Check wave completion
if (bossWave && currentBoss === null || !bossWave && enemiesKilled >= enemiesInWave && enemies.length === 0) {
if (waveTimer >= nextWaveDelay) {
currentWave++;
startWave();
}
}
// Update UI
scoreText.setText('Score: ' + LK.getScore());
healthText.setText('Lives: ' + player.health);
// Victory condition (survive 20 waves)
if (currentWave > 20) {
storage.totalScore = totalScore + LK.getScore();
if (LK.getScore() > highScore) {
storage.highScore = LK.getScore();
}
LK.showYouWin();
}
};
// Start background music
LK.playMusic('bgmusic'); ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,528 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+var storage = LK.import("@upit/storage.v1");
+
+/****
+* Classes
+****/
+var Boss = Container.expand(function () {
+ var self = Container.call(this);
+ var graphics = self.attachAsset('boss', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 1;
+ self.health = 50;
+ self.maxHealth = 50;
+ self.shootTimer = 0;
+ self.shootInterval = 30;
+ self.moveTimer = 0;
+ self.moveDirection = 1;
+ self.update = function () {
+ // Boss movement pattern
+ self.x += self.moveDirection * 2;
+ if (self.x <= graphics.width / 2 || self.x >= 2048 - graphics.width / 2) {
+ self.moveDirection *= -1;
+ }
+ // Boss shooting pattern
+ self.shootTimer++;
+ if (self.shootTimer >= self.shootInterval) {
+ self.shootTimer = 0;
+ // Triple shot
+ for (var i = -1; i <= 1; i++) {
+ var bullet = new EnemyBullet();
+ bullet.x = self.x + i * 50;
+ bullet.y = self.y + graphics.height / 2;
+ enemyBullets.push(bullet);
+ game.addChild(bullet);
+ }
+ }
+ };
+ self.takeDamage = function (damage) {
+ self.health -= damage;
+ LK.effects.flashObject(self, 0xffffff, 300);
+ if (self.health <= 0) {
+ self.destroy();
+ return true;
+ }
+ return false;
+ };
+ return self;
+});
+var Enemy = Container.expand(function () {
+ var self = Container.call(this);
+ var graphics = self.attachAsset('enemy1', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 3;
+ self.health = 1;
+ self.maxHealth = 1;
+ self.shootTimer = 0;
+ self.shootInterval = 120;
+ self.movePattern = 'straight';
+ self.moveTimer = 0;
+ self.update = function () {
+ // Movement patterns
+ if (self.movePattern === 'straight') {
+ self.y += self.speed;
+ } else if (self.movePattern === 'zigzag') {
+ self.y += self.speed;
+ self.x += Math.sin(self.moveTimer * 0.1) * 2;
+ }
+ self.moveTimer++;
+ // Shooting
+ self.shootTimer++;
+ if (self.shootTimer >= self.shootInterval) {
+ self.shootTimer = 0;
+ if (self.y > 0 && self.y < 2732) {
+ var bullet = new EnemyBullet();
+ bullet.x = self.x;
+ bullet.y = self.y + graphics.height / 2;
+ enemyBullets.push(bullet);
+ game.addChild(bullet);
+ }
+ }
+ };
+ self.takeDamage = function (damage) {
+ self.health -= damage;
+ LK.effects.flashObject(self, 0xffffff, 200);
+ if (self.health <= 0) {
+ self.destroy();
+ return true;
+ }
+ return false;
+ };
+ return self;
+});
+var EnemyBullet = Container.expand(function () {
+ var self = Container.call(this);
+ var graphics = self.attachAsset('enemyBullet', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 8;
+ self.damage = 1;
+ self.update = function () {
+ self.y += self.speed;
+ };
+ return self;
+});
+var FastEnemy = Container.expand(function () {
+ var self = Container.call(this);
+ var graphics = self.attachAsset('enemy2', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 5;
+ self.health = 2;
+ self.maxHealth = 2;
+ self.shootInterval = 80;
+ self.movePattern = 'zigzag';
+ return self;
+});
+var Player = Container.expand(function () {
+ var self = Container.call(this);
+ var graphics = self.attachAsset('player', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.health = 3;
+ self.maxHealth = 3;
+ self.shootTimer = 0;
+ self.shootInterval = 10;
+ self.rapidFire = false;
+ self.rapidFireTimer = 0;
+ self.multiShot = false;
+ self.multiShotTimer = 0;
+ self.invulnerable = false;
+ self.invulnerableTimer = 0;
+ self.update = function () {
+ // Power-up timers
+ if (self.rapidFire) {
+ self.rapidFireTimer--;
+ if (self.rapidFireTimer <= 0) {
+ self.rapidFire = false;
+ self.shootInterval = 10;
+ }
+ }
+ if (self.multiShot) {
+ self.multiShotTimer--;
+ if (self.multiShotTimer <= 0) {
+ self.multiShot = false;
+ }
+ }
+ if (self.invulnerable) {
+ self.invulnerableTimer--;
+ graphics.alpha = 0.5 + Math.sin(LK.ticks * 0.5) * 0.3;
+ if (self.invulnerableTimer <= 0) {
+ self.invulnerable = false;
+ graphics.alpha = 1;
+ }
+ }
+ // Auto-shooting
+ self.shootTimer++;
+ if (self.shootTimer >= self.shootInterval) {
+ self.shootTimer = 0;
+ self.shoot();
+ }
+ };
+ self.shoot = function () {
+ LK.getSound('shoot').play();
+ if (self.multiShot) {
+ // Triple shot
+ for (var i = -1; i <= 1; i++) {
+ var bullet = new PlayerBullet();
+ bullet.x = self.x + i * 30;
+ bullet.y = self.y - graphics.height / 2;
+ playerBullets.push(bullet);
+ game.addChild(bullet);
+ }
+ } else {
+ // Single shot
+ var bullet = new PlayerBullet();
+ bullet.x = self.x;
+ bullet.y = self.y - graphics.height / 2;
+ playerBullets.push(bullet);
+ game.addChild(bullet);
+ }
+ };
+ self.takeDamage = function () {
+ if (self.invulnerable) return false;
+ self.health--;
+ self.invulnerable = true;
+ self.invulnerableTimer = 120;
+ LK.effects.flashObject(self, 0xff0000, 500);
+ if (self.health <= 0) {
+ return true;
+ }
+ return false;
+ };
+ self.applyPowerUp = function (powerUpType) {
+ LK.getSound('powerup').play();
+ if (powerUpType === 'rapidfire') {
+ self.rapidFire = true;
+ self.rapidFireTimer = 600; // 10 seconds at 60fps
+ self.shootInterval = 5;
+ } else if (powerUpType === 'multishot') {
+ self.multiShot = true;
+ self.multiShotTimer = 600;
+ } else if (powerUpType === 'shield') {
+ if (self.health < self.maxHealth) {
+ self.health++;
+ }
+ }
+ };
+ return self;
+});
+var PlayerBullet = Container.expand(function () {
+ var self = Container.call(this);
+ var graphics = self.attachAsset('playerBullet', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 15;
+ self.damage = 1;
+ self.update = function () {
+ self.y -= self.speed;
+ };
+ return self;
+});
+var PowerUp = Container.expand(function () {
+ var self = Container.call(this);
+ var graphics = self.attachAsset('powerup', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 4;
+ self.type = 'rapidfire'; // rapidfire, shield, multishot
+ self.moveTimer = 0;
+ self.update = function () {
+ self.y += self.speed;
+ self.moveTimer++;
+ graphics.rotation += 0.1;
+ // Pulsing effect
+ var scale = 1 + Math.sin(self.moveTimer * 0.2) * 0.2;
+ graphics.scaleX = scale;
+ graphics.scaleY = scale;
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x001122
+});
+
+/****
+* Game Code
+****/
+// Game state variables
+var gameState = 'playing'; // playing, gameover
+var currentWave = 1;
+var enemiesInWave = 0;
+var enemiesKilled = 0;
+var waveTimer = 0;
+var nextWaveDelay = 180; // 3 seconds
+var bossWave = false;
+var currentBoss = null;
+// Game arrays
+var playerBullets = [];
+var enemyBullets = [];
+var enemies = [];
+var powerUps = [];
+// Spawn timers
+var enemySpawnTimer = 0;
+var powerUpSpawnTimer = 0;
+// Player stats
+var playerLives = storage.playerLives || 3;
+var totalScore = storage.totalScore || 0;
+var highScore = storage.highScore || 0;
+// Create player
+var player = game.addChild(new Player());
+player.x = 2048 / 2;
+player.y = 2732 - 200;
+// UI Elements
+var scoreText = new Text2('Score: 0', {
+ size: 60,
+ fill: 0xFFFFFF
+});
+scoreText.anchor.set(0, 0);
+scoreText.x = 150;
+scoreText.y = 50;
+LK.gui.topLeft.addChild(scoreText);
+var waveText = new Text2('Wave: 1', {
+ size: 60,
+ fill: 0xFFFFFF
+});
+waveText.anchor.set(0.5, 0);
+LK.gui.top.addChild(waveText);
+var healthText = new Text2('Lives: 3', {
+ size: 60,
+ fill: 0xFFFFFF
+});
+healthText.anchor.set(1, 0);
+healthText.x = -50;
+healthText.y = 50;
+LK.gui.topRight.addChild(healthText);
+// Touch controls
+var dragActive = false;
+game.down = function (x, y, obj) {
+ dragActive = true;
+ player.x = x;
+ player.y = y;
+};
+game.move = function (x, y, obj) {
+ if (dragActive && gameState === 'playing') {
+ player.x = Math.max(40, Math.min(2048 - 40, x));
+ player.y = Math.max(100, Math.min(2732 - 100, y));
+ }
+};
+game.up = function (x, y, obj) {
+ dragActive = false;
+};
+// Wave generation
+function startWave() {
+ enemiesInWave = currentWave * 3 + Math.floor(currentWave / 2);
+ enemiesKilled = 0;
+ waveTimer = 0;
+ // Boss every 5th wave
+ if (currentWave % 5 === 0) {
+ bossWave = true;
+ spawnBoss();
+ } else {
+ bossWave = false;
+ }
+ waveText.setText('Wave: ' + currentWave);
+}
+function spawnBoss() {
+ currentBoss = new Boss();
+ currentBoss.x = 2048 / 2;
+ currentBoss.y = 200;
+ enemies.push(currentBoss);
+ game.addChild(currentBoss);
+}
+function spawnEnemy() {
+ var enemy;
+ // 30% chance for fast enemy after wave 3
+ if (currentWave > 3 && Math.random() < 0.3) {
+ enemy = new FastEnemy();
+ } else {
+ enemy = new Enemy();
+ }
+ enemy.x = Math.random() * (2048 - 100) + 50;
+ enemy.y = -50;
+ enemies.push(enemy);
+ game.addChild(enemy);
+}
+function spawnPowerUp() {
+ var powerUp = new PowerUp();
+ powerUp.x = Math.random() * (2048 - 80) + 40;
+ powerUp.y = -40;
+ var types = ['rapidfire', 'multishot', 'shield'];
+ powerUp.type = types[Math.floor(Math.random() * types.length)];
+ powerUps.push(powerUp);
+ game.addChild(powerUp);
+}
+// Start first wave
+startWave();
+// Main game update loop
+game.update = function () {
+ if (gameState !== 'playing') return;
+ // Update wave timer
+ waveTimer++;
+ // Spawn enemies during wave
+ if (!bossWave && enemiesKilled < enemiesInWave) {
+ enemySpawnTimer++;
+ var spawnRate = Math.max(30, 120 - currentWave * 5);
+ if (enemySpawnTimer >= spawnRate) {
+ enemySpawnTimer = 0;
+ spawnEnemy();
+ }
+ }
+ // Spawn power-ups occasionally
+ powerUpSpawnTimer++;
+ if (powerUpSpawnTimer >= 900) {
+ // Every 15 seconds
+ powerUpSpawnTimer = 0;
+ if (Math.random() < 0.7) {
+ spawnPowerUp();
+ }
+ }
+ // Update and check player bullets
+ for (var i = playerBullets.length - 1; i >= 0; i--) {
+ var bullet = playerBullets[i];
+ if (bullet.lastY === undefined) bullet.lastY = bullet.y;
+ // Remove off-screen bullets
+ if (bullet.lastY >= -30 && bullet.y < -30) {
+ bullet.destroy();
+ playerBullets.splice(i, 1);
+ continue;
+ }
+ // Check collision with enemies
+ var hitEnemy = false;
+ for (var j = enemies.length - 1; j >= 0; j--) {
+ var enemy = enemies[j];
+ if (bullet.intersects(enemy)) {
+ if (enemy.takeDamage(bullet.damage)) {
+ // Enemy destroyed
+ LK.getSound('enemyHit').play();
+ LK.setScore(LK.getScore() + (enemy === currentBoss ? 500 : 100));
+ enemies.splice(j, 1);
+ enemiesKilled++;
+ if (enemy === currentBoss) {
+ currentBoss = null;
+ bossWave = false;
+ }
+ }
+ bullet.destroy();
+ playerBullets.splice(i, 1);
+ hitEnemy = true;
+ break;
+ }
+ }
+ if (!hitEnemy) {
+ bullet.lastY = bullet.y;
+ }
+ }
+ // Update and check enemy bullets
+ for (var i = enemyBullets.length - 1; i >= 0; i--) {
+ var bullet = enemyBullets[i];
+ if (bullet.lastY === undefined) bullet.lastY = bullet.y;
+ // Remove off-screen bullets
+ if (bullet.lastY <= 2760 && bullet.y > 2760) {
+ bullet.destroy();
+ enemyBullets.splice(i, 1);
+ continue;
+ }
+ // Check collision with player
+ if (bullet.intersects(player)) {
+ if (player.takeDamage()) {
+ // Player died
+ LK.getSound('explosion').play();
+ gameState = 'gameover';
+ // Update storage
+ storage.totalScore = totalScore + LK.getScore();
+ if (LK.getScore() > highScore) {
+ storage.highScore = LK.getScore();
+ }
+ LK.showGameOver();
+ return;
+ }
+ bullet.destroy();
+ enemyBullets.splice(i, 1);
+ } else {
+ bullet.lastY = bullet.y;
+ }
+ }
+ // Update and check enemies
+ for (var i = enemies.length - 1; i >= 0; i--) {
+ var enemy = enemies[i];
+ if (enemy.lastY === undefined) enemy.lastY = enemy.y;
+ // Remove off-screen enemies (except boss)
+ if (enemy !== currentBoss && enemy.lastY <= 2760 && enemy.y > 2760) {
+ enemy.destroy();
+ enemies.splice(i, 1);
+ continue;
+ }
+ // Check collision with player
+ if (enemy.intersects(player)) {
+ if (player.takeDamage()) {
+ // Player died
+ LK.getSound('explosion').play();
+ gameState = 'gameover';
+ // Update storage
+ storage.totalScore = totalScore + LK.getScore();
+ if (LK.getScore() > highScore) {
+ storage.highScore = LK.getScore();
+ }
+ LK.showGameOver();
+ return;
+ }
+ }
+ enemy.lastY = enemy.y;
+ }
+ // Update and check power-ups
+ for (var i = powerUps.length - 1; i >= 0; i--) {
+ var powerUp = powerUps[i];
+ if (powerUp.lastY === undefined) powerUp.lastY = powerUp.y;
+ // Remove off-screen power-ups
+ if (powerUp.lastY <= 2760 && powerUp.y > 2760) {
+ powerUp.destroy();
+ powerUps.splice(i, 1);
+ continue;
+ }
+ // Check collision with player
+ if (powerUp.intersects(player)) {
+ player.applyPowerUp(powerUp.type);
+ powerUp.destroy();
+ powerUps.splice(i, 1);
+ } else {
+ powerUp.lastY = powerUp.y;
+ }
+ }
+ // Check wave completion
+ if (bossWave && currentBoss === null || !bossWave && enemiesKilled >= enemiesInWave && enemies.length === 0) {
+ if (waveTimer >= nextWaveDelay) {
+ currentWave++;
+ startWave();
+ }
+ }
+ // Update UI
+ scoreText.setText('Score: ' + LK.getScore());
+ healthText.setText('Lives: ' + player.health);
+ // Victory condition (survive 20 waves)
+ if (currentWave > 20) {
+ storage.totalScore = totalScore + LK.getScore();
+ if (LK.getScore() > highScore) {
+ storage.highScore = LK.getScore();
+ }
+ LK.showYouWin();
+ }
+};
+// Start background music
+LK.playMusic('bgmusic');
\ No newline at end of file