/**** * 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 bossGraphics = self.attachAsset('boss', { anchorX: 0.5, anchorY: 0.5 }); self.health = 20; self.maxHealth = 20; self.points = 2000; self.speed = 1; self.phase = 1; self.fireRate = 60; // Frames between shots self.lastShot = 0; self.movementTimer = 0; self.attacking = false; self.update = function () { // Boss enters from top if (self.y < 400) { self.y += self.speed; } else { self.attacking = true; // Phase-based movement if (self.phase === 1) { // Side-to-side movement self.x += Math.sin(self.movementTimer / 30) * 5; self.movementTimer++; // Regular shooting self.lastShot++; if (self.lastShot >= self.fireRate) { self.shoot(); self.lastShot = 0; } } else if (self.phase === 2) { // More aggressive movement self.x += Math.sin(self.movementTimer / 20) * 7; self.y += Math.cos(self.movementTimer / 40) * 2; self.movementTimer++; // More frequent shooting self.lastShot++; if (self.lastShot >= self.fireRate * 0.7) { self.shoot(); self.lastShot = 0; } } else if (self.phase === 3) { // Erratic movement self.x += Math.sin(self.movementTimer / 10) * 8; self.y += Math.cos(self.movementTimer / 15) * 3; self.movementTimer++; // Rapid shooting self.lastShot++; if (self.lastShot >= self.fireRate * 0.4) { self.shoot(); self.lastShot = 0; } } } // Change phase based on health with enhanced visual feedback if (self.health <= self.maxHealth * 0.65 && self.phase === 1) { self.phase = 2; LK.effects.flashObject(self, 0xff0000, 500); // Add dramatic phase change effect bossGraphics.tint = 0xff6600; // Change to orange glow // Create multiple explosions around boss for (var i = 0; i < 3; i++) { var damageExplosion = new Explosion(); damageExplosion.x = self.x + (Math.random() * 120 - 60); damageExplosion.y = self.y + (Math.random() * 80 - 40); game.addChild(damageExplosion); } } else if (self.health <= self.maxHealth * 0.3 && self.phase === 2) { self.phase = 3; LK.effects.flashObject(self, 0xff0000, 500); // More dramatic effect for final phase bossGraphics.tint = 0xff0000; // Change to red glow bossGraphics.scale.x = 1.1; // Slightly expand bossGraphics.scale.y = 1.1; // Create more explosions for critical damage for (var i = 0; i < 5; i++) { var damageExplosion = new Explosion(); damageExplosion.x = self.x + (Math.random() * 160 - 80); damageExplosion.y = self.y + (Math.random() * 100 - 50); game.addChild(damageExplosion); } } }; self.shoot = function () { // Different shot patterns based on phase if (self.phase === 1) { // Single shot var bullet = new EnemyBullet(); bullet.x = self.x; bullet.y = self.y + 80; game.addChild(bullet); enemyBullets.push(bullet); } else if (self.phase === 2) { // Double shot for (var i = -1; i <= 1; i += 2) { var bullet = new EnemyBullet(); bullet.x = self.x + i * 50; bullet.y = self.y + 80; game.addChild(bullet); enemyBullets.push(bullet); } } else if (self.phase === 3) { // Triple shot for (var i = -1; i <= 1; i++) { var bullet = new EnemyBullet(); bullet.x = self.x + i * 50; bullet.y = self.y + 80; game.addChild(bullet); enemyBullets.push(bullet); } } LK.getSound('enemyShoot').play(); }; self.takeDamage = function (amount) { self.health -= amount; // Flash when taking damage LK.effects.flashObject(self, 0xffffff, 200); if (self.health <= 0) { // Multiple explosions for boss for (var i = 0; i < 5; i++) { var explosion = new Explosion(); explosion.x = self.x + (Math.random() * 200 - 100); explosion.y = self.y + (Math.random() * 100 - 50); game.addChild(explosion); } // Add points to score score += self.points; updateScore(); // Boss drops multiple power-ups // Drop advanced weapon power-up based on level var weaponPowerUp = new PowerUp(); weaponPowerUp.x = self.x - 60; weaponPowerUp.y = self.y; if (level >= 3) { weaponPowerUp.setType("plasma"); } else { weaponPowerUp.setType("laser"); } game.addChild(weaponPowerUp); powerUps.push(weaponPowerUp); // Drop shield power-up var shieldPowerUp = new PowerUp(); shieldPowerUp.x = self.x + 60; shieldPowerUp.y = self.y; shieldPowerUp.setType("shield"); game.addChild(shieldPowerUp); powerUps.push(shieldPowerUp); LK.getSound('explosion').play(); // Level complete levelComplete = true; self.destroy(); return true; } return false; }; return self; }); var Enemy = Container.expand(function () { var self = Container.call(this); var enemyGraphics = self.attachAsset('enemyShip', { anchorX: 0.5, anchorY: 0.5 }); self.health = 1; self.points = 100; self.speed = 2; self.fireRate = 180; // Frames between shots self.lastShot = 0; self.movementPattern = "straight"; // Default movement self.movementTimer = 0; self.update = function () { // Handle movement patterns if (self.movementPattern === "straight") { self.y += self.speed; } else if (self.movementPattern === "zigzag") { self.y += self.speed; self.x += Math.sin(self.movementTimer / 20) * 3; self.movementTimer++; } else if (self.movementPattern === "circle") { self.y += self.speed * 0.7; self.x += Math.sin(self.movementTimer / 15) * 4; self.movementTimer++; } // Shooting logic self.lastShot++; if (self.lastShot >= self.fireRate && self.y > 0 && Math.random() < 0.3) { self.shoot(); self.lastShot = 0; } }; self.shoot = function () { var bullet = new EnemyBullet(); bullet.x = self.x; bullet.y = self.y + 40; game.addChild(bullet); enemyBullets.push(bullet); LK.getSound('enemyShoot').play(); }; self.takeDamage = function (amount) { self.health -= amount; if (self.health <= 0) { // Create explosion var explosion = new Explosion(); explosion.x = self.x; explosion.y = self.y; game.addChild(explosion); // Add points to score score += self.points; updateScore(); // Random chance to drop power-up if (Math.random() < 0.1) { var powerUp = new PowerUp(); powerUp.x = self.x; powerUp.y = self.y; // Random power-up type var rand = Math.random(); if (rand < 0.5) { powerUp.setType("weapon"); } else if (rand < 0.8) { powerUp.setType("shield"); } else if (level >= 2) { // Special weapon drops in higher levels if (level >= 3 && rand < 0.9) { powerUp.setType("plasma"); } else { powerUp.setType("laser"); } } game.addChild(powerUp); powerUps.push(powerUp); } LK.getSound('explosion').play(); self.destroy(); return true; } return false; }; return self; }); var ScoutShip = Enemy.expand(function () { var self = Enemy.call(this); // Replace default graphics with scout ship graphics self.removeChild(self.children[0]); var shipGraphics = self.attachAsset('scoutShip', { anchorX: 0.5, anchorY: 0.5 }); // Set scout-specific properties self.health = 1; self.points = 150; self.speed = 4; // Faster movement self.fireRate = 240; // Shoots less frequently self.movementPattern = "erratic"; // Override update method for erratic movement var originalUpdate = self.update; self.update = function () { if (self.movementPattern === "erratic") { self.y += self.speed; self.x += Math.sin(self.movementTimer / 10) * 6; self.movementTimer++; } else { // Use original update for other movement patterns originalUpdate.call(self); } // Handle shooting with lower probability self.lastShot++; if (self.lastShot >= self.fireRate && self.y > 0 && Math.random() < 0.2) { self.shoot(); self.lastShot = 0; } }; return self; }); var EliteScoutShip = ScoutShip.expand(function () { var self = ScoutShip.call(this); // Replace graphics with recolored version self.removeChild(self.children[0]); var shipGraphics = self.attachAsset('scoutShip', { anchorX: 0.5, anchorY: 0.5, tint: 0x33ffff, scaleX: 1.3, scaleY: 1.3 }); // Enhanced elite properties self.health = 3; self.points = 350; self.speed = 6; // Even faster // Override update for more complex movement var originalUpdate = self.update; self.update = function () { // Teleport-like rapid movement changes if (LK.ticks % 90 === 0 && self.y > 200) { // Create a flicker effect before "teleporting" shipGraphics.alpha = 0.5; // Schedule the "teleport" LK.setTimeout(function () { // Random new position self.x = 300 + Math.random() * (2048 - 600); shipGraphics.alpha = 1; // Create visual effect at new position var flashEffect = new Explosion(); flashEffect.x = self.x; flashEffect.y = self.y; game.addChild(flashEffect); }, 20); } // Use original movement pattern with more extreme values self.y += self.speed; self.x += Math.sin(self.movementTimer / 8) * 8; self.movementTimer++; // Fire more bullets in a spread pattern self.lastShot++; if (self.lastShot >= self.fireRate && self.y > 0 && Math.random() < 0.3) { // Triple spread shot for (var i = -1; i <= 1; i++) { var bullet = new EnemyBullet(); bullet.x = self.x + i * 20; bullet.y = self.y + 40; // Angled shots var angle = Math.PI / 2 + i * 0.3; bullet.speedX = Math.cos(angle) * 10; bullet.speedY = Math.sin(angle) * 10; // Override update for angled movement bullet.update = function () { this.x += this.speedX; this.y += this.speedY; }; game.addChild(bullet); enemyBullets.push(bullet); } LK.getSound('enemyShoot').play(); self.lastShot = 0; } }; return self; }); var HunterShip = Enemy.expand(function () { var self = Enemy.call(this); // Replace default graphics with hunter ship graphics self.removeChild(self.children[0]); var shipGraphics = self.attachAsset('hunterShip', { anchorX: 0.5, anchorY: 0.5 }); // Set hunter-specific properties self.health = 3; self.points = 250; self.speed = 3; self.fireRate = 100; // Fires more frequently self.movementPattern = "pursuit"; // New movement pattern that follows player // Override update method to add pursuit behavior var originalUpdate = self.update; self.update = function () { if (self.movementPattern === "pursuit") { // Move towards player's x position if (player.x > self.x) { self.x += Math.min(self.speed * 0.7, player.x - self.x); } else if (player.x < self.x) { self.x -= Math.min(self.speed * 0.7, self.x - player.x); } self.y += self.speed * 0.8; } else { // Use original update for other movement patterns originalUpdate.call(self); } // Handle shooting regardless of movement pattern self.lastShot++; if (self.lastShot >= self.fireRate && self.y > 0 && Math.random() < 0.4) { self.shoot(); self.lastShot = 0; } }; return self; }); var EliteHunterShip = HunterShip.expand(function () { var self = HunterShip.call(this); // Replace graphics with recolored version self.removeChild(self.children[0]); var shipGraphics = self.attachAsset('hunterShip', { anchorX: 0.5, anchorY: 0.5, tint: 0xff3300, scaleX: 1.2, scaleY: 1.2 }); // Enhanced elite properties self.health = 5; self.points = 500; self.speed = 4; self.fireRate = 70; // Override update for more aggressive behavior var originalUpdate = self.update; self.update = function () { if (self.movementPattern === "pursuit") { // More aggressive pursuit var targetX = player.x; var dx = targetX - self.x; self.x += dx * 0.05; // More precise tracking self.y += self.speed * 0.9; // Rotate slightly toward movement direction shipGraphics.rotation = dx * 0.003; } else { originalUpdate.call(self); } // More frequent shooting with double bullets self.lastShot++; if (self.lastShot >= self.fireRate && self.y > 0 && Math.random() < 0.5) { self.shoot(); // Add slight delay for second shot LK.setTimeout(function () { self.shoot(); }, 10); self.lastShot = 0; } }; return self; }); var CarrierShip = Enemy.expand(function () { var self = Enemy.call(this); // Replace default graphics with carrier ship graphics self.removeChild(self.children[0]); var shipGraphics = self.attachAsset('carrierShip', { anchorX: 0.5, anchorY: 0.5 }); // Set carrier-specific properties self.health = 5; self.points = 400; self.speed = 1; // Slower movement self.fireRate = 200; self.lastSpawn = 0; // Timer for spawning small ships self.spawnRate = 180; // How often to spawn small ships // Override update method to add spawning behavior var originalUpdate = self.update; self.update = function () { originalUpdate.call(self); // Spawn small scout ships periodically self.lastSpawn++; if (self.lastSpawn >= self.spawnRate && self.y > 100 && self.y < 1000) { self.spawnScout(); self.lastSpawn = 0; } }; // Method to spawn a scout ship self.spawnScout = function () { var scout = new ScoutShip(); scout.x = self.x; scout.y = self.y + 50; game.addChild(scout); enemies.push(scout); }; // Override takeDamage to drop power-ups more often var originalTakeDamage = self.takeDamage; self.takeDamage = function (amount) { if (originalTakeDamage.call(self, amount)) { // If ship was destroyed and original method returned true // Carriers have a higher chance to drop power-ups (40%) if (Math.random() < 0.4) { var powerUp = new PowerUp(); powerUp.x = self.x; powerUp.y = self.y; // Random power-up type with better odds for weapon power-ups var rand = Math.random(); if (rand < 0.7) { powerUp.type = "weapon"; } else { powerUp.type = "shield"; } game.addChild(powerUp); powerUps.push(powerUp); } return true; } return false; }; 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 = 10; self.damage = 1; self.update = function () { self.y += self.speed; }; return self; }); var Explosion = Container.expand(function () { var self = Container.call(this); var explosionGraphics = self.attachAsset('explosion', { anchorX: 0.5, anchorY: 0.5, alpha: 0.9 }); self.lifetime = 30; // frames self.update = function () { self.lifetime--; // Scale up and fade out with improved effects explosionGraphics.scale.x = 1 + (30 - self.lifetime) / 12; explosionGraphics.scale.y = 1 + (30 - self.lifetime) / 12; explosionGraphics.alpha = self.lifetime / 30; explosionGraphics.rotation += 0.05; // Add rotation for more dynamic effect // Add pulsing glow effect if (self.lifetime % 3 === 0) { explosionGraphics.tint = 0xffcc00; // Original color } else if (self.lifetime % 3 === 1) { explosionGraphics.tint = 0xff6600; // Orange } else { explosionGraphics.tint = 0xff2200; // Red-orange } if (self.lifetime <= 0) { self.destroy(); } }; return self; }); var LaserBullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('laserBullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -20; // Faster than regular bullets self.damage = 2; // More damage self.update = function () { self.y += self.speed; // Add laser trail effect if (LK.ticks % 3 === 0) { var trailEffect = LK.getAsset('laserBullet', { anchorX: 0.5, anchorY: 0.5, alpha: 0.5, scaleX: 0.7, scaleY: 0.7 }); trailEffect.x = self.x; trailEffect.y = self.y + 15; game.addChild(trailEffect); // Create a simple fade-out animation var trailDuration = 10; var fadeInterval = LK.setInterval(function () { trailDuration--; trailEffect.alpha -= 0.05; trailEffect.scaleX -= 0.05; trailEffect.scaleY -= 0.05; if (trailDuration <= 0) { LK.clearInterval(fadeInterval); trailEffect.destroy(); } }, 1); } // Add pulsing glow effect var time = LK.ticks % 10; bulletGraphics.tint = time < 5 ? 0x00ffaa : 0x00ddaa; }; return self; }); var MegaBoss = Container.expand(function () { var self = Container.call(this); var bossGraphics = self.attachAsset('boss', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.8, scaleY: 1.8, tint: 0xff3300 }); self.health = 50; self.maxHealth = 50; self.points = 5000; self.speed = 0.8; self.phase = 1; self.fireRate = 45; // Faster than normal boss self.lastShot = 0; self.specialAttackTimer = 0; self.movementTimer = 0; self.attacking = false; // Create energy shield effect var shieldGraphics = LK.getAsset('shieldEffect', { anchorX: 0.5, anchorY: 0.5, alpha: 0.3, scaleX: 2.2, scaleY: 2.2, tint: 0xff6600 }); self.addChild(shieldGraphics); self.update = function () { // Boss enters from top if (self.y < 500) { self.y += self.speed; } else { self.attacking = true; // Phase-based movement and attacks if (self.phase === 1) { // Phase 1: Circular movement self.x = 2048 / 2 + Math.sin(self.movementTimer / 40) * 500; self.y = 500 + Math.cos(self.movementTimer / 40) * 200; self.movementTimer++; // Regular shooting self.lastShot++; if (self.lastShot >= self.fireRate) { self.shootSpread(3, 20); // 3 bullets in spread self.lastShot = 0; } } else if (self.phase === 2) { // Phase 2: Figure-8 movement self.x = 2048 / 2 + Math.sin(self.movementTimer / 50) * 400; self.y = 500 + Math.sin(self.movementTimer / 25) * 150; self.movementTimer++; // More frequent shooting self.lastShot++; if (self.lastShot >= self.fireRate * 0.6) { self.shootSpread(5, 15); // 5 bullets in spread self.lastShot = 0; } // Special attack: summon enemies self.specialAttackTimer++; if (self.specialAttackTimer >= 300) { // Every 5 seconds self.summonMinions(); self.specialAttackTimer = 0; } } else if (self.phase === 3) { // Phase 3: Erratic movement self.x += Math.sin(self.movementTimer / 10) * 12; self.y = 400 + Math.sin(self.movementTimer / 5) * 100; self.movementTimer++; // Rapid shooting with pattern self.lastShot++; if (self.lastShot >= self.fireRate * 0.3) { if (self.lastShot % 3 === 0) { self.shootCircle(8); // Circle of 8 bullets } else { self.shootSpread(3, 30); // 3 bullets in spread } self.lastShot = 0; } // Special attack: laser beam self.specialAttackTimer++; if (self.specialAttackTimer >= 240) { // Every 4 seconds self.firingLaser = true; self.fireLaserBeam(); self.specialAttackTimer = 0; } } // Shield effect animation shieldGraphics.rotation += 0.02; shieldGraphics.alpha = 0.2 + Math.sin(LK.ticks / 10) * 0.1; } // Change phase based on health if (self.health <= self.maxHealth * 0.65 && self.phase === 1) { self.phase = 2; LK.effects.flashObject(self, 0xff0000, 800); bossGraphics.tint = 0xff4400; // Create explosion effects for (var i = 0; i < 5; i++) { var damageExplosion = new Explosion(); damageExplosion.x = self.x + (Math.random() * 150 - 75); damageExplosion.y = self.y + (Math.random() * 150 - 75); game.addChild(damageExplosion); } } else if (self.health <= self.maxHealth * 0.3 && self.phase === 2) { self.phase = 3; LK.effects.flashObject(self, 0xff0000, 1000); bossGraphics.tint = 0xff0000; bossGraphics.scale.x = 1.3; bossGraphics.scale.y = 1.3; // More dramatic explosions for (var i = 0; i < 8; i++) { var damageExplosion = new Explosion(); damageExplosion.x = self.x + (Math.random() * 200 - 100); damageExplosion.y = self.y + (Math.random() * 200 - 100); game.addChild(damageExplosion); } } }; self.shootSpread = function (count, angle) { var spreadAngle = angle * (Math.PI / 180); var startAngle = Math.PI / 2 - spreadAngle / 2; var angleStep = spreadAngle / (count - 1); for (var i = 0; i < count; i++) { var bullet = new EnemyBullet(); var currentAngle = startAngle + angleStep * i; bullet.x = self.x; bullet.y = self.y + 80; bullet.speedX = Math.cos(currentAngle) * 8; bullet.speedY = Math.sin(currentAngle) * 8; // Override update method for angled movement bullet.update = function () { this.x += this.speedX; this.y += this.speedY; }; game.addChild(bullet); enemyBullets.push(bullet); } LK.getSound('enemyShoot').play(); }; self.shootCircle = function (count) { var angleStep = Math.PI * 2 / count; for (var i = 0; i < count; i++) { var bullet = new EnemyBullet(); var currentAngle = angleStep * i; bullet.x = self.x; bullet.y = self.y; bullet.speedX = Math.cos(currentAngle) * 7; bullet.speedY = Math.sin(currentAngle) * 7; // Override update method for circular pattern bullet.update = function () { this.x += this.speedX; this.y += this.speedY; }; game.addChild(bullet); enemyBullets.push(bullet); } LK.getSound('enemyShoot').play(); }; self.summonMinions = function () { // Spawn 2-3 smaller enemies var count = 2 + Math.floor(Math.random() * 2); for (var i = 0; i < count; i++) { var enemy; if (Math.random() < 0.5) { enemy = new ScoutShip(); } else { enemy = new HunterShip(); } enemy.x = self.x + (Math.random() * 300 - 150); enemy.y = self.y + 100; game.addChild(enemy); enemies.push(enemy); // Visual effect for spawning var spawnEffect = new Explosion(); spawnEffect.x = enemy.x; spawnEffect.y = enemy.y; game.addChild(spawnEffect); } }; self.fireLaserBeam = function () { // Visual effect for charging laser var chargeEffect = new Explosion(); chargeEffect.x = self.x; chargeEffect.y = self.y + 50; game.addChild(chargeEffect); // Create laser beam after short delay LK.setTimeout(function () { var laserBeam = new Container(); var laserGraphics = LK.getAsset('laserBullet', { anchorX: 0.5, anchorY: 0, scaleX: 8, scaleY: 30, tint: 0xff3300 }); laserBeam.addChild(laserGraphics); laserBeam.x = self.x; laserBeam.y = self.y + 80; game.addChild(laserBeam); // Damage player if in path of laser if (Math.abs(player.x - self.x) < 150) { player.takeDamage(2); } // Remove laser after a short time LK.setTimeout(function () { laserBeam.destroy(); self.firingLaser = false; }, 1000); }, 500); }; self.takeDamage = function (amount) { self.health -= amount; LK.effects.flashObject(self, 0xffffff, 200); if (self.health <= 0) { // Multiple explosions for boss death for (var i = 0; i < 12; i++) { var explosion = new Explosion(); explosion.x = self.x + (Math.random() * 300 - 150); explosion.y = self.y + (Math.random() * 200 - 100); game.addChild(explosion); // Stagger explosions LK.setTimeout(function () { var delayedExplosion = new Explosion(); delayedExplosion.x = self.x + (Math.random() * 300 - 150); delayedExplosion.y = self.y + (Math.random() * 200 - 100); game.addChild(delayedExplosion); }, 100 + i * 100); } // Add points to score score += self.points; updateScore(); // Drop multiple power-ups for (var i = 0; i < 3; i++) { var powerUp = new PowerUp(); powerUp.x = self.x + (i - 1) * 80; powerUp.y = self.y; if (i === 0) { powerUp.setType("shield"); } else if (i === 1) { powerUp.setType("ultra"); } else { powerUp.setType("plasma"); } game.addChild(powerUp); powerUps.push(powerUp); } LK.getSound('explosion').play(); levelComplete = true; self.destroy(); return true; } return false; }; return self; }); var PlasmaBullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('plasmaBullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -12; // Medium speed self.damage = 3; // Highest damage // Add pulsating effect self.pulseFactor = 0; self.update = function () { self.y += self.speed; // Enhanced pulsating effect with rotation self.pulseFactor += 0.1; var scale = 1 + Math.sin(self.pulseFactor) * 0.2; bulletGraphics.scale.x = scale; bulletGraphics.scale.y = scale; bulletGraphics.rotation += 0.1; // Add rotation for energy ball effect // Add color cycling for plasma effect var colorPhase = LK.ticks % 120 / 120; var r = Math.floor(255 * Math.sin(Math.PI * colorPhase)); var g = Math.floor(50 * Math.sin(Math.PI * (colorPhase + 0.33))); var b = Math.floor(255 * Math.sin(Math.PI * (colorPhase + 0.67))); bulletGraphics.tint = r << 16 | g << 8 | b; // Add slight x-axis wobble for unstable plasma effect self.x += Math.sin(self.pulseFactor * 2) * 0.8; }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); var shipGraphics = self.attachAsset('playerShip', { anchorX: 0.5, anchorY: 0.5 }); self.health = 3; self.maxHealth = 3; self.weaponLevel = 1; self.weaponType = "standard"; // Initialize with standard weapon self.weaponUpgrades = 0; self.weaponTimer = 0; self.speed = 10; self.shieldEffect = null; // Reference to shield visual effect self.fireRate = 15; // Frames between shots self.lastShot = 0; self.shieldActive = false; self.shieldTimer = 0; self.invulnerable = false; self.invulnerabilityTimer = 0; self.update = function () { // Decrement timers if (self.weaponTimer > 0) { self.weaponTimer--; if (self.weaponTimer === 0) { self.weaponLevel = 1; // Reset weapon level when timer expires self.weaponType = "standard"; } } if (self.shieldActive) { self.shieldTimer--; if (self.shieldTimer === 0) { self.shieldActive = false; // Remove shield visual effect if (self.shieldEffect) { self.shieldEffect.destroy(); self.shieldEffect = null; } } } if (self.invulnerable) { self.invulnerabilityTimer--; // Flash while invulnerable self.visible = self.invulnerabilityTimer % 6 < 3; if (self.invulnerabilityTimer === 0) { self.invulnerable = false; self.visible = true; } } // Auto-fire self.lastShot++; if (self.lastShot >= self.fireRate) { self.shoot(); self.lastShot = 0; } // Update shield effect position if active if (self.shieldActive && self.shieldEffect) { self.shieldEffect.x = self.x; self.shieldEffect.y = self.y; } }; self.shoot = function () { // Choose bullet type based on weaponType var BulletClass; switch (self.weaponType) { case "laser": BulletClass = LaserBullet; break; case "plasma": BulletClass = PlasmaBullet; break; case "ultra": BulletClass = UltraBullet; break; default: BulletClass = PlayerBullet; } if (self.weaponLevel === 1) { // Single shot var bullet = new BulletClass(); bullet.x = self.x; bullet.y = self.y - 40; game.addChild(bullet); playerBullets.push(bullet); } else if (self.weaponLevel === 2) { // Double shot for (var i = -1; i <= 1; i += 2) { var bullet = new BulletClass(); bullet.x = self.x + i * 20; bullet.y = self.y - 40; game.addChild(bullet); playerBullets.push(bullet); } } else if (self.weaponLevel === 3) { // Triple shot for (var i = -1; i <= 1; i++) { var bullet = new BulletClass(); bullet.x = self.x + i * 25; bullet.y = self.y - 40; game.addChild(bullet); playerBullets.push(bullet); } } else if (self.weaponLevel >= 4) { // Quad shot - for level 4+ for (var i = -1.5; i <= 1.5; i += 1) { var bullet = new BulletClass(); bullet.x = self.x + i * 25; bullet.y = self.y - 40; game.addChild(bullet); playerBullets.push(bullet); } } LK.getSound('playerShoot').play(); }; self.takeDamage = function (amount) { if (self.invulnerable) { return false; } if (self.shieldActive) { // Shield absorbs the hit self.shieldActive = false; self.shieldTimer = 0; return false; } self.health -= amount; LK.getSound('damage').play(); // Make player invulnerable briefly self.invulnerable = true; self.invulnerabilityTimer = 90; // 1.5 seconds at 60fps if (self.health <= 0) { // Game over logic var explosion = new Explosion(); explosion.x = self.x; explosion.y = self.y; game.addChild(explosion); LK.getSound('explosion').play(); // Record high score if needed if (score > highScore) { highScore = score; storage.highScore = highScore; } gameOver = true; return true; } return false; }; self.collectPowerUp = function (powerUp) { if (powerUp.type === "weapon") { // Increment weapon level - now up to level 4 self.weaponLevel = Math.min(self.weaponLevel + 1, 4); self.weaponTimer = 600; // 10 seconds at 60fps // Determine weapon type based on collected power-ups if (self.weaponUpgrades === undefined) { self.weaponUpgrades = 0; } self.weaponUpgrades++; if (self.weaponUpgrades >= 3) { self.weaponType = "plasma"; // Advanced weapon } else if (self.weaponUpgrades >= 1) { self.weaponType = "laser"; // Medium weapon } else { self.weaponType = "standard"; // Basic weapon } } else if (powerUp.type === "shield") { self.shieldActive = true; self.shieldTimer = 600; // 10 seconds at 60fps // Create shield visual effect if it doesn't exist if (!self.shieldEffect) { self.shieldEffect = new ShieldEffect(); self.shieldEffect.x = self.x; self.shieldEffect.y = self.y; game.addChild(self.shieldEffect); } } else if (powerUp.type === "laser") { // Direct upgrade to laser weapon self.weaponType = "laser"; self.weaponLevel = Math.min(self.weaponLevel + 1, 4); self.weaponTimer = 600; // 10 seconds at 60fps } else if (powerUp.type === "plasma") { // Direct upgrade to plasma weapon self.weaponType = "plasma"; self.weaponLevel = Math.min(self.weaponLevel + 1, 4); self.weaponTimer = 600; // 10 seconds at 60fps } else if (powerUp.type === "ultra") { // Ultimate weapon upgrade self.weaponType = "ultra"; self.weaponLevel = 4; // Set to max level self.weaponTimer = 900; // 15 seconds at 60fps } LK.getSound('powerUp').play(); }; return self; }); var PlayerBullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = 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 powerUpGraphics = self.attachAsset('powerUp', { anchorX: 0.5, anchorY: 0.5 }); self.type = "weapon"; // Default type self.speed = 5; self.pulseTimer = 0; // Set different colors based on type self.setType = function (type) { self.type = type; if (type === "weapon") { powerUpGraphics.tint = 0x00ff00; // Green for weapons } else if (type === "shield") { powerUpGraphics.tint = 0x33ccff; // Blue for shields } else if (type === "laser") { powerUpGraphics.tint = 0x00ffaa; // Cyan for laser upgrade } else if (type === "plasma") { powerUpGraphics.tint = 0xff00ff; // Magenta for plasma upgrade } else if (type === "ultra") { powerUpGraphics.tint = 0xffff00; // Yellow for ultra weapon } }; self.update = function () { self.y += self.speed; // Enhance visual effect with pulsating and rotation self.pulseTimer += 0.1; powerUpGraphics.scale.x = 1 + Math.sin(self.pulseTimer) * 0.2; powerUpGraphics.scale.y = 1 + Math.sin(self.pulseTimer) * 0.2; powerUpGraphics.rotation += 0.02; // Slight oscillation for visual effect self.x += Math.sin(LK.ticks / 10) * 1; }; return self; }); var ShieldEffect = Container.expand(function () { var self = Container.call(this); var shieldGraphics = self.attachAsset('shieldEffect', { anchorX: 0.5, anchorY: 0.5, alpha: 0.5 }); self.pulseFactor = 0; self.update = function () { // Pulsating effect with enhanced visuals self.pulseFactor += 0.05; shieldGraphics.alpha = 0.3 + Math.sin(self.pulseFactor) * 0.2; shieldGraphics.rotation += 0.01; // Slow rotation for energy field effect // Create shimmering effect with color changes var blueIntensity = 0.5 + Math.sin(self.pulseFactor * 1.5) * 0.3; var cyanIntensity = 0.7 + Math.cos(self.pulseFactor * 0.8) * 0.3; shieldGraphics.tint = Math.floor(0x33 * blueIntensity) << 16 | Math.floor(0xcc * cyanIntensity) << 8 | 0xff; // Scale effect for "energy bubble" appearance var scaleVar = 1 + Math.sin(self.pulseFactor * 0.7) * 0.05; shieldGraphics.scale.x = scaleVar; shieldGraphics.scale.y = scaleVar; }; return self; }); var UltraBullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('plasmaBullet', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5, tint: 0xffff00 }); self.speed = -18; // Very fast self.damage = 5; // Highest damage self.pulseFactor = 0; self.update = function () { self.y += self.speed; // Dynamic visual effects self.pulseFactor += 0.15; var scale = 1.2 + Math.sin(self.pulseFactor) * 0.3; bulletGraphics.scale.x = scale; bulletGraphics.scale.y = scale; bulletGraphics.rotation += 0.15; // Electric discharge effect if (LK.ticks % 2 === 0) { var sparkEffect = LK.getAsset('plasmaBullet', { anchorX: 0.5, anchorY: 0.5, alpha: 0.7, scaleX: 0.4, scaleY: 0.4, tint: 0xffff00 }); sparkEffect.x = self.x + (Math.random() * 40 - 20); sparkEffect.y = self.y + (Math.random() * 40 - 20); game.addChild(sparkEffect); // Create fade-out effect var sparkDuration = 8; var fadeInterval = LK.setInterval(function () { sparkDuration--; sparkEffect.alpha -= 0.09; sparkEffect.scaleX -= 0.04; sparkEffect.scaleY -= 0.04; if (sparkDuration <= 0) { LK.clearInterval(fadeInterval); sparkEffect.destroy(); } }, 1); } // Colorful effect var time = LK.ticks % 20; var r = 255; var g = 255; var b = Math.floor(100 + time * 7); bulletGraphics.tint = r << 16 | g << 8 | b; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000022 }); /**** * Game Code ****/ // Game variables // Initialize main assets with high-quality shapes var score = 0; var highScore = storage.highScore || 0; var level = 1; var enemySpawnTimer = 0; var enemySpawnRate = 60; // Frames between enemy spawns var playerBullets = []; var enemyBullets = []; var enemies = []; var powerUps = []; var bossSpawned = false; var levelComplete = false; var gameOver = false; var nextEnemy = 0; // Create dynamic starfield background var stars = []; var starLayers = 3; // Multiple layers for parallax effect // Initialize stars for (var layer = 0; layer < starLayers; layer++) { var count = 30 + layer * 20; // More stars in deeper layers var speed = 1 + layer * 1.5; // Deeper layers move faster var size = 3 - layer * 0.8; // Deeper layers have smaller stars var alpha = 0.7 - layer * 0.2; // Deeper layers are more transparent for (var i = 0; i < count; i++) { var star = new Container(); var starGraphic = LK.getAsset('powerUp', { anchorX: 0.5, anchorY: 0.5, tint: 0xFFFFFF, alpha: alpha, scaleX: size / 60, scaleY: size / 60 }); star.addChild(starGraphic); star.x = Math.random() * 2048; star.y = Math.random() * 2732; star.speed = speed; star.layer = layer; // Add occasional color variation to brightest stars if (layer === 0 && Math.random() < 0.3) { var colors = [0xFFFFCC, 0xCCFFFF, 0xFFCCFF]; // Yellow, blue, pink tints starGraphic.tint = colors[Math.floor(Math.random() * colors.length)]; } game.addChild(star); stars.push(star); } } // Add function to update stars in main update loop function updateStars() { for (var i = 0; i < stars.length; i++) { var star = stars[i]; star.y += star.speed; // Reset stars when they go off screen if (star.y > 2732) { star.y = -10; star.x = Math.random() * 2048; } } } // UI elements var scoreTxt = new Text2('Score: 0', { size: 60, fill: 0xFFFFFF }); scoreTxt.anchor.set(0, 0); LK.gui.topRight.addChild(scoreTxt); var levelTxt = new Text2('Level: 1', { size: 60, fill: 0xFFFFFF }); levelTxt.anchor.set(1, 0); LK.gui.topLeft.addChild(levelTxt); // Move it away from the top-left corner levelTxt.x = 200; var healthTxt = new Text2('Health: 3', { size: 60, fill: 0xFFFFFF }); healthTxt.anchor.set(0.5, 0); LK.gui.top.addChild(healthTxt); // Weapon type indicator var weaponTxt = new Text2('Weapon: Standard', { size: 40, fill: 0xFFFFFF }); weaponTxt.style = { fill: 0xFFFFFF }; // Initialize style object weaponTxt.anchor.set(0, 0); LK.gui.bottomLeft.addChild(weaponTxt); weaponTxt.y = -100; // Position it above the bottom edge // Function to update weapon display function updateWeapon() { var typeText = player.weaponType.charAt(0).toUpperCase() + player.weaponType.slice(1); weaponTxt.setText('Weapon: ' + typeText + ' (Lv.' + player.weaponLevel + ')'); // Set text color based on weapon type if (player.weaponType === "standard") { weaponTxt.style.fill = 0x66ffff; } else if (player.weaponType === "laser") { weaponTxt.style.fill = 0x00ffaa; } else if (player.weaponType === "plasma") { weaponTxt.style.fill = 0xff00ff; } else if (player.weaponType === "ultra") { weaponTxt.style.fill = 0xffff00; } } // Create player var player = new Player(); player.x = 2048 / 2; player.y = 2732 - 300; game.addChild(player); // Function to update score display function updateScore() { scoreTxt.setText('Score: ' + score); // Update LK score system for leaderboards LK.setScore(score); } // Function to update health display function updateHealth() { healthTxt.setText('Health: ' + player.health); } // Function to update level display function updateLevel() { levelTxt.setText('Level: ' + level); } // Function to spawn regular enemies function spawnEnemy() { var enemyType; var enemy; // Select enemy type based on level and randomness if (level === 1) { // Level 1: Only basic enemies enemy = new Enemy(); enemy.health = 1; enemy.movementPattern = "straight"; enemy.fireRate = 180; } else if (level === 2) { // Level 2: Basic enemies and some hunters var rand = Math.random(); if (rand < 0.3) { enemy = new HunterShip(); } else if (rand < 0.6) { enemy = new Enemy(); enemy.health = 2; enemy.points = 200; enemy.movementPattern = "zigzag"; enemy.fireRate = 150; } else { enemy = new Enemy(); enemy.health = 1; enemy.movementPattern = "straight"; enemy.fireRate = 180; } } else if (level >= 3 && level < 5) { // Level 3-4: All enemy types var rand = Math.random(); if (rand < 0.25) { enemy = new CarrierShip(); } else if (rand < 0.5) { enemy = new HunterShip(); } else if (rand < 0.7) { enemy = new ScoutShip(); } else if (rand < 0.85) { enemy = new Enemy(); enemy.health = 3; enemy.points = 300; enemy.movementPattern = "circle"; enemy.fireRate = 120; } else { enemy = new Enemy(); enemy.health = 2; enemy.points = 200; enemy.movementPattern = "zigzag"; enemy.fireRate = 150; } } else if (level >= 5) { // Level 5+: Include elite enemies var rand = Math.random(); if (rand < 0.2) { enemy = new CarrierShip(); // Enhance carrier properties at higher levels if (level >= 6) { enemy.health += 2; enemy.spawnRate = 150; // Faster spawning } } else if (rand < 0.35) { enemy = new EliteHunterShip(); // Elite hunter } else if (rand < 0.5) { enemy = new HunterShip(); } else if (rand < 0.65) { enemy = new EliteScoutShip(); // Elite scout } else if (rand < 0.8) { enemy = new ScoutShip(); } else { enemy = new Enemy(); enemy.health = 3 + Math.min(level - 5, 3); // Scale up health enemy.points = 300 + (level - 5) * 50; enemy.movementPattern = "circle"; enemy.fireRate = Math.max(120 - (level - 5) * 10, 70); // Scale down fire rate (faster shooting) } } // Random position at top of screen enemy.x = 200 + Math.random() * (2048 - 400); enemy.y = -100; game.addChild(enemy); enemies.push(enemy); } // Function to spawn boss function spawnBoss() { var boss; // At higher levels, spawn the MegaBoss instead if (level >= 4) { boss = new MegaBoss(); boss.x = 2048 / 2; boss.y = -300; // Scale mega boss difficulty with level boss.health = 50 + (level - 4) * 15; boss.maxHealth = boss.health; } else { boss = new Boss(); boss.x = 2048 / 2; boss.y = -200; // Scale boss difficulty with level boss.health = 20 + (level - 1) * 10; boss.maxHealth = boss.health; } game.addChild(boss); enemies.push(boss); bossSpawned = true; } // Function to start the next level function startNextLevel() { level++; updateLevel(); enemies = []; enemyBullets = []; bossSpawned = false; levelComplete = false; nextEnemy = 0; // Speed up enemy spawns as level increases enemySpawnRate = Math.max(60 - (level - 1) * 5, 30); } // Mouse/Touch handlers var dragNode = null; function handleMove(x, y, obj) { if (dragNode) { // Clamp position to stay on screen dragNode.x = Math.max(60, Math.min(x, 2048 - 60)); dragNode.y = Math.max(60, Math.min(y, 2732 - 60)); } } game.move = handleMove; game.down = function (x, y, obj) { dragNode = player; handleMove(x, y, obj); }; game.up = function (x, y, obj) { dragNode = null; }; // Main game update loop game.update = function () { // Update starfield background for space atmosphere updateStars(); if (gameOver) { // Show game over screen LK.showGameOver(); return; } if (levelComplete) { startNextLevel(); } // Update player player.update(); updateHealth(); updateWeapon(); // Spawn enemies if (!bossSpawned) { enemySpawnTimer++; if (enemySpawnTimer >= enemySpawnRate) { enemySpawnTimer = 0; spawnEnemy(); nextEnemy++; // Spawn boss after certain number of enemies if (nextEnemy >= 15 + level * 5) { spawnBoss(); } } } // Update player bullets for (var i = playerBullets.length - 1; i >= 0; i--) { var bullet = playerBullets[i]; // Check if bullet is off screen if (bullet.y < -50) { bullet.destroy(); playerBullets.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)) { if (enemy.takeDamage(bullet.damage)) { enemies.splice(j, 1); } bullet.destroy(); playerBullets.splice(i, 1); break; } } } // Update enemy bullets for (var i = enemyBullets.length - 1; i >= 0; i--) { var bullet = enemyBullets[i]; // Check if bullet is off screen if (bullet.y > 2732 + 50) { bullet.destroy(); enemyBullets.splice(i, 1); continue; } // Check for collision with player if (bullet.intersects(player)) { if (player.takeDamage(bullet.damage)) { // Player destroyed, game over gameOver = true; } bullet.destroy(); enemyBullets.splice(i, 1); } } // Update enemies for (var i = enemies.length - 1; i >= 0; i--) { var enemy = enemies[i]; // Check if enemy is off screen if (enemy.y > 2732 + 100) { enemy.destroy(); enemies.splice(i, 1); continue; } // Check for collision with player if (enemy.intersects(player)) { if (player.takeDamage(1)) { // Player destroyed, game over gameOver = true; } // Enemy also takes damage if (enemy.takeDamage(1)) { enemies.splice(i, 1); } continue; } } // Update power-ups for (var i = powerUps.length - 1; i >= 0; i--) { var powerUp = powerUps[i]; // Check if power-up is off screen if (powerUp.y > 2732 + 50) { powerUp.destroy(); powerUps.splice(i, 1); continue; } // Check for collision with player if (powerUp.intersects(player)) { player.collectPowerUp(powerUp); powerUp.destroy(); powerUps.splice(i, 1); } } // Check if level is complete (no enemies and boss killed) if (bossSpawned && enemies.length === 0) { levelComplete = true; } }; // Start background music LK.playMusic('bgMusic');
/****
* 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 bossGraphics = self.attachAsset('boss', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 20;
self.maxHealth = 20;
self.points = 2000;
self.speed = 1;
self.phase = 1;
self.fireRate = 60; // Frames between shots
self.lastShot = 0;
self.movementTimer = 0;
self.attacking = false;
self.update = function () {
// Boss enters from top
if (self.y < 400) {
self.y += self.speed;
} else {
self.attacking = true;
// Phase-based movement
if (self.phase === 1) {
// Side-to-side movement
self.x += Math.sin(self.movementTimer / 30) * 5;
self.movementTimer++;
// Regular shooting
self.lastShot++;
if (self.lastShot >= self.fireRate) {
self.shoot();
self.lastShot = 0;
}
} else if (self.phase === 2) {
// More aggressive movement
self.x += Math.sin(self.movementTimer / 20) * 7;
self.y += Math.cos(self.movementTimer / 40) * 2;
self.movementTimer++;
// More frequent shooting
self.lastShot++;
if (self.lastShot >= self.fireRate * 0.7) {
self.shoot();
self.lastShot = 0;
}
} else if (self.phase === 3) {
// Erratic movement
self.x += Math.sin(self.movementTimer / 10) * 8;
self.y += Math.cos(self.movementTimer / 15) * 3;
self.movementTimer++;
// Rapid shooting
self.lastShot++;
if (self.lastShot >= self.fireRate * 0.4) {
self.shoot();
self.lastShot = 0;
}
}
}
// Change phase based on health with enhanced visual feedback
if (self.health <= self.maxHealth * 0.65 && self.phase === 1) {
self.phase = 2;
LK.effects.flashObject(self, 0xff0000, 500);
// Add dramatic phase change effect
bossGraphics.tint = 0xff6600; // Change to orange glow
// Create multiple explosions around boss
for (var i = 0; i < 3; i++) {
var damageExplosion = new Explosion();
damageExplosion.x = self.x + (Math.random() * 120 - 60);
damageExplosion.y = self.y + (Math.random() * 80 - 40);
game.addChild(damageExplosion);
}
} else if (self.health <= self.maxHealth * 0.3 && self.phase === 2) {
self.phase = 3;
LK.effects.flashObject(self, 0xff0000, 500);
// More dramatic effect for final phase
bossGraphics.tint = 0xff0000; // Change to red glow
bossGraphics.scale.x = 1.1; // Slightly expand
bossGraphics.scale.y = 1.1;
// Create more explosions for critical damage
for (var i = 0; i < 5; i++) {
var damageExplosion = new Explosion();
damageExplosion.x = self.x + (Math.random() * 160 - 80);
damageExplosion.y = self.y + (Math.random() * 100 - 50);
game.addChild(damageExplosion);
}
}
};
self.shoot = function () {
// Different shot patterns based on phase
if (self.phase === 1) {
// Single shot
var bullet = new EnemyBullet();
bullet.x = self.x;
bullet.y = self.y + 80;
game.addChild(bullet);
enemyBullets.push(bullet);
} else if (self.phase === 2) {
// Double shot
for (var i = -1; i <= 1; i += 2) {
var bullet = new EnemyBullet();
bullet.x = self.x + i * 50;
bullet.y = self.y + 80;
game.addChild(bullet);
enemyBullets.push(bullet);
}
} else if (self.phase === 3) {
// Triple shot
for (var i = -1; i <= 1; i++) {
var bullet = new EnemyBullet();
bullet.x = self.x + i * 50;
bullet.y = self.y + 80;
game.addChild(bullet);
enemyBullets.push(bullet);
}
}
LK.getSound('enemyShoot').play();
};
self.takeDamage = function (amount) {
self.health -= amount;
// Flash when taking damage
LK.effects.flashObject(self, 0xffffff, 200);
if (self.health <= 0) {
// Multiple explosions for boss
for (var i = 0; i < 5; i++) {
var explosion = new Explosion();
explosion.x = self.x + (Math.random() * 200 - 100);
explosion.y = self.y + (Math.random() * 100 - 50);
game.addChild(explosion);
}
// Add points to score
score += self.points;
updateScore();
// Boss drops multiple power-ups
// Drop advanced weapon power-up based on level
var weaponPowerUp = new PowerUp();
weaponPowerUp.x = self.x - 60;
weaponPowerUp.y = self.y;
if (level >= 3) {
weaponPowerUp.setType("plasma");
} else {
weaponPowerUp.setType("laser");
}
game.addChild(weaponPowerUp);
powerUps.push(weaponPowerUp);
// Drop shield power-up
var shieldPowerUp = new PowerUp();
shieldPowerUp.x = self.x + 60;
shieldPowerUp.y = self.y;
shieldPowerUp.setType("shield");
game.addChild(shieldPowerUp);
powerUps.push(shieldPowerUp);
LK.getSound('explosion').play();
// Level complete
levelComplete = true;
self.destroy();
return true;
}
return false;
};
return self;
});
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemyShip', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 1;
self.points = 100;
self.speed = 2;
self.fireRate = 180; // Frames between shots
self.lastShot = 0;
self.movementPattern = "straight"; // Default movement
self.movementTimer = 0;
self.update = function () {
// Handle movement patterns
if (self.movementPattern === "straight") {
self.y += self.speed;
} else if (self.movementPattern === "zigzag") {
self.y += self.speed;
self.x += Math.sin(self.movementTimer / 20) * 3;
self.movementTimer++;
} else if (self.movementPattern === "circle") {
self.y += self.speed * 0.7;
self.x += Math.sin(self.movementTimer / 15) * 4;
self.movementTimer++;
}
// Shooting logic
self.lastShot++;
if (self.lastShot >= self.fireRate && self.y > 0 && Math.random() < 0.3) {
self.shoot();
self.lastShot = 0;
}
};
self.shoot = function () {
var bullet = new EnemyBullet();
bullet.x = self.x;
bullet.y = self.y + 40;
game.addChild(bullet);
enemyBullets.push(bullet);
LK.getSound('enemyShoot').play();
};
self.takeDamage = function (amount) {
self.health -= amount;
if (self.health <= 0) {
// Create explosion
var explosion = new Explosion();
explosion.x = self.x;
explosion.y = self.y;
game.addChild(explosion);
// Add points to score
score += self.points;
updateScore();
// Random chance to drop power-up
if (Math.random() < 0.1) {
var powerUp = new PowerUp();
powerUp.x = self.x;
powerUp.y = self.y;
// Random power-up type
var rand = Math.random();
if (rand < 0.5) {
powerUp.setType("weapon");
} else if (rand < 0.8) {
powerUp.setType("shield");
} else if (level >= 2) {
// Special weapon drops in higher levels
if (level >= 3 && rand < 0.9) {
powerUp.setType("plasma");
} else {
powerUp.setType("laser");
}
}
game.addChild(powerUp);
powerUps.push(powerUp);
}
LK.getSound('explosion').play();
self.destroy();
return true;
}
return false;
};
return self;
});
var ScoutShip = Enemy.expand(function () {
var self = Enemy.call(this);
// Replace default graphics with scout ship graphics
self.removeChild(self.children[0]);
var shipGraphics = self.attachAsset('scoutShip', {
anchorX: 0.5,
anchorY: 0.5
});
// Set scout-specific properties
self.health = 1;
self.points = 150;
self.speed = 4; // Faster movement
self.fireRate = 240; // Shoots less frequently
self.movementPattern = "erratic";
// Override update method for erratic movement
var originalUpdate = self.update;
self.update = function () {
if (self.movementPattern === "erratic") {
self.y += self.speed;
self.x += Math.sin(self.movementTimer / 10) * 6;
self.movementTimer++;
} else {
// Use original update for other movement patterns
originalUpdate.call(self);
}
// Handle shooting with lower probability
self.lastShot++;
if (self.lastShot >= self.fireRate && self.y > 0 && Math.random() < 0.2) {
self.shoot();
self.lastShot = 0;
}
};
return self;
});
var EliteScoutShip = ScoutShip.expand(function () {
var self = ScoutShip.call(this);
// Replace graphics with recolored version
self.removeChild(self.children[0]);
var shipGraphics = self.attachAsset('scoutShip', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0x33ffff,
scaleX: 1.3,
scaleY: 1.3
});
// Enhanced elite properties
self.health = 3;
self.points = 350;
self.speed = 6; // Even faster
// Override update for more complex movement
var originalUpdate = self.update;
self.update = function () {
// Teleport-like rapid movement changes
if (LK.ticks % 90 === 0 && self.y > 200) {
// Create a flicker effect before "teleporting"
shipGraphics.alpha = 0.5;
// Schedule the "teleport"
LK.setTimeout(function () {
// Random new position
self.x = 300 + Math.random() * (2048 - 600);
shipGraphics.alpha = 1;
// Create visual effect at new position
var flashEffect = new Explosion();
flashEffect.x = self.x;
flashEffect.y = self.y;
game.addChild(flashEffect);
}, 20);
}
// Use original movement pattern with more extreme values
self.y += self.speed;
self.x += Math.sin(self.movementTimer / 8) * 8;
self.movementTimer++;
// Fire more bullets in a spread pattern
self.lastShot++;
if (self.lastShot >= self.fireRate && self.y > 0 && Math.random() < 0.3) {
// Triple spread shot
for (var i = -1; i <= 1; i++) {
var bullet = new EnemyBullet();
bullet.x = self.x + i * 20;
bullet.y = self.y + 40;
// Angled shots
var angle = Math.PI / 2 + i * 0.3;
bullet.speedX = Math.cos(angle) * 10;
bullet.speedY = Math.sin(angle) * 10;
// Override update for angled movement
bullet.update = function () {
this.x += this.speedX;
this.y += this.speedY;
};
game.addChild(bullet);
enemyBullets.push(bullet);
}
LK.getSound('enemyShoot').play();
self.lastShot = 0;
}
};
return self;
});
var HunterShip = Enemy.expand(function () {
var self = Enemy.call(this);
// Replace default graphics with hunter ship graphics
self.removeChild(self.children[0]);
var shipGraphics = self.attachAsset('hunterShip', {
anchorX: 0.5,
anchorY: 0.5
});
// Set hunter-specific properties
self.health = 3;
self.points = 250;
self.speed = 3;
self.fireRate = 100; // Fires more frequently
self.movementPattern = "pursuit"; // New movement pattern that follows player
// Override update method to add pursuit behavior
var originalUpdate = self.update;
self.update = function () {
if (self.movementPattern === "pursuit") {
// Move towards player's x position
if (player.x > self.x) {
self.x += Math.min(self.speed * 0.7, player.x - self.x);
} else if (player.x < self.x) {
self.x -= Math.min(self.speed * 0.7, self.x - player.x);
}
self.y += self.speed * 0.8;
} else {
// Use original update for other movement patterns
originalUpdate.call(self);
}
// Handle shooting regardless of movement pattern
self.lastShot++;
if (self.lastShot >= self.fireRate && self.y > 0 && Math.random() < 0.4) {
self.shoot();
self.lastShot = 0;
}
};
return self;
});
var EliteHunterShip = HunterShip.expand(function () {
var self = HunterShip.call(this);
// Replace graphics with recolored version
self.removeChild(self.children[0]);
var shipGraphics = self.attachAsset('hunterShip', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0xff3300,
scaleX: 1.2,
scaleY: 1.2
});
// Enhanced elite properties
self.health = 5;
self.points = 500;
self.speed = 4;
self.fireRate = 70;
// Override update for more aggressive behavior
var originalUpdate = self.update;
self.update = function () {
if (self.movementPattern === "pursuit") {
// More aggressive pursuit
var targetX = player.x;
var dx = targetX - self.x;
self.x += dx * 0.05; // More precise tracking
self.y += self.speed * 0.9;
// Rotate slightly toward movement direction
shipGraphics.rotation = dx * 0.003;
} else {
originalUpdate.call(self);
}
// More frequent shooting with double bullets
self.lastShot++;
if (self.lastShot >= self.fireRate && self.y > 0 && Math.random() < 0.5) {
self.shoot();
// Add slight delay for second shot
LK.setTimeout(function () {
self.shoot();
}, 10);
self.lastShot = 0;
}
};
return self;
});
var CarrierShip = Enemy.expand(function () {
var self = Enemy.call(this);
// Replace default graphics with carrier ship graphics
self.removeChild(self.children[0]);
var shipGraphics = self.attachAsset('carrierShip', {
anchorX: 0.5,
anchorY: 0.5
});
// Set carrier-specific properties
self.health = 5;
self.points = 400;
self.speed = 1; // Slower movement
self.fireRate = 200;
self.lastSpawn = 0; // Timer for spawning small ships
self.spawnRate = 180; // How often to spawn small ships
// Override update method to add spawning behavior
var originalUpdate = self.update;
self.update = function () {
originalUpdate.call(self);
// Spawn small scout ships periodically
self.lastSpawn++;
if (self.lastSpawn >= self.spawnRate && self.y > 100 && self.y < 1000) {
self.spawnScout();
self.lastSpawn = 0;
}
};
// Method to spawn a scout ship
self.spawnScout = function () {
var scout = new ScoutShip();
scout.x = self.x;
scout.y = self.y + 50;
game.addChild(scout);
enemies.push(scout);
};
// Override takeDamage to drop power-ups more often
var originalTakeDamage = self.takeDamage;
self.takeDamage = function (amount) {
if (originalTakeDamage.call(self, amount)) {
// If ship was destroyed and original method returned true
// Carriers have a higher chance to drop power-ups (40%)
if (Math.random() < 0.4) {
var powerUp = new PowerUp();
powerUp.x = self.x;
powerUp.y = self.y;
// Random power-up type with better odds for weapon power-ups
var rand = Math.random();
if (rand < 0.7) {
powerUp.type = "weapon";
} else {
powerUp.type = "shield";
}
game.addChild(powerUp);
powerUps.push(powerUp);
}
return true;
}
return false;
};
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 = 10;
self.damage = 1;
self.update = function () {
self.y += self.speed;
};
return self;
});
var Explosion = Container.expand(function () {
var self = Container.call(this);
var explosionGraphics = self.attachAsset('explosion', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.9
});
self.lifetime = 30; // frames
self.update = function () {
self.lifetime--;
// Scale up and fade out with improved effects
explosionGraphics.scale.x = 1 + (30 - self.lifetime) / 12;
explosionGraphics.scale.y = 1 + (30 - self.lifetime) / 12;
explosionGraphics.alpha = self.lifetime / 30;
explosionGraphics.rotation += 0.05; // Add rotation for more dynamic effect
// Add pulsing glow effect
if (self.lifetime % 3 === 0) {
explosionGraphics.tint = 0xffcc00; // Original color
} else if (self.lifetime % 3 === 1) {
explosionGraphics.tint = 0xff6600; // Orange
} else {
explosionGraphics.tint = 0xff2200; // Red-orange
}
if (self.lifetime <= 0) {
self.destroy();
}
};
return self;
});
var LaserBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('laserBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -20; // Faster than regular bullets
self.damage = 2; // More damage
self.update = function () {
self.y += self.speed;
// Add laser trail effect
if (LK.ticks % 3 === 0) {
var trailEffect = LK.getAsset('laserBullet', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.5,
scaleX: 0.7,
scaleY: 0.7
});
trailEffect.x = self.x;
trailEffect.y = self.y + 15;
game.addChild(trailEffect);
// Create a simple fade-out animation
var trailDuration = 10;
var fadeInterval = LK.setInterval(function () {
trailDuration--;
trailEffect.alpha -= 0.05;
trailEffect.scaleX -= 0.05;
trailEffect.scaleY -= 0.05;
if (trailDuration <= 0) {
LK.clearInterval(fadeInterval);
trailEffect.destroy();
}
}, 1);
}
// Add pulsing glow effect
var time = LK.ticks % 10;
bulletGraphics.tint = time < 5 ? 0x00ffaa : 0x00ddaa;
};
return self;
});
var MegaBoss = Container.expand(function () {
var self = Container.call(this);
var bossGraphics = self.attachAsset('boss', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.8,
scaleY: 1.8,
tint: 0xff3300
});
self.health = 50;
self.maxHealth = 50;
self.points = 5000;
self.speed = 0.8;
self.phase = 1;
self.fireRate = 45; // Faster than normal boss
self.lastShot = 0;
self.specialAttackTimer = 0;
self.movementTimer = 0;
self.attacking = false;
// Create energy shield effect
var shieldGraphics = LK.getAsset('shieldEffect', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.3,
scaleX: 2.2,
scaleY: 2.2,
tint: 0xff6600
});
self.addChild(shieldGraphics);
self.update = function () {
// Boss enters from top
if (self.y < 500) {
self.y += self.speed;
} else {
self.attacking = true;
// Phase-based movement and attacks
if (self.phase === 1) {
// Phase 1: Circular movement
self.x = 2048 / 2 + Math.sin(self.movementTimer / 40) * 500;
self.y = 500 + Math.cos(self.movementTimer / 40) * 200;
self.movementTimer++;
// Regular shooting
self.lastShot++;
if (self.lastShot >= self.fireRate) {
self.shootSpread(3, 20); // 3 bullets in spread
self.lastShot = 0;
}
} else if (self.phase === 2) {
// Phase 2: Figure-8 movement
self.x = 2048 / 2 + Math.sin(self.movementTimer / 50) * 400;
self.y = 500 + Math.sin(self.movementTimer / 25) * 150;
self.movementTimer++;
// More frequent shooting
self.lastShot++;
if (self.lastShot >= self.fireRate * 0.6) {
self.shootSpread(5, 15); // 5 bullets in spread
self.lastShot = 0;
}
// Special attack: summon enemies
self.specialAttackTimer++;
if (self.specialAttackTimer >= 300) {
// Every 5 seconds
self.summonMinions();
self.specialAttackTimer = 0;
}
} else if (self.phase === 3) {
// Phase 3: Erratic movement
self.x += Math.sin(self.movementTimer / 10) * 12;
self.y = 400 + Math.sin(self.movementTimer / 5) * 100;
self.movementTimer++;
// Rapid shooting with pattern
self.lastShot++;
if (self.lastShot >= self.fireRate * 0.3) {
if (self.lastShot % 3 === 0) {
self.shootCircle(8); // Circle of 8 bullets
} else {
self.shootSpread(3, 30); // 3 bullets in spread
}
self.lastShot = 0;
}
// Special attack: laser beam
self.specialAttackTimer++;
if (self.specialAttackTimer >= 240) {
// Every 4 seconds
self.firingLaser = true;
self.fireLaserBeam();
self.specialAttackTimer = 0;
}
}
// Shield effect animation
shieldGraphics.rotation += 0.02;
shieldGraphics.alpha = 0.2 + Math.sin(LK.ticks / 10) * 0.1;
}
// Change phase based on health
if (self.health <= self.maxHealth * 0.65 && self.phase === 1) {
self.phase = 2;
LK.effects.flashObject(self, 0xff0000, 800);
bossGraphics.tint = 0xff4400;
// Create explosion effects
for (var i = 0; i < 5; i++) {
var damageExplosion = new Explosion();
damageExplosion.x = self.x + (Math.random() * 150 - 75);
damageExplosion.y = self.y + (Math.random() * 150 - 75);
game.addChild(damageExplosion);
}
} else if (self.health <= self.maxHealth * 0.3 && self.phase === 2) {
self.phase = 3;
LK.effects.flashObject(self, 0xff0000, 1000);
bossGraphics.tint = 0xff0000;
bossGraphics.scale.x = 1.3;
bossGraphics.scale.y = 1.3;
// More dramatic explosions
for (var i = 0; i < 8; i++) {
var damageExplosion = new Explosion();
damageExplosion.x = self.x + (Math.random() * 200 - 100);
damageExplosion.y = self.y + (Math.random() * 200 - 100);
game.addChild(damageExplosion);
}
}
};
self.shootSpread = function (count, angle) {
var spreadAngle = angle * (Math.PI / 180);
var startAngle = Math.PI / 2 - spreadAngle / 2;
var angleStep = spreadAngle / (count - 1);
for (var i = 0; i < count; i++) {
var bullet = new EnemyBullet();
var currentAngle = startAngle + angleStep * i;
bullet.x = self.x;
bullet.y = self.y + 80;
bullet.speedX = Math.cos(currentAngle) * 8;
bullet.speedY = Math.sin(currentAngle) * 8;
// Override update method for angled movement
bullet.update = function () {
this.x += this.speedX;
this.y += this.speedY;
};
game.addChild(bullet);
enemyBullets.push(bullet);
}
LK.getSound('enemyShoot').play();
};
self.shootCircle = function (count) {
var angleStep = Math.PI * 2 / count;
for (var i = 0; i < count; i++) {
var bullet = new EnemyBullet();
var currentAngle = angleStep * i;
bullet.x = self.x;
bullet.y = self.y;
bullet.speedX = Math.cos(currentAngle) * 7;
bullet.speedY = Math.sin(currentAngle) * 7;
// Override update method for circular pattern
bullet.update = function () {
this.x += this.speedX;
this.y += this.speedY;
};
game.addChild(bullet);
enemyBullets.push(bullet);
}
LK.getSound('enemyShoot').play();
};
self.summonMinions = function () {
// Spawn 2-3 smaller enemies
var count = 2 + Math.floor(Math.random() * 2);
for (var i = 0; i < count; i++) {
var enemy;
if (Math.random() < 0.5) {
enemy = new ScoutShip();
} else {
enemy = new HunterShip();
}
enemy.x = self.x + (Math.random() * 300 - 150);
enemy.y = self.y + 100;
game.addChild(enemy);
enemies.push(enemy);
// Visual effect for spawning
var spawnEffect = new Explosion();
spawnEffect.x = enemy.x;
spawnEffect.y = enemy.y;
game.addChild(spawnEffect);
}
};
self.fireLaserBeam = function () {
// Visual effect for charging laser
var chargeEffect = new Explosion();
chargeEffect.x = self.x;
chargeEffect.y = self.y + 50;
game.addChild(chargeEffect);
// Create laser beam after short delay
LK.setTimeout(function () {
var laserBeam = new Container();
var laserGraphics = LK.getAsset('laserBullet', {
anchorX: 0.5,
anchorY: 0,
scaleX: 8,
scaleY: 30,
tint: 0xff3300
});
laserBeam.addChild(laserGraphics);
laserBeam.x = self.x;
laserBeam.y = self.y + 80;
game.addChild(laserBeam);
// Damage player if in path of laser
if (Math.abs(player.x - self.x) < 150) {
player.takeDamage(2);
}
// Remove laser after a short time
LK.setTimeout(function () {
laserBeam.destroy();
self.firingLaser = false;
}, 1000);
}, 500);
};
self.takeDamage = function (amount) {
self.health -= amount;
LK.effects.flashObject(self, 0xffffff, 200);
if (self.health <= 0) {
// Multiple explosions for boss death
for (var i = 0; i < 12; i++) {
var explosion = new Explosion();
explosion.x = self.x + (Math.random() * 300 - 150);
explosion.y = self.y + (Math.random() * 200 - 100);
game.addChild(explosion);
// Stagger explosions
LK.setTimeout(function () {
var delayedExplosion = new Explosion();
delayedExplosion.x = self.x + (Math.random() * 300 - 150);
delayedExplosion.y = self.y + (Math.random() * 200 - 100);
game.addChild(delayedExplosion);
}, 100 + i * 100);
}
// Add points to score
score += self.points;
updateScore();
// Drop multiple power-ups
for (var i = 0; i < 3; i++) {
var powerUp = new PowerUp();
powerUp.x = self.x + (i - 1) * 80;
powerUp.y = self.y;
if (i === 0) {
powerUp.setType("shield");
} else if (i === 1) {
powerUp.setType("ultra");
} else {
powerUp.setType("plasma");
}
game.addChild(powerUp);
powerUps.push(powerUp);
}
LK.getSound('explosion').play();
levelComplete = true;
self.destroy();
return true;
}
return false;
};
return self;
});
var PlasmaBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('plasmaBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -12; // Medium speed
self.damage = 3; // Highest damage
// Add pulsating effect
self.pulseFactor = 0;
self.update = function () {
self.y += self.speed;
// Enhanced pulsating effect with rotation
self.pulseFactor += 0.1;
var scale = 1 + Math.sin(self.pulseFactor) * 0.2;
bulletGraphics.scale.x = scale;
bulletGraphics.scale.y = scale;
bulletGraphics.rotation += 0.1; // Add rotation for energy ball effect
// Add color cycling for plasma effect
var colorPhase = LK.ticks % 120 / 120;
var r = Math.floor(255 * Math.sin(Math.PI * colorPhase));
var g = Math.floor(50 * Math.sin(Math.PI * (colorPhase + 0.33)));
var b = Math.floor(255 * Math.sin(Math.PI * (colorPhase + 0.67)));
bulletGraphics.tint = r << 16 | g << 8 | b;
// Add slight x-axis wobble for unstable plasma effect
self.x += Math.sin(self.pulseFactor * 2) * 0.8;
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var shipGraphics = self.attachAsset('playerShip', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 3;
self.maxHealth = 3;
self.weaponLevel = 1;
self.weaponType = "standard"; // Initialize with standard weapon
self.weaponUpgrades = 0;
self.weaponTimer = 0;
self.speed = 10;
self.shieldEffect = null; // Reference to shield visual effect
self.fireRate = 15; // Frames between shots
self.lastShot = 0;
self.shieldActive = false;
self.shieldTimer = 0;
self.invulnerable = false;
self.invulnerabilityTimer = 0;
self.update = function () {
// Decrement timers
if (self.weaponTimer > 0) {
self.weaponTimer--;
if (self.weaponTimer === 0) {
self.weaponLevel = 1; // Reset weapon level when timer expires
self.weaponType = "standard";
}
}
if (self.shieldActive) {
self.shieldTimer--;
if (self.shieldTimer === 0) {
self.shieldActive = false;
// Remove shield visual effect
if (self.shieldEffect) {
self.shieldEffect.destroy();
self.shieldEffect = null;
}
}
}
if (self.invulnerable) {
self.invulnerabilityTimer--;
// Flash while invulnerable
self.visible = self.invulnerabilityTimer % 6 < 3;
if (self.invulnerabilityTimer === 0) {
self.invulnerable = false;
self.visible = true;
}
}
// Auto-fire
self.lastShot++;
if (self.lastShot >= self.fireRate) {
self.shoot();
self.lastShot = 0;
}
// Update shield effect position if active
if (self.shieldActive && self.shieldEffect) {
self.shieldEffect.x = self.x;
self.shieldEffect.y = self.y;
}
};
self.shoot = function () {
// Choose bullet type based on weaponType
var BulletClass;
switch (self.weaponType) {
case "laser":
BulletClass = LaserBullet;
break;
case "plasma":
BulletClass = PlasmaBullet;
break;
case "ultra":
BulletClass = UltraBullet;
break;
default:
BulletClass = PlayerBullet;
}
if (self.weaponLevel === 1) {
// Single shot
var bullet = new BulletClass();
bullet.x = self.x;
bullet.y = self.y - 40;
game.addChild(bullet);
playerBullets.push(bullet);
} else if (self.weaponLevel === 2) {
// Double shot
for (var i = -1; i <= 1; i += 2) {
var bullet = new BulletClass();
bullet.x = self.x + i * 20;
bullet.y = self.y - 40;
game.addChild(bullet);
playerBullets.push(bullet);
}
} else if (self.weaponLevel === 3) {
// Triple shot
for (var i = -1; i <= 1; i++) {
var bullet = new BulletClass();
bullet.x = self.x + i * 25;
bullet.y = self.y - 40;
game.addChild(bullet);
playerBullets.push(bullet);
}
} else if (self.weaponLevel >= 4) {
// Quad shot - for level 4+
for (var i = -1.5; i <= 1.5; i += 1) {
var bullet = new BulletClass();
bullet.x = self.x + i * 25;
bullet.y = self.y - 40;
game.addChild(bullet);
playerBullets.push(bullet);
}
}
LK.getSound('playerShoot').play();
};
self.takeDamage = function (amount) {
if (self.invulnerable) {
return false;
}
if (self.shieldActive) {
// Shield absorbs the hit
self.shieldActive = false;
self.shieldTimer = 0;
return false;
}
self.health -= amount;
LK.getSound('damage').play();
// Make player invulnerable briefly
self.invulnerable = true;
self.invulnerabilityTimer = 90; // 1.5 seconds at 60fps
if (self.health <= 0) {
// Game over logic
var explosion = new Explosion();
explosion.x = self.x;
explosion.y = self.y;
game.addChild(explosion);
LK.getSound('explosion').play();
// Record high score if needed
if (score > highScore) {
highScore = score;
storage.highScore = highScore;
}
gameOver = true;
return true;
}
return false;
};
self.collectPowerUp = function (powerUp) {
if (powerUp.type === "weapon") {
// Increment weapon level - now up to level 4
self.weaponLevel = Math.min(self.weaponLevel + 1, 4);
self.weaponTimer = 600; // 10 seconds at 60fps
// Determine weapon type based on collected power-ups
if (self.weaponUpgrades === undefined) {
self.weaponUpgrades = 0;
}
self.weaponUpgrades++;
if (self.weaponUpgrades >= 3) {
self.weaponType = "plasma"; // Advanced weapon
} else if (self.weaponUpgrades >= 1) {
self.weaponType = "laser"; // Medium weapon
} else {
self.weaponType = "standard"; // Basic weapon
}
} else if (powerUp.type === "shield") {
self.shieldActive = true;
self.shieldTimer = 600; // 10 seconds at 60fps
// Create shield visual effect if it doesn't exist
if (!self.shieldEffect) {
self.shieldEffect = new ShieldEffect();
self.shieldEffect.x = self.x;
self.shieldEffect.y = self.y;
game.addChild(self.shieldEffect);
}
} else if (powerUp.type === "laser") {
// Direct upgrade to laser weapon
self.weaponType = "laser";
self.weaponLevel = Math.min(self.weaponLevel + 1, 4);
self.weaponTimer = 600; // 10 seconds at 60fps
} else if (powerUp.type === "plasma") {
// Direct upgrade to plasma weapon
self.weaponType = "plasma";
self.weaponLevel = Math.min(self.weaponLevel + 1, 4);
self.weaponTimer = 600; // 10 seconds at 60fps
} else if (powerUp.type === "ultra") {
// Ultimate weapon upgrade
self.weaponType = "ultra";
self.weaponLevel = 4; // Set to max level
self.weaponTimer = 900; // 15 seconds at 60fps
}
LK.getSound('powerUp').play();
};
return self;
});
var PlayerBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = 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 powerUpGraphics = self.attachAsset('powerUp', {
anchorX: 0.5,
anchorY: 0.5
});
self.type = "weapon"; // Default type
self.speed = 5;
self.pulseTimer = 0;
// Set different colors based on type
self.setType = function (type) {
self.type = type;
if (type === "weapon") {
powerUpGraphics.tint = 0x00ff00; // Green for weapons
} else if (type === "shield") {
powerUpGraphics.tint = 0x33ccff; // Blue for shields
} else if (type === "laser") {
powerUpGraphics.tint = 0x00ffaa; // Cyan for laser upgrade
} else if (type === "plasma") {
powerUpGraphics.tint = 0xff00ff; // Magenta for plasma upgrade
} else if (type === "ultra") {
powerUpGraphics.tint = 0xffff00; // Yellow for ultra weapon
}
};
self.update = function () {
self.y += self.speed;
// Enhance visual effect with pulsating and rotation
self.pulseTimer += 0.1;
powerUpGraphics.scale.x = 1 + Math.sin(self.pulseTimer) * 0.2;
powerUpGraphics.scale.y = 1 + Math.sin(self.pulseTimer) * 0.2;
powerUpGraphics.rotation += 0.02;
// Slight oscillation for visual effect
self.x += Math.sin(LK.ticks / 10) * 1;
};
return self;
});
var ShieldEffect = Container.expand(function () {
var self = Container.call(this);
var shieldGraphics = self.attachAsset('shieldEffect', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.5
});
self.pulseFactor = 0;
self.update = function () {
// Pulsating effect with enhanced visuals
self.pulseFactor += 0.05;
shieldGraphics.alpha = 0.3 + Math.sin(self.pulseFactor) * 0.2;
shieldGraphics.rotation += 0.01; // Slow rotation for energy field effect
// Create shimmering effect with color changes
var blueIntensity = 0.5 + Math.sin(self.pulseFactor * 1.5) * 0.3;
var cyanIntensity = 0.7 + Math.cos(self.pulseFactor * 0.8) * 0.3;
shieldGraphics.tint = Math.floor(0x33 * blueIntensity) << 16 | Math.floor(0xcc * cyanIntensity) << 8 | 0xff;
// Scale effect for "energy bubble" appearance
var scaleVar = 1 + Math.sin(self.pulseFactor * 0.7) * 0.05;
shieldGraphics.scale.x = scaleVar;
shieldGraphics.scale.y = scaleVar;
};
return self;
});
var UltraBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('plasmaBullet', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5,
tint: 0xffff00
});
self.speed = -18; // Very fast
self.damage = 5; // Highest damage
self.pulseFactor = 0;
self.update = function () {
self.y += self.speed;
// Dynamic visual effects
self.pulseFactor += 0.15;
var scale = 1.2 + Math.sin(self.pulseFactor) * 0.3;
bulletGraphics.scale.x = scale;
bulletGraphics.scale.y = scale;
bulletGraphics.rotation += 0.15;
// Electric discharge effect
if (LK.ticks % 2 === 0) {
var sparkEffect = LK.getAsset('plasmaBullet', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.7,
scaleX: 0.4,
scaleY: 0.4,
tint: 0xffff00
});
sparkEffect.x = self.x + (Math.random() * 40 - 20);
sparkEffect.y = self.y + (Math.random() * 40 - 20);
game.addChild(sparkEffect);
// Create fade-out effect
var sparkDuration = 8;
var fadeInterval = LK.setInterval(function () {
sparkDuration--;
sparkEffect.alpha -= 0.09;
sparkEffect.scaleX -= 0.04;
sparkEffect.scaleY -= 0.04;
if (sparkDuration <= 0) {
LK.clearInterval(fadeInterval);
sparkEffect.destroy();
}
}, 1);
}
// Colorful effect
var time = LK.ticks % 20;
var r = 255;
var g = 255;
var b = Math.floor(100 + time * 7);
bulletGraphics.tint = r << 16 | g << 8 | b;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000022
});
/****
* Game Code
****/
// Game variables
// Initialize main assets with high-quality shapes
var score = 0;
var highScore = storage.highScore || 0;
var level = 1;
var enemySpawnTimer = 0;
var enemySpawnRate = 60; // Frames between enemy spawns
var playerBullets = [];
var enemyBullets = [];
var enemies = [];
var powerUps = [];
var bossSpawned = false;
var levelComplete = false;
var gameOver = false;
var nextEnemy = 0;
// Create dynamic starfield background
var stars = [];
var starLayers = 3; // Multiple layers for parallax effect
// Initialize stars
for (var layer = 0; layer < starLayers; layer++) {
var count = 30 + layer * 20; // More stars in deeper layers
var speed = 1 + layer * 1.5; // Deeper layers move faster
var size = 3 - layer * 0.8; // Deeper layers have smaller stars
var alpha = 0.7 - layer * 0.2; // Deeper layers are more transparent
for (var i = 0; i < count; i++) {
var star = new Container();
var starGraphic = LK.getAsset('powerUp', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0xFFFFFF,
alpha: alpha,
scaleX: size / 60,
scaleY: size / 60
});
star.addChild(starGraphic);
star.x = Math.random() * 2048;
star.y = Math.random() * 2732;
star.speed = speed;
star.layer = layer;
// Add occasional color variation to brightest stars
if (layer === 0 && Math.random() < 0.3) {
var colors = [0xFFFFCC, 0xCCFFFF, 0xFFCCFF]; // Yellow, blue, pink tints
starGraphic.tint = colors[Math.floor(Math.random() * colors.length)];
}
game.addChild(star);
stars.push(star);
}
}
// Add function to update stars in main update loop
function updateStars() {
for (var i = 0; i < stars.length; i++) {
var star = stars[i];
star.y += star.speed;
// Reset stars when they go off screen
if (star.y > 2732) {
star.y = -10;
star.x = Math.random() * 2048;
}
}
}
// UI elements
var scoreTxt = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(scoreTxt);
var levelTxt = new Text2('Level: 1', {
size: 60,
fill: 0xFFFFFF
});
levelTxt.anchor.set(1, 0);
LK.gui.topLeft.addChild(levelTxt);
// Move it away from the top-left corner
levelTxt.x = 200;
var healthTxt = new Text2('Health: 3', {
size: 60,
fill: 0xFFFFFF
});
healthTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(healthTxt);
// Weapon type indicator
var weaponTxt = new Text2('Weapon: Standard', {
size: 40,
fill: 0xFFFFFF
});
weaponTxt.style = {
fill: 0xFFFFFF
}; // Initialize style object
weaponTxt.anchor.set(0, 0);
LK.gui.bottomLeft.addChild(weaponTxt);
weaponTxt.y = -100; // Position it above the bottom edge
// Function to update weapon display
function updateWeapon() {
var typeText = player.weaponType.charAt(0).toUpperCase() + player.weaponType.slice(1);
weaponTxt.setText('Weapon: ' + typeText + ' (Lv.' + player.weaponLevel + ')');
// Set text color based on weapon type
if (player.weaponType === "standard") {
weaponTxt.style.fill = 0x66ffff;
} else if (player.weaponType === "laser") {
weaponTxt.style.fill = 0x00ffaa;
} else if (player.weaponType === "plasma") {
weaponTxt.style.fill = 0xff00ff;
} else if (player.weaponType === "ultra") {
weaponTxt.style.fill = 0xffff00;
}
}
// Create player
var player = new Player();
player.x = 2048 / 2;
player.y = 2732 - 300;
game.addChild(player);
// Function to update score display
function updateScore() {
scoreTxt.setText('Score: ' + score);
// Update LK score system for leaderboards
LK.setScore(score);
}
// Function to update health display
function updateHealth() {
healthTxt.setText('Health: ' + player.health);
}
// Function to update level display
function updateLevel() {
levelTxt.setText('Level: ' + level);
}
// Function to spawn regular enemies
function spawnEnemy() {
var enemyType;
var enemy;
// Select enemy type based on level and randomness
if (level === 1) {
// Level 1: Only basic enemies
enemy = new Enemy();
enemy.health = 1;
enemy.movementPattern = "straight";
enemy.fireRate = 180;
} else if (level === 2) {
// Level 2: Basic enemies and some hunters
var rand = Math.random();
if (rand < 0.3) {
enemy = new HunterShip();
} else if (rand < 0.6) {
enemy = new Enemy();
enemy.health = 2;
enemy.points = 200;
enemy.movementPattern = "zigzag";
enemy.fireRate = 150;
} else {
enemy = new Enemy();
enemy.health = 1;
enemy.movementPattern = "straight";
enemy.fireRate = 180;
}
} else if (level >= 3 && level < 5) {
// Level 3-4: All enemy types
var rand = Math.random();
if (rand < 0.25) {
enemy = new CarrierShip();
} else if (rand < 0.5) {
enemy = new HunterShip();
} else if (rand < 0.7) {
enemy = new ScoutShip();
} else if (rand < 0.85) {
enemy = new Enemy();
enemy.health = 3;
enemy.points = 300;
enemy.movementPattern = "circle";
enemy.fireRate = 120;
} else {
enemy = new Enemy();
enemy.health = 2;
enemy.points = 200;
enemy.movementPattern = "zigzag";
enemy.fireRate = 150;
}
} else if (level >= 5) {
// Level 5+: Include elite enemies
var rand = Math.random();
if (rand < 0.2) {
enemy = new CarrierShip();
// Enhance carrier properties at higher levels
if (level >= 6) {
enemy.health += 2;
enemy.spawnRate = 150; // Faster spawning
}
} else if (rand < 0.35) {
enemy = new EliteHunterShip(); // Elite hunter
} else if (rand < 0.5) {
enemy = new HunterShip();
} else if (rand < 0.65) {
enemy = new EliteScoutShip(); // Elite scout
} else if (rand < 0.8) {
enemy = new ScoutShip();
} else {
enemy = new Enemy();
enemy.health = 3 + Math.min(level - 5, 3); // Scale up health
enemy.points = 300 + (level - 5) * 50;
enemy.movementPattern = "circle";
enemy.fireRate = Math.max(120 - (level - 5) * 10, 70); // Scale down fire rate (faster shooting)
}
}
// Random position at top of screen
enemy.x = 200 + Math.random() * (2048 - 400);
enemy.y = -100;
game.addChild(enemy);
enemies.push(enemy);
}
// Function to spawn boss
function spawnBoss() {
var boss;
// At higher levels, spawn the MegaBoss instead
if (level >= 4) {
boss = new MegaBoss();
boss.x = 2048 / 2;
boss.y = -300;
// Scale mega boss difficulty with level
boss.health = 50 + (level - 4) * 15;
boss.maxHealth = boss.health;
} else {
boss = new Boss();
boss.x = 2048 / 2;
boss.y = -200;
// Scale boss difficulty with level
boss.health = 20 + (level - 1) * 10;
boss.maxHealth = boss.health;
}
game.addChild(boss);
enemies.push(boss);
bossSpawned = true;
}
// Function to start the next level
function startNextLevel() {
level++;
updateLevel();
enemies = [];
enemyBullets = [];
bossSpawned = false;
levelComplete = false;
nextEnemy = 0;
// Speed up enemy spawns as level increases
enemySpawnRate = Math.max(60 - (level - 1) * 5, 30);
}
// Mouse/Touch handlers
var dragNode = null;
function handleMove(x, y, obj) {
if (dragNode) {
// Clamp position to stay on screen
dragNode.x = Math.max(60, Math.min(x, 2048 - 60));
dragNode.y = Math.max(60, Math.min(y, 2732 - 60));
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
dragNode = player;
handleMove(x, y, obj);
};
game.up = function (x, y, obj) {
dragNode = null;
};
// Main game update loop
game.update = function () {
// Update starfield background for space atmosphere
updateStars();
if (gameOver) {
// Show game over screen
LK.showGameOver();
return;
}
if (levelComplete) {
startNextLevel();
}
// Update player
player.update();
updateHealth();
updateWeapon();
// Spawn enemies
if (!bossSpawned) {
enemySpawnTimer++;
if (enemySpawnTimer >= enemySpawnRate) {
enemySpawnTimer = 0;
spawnEnemy();
nextEnemy++;
// Spawn boss after certain number of enemies
if (nextEnemy >= 15 + level * 5) {
spawnBoss();
}
}
}
// Update player bullets
for (var i = playerBullets.length - 1; i >= 0; i--) {
var bullet = playerBullets[i];
// Check if bullet is off screen
if (bullet.y < -50) {
bullet.destroy();
playerBullets.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)) {
if (enemy.takeDamage(bullet.damage)) {
enemies.splice(j, 1);
}
bullet.destroy();
playerBullets.splice(i, 1);
break;
}
}
}
// Update enemy bullets
for (var i = enemyBullets.length - 1; i >= 0; i--) {
var bullet = enemyBullets[i];
// Check if bullet is off screen
if (bullet.y > 2732 + 50) {
bullet.destroy();
enemyBullets.splice(i, 1);
continue;
}
// Check for collision with player
if (bullet.intersects(player)) {
if (player.takeDamage(bullet.damage)) {
// Player destroyed, game over
gameOver = true;
}
bullet.destroy();
enemyBullets.splice(i, 1);
}
}
// Update enemies
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
// Check if enemy is off screen
if (enemy.y > 2732 + 100) {
enemy.destroy();
enemies.splice(i, 1);
continue;
}
// Check for collision with player
if (enemy.intersects(player)) {
if (player.takeDamage(1)) {
// Player destroyed, game over
gameOver = true;
}
// Enemy also takes damage
if (enemy.takeDamage(1)) {
enemies.splice(i, 1);
}
continue;
}
}
// Update power-ups
for (var i = powerUps.length - 1; i >= 0; i--) {
var powerUp = powerUps[i];
// Check if power-up is off screen
if (powerUp.y > 2732 + 50) {
powerUp.destroy();
powerUps.splice(i, 1);
continue;
}
// Check for collision with player
if (powerUp.intersects(player)) {
player.collectPowerUp(powerUp);
powerUp.destroy();
powerUps.splice(i, 1);
}
}
// Check if level is complete (no enemies and boss killed)
if (bossSpawned && enemies.length === 0) {
levelComplete = true;
}
};
// Start background music
LK.playMusic('bgMusic');
a boss robot space ship . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
a enemy space ship. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
a red enemy bullet plasma. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
a enemy space ship crarrier ship. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
a explosion. In-Game asset. 2d. High contrast. No shadows
a enemy space ship hunter ship. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
a blue plasma laser. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
a blue plasma flame fire. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
a player bullet. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
a player space ship good. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
a level up power up orb. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
a tiny enemy ship. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
a shield. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat