User prompt
Make the AllyAngel face upwards
User prompt
Make less enemies spawn so it’s not crowded
User prompt
Delete the angel boss please
User prompt
Auto create AngelAlly when player enters bottom left corner
User prompt
Make the regular angel boss spawn at the top of the screen
User prompt
Make the regular angel boss shoot downwards
User prompt
Make the regular angel boss spawn at the top
User prompt
Make the ally angle boss spawn at the bottom of the screen and shoot upwards
User prompt
Make the angel invincible when he charges at you also make so that when he dies he joins your team
User prompt
If you get hit by the angels balls then it will charge at you
User prompt
Make the angel boss shoot big white circle
User prompt
Make the angel boss have his own asset
User prompt
Make so that if you stay in the bottom left corner enemies will not go close to you
User prompt
If you go to the bottom left corner make the player stop shooting
User prompt
Make it spawn 4 small exploding sharks after a super boss dies instead of the number before
User prompt
Make infinity waves
User prompt
Make intense music play in the background
User prompt
Make a asset for the super boss please I’ve asked this many times and you haven’t done it
User prompt
Can you make the cover have sharks instead of aliens
User prompt
If you defeat the super boss make it spawn super tiny sharks that will chase you and if they touch you they will explode and and do a lot of damage
User prompt
Make a asset for the super boss
User prompt
Make the super boss a asset
User prompt
After defeating the boss 2 times make a super boss spawn that will charge 3 laser cannon
User prompt
As the waves go on make less enemies
User prompt
Make so the that the max clones you can have is 2
/**** * 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); self.health = 200; self.maxHealth = 200; self.speed = 4; self.fireRate = 90; self.fireTimer = 0; self.mineFireRate = 180; self.mineFireTimer = 60; self.scoreValue = 500; self.movingRight = true; // Create boss graphics (larger enemy ship) var bossGraphics = self.attachAsset('bossShip', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5 }); // Create boss health bar background self.healthBarBg = LK.getAsset('healthBarBackground', { anchorX: 0.5, anchorY: 0, scaleX: 2, scaleY: 1, y: -100 }); // Create boss health bar self.healthBar = LK.getAsset('healthBar', { anchorX: 0.5, anchorY: 0, scaleX: 2, scaleY: 1, y: -95 }); self.addChild(self.healthBarBg); self.addChild(self.healthBar); self.takeDamage = function (amount) { self.health -= amount; // Update health bar self.healthBar.scale.x = self.health / self.maxHealth * 2; if (self.health <= 0) { // Boss explosion effect - bigger and longer LK.effects.flashObject(self, 0xff0000, 1000); LK.getSound('explosion').play(); // Always spawn a clone power-up when boss is defeated var clonePowerUp = new ClonePowerUp(); clonePowerUp.x = self.x; clonePowerUp.y = self.y; clonePowerUps.push(clonePowerUp); game.addChild(clonePowerUp); return true; // Boss is destroyed } else { // Flash red when taking damage LK.effects.flashObject(self, 0xff0000, 200); return false; } }; self.shootBullet = function () { if (self.fireTimer <= 0) { // Shoot multiple bullets in a spread pattern for (var i = -2; i <= 2; i++) { var bullet = new EnemyBullet(); bullet.x = self.x + i * 30; bullet.y = self.y + 80; enemyBullets.push(bullet); game.addChild(bullet); } LK.getSound('enemyShoot').play(); self.fireTimer = self.fireRate; } }; self.shootMine = function () { if (self.mineFireTimer <= 0) { var mine = new Mine(); mine.x = self.x; mine.y = self.y + 100; enemyBullets.push(mine); game.addChild(mine); LK.getSound('enemyShoot').play(); self.mineFireTimer = self.mineFireRate; } }; self.update = function () { // Basic movement pattern - side to side if (self.movingRight) { self.x += self.speed; if (self.x > 2048 - 200) { self.movingRight = false; } } else { self.x -= self.speed; if (self.x < 200) { self.movingRight = true; } } // Decrease fire timers self.fireTimer--; self.mineFireTimer--; // Shoot regular bullets if (self.fireTimer <= 0) { self.shootBullet(); } // Shoot mines if (self.mineFireTimer <= 0) { self.shootMine(); } }; return self; }); var Bullet = Container.expand(function () { var self = Container.call(this); self.speed = 15; self.damage = 1; self.isPlayerBullet = true; var bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.update = function () { if (self.isAutoHit && self.targetEnemy && enemies.includes(self.targetEnemy)) { // Auto-hit bullets home in on their target var dx = self.targetEnemy.x - self.x; var dy = self.targetEnemy.y - self.y; var dist = Math.hypot(dx, dy); // If we're very close to the enemy, hit it automatically if (dist < 30) { // Handle direct hit var destroyed = self.targetEnemy.takeDamage(self.damage); if (destroyed) { enemiesDefeated++; totalEnemiesDefeated++; LK.setScore(LK.getScore() + self.targetEnemy.scoreValue); scoreTxt.setText('Score: ' + LK.getScore()); self.targetEnemy.destroy(); enemies.splice(enemies.indexOf(self.targetEnemy), 1); } // Mark bullet for removal self.y = -100; // This will cause bullet to be removed in game.update } else { // Home in on the target with perfect tracking self.vx = dx / dist * self.speed * 1.5; self.vy = dy / dist * self.speed * 1.5; self.x += self.vx; self.y += self.vy; // Rotate bullet to face direction of travel self.rotation = Math.atan2(self.vy, self.vx); } } else if (self.hasCustomVelocity) { // Use vectorized movement if bullet has custom velocity self.x += self.vx; self.y += self.vy; // Rotate bullet to face direction of travel self.rotation = Math.atan2(self.vy, self.vx); } else { // Default upward movement self.y -= self.speed; } }; return self; }); var ClonePowerUp = Container.expand(function () { var self = Container.call(this); var powerUpGraphics = self.attachAsset('powerUp', { anchorX: 0.5, anchorY: 0.5, scaleX: 2, scaleY: 2 }); // Set to cyan color powerUpGraphics.tint = 0x00FFFF; self.speed = 2; self.update = function () { self.y += self.speed; // Pulse effect var scale = 2 + Math.sin(LK.ticks * 0.15) * 0.2; self.scale.set(scale, scale); }; return self; }); var Enemy = Container.expand(function () { var self = Container.call(this); self.health = 2; self.speed = 3 + Math.random() * 2; self.fireRate = 90 + Math.floor(Math.random() * 60); self.fireTimer = Math.floor(Math.random() * 60); self.scoreValue = 10; self.movingRight = Math.random() > 0.5; self.moveCounter = 0; self.moveChangeTime = 60 + Math.floor(Math.random() * 120); var enemyGraphics = self.attachAsset('enemyShip', { anchorX: 0.5, anchorY: 0.5 }); self.takeDamage = function (amount) { self.health -= amount; if (self.health <= 0) { // Chance to drop regular power up if (Math.random() < 0.15) { var powerUp = new PowerUp(); powerUp.x = self.x; powerUp.y = self.y; powerUps.push(powerUp); game.addChild(powerUp); } // Small chance to drop clone power up if (Math.random() < 0.05) { var clonePowerUp = new ClonePowerUp(); clonePowerUp.x = self.x; clonePowerUp.y = self.y; clonePowerUps.push(clonePowerUp); game.addChild(clonePowerUp); } // Explosion effect LK.effects.flashObject(self, 0xff0000, 300); LK.getSound('explosion').play(); return true; // Enemy is destroyed } else { // Flash red when taking damage LK.effects.flashObject(self, 0xff0000, 200); return false; } }; self.shoot = function () { if (self.fireTimer <= 0) { var bullet = new EnemyBullet(); bullet.x = self.x; bullet.y = self.y + 40; enemyBullets.push(bullet); game.addChild(bullet); LK.getSound('enemyShoot').play(); self.fireTimer = self.fireRate; } }; self.update = function () { // Basic movement pattern self.y += self.speed * 0.5; // Horizontal movement if (self.movingRight) { self.x += self.speed; } else { self.x -= self.speed; } // Reverse direction if reaching screen edges if (self.x < 100) { self.movingRight = true; } else if (self.x > 2048 - 100) { self.movingRight = false; } // Randomly change direction self.moveCounter++; if (self.moveCounter >= self.moveChangeTime) { self.movingRight = !self.movingRight; self.moveCounter = 0; } // Decrease fire timer and shoot self.fireTimer--; if (self.fireTimer <= 0) { self.shoot(); } }; return self; }); var EnemyBullet = Container.expand(function () { var self = Container.call(this); self.speed = 8; self.damage = 1; self.isPlayerBullet = false; var bulletGraphics = self.attachAsset('enemyBullet', { anchorX: 0.5, anchorY: 0.5 }); self.update = function () { self.y += self.speed; }; return self; }); var Mine = Container.expand(function () { var self = Container.call(this); self.speed = 4; self.damage = 15; self.isPlayerBullet = false; self.rotationSpeed = 0.05; var mineGraphics = self.attachAsset('enemyBullet', { anchorX: 0.5, anchorY: 0.5, scaleX: 2, scaleY: 2 }); mineGraphics.tint = 0xFF5500; self.update = function () { self.y += self.speed; self.rotation += self.rotationSpeed; // Slight wobble movement self.x += Math.sin(LK.ticks * 0.1) * 2; }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); self.health = 100; self.maxHealth = 100; self.speed = 10; self.fireRate = 15; self.fireTimer = 0; self.powerUpTimer = 0; self.hasPowerUp = false; self.invincible = false; self.invincibleTimer = 0; var playerGraphics = self.attachAsset('playerShip', { anchorX: 0.5, anchorY: 0.5 }); self.takeDamage = function (amount) { if (self.invincible) return; self.health -= amount; if (self.health <= 0) { self.health = 0; } else { // Flash player when taking damage self.invincible = true; self.invincibleTimer = 60; // 1 second invincibility LK.effects.flashObject(self, 0xff0000, 1000); LK.getSound('playerHit').play(); } }; self.shoot = function () { if (self.fireTimer <= 0) { var bullet = new Bullet(); bullet.x = self.x; bullet.y = self.y - 50; // If player has power up, enhance bullet if (self.hasPowerUp) { bullet.damage = 2; bullet.speed = 20; bullet.scale.set(1.5, 1.5); } bullets.push(bullet); game.addChild(bullet); LK.getSound('shoot').play(); self.fireTimer = self.fireRate; } }; self.update = function () { // Decrease fire timer if (self.fireTimer > 0) { self.fireTimer--; } // Handle power up timer if (self.hasPowerUp) { self.powerUpTimer--; if (self.powerUpTimer <= 0) { self.hasPowerUp = false; playerGraphics.tint = 0xFFFFFF; } } // Handle invincibility timer if (self.invincible) { self.invincibleTimer--; if (self.invincibleTimer <= 0) { self.invincible = false; } // Flicker effect during invincibility self.alpha = LK.ticks % 6 < 3 ? 0.7 : 1; } else { self.alpha = 1; } }; self.activatePowerUp = function () { self.hasPowerUp = true; self.powerUpTimer = 300; // 5 seconds playerGraphics.tint = 0x2ecc71; // Green tint when powered up LK.getSound('powerUpCollect').play(); }; return self; }); var PlayerClone = Container.expand(function () { var self = Container.call(this); self.health = 50; self.maxHealth = 50; self.target = null; self.speed = 2; // Super slow speed (was 8) self.fireRate = 80; // Even slower fire rate self.fireTimer = 0; // Create clone graphics (same as player but with different tint) var cloneGraphics = self.attachAsset('playerShip', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.7, scaleY: 0.7 }); cloneGraphics.tint = 0x00FFFF; // Cyan tint // Create health bar background self.healthBarBg = LK.getAsset('healthBarBackground', { anchorX: 0.5, anchorY: 0, scaleX: 0.3, scaleY: 0.3, y: -40 }); // Create health bar self.healthBar = LK.getAsset('healthBar', { anchorX: 0.5, anchorY: 0, scaleX: 0.3, scaleY: 0.3, y: -38 }); self.addChild(self.healthBarBg); self.addChild(self.healthBar); self.takeDamage = function (amount) { self.health -= amount; // Update health bar self.healthBar.scale.x = self.health / self.maxHealth * 0.3; if (self.health <= 0) { // Clone destruction effect LK.effects.flashObject(self, 0x00FFFF, 500); LK.getSound('playerHit').play(); return true; // Clone is destroyed } else { // Flash cyan when taking damage LK.effects.flashObject(self, 0x00FFFF, 200); return false; } }; self.shoot = function () { if (self.fireTimer <= 0) { // Shoot auto-hit bullets in 4 cardinal directions (up, down, left, right) for (var i = 0; i < 4; i++) { var angle = i * Math.PI / 2; // 90 degree increments (cardinal directions only) // Only shoot if there are enemies to hit if (enemies.length > 0) { // Find a random enemy to hit directly var targetEnemy = enemies[Math.floor(Math.random() * enemies.length)]; var bullet = new Bullet(); bullet.x = self.x; bullet.y = self.y; bullet.damage = 10; // More damage for auto-hit bullets bullet.isAutoHit = true; // Mark this as an auto-hit bullet bullet.targetEnemy = targetEnemy; // Store the target enemy bullet.speed = 20; bullet.scale.set(1.2, 1.2); // Set initial direction based on cardinal direction var dirX = Math.cos(angle); var dirY = Math.sin(angle); bullet.vx = dirX * bullet.speed; bullet.vy = dirY * bullet.speed; bullet.hasCustomVelocity = true; bullets.push(bullet); game.addChild(bullet); } } LK.getSound('shoot').play(); self.fireTimer = self.fireRate; // Slower fire rate } }; self.findTarget = function () { if (enemies.length > 0) { // Just find the closest enemy for movement purposes var closest = enemies[0]; var closestDist = Math.hypot(closest.x - self.x, closest.y - self.y); for (var i = 1; i < enemies.length; i++) { var dist = Math.hypot(enemies[i].x - self.x, enemies[i].y - self.y); if (dist < closestDist) { closest = enemies[i]; closestDist = dist; } } self.target = closest; } else { self.target = null; } }; self.update = function () { // Find a target if we don't have one or current target is destroyed if (!self.target || !enemies.includes(self.target)) { self.findTarget(); } // Always shoot if we can, regardless of position if (self.fireTimer <= 0) { self.shoot(); } // Move toward target if (self.target) { var dx = self.target.x - self.x; var dy = self.target.y - self.y; var dist = Math.hypot(dx, dy); // Update rotation to face the target self.rotation = Math.atan2(dy, dx); if (dist > 200) { // Move toward target if not too close - super slow! self.x += dx / dist * self.speed; self.y += dy / dist * self.speed; } else { // When close, just shoot (but don't try to get closer) // No need to call shoot here as we do it regardless now } } else { // No target, move back toward player var dx = player.x - self.x; var dy = player.y - 150 - self.y; var dist = Math.hypot(dx, dy); // Update rotation to face direction of movement if (dist > 10) { self.rotation = Math.atan2(dy, dx); } if (dist > 50) { self.x += dx / dist * self.speed; self.y += dy / dist * self.speed; } } // Decrease fire timer if (self.fireTimer > 0) { self.fireTimer--; } // Update health bar position self.healthBarBg.x = 0; self.healthBar.x = 0; }; 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.update = function () { self.y += self.speed; // Slight wobble effect self.x += Math.sin(LK.ticks * 0.1) * 1.5; // Pulse effect var scale = 1 + Math.sin(LK.ticks * 0.15) * 0.1; self.scale.set(scale, scale); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // Game state variables var gameActive = true; var player; var bullets = []; var enemies = []; var enemyBullets = []; var powerUps = []; var clonePowerUps = []; var playerClones = []; var waveNumber = 1; var enemiesThisWave = 5; var enemiesDefeated = 0; var totalEnemiesDefeated = 0; var waveDelay = 0; var spawnDelay = 0; var dragNode = null; var boss = null; var isBossWave = false; var clonePowerUpSpawnTimer = 0; // GUI elements var healthBar; var healthBarBg; var scoreTxt; var waveTxt; var signTxt; // Initialize game elements function initGame() { // Set background game.setBackgroundColor(0x0a0a2a); // Initialize player player = new Player(); player.x = 2048 / 2; player.y = 2732 - 300; game.addChild(player); // Create GUI elements createGUI(); // Start game gameActive = true; waveNumber = 1; enemiesThisWave = 5; enemiesDefeated = 0; totalEnemiesDefeated = 0; playerClones = []; clonePowerUps = []; LK.setScore(0); // Play background music LK.playMusic('bgMusic', { fade: { start: 0, end: 0.7, duration: 1000 } }); } function createGUI() { // Health bar background healthBarBg = LK.getAsset('healthBarBackground', { anchorX: 0, anchorY: 0, x: 20, y: 20 }); // Health bar healthBar = LK.getAsset('healthBar', { anchorX: 0, anchorY: 0, x: 25, y: 25 }); // Score text scoreTxt = new Text2('Score: 0', { size: 60, fill: 0xFFFFFF }); scoreTxt.anchor.set(1, 0); // Wave text waveTxt = new Text2('Wave: 1', { size: 60, fill: 0xFFFFFF }); waveTxt.anchor.set(0.5, 0); // Create sign signTxt = new Text2('cyan powerup = slow clone with auto-hit bullets!', { size: 80, fill: 0xFFFFFF }); signTxt.anchor.set(1, 1); // Add GUI elements LK.gui.topRight.addChild(scoreTxt); LK.gui.top.addChild(waveTxt); LK.gui.topLeft.addChild(healthBarBg); LK.gui.topLeft.addChild(healthBar); LK.gui.bottomRight.addChild(signTxt); } // Spawn a wave of enemies function spawnEnemyWave() { // Check if this is a boss wave (every 3 waves after wave 3) if (waveNumber >= 3 && (waveNumber - 3) % 3 === 0) { isBossWave = true; // Show boss warning message var bossWarning = new Text2('BOSS INCOMING!', { size: 120, fill: 0xFF0000 }); bossWarning.anchor.set(0.5, 0.5); LK.gui.center.addChild(bossWarning); // Fade out warning message tween(bossWarning, { alpha: 0 }, { duration: 2000, onFinish: function onFinish() { bossWarning.destroy(); // Spawn the boss if (!gameActive) return; boss = new Boss(); boss.x = 2048 / 2; boss.y = 200; enemies.push(boss); game.addChild(boss); } }); } else { isBossWave = false; // Regular enemy wave for (var i = 0; i < enemiesThisWave; i++) { // Set a delay for each enemy spawn LK.setTimeout(function () { if (!gameActive) return; var enemy = new Enemy(); enemy.x = 200 + Math.random() * (2048 - 400); enemy.y = -100 - Math.random() * 400; // Increase difficulty with each wave if (waveNumber > 1) { enemy.health += Math.floor(waveNumber / 2); enemy.speed += waveNumber * 0.2; enemy.scoreValue += waveNumber * 2; } enemies.push(enemy); game.addChild(enemy); }, i * 1000); } } } // Handle player movement function handleMove(x, y, obj) { if (dragNode && gameActive) { // Limit player movement to screen bounds var newX = Math.max(50, Math.min(2048 - 50, x)); var newY = Math.max(50, Math.min(2732 - 50, y)); dragNode.x = newX; dragNode.y = newY; } } // Game down handler game.down = function (x, y, obj) { if (gameActive) { dragNode = player; handleMove(x, y, obj); // Shoot when pressing down player.shoot(); } }; // Game move handler game.move = handleMove; // Game up handler game.up = function (x, y, obj) { dragNode = null; }; // Update game state game.update = function () { if (!gameActive) return; // Update player player.update(); // Auto-fire for player if (LK.ticks % 10 === 0) { player.shoot(); } // Update health bar healthBar.scale.x = player.health / player.maxHealth; // Update player clones for (var i = playerClones.length - 1; i >= 0; i--) { var clone = playerClones[i]; clone.update(); // Remove destroyed clones if (clone.health <= 0) { clone.destroy(); playerClones.splice(i, 1); } } // Update clone power-ups for (var i = clonePowerUps.length - 1; i >= 0; i--) { var clonePowerUp = clonePowerUps[i]; clonePowerUp.update(); // Remove power-ups that go off screen if (clonePowerUp.y > 2732 + 50) { clonePowerUp.destroy(); clonePowerUps.splice(i, 1); continue; } // Check for player collision if (gameActive && clonePowerUp.intersects(player)) { // Only create a new clone if we have less than 2 if (playerClones.length < 2) { // Create a new player clone var newClone = new PlayerClone(); newClone.x = player.x + 150; newClone.y = player.y - 150; playerClones.push(newClone); game.addChild(newClone); // Play power-up sound LK.getSound('powerUpCollect').play(); } else { // Flash player to indicate max clones reached LK.effects.flashObject(player, 0x00FFFF, 300); } // Remove the power-up clonePowerUp.destroy(); clonePowerUps.splice(i, 1); } } // Update bullets for (var i = bullets.length - 1; i >= 0; i--) { var bullet = bullets[i]; bullet.update(); // Remove bullets that go off screen if (bullet.y < -50) { bullet.destroy(); bullets.splice(i, 1); continue; } // Check for enemy collisions for (var j = enemies.length - 1; j >= 0; j--) { var enemy = enemies[j]; if (bullet.intersects(enemy)) { // Enemy takes damage var destroyed = enemy.takeDamage(bullet.damage); if (destroyed) { enemiesDefeated++; totalEnemiesDefeated++; LK.setScore(LK.getScore() + enemy.scoreValue); scoreTxt.setText('Score: ' + LK.getScore()); enemy.destroy(); enemies.splice(j, 1); } // Remove bullet bullet.destroy(); bullets.splice(i, 1); break; } } } // Update enemy bullets for (var i = enemyBullets.length - 1; i >= 0; i--) { var bullet = enemyBullets[i]; bullet.update(); // Remove bullets that go off screen if (bullet.y > 2732 + 50) { bullet.destroy(); enemyBullets.splice(i, 1); continue; } // Check for player collision if (gameActive && bullet.intersects(player)) { player.takeDamage(bullet.damage); bullet.destroy(); enemyBullets.splice(i, 1); // Check if player is defeated if (player.health <= 0) { gameActive = false; LK.showGameOver(); } continue; } // Check for clone collisions var cloneHit = false; for (var j = playerClones.length - 1; j >= 0; j--) { var clone = playerClones[j]; if (bullet.intersects(clone)) { var destroyed = clone.takeDamage(bullet.damage); if (destroyed) { clone.destroy(); playerClones.splice(j, 1); } bullet.destroy(); enemyBullets.splice(i, 1); cloneHit = true; break; } } if (cloneHit) continue; } // Update enemies for (var i = enemies.length - 1; i >= 0; i--) { var enemy = enemies[i]; enemy.update(); // Enemies die when they reach the bottom of the screen if (enemy.y > 2732 - 50) { // Grant score for the enemy LK.setScore(LK.getScore() + enemy.scoreValue); scoreTxt.setText('Score: ' + LK.getScore()); // Show explosion effect LK.effects.flashObject(enemy, 0xff0000, 300); LK.getSound('explosion').play(); // Remove the enemy enemy.destroy(); enemies.splice(i, 1); continue; } // Check for collision with player if (gameActive && enemy.intersects(player)) { player.takeDamage(10); // Destroy enemy on collision enemy.destroy(); enemies.splice(i, 1); // Check if player is defeated if (player.health <= 0) { gameActive = false; LK.showGameOver(); } } } // Update power-ups for (var i = powerUps.length - 1; i >= 0; i--) { var powerUp = powerUps[i]; powerUp.update(); // Remove power-ups that go off screen if (powerUp.y > 2732 + 50) { powerUp.destroy(); powerUps.splice(i, 1); continue; } // Check for player collision if (gameActive && powerUp.intersects(player)) { player.activatePowerUp(); powerUp.destroy(); powerUps.splice(i, 1); } } // Check if wave is complete - we simply need to check if enemies array is empty if (enemies.length === 0 && waveDelay <= 0) { // Start next wave waveNumber++; enemiesThisWave = 5 + waveNumber * 2; enemiesDefeated = 0; waveTxt.setText('Wave: ' + waveNumber); // Show wave message var waveMessage = new Text2('WAVE ' + waveNumber, { size: 120, fill: 0xFFFFFF }); waveMessage.anchor.set(0.5, 0.5); LK.gui.center.addChild(waveMessage); // Fade out wave message tween(waveMessage, { alpha: 0 }, { duration: 2000, onFinish: function onFinish() { waveMessage.destroy(); } }); // Set delay before spawning next wave waveDelay = 120; // 2 seconds } // Count down wave delay if (waveDelay > 0) { waveDelay--; if (waveDelay === 0) { // Spawn next wave spawnEnemyWave(); } } // Count down spawn delay if (spawnDelay > 0) { spawnDelay--; if (spawnDelay === 0) { // Start first wave spawnEnemyWave(); } } }; // Initialize the game initGame(); // Set a short delay before spawning the first wave spawnDelay = 60; // 1 second
/****
* 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);
self.health = 200;
self.maxHealth = 200;
self.speed = 4;
self.fireRate = 90;
self.fireTimer = 0;
self.mineFireRate = 180;
self.mineFireTimer = 60;
self.scoreValue = 500;
self.movingRight = true;
// Create boss graphics (larger enemy ship)
var bossGraphics = self.attachAsset('bossShip', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
// Create boss health bar background
self.healthBarBg = LK.getAsset('healthBarBackground', {
anchorX: 0.5,
anchorY: 0,
scaleX: 2,
scaleY: 1,
y: -100
});
// Create boss health bar
self.healthBar = LK.getAsset('healthBar', {
anchorX: 0.5,
anchorY: 0,
scaleX: 2,
scaleY: 1,
y: -95
});
self.addChild(self.healthBarBg);
self.addChild(self.healthBar);
self.takeDamage = function (amount) {
self.health -= amount;
// Update health bar
self.healthBar.scale.x = self.health / self.maxHealth * 2;
if (self.health <= 0) {
// Boss explosion effect - bigger and longer
LK.effects.flashObject(self, 0xff0000, 1000);
LK.getSound('explosion').play();
// Always spawn a clone power-up when boss is defeated
var clonePowerUp = new ClonePowerUp();
clonePowerUp.x = self.x;
clonePowerUp.y = self.y;
clonePowerUps.push(clonePowerUp);
game.addChild(clonePowerUp);
return true; // Boss is destroyed
} else {
// Flash red when taking damage
LK.effects.flashObject(self, 0xff0000, 200);
return false;
}
};
self.shootBullet = function () {
if (self.fireTimer <= 0) {
// Shoot multiple bullets in a spread pattern
for (var i = -2; i <= 2; i++) {
var bullet = new EnemyBullet();
bullet.x = self.x + i * 30;
bullet.y = self.y + 80;
enemyBullets.push(bullet);
game.addChild(bullet);
}
LK.getSound('enemyShoot').play();
self.fireTimer = self.fireRate;
}
};
self.shootMine = function () {
if (self.mineFireTimer <= 0) {
var mine = new Mine();
mine.x = self.x;
mine.y = self.y + 100;
enemyBullets.push(mine);
game.addChild(mine);
LK.getSound('enemyShoot').play();
self.mineFireTimer = self.mineFireRate;
}
};
self.update = function () {
// Basic movement pattern - side to side
if (self.movingRight) {
self.x += self.speed;
if (self.x > 2048 - 200) {
self.movingRight = false;
}
} else {
self.x -= self.speed;
if (self.x < 200) {
self.movingRight = true;
}
}
// Decrease fire timers
self.fireTimer--;
self.mineFireTimer--;
// Shoot regular bullets
if (self.fireTimer <= 0) {
self.shootBullet();
}
// Shoot mines
if (self.mineFireTimer <= 0) {
self.shootMine();
}
};
return self;
});
var Bullet = Container.expand(function () {
var self = Container.call(this);
self.speed = 15;
self.damage = 1;
self.isPlayerBullet = true;
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
if (self.isAutoHit && self.targetEnemy && enemies.includes(self.targetEnemy)) {
// Auto-hit bullets home in on their target
var dx = self.targetEnemy.x - self.x;
var dy = self.targetEnemy.y - self.y;
var dist = Math.hypot(dx, dy);
// If we're very close to the enemy, hit it automatically
if (dist < 30) {
// Handle direct hit
var destroyed = self.targetEnemy.takeDamage(self.damage);
if (destroyed) {
enemiesDefeated++;
totalEnemiesDefeated++;
LK.setScore(LK.getScore() + self.targetEnemy.scoreValue);
scoreTxt.setText('Score: ' + LK.getScore());
self.targetEnemy.destroy();
enemies.splice(enemies.indexOf(self.targetEnemy), 1);
}
// Mark bullet for removal
self.y = -100; // This will cause bullet to be removed in game.update
} else {
// Home in on the target with perfect tracking
self.vx = dx / dist * self.speed * 1.5;
self.vy = dy / dist * self.speed * 1.5;
self.x += self.vx;
self.y += self.vy;
// Rotate bullet to face direction of travel
self.rotation = Math.atan2(self.vy, self.vx);
}
} else if (self.hasCustomVelocity) {
// Use vectorized movement if bullet has custom velocity
self.x += self.vx;
self.y += self.vy;
// Rotate bullet to face direction of travel
self.rotation = Math.atan2(self.vy, self.vx);
} else {
// Default upward movement
self.y -= self.speed;
}
};
return self;
});
var ClonePowerUp = Container.expand(function () {
var self = Container.call(this);
var powerUpGraphics = self.attachAsset('powerUp', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
// Set to cyan color
powerUpGraphics.tint = 0x00FFFF;
self.speed = 2;
self.update = function () {
self.y += self.speed;
// Pulse effect
var scale = 2 + Math.sin(LK.ticks * 0.15) * 0.2;
self.scale.set(scale, scale);
};
return self;
});
var Enemy = Container.expand(function () {
var self = Container.call(this);
self.health = 2;
self.speed = 3 + Math.random() * 2;
self.fireRate = 90 + Math.floor(Math.random() * 60);
self.fireTimer = Math.floor(Math.random() * 60);
self.scoreValue = 10;
self.movingRight = Math.random() > 0.5;
self.moveCounter = 0;
self.moveChangeTime = 60 + Math.floor(Math.random() * 120);
var enemyGraphics = self.attachAsset('enemyShip', {
anchorX: 0.5,
anchorY: 0.5
});
self.takeDamage = function (amount) {
self.health -= amount;
if (self.health <= 0) {
// Chance to drop regular power up
if (Math.random() < 0.15) {
var powerUp = new PowerUp();
powerUp.x = self.x;
powerUp.y = self.y;
powerUps.push(powerUp);
game.addChild(powerUp);
}
// Small chance to drop clone power up
if (Math.random() < 0.05) {
var clonePowerUp = new ClonePowerUp();
clonePowerUp.x = self.x;
clonePowerUp.y = self.y;
clonePowerUps.push(clonePowerUp);
game.addChild(clonePowerUp);
}
// Explosion effect
LK.effects.flashObject(self, 0xff0000, 300);
LK.getSound('explosion').play();
return true; // Enemy is destroyed
} else {
// Flash red when taking damage
LK.effects.flashObject(self, 0xff0000, 200);
return false;
}
};
self.shoot = function () {
if (self.fireTimer <= 0) {
var bullet = new EnemyBullet();
bullet.x = self.x;
bullet.y = self.y + 40;
enemyBullets.push(bullet);
game.addChild(bullet);
LK.getSound('enemyShoot').play();
self.fireTimer = self.fireRate;
}
};
self.update = function () {
// Basic movement pattern
self.y += self.speed * 0.5;
// Horizontal movement
if (self.movingRight) {
self.x += self.speed;
} else {
self.x -= self.speed;
}
// Reverse direction if reaching screen edges
if (self.x < 100) {
self.movingRight = true;
} else if (self.x > 2048 - 100) {
self.movingRight = false;
}
// Randomly change direction
self.moveCounter++;
if (self.moveCounter >= self.moveChangeTime) {
self.movingRight = !self.movingRight;
self.moveCounter = 0;
}
// Decrease fire timer and shoot
self.fireTimer--;
if (self.fireTimer <= 0) {
self.shoot();
}
};
return self;
});
var EnemyBullet = Container.expand(function () {
var self = Container.call(this);
self.speed = 8;
self.damage = 1;
self.isPlayerBullet = false;
var bulletGraphics = self.attachAsset('enemyBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
self.y += self.speed;
};
return self;
});
var Mine = Container.expand(function () {
var self = Container.call(this);
self.speed = 4;
self.damage = 15;
self.isPlayerBullet = false;
self.rotationSpeed = 0.05;
var mineGraphics = self.attachAsset('enemyBullet', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
mineGraphics.tint = 0xFF5500;
self.update = function () {
self.y += self.speed;
self.rotation += self.rotationSpeed;
// Slight wobble movement
self.x += Math.sin(LK.ticks * 0.1) * 2;
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
self.health = 100;
self.maxHealth = 100;
self.speed = 10;
self.fireRate = 15;
self.fireTimer = 0;
self.powerUpTimer = 0;
self.hasPowerUp = false;
self.invincible = false;
self.invincibleTimer = 0;
var playerGraphics = self.attachAsset('playerShip', {
anchorX: 0.5,
anchorY: 0.5
});
self.takeDamage = function (amount) {
if (self.invincible) return;
self.health -= amount;
if (self.health <= 0) {
self.health = 0;
} else {
// Flash player when taking damage
self.invincible = true;
self.invincibleTimer = 60; // 1 second invincibility
LK.effects.flashObject(self, 0xff0000, 1000);
LK.getSound('playerHit').play();
}
};
self.shoot = function () {
if (self.fireTimer <= 0) {
var bullet = new Bullet();
bullet.x = self.x;
bullet.y = self.y - 50;
// If player has power up, enhance bullet
if (self.hasPowerUp) {
bullet.damage = 2;
bullet.speed = 20;
bullet.scale.set(1.5, 1.5);
}
bullets.push(bullet);
game.addChild(bullet);
LK.getSound('shoot').play();
self.fireTimer = self.fireRate;
}
};
self.update = function () {
// Decrease fire timer
if (self.fireTimer > 0) {
self.fireTimer--;
}
// Handle power up timer
if (self.hasPowerUp) {
self.powerUpTimer--;
if (self.powerUpTimer <= 0) {
self.hasPowerUp = false;
playerGraphics.tint = 0xFFFFFF;
}
}
// Handle invincibility timer
if (self.invincible) {
self.invincibleTimer--;
if (self.invincibleTimer <= 0) {
self.invincible = false;
}
// Flicker effect during invincibility
self.alpha = LK.ticks % 6 < 3 ? 0.7 : 1;
} else {
self.alpha = 1;
}
};
self.activatePowerUp = function () {
self.hasPowerUp = true;
self.powerUpTimer = 300; // 5 seconds
playerGraphics.tint = 0x2ecc71; // Green tint when powered up
LK.getSound('powerUpCollect').play();
};
return self;
});
var PlayerClone = Container.expand(function () {
var self = Container.call(this);
self.health = 50;
self.maxHealth = 50;
self.target = null;
self.speed = 2; // Super slow speed (was 8)
self.fireRate = 80; // Even slower fire rate
self.fireTimer = 0;
// Create clone graphics (same as player but with different tint)
var cloneGraphics = self.attachAsset('playerShip', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.7,
scaleY: 0.7
});
cloneGraphics.tint = 0x00FFFF; // Cyan tint
// Create health bar background
self.healthBarBg = LK.getAsset('healthBarBackground', {
anchorX: 0.5,
anchorY: 0,
scaleX: 0.3,
scaleY: 0.3,
y: -40
});
// Create health bar
self.healthBar = LK.getAsset('healthBar', {
anchorX: 0.5,
anchorY: 0,
scaleX: 0.3,
scaleY: 0.3,
y: -38
});
self.addChild(self.healthBarBg);
self.addChild(self.healthBar);
self.takeDamage = function (amount) {
self.health -= amount;
// Update health bar
self.healthBar.scale.x = self.health / self.maxHealth * 0.3;
if (self.health <= 0) {
// Clone destruction effect
LK.effects.flashObject(self, 0x00FFFF, 500);
LK.getSound('playerHit').play();
return true; // Clone is destroyed
} else {
// Flash cyan when taking damage
LK.effects.flashObject(self, 0x00FFFF, 200);
return false;
}
};
self.shoot = function () {
if (self.fireTimer <= 0) {
// Shoot auto-hit bullets in 4 cardinal directions (up, down, left, right)
for (var i = 0; i < 4; i++) {
var angle = i * Math.PI / 2; // 90 degree increments (cardinal directions only)
// Only shoot if there are enemies to hit
if (enemies.length > 0) {
// Find a random enemy to hit directly
var targetEnemy = enemies[Math.floor(Math.random() * enemies.length)];
var bullet = new Bullet();
bullet.x = self.x;
bullet.y = self.y;
bullet.damage = 10; // More damage for auto-hit bullets
bullet.isAutoHit = true; // Mark this as an auto-hit bullet
bullet.targetEnemy = targetEnemy; // Store the target enemy
bullet.speed = 20;
bullet.scale.set(1.2, 1.2);
// Set initial direction based on cardinal direction
var dirX = Math.cos(angle);
var dirY = Math.sin(angle);
bullet.vx = dirX * bullet.speed;
bullet.vy = dirY * bullet.speed;
bullet.hasCustomVelocity = true;
bullets.push(bullet);
game.addChild(bullet);
}
}
LK.getSound('shoot').play();
self.fireTimer = self.fireRate; // Slower fire rate
}
};
self.findTarget = function () {
if (enemies.length > 0) {
// Just find the closest enemy for movement purposes
var closest = enemies[0];
var closestDist = Math.hypot(closest.x - self.x, closest.y - self.y);
for (var i = 1; i < enemies.length; i++) {
var dist = Math.hypot(enemies[i].x - self.x, enemies[i].y - self.y);
if (dist < closestDist) {
closest = enemies[i];
closestDist = dist;
}
}
self.target = closest;
} else {
self.target = null;
}
};
self.update = function () {
// Find a target if we don't have one or current target is destroyed
if (!self.target || !enemies.includes(self.target)) {
self.findTarget();
}
// Always shoot if we can, regardless of position
if (self.fireTimer <= 0) {
self.shoot();
}
// Move toward target
if (self.target) {
var dx = self.target.x - self.x;
var dy = self.target.y - self.y;
var dist = Math.hypot(dx, dy);
// Update rotation to face the target
self.rotation = Math.atan2(dy, dx);
if (dist > 200) {
// Move toward target if not too close - super slow!
self.x += dx / dist * self.speed;
self.y += dy / dist * self.speed;
} else {
// When close, just shoot (but don't try to get closer)
// No need to call shoot here as we do it regardless now
}
} else {
// No target, move back toward player
var dx = player.x - self.x;
var dy = player.y - 150 - self.y;
var dist = Math.hypot(dx, dy);
// Update rotation to face direction of movement
if (dist > 10) {
self.rotation = Math.atan2(dy, dx);
}
if (dist > 50) {
self.x += dx / dist * self.speed;
self.y += dy / dist * self.speed;
}
}
// Decrease fire timer
if (self.fireTimer > 0) {
self.fireTimer--;
}
// Update health bar position
self.healthBarBg.x = 0;
self.healthBar.x = 0;
};
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.update = function () {
self.y += self.speed;
// Slight wobble effect
self.x += Math.sin(LK.ticks * 0.1) * 1.5;
// Pulse effect
var scale = 1 + Math.sin(LK.ticks * 0.15) * 0.1;
self.scale.set(scale, scale);
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Game state variables
var gameActive = true;
var player;
var bullets = [];
var enemies = [];
var enemyBullets = [];
var powerUps = [];
var clonePowerUps = [];
var playerClones = [];
var waveNumber = 1;
var enemiesThisWave = 5;
var enemiesDefeated = 0;
var totalEnemiesDefeated = 0;
var waveDelay = 0;
var spawnDelay = 0;
var dragNode = null;
var boss = null;
var isBossWave = false;
var clonePowerUpSpawnTimer = 0;
// GUI elements
var healthBar;
var healthBarBg;
var scoreTxt;
var waveTxt;
var signTxt;
// Initialize game elements
function initGame() {
// Set background
game.setBackgroundColor(0x0a0a2a);
// Initialize player
player = new Player();
player.x = 2048 / 2;
player.y = 2732 - 300;
game.addChild(player);
// Create GUI elements
createGUI();
// Start game
gameActive = true;
waveNumber = 1;
enemiesThisWave = 5;
enemiesDefeated = 0;
totalEnemiesDefeated = 0;
playerClones = [];
clonePowerUps = [];
LK.setScore(0);
// Play background music
LK.playMusic('bgMusic', {
fade: {
start: 0,
end: 0.7,
duration: 1000
}
});
}
function createGUI() {
// Health bar background
healthBarBg = LK.getAsset('healthBarBackground', {
anchorX: 0,
anchorY: 0,
x: 20,
y: 20
});
// Health bar
healthBar = LK.getAsset('healthBar', {
anchorX: 0,
anchorY: 0,
x: 25,
y: 25
});
// Score text
scoreTxt = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(1, 0);
// Wave text
waveTxt = new Text2('Wave: 1', {
size: 60,
fill: 0xFFFFFF
});
waveTxt.anchor.set(0.5, 0);
// Create sign
signTxt = new Text2('cyan powerup = slow clone with auto-hit bullets!', {
size: 80,
fill: 0xFFFFFF
});
signTxt.anchor.set(1, 1);
// Add GUI elements
LK.gui.topRight.addChild(scoreTxt);
LK.gui.top.addChild(waveTxt);
LK.gui.topLeft.addChild(healthBarBg);
LK.gui.topLeft.addChild(healthBar);
LK.gui.bottomRight.addChild(signTxt);
}
// Spawn a wave of enemies
function spawnEnemyWave() {
// Check if this is a boss wave (every 3 waves after wave 3)
if (waveNumber >= 3 && (waveNumber - 3) % 3 === 0) {
isBossWave = true;
// Show boss warning message
var bossWarning = new Text2('BOSS INCOMING!', {
size: 120,
fill: 0xFF0000
});
bossWarning.anchor.set(0.5, 0.5);
LK.gui.center.addChild(bossWarning);
// Fade out warning message
tween(bossWarning, {
alpha: 0
}, {
duration: 2000,
onFinish: function onFinish() {
bossWarning.destroy();
// Spawn the boss
if (!gameActive) return;
boss = new Boss();
boss.x = 2048 / 2;
boss.y = 200;
enemies.push(boss);
game.addChild(boss);
}
});
} else {
isBossWave = false;
// Regular enemy wave
for (var i = 0; i < enemiesThisWave; i++) {
// Set a delay for each enemy spawn
LK.setTimeout(function () {
if (!gameActive) return;
var enemy = new Enemy();
enemy.x = 200 + Math.random() * (2048 - 400);
enemy.y = -100 - Math.random() * 400;
// Increase difficulty with each wave
if (waveNumber > 1) {
enemy.health += Math.floor(waveNumber / 2);
enemy.speed += waveNumber * 0.2;
enemy.scoreValue += waveNumber * 2;
}
enemies.push(enemy);
game.addChild(enemy);
}, i * 1000);
}
}
}
// Handle player movement
function handleMove(x, y, obj) {
if (dragNode && gameActive) {
// Limit player movement to screen bounds
var newX = Math.max(50, Math.min(2048 - 50, x));
var newY = Math.max(50, Math.min(2732 - 50, y));
dragNode.x = newX;
dragNode.y = newY;
}
}
// Game down handler
game.down = function (x, y, obj) {
if (gameActive) {
dragNode = player;
handleMove(x, y, obj);
// Shoot when pressing down
player.shoot();
}
};
// Game move handler
game.move = handleMove;
// Game up handler
game.up = function (x, y, obj) {
dragNode = null;
};
// Update game state
game.update = function () {
if (!gameActive) return;
// Update player
player.update();
// Auto-fire for player
if (LK.ticks % 10 === 0) {
player.shoot();
}
// Update health bar
healthBar.scale.x = player.health / player.maxHealth;
// Update player clones
for (var i = playerClones.length - 1; i >= 0; i--) {
var clone = playerClones[i];
clone.update();
// Remove destroyed clones
if (clone.health <= 0) {
clone.destroy();
playerClones.splice(i, 1);
}
}
// Update clone power-ups
for (var i = clonePowerUps.length - 1; i >= 0; i--) {
var clonePowerUp = clonePowerUps[i];
clonePowerUp.update();
// Remove power-ups that go off screen
if (clonePowerUp.y > 2732 + 50) {
clonePowerUp.destroy();
clonePowerUps.splice(i, 1);
continue;
}
// Check for player collision
if (gameActive && clonePowerUp.intersects(player)) {
// Only create a new clone if we have less than 2
if (playerClones.length < 2) {
// Create a new player clone
var newClone = new PlayerClone();
newClone.x = player.x + 150;
newClone.y = player.y - 150;
playerClones.push(newClone);
game.addChild(newClone);
// Play power-up sound
LK.getSound('powerUpCollect').play();
} else {
// Flash player to indicate max clones reached
LK.effects.flashObject(player, 0x00FFFF, 300);
}
// Remove the power-up
clonePowerUp.destroy();
clonePowerUps.splice(i, 1);
}
}
// Update bullets
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
bullet.update();
// Remove bullets that go off screen
if (bullet.y < -50) {
bullet.destroy();
bullets.splice(i, 1);
continue;
}
// Check for enemy collisions
for (var j = enemies.length - 1; j >= 0; j--) {
var enemy = enemies[j];
if (bullet.intersects(enemy)) {
// Enemy takes damage
var destroyed = enemy.takeDamage(bullet.damage);
if (destroyed) {
enemiesDefeated++;
totalEnemiesDefeated++;
LK.setScore(LK.getScore() + enemy.scoreValue);
scoreTxt.setText('Score: ' + LK.getScore());
enemy.destroy();
enemies.splice(j, 1);
}
// Remove bullet
bullet.destroy();
bullets.splice(i, 1);
break;
}
}
}
// Update enemy bullets
for (var i = enemyBullets.length - 1; i >= 0; i--) {
var bullet = enemyBullets[i];
bullet.update();
// Remove bullets that go off screen
if (bullet.y > 2732 + 50) {
bullet.destroy();
enemyBullets.splice(i, 1);
continue;
}
// Check for player collision
if (gameActive && bullet.intersects(player)) {
player.takeDamage(bullet.damage);
bullet.destroy();
enemyBullets.splice(i, 1);
// Check if player is defeated
if (player.health <= 0) {
gameActive = false;
LK.showGameOver();
}
continue;
}
// Check for clone collisions
var cloneHit = false;
for (var j = playerClones.length - 1; j >= 0; j--) {
var clone = playerClones[j];
if (bullet.intersects(clone)) {
var destroyed = clone.takeDamage(bullet.damage);
if (destroyed) {
clone.destroy();
playerClones.splice(j, 1);
}
bullet.destroy();
enemyBullets.splice(i, 1);
cloneHit = true;
break;
}
}
if (cloneHit) continue;
}
// Update enemies
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
enemy.update();
// Enemies die when they reach the bottom of the screen
if (enemy.y > 2732 - 50) {
// Grant score for the enemy
LK.setScore(LK.getScore() + enemy.scoreValue);
scoreTxt.setText('Score: ' + LK.getScore());
// Show explosion effect
LK.effects.flashObject(enemy, 0xff0000, 300);
LK.getSound('explosion').play();
// Remove the enemy
enemy.destroy();
enemies.splice(i, 1);
continue;
}
// Check for collision with player
if (gameActive && enemy.intersects(player)) {
player.takeDamage(10);
// Destroy enemy on collision
enemy.destroy();
enemies.splice(i, 1);
// Check if player is defeated
if (player.health <= 0) {
gameActive = false;
LK.showGameOver();
}
}
}
// Update power-ups
for (var i = powerUps.length - 1; i >= 0; i--) {
var powerUp = powerUps[i];
powerUp.update();
// Remove power-ups that go off screen
if (powerUp.y > 2732 + 50) {
powerUp.destroy();
powerUps.splice(i, 1);
continue;
}
// Check for player collision
if (gameActive && powerUp.intersects(player)) {
player.activatePowerUp();
powerUp.destroy();
powerUps.splice(i, 1);
}
}
// Check if wave is complete - we simply need to check if enemies array is empty
if (enemies.length === 0 && waveDelay <= 0) {
// Start next wave
waveNumber++;
enemiesThisWave = 5 + waveNumber * 2;
enemiesDefeated = 0;
waveTxt.setText('Wave: ' + waveNumber);
// Show wave message
var waveMessage = new Text2('WAVE ' + waveNumber, {
size: 120,
fill: 0xFFFFFF
});
waveMessage.anchor.set(0.5, 0.5);
LK.gui.center.addChild(waveMessage);
// Fade out wave message
tween(waveMessage, {
alpha: 0
}, {
duration: 2000,
onFinish: function onFinish() {
waveMessage.destroy();
}
});
// Set delay before spawning next wave
waveDelay = 120; // 2 seconds
}
// Count down wave delay
if (waveDelay > 0) {
waveDelay--;
if (waveDelay === 0) {
// Spawn next wave
spawnEnemyWave();
}
}
// Count down spawn delay
if (spawnDelay > 0) {
spawnDelay--;
if (spawnDelay === 0) {
// Start first wave
spawnEnemyWave();
}
}
};
// Initialize the game
initGame();
// Set a short delay before spawning the first wave
spawnDelay = 60; // 1 second