/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Asteroid = Container.expand(function () { var self = Container.call(this); var size = 1.0 + Math.random() * 2.0; // Random size between 1.0 and 3.0 var asteroidGraphics = self.attachAsset('asteroid', { anchorX: 0.5, anchorY: 0.5, scaleX: size * 1.5, scaleY: size * 1.5 }); self.speed = 1 + Math.random() * 4; // Random speed self.rotationSpeed = (Math.random() - 0.5) * 0.05; // Random rotation self.update = function () { self.y += self.speed; self.rotation += self.rotationSpeed; }; return self; }); var Boss = Container.expand(function () { var self = Container.call(this); var bossGraphics = self.attachAsset('boss', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.health = 30; self.maxHealth = 30; self.speed = 3; self.points = 500; self.phase = 1; self.moveDirection = 1; self.fireRate = 60; self.lastFired = 0; self.patternTimer = 0; self.currentPattern = 'move'; self.update = function () { self.patternTimer++; // Change patterns every few seconds if (self.patternTimer >= 180) { self.patternTimer = 0; self.currentPattern = self.currentPattern === 'move' ? 'attack' : 'move'; } // Movement pattern if (self.currentPattern === 'move') { self.x += self.speed * self.moveDirection; // Reverse direction if approaching screen edge if (self.x < 300 || self.x > 2048 - 300) { self.moveDirection *= -1; } } // Attack pattern if (self.currentPattern === 'attack') { self.lastFired++; if (self.lastFired >= self.fireRate) { self.lastFired = 0; return true; // Signal to create bullets } } // Change phase based on health if (self.health <= self.maxHealth * 0.6 && self.phase === 1) { self.phase = 2; self.speed = 4; self.fireRate = 45; } else if (self.health <= self.maxHealth * 0.3 && self.phase === 2) { self.phase = 3; self.speed = 5; self.fireRate = 30; } return false; }; self.takeDamage = function (amount) { self.health -= amount; // Flash boss red when hit LK.effects.flashObject(self, 0xff0000, 300); return self.health <= 0; }; return self; }); var Bullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.speed = -15; // Negative because bullets move upward self.damage = 1; self.update = function () { self.y += self.speed; }; return self; }); var Button = Container.expand(function (options) { var self = Container.call(this); var buttonGraphics = self.attachAsset('button', { anchorX: options.anchorX || 0.5, anchorY: options.anchorY || 0.5 }); var buttonText = new Text2(options.text, { size: options.size || 50, fill: options.fill || 0xFFFFFF }); buttonText.anchor.set(0.5, 0.5); self.addChild(buttonText); self.x = options.x || 0; self.y = options.y || 0; self.on('down', options.onDown || function () {}); return self; }); // --- 31. Add a new asteroid type: ComboAsteroid (drops combo powerup on death) var ComboAsteroid = Container.expand(function () { var self = Container.call(this); var asteroidGraphics = self.attachAsset('asteroid', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.speed = 2.5; self.update = function () { self.y += self.speed; }; self.dropCombo = function () { var combo = new ComboPowerup(); combo.x = self.x; combo.y = self.y; game.addChild(combo); powerups.push(combo); }; return self; }); // --- 38. Add a new asteroid type: ComboHealthAsteroid (drops combo and health powerups) var ComboHealthAsteroid = Container.expand(function () { var self = Container.call(this); var asteroidGraphics = self.attachAsset('asteroid', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.speed = 2.5; self.update = function () { self.y += self.speed; }; self.dropComboAndHealth = function () { var combo = new ComboPowerup(); combo.x = self.x; combo.y = self.y; game.addChild(combo); powerups.push(combo); var health = new HealthPowerup(); health.x = self.x - 30; health.y = self.y; game.addChild(health); powerups.push(health); }; return self; }); // --- 37. Add a new asteroid type: ComboMagnetAsteroid (drops combo and magnet powerups) var ComboMagnetAsteroid = Container.expand(function () { var self = Container.call(this); var asteroidGraphics = self.attachAsset('asteroid', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.speed = 2.5; self.update = function () { self.y += self.speed; }; self.dropComboAndMagnet = function () { var combo = new ComboPowerup(); combo.x = self.x; combo.y = self.y; game.addChild(combo); powerups.push(combo); var magnet = new MagnetPowerup(); magnet.x = self.x + 30; magnet.y = self.y; game.addChild(magnet); powerups.push(magnet); }; return self; }); // --- 1. Combo Powerup: Grants both shield and fire rate for 5 seconds var ComboPowerup = Container.expand(function () { var self = Container.call(this); var powerupGraphics = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5, scaleX: 3.5, scaleY: 3.5 }); self.type = 'combo'; self.speed = 3; powerupGraphics.tint = 0xff00ff; // Magenta for combo self.update = function () { self.y += self.speed; var scale = 1 + Math.sin(LK.ticks * 0.1) * 0.1; powerupGraphics.scale.set(scale, scale); }; return self; }); // --- 39. Add a new asteroid type: ComboScoreMultiplierAsteroid (drops combo and score multiplier powerups) var ComboScoreMultiplierAsteroid = Container.expand(function () { var self = Container.call(this); var asteroidGraphics = self.attachAsset('asteroid', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.speed = 2.5; self.update = function () { self.y += self.speed; }; self.dropComboAndScoreMultiplier = function () { var combo = new ComboPowerup(); combo.x = self.x; combo.y = self.y; game.addChild(combo); powerups.push(combo); var sm = new ScoreMultiplierPowerup(); sm.x = self.x + 30; sm.y = self.y; game.addChild(sm); powerups.push(sm); }; return self; }); // --- 36. Add a new asteroid type: ComboSwarmAsteroid (spawns SwarmEnemies and drops combo powerup) var ComboSwarmAsteroid = Container.expand(function () { var self = Container.call(this); var asteroidGraphics = self.attachAsset('asteroid', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.speed = 2.5; self.update = function () { self.y += self.speed; }; self.spawnSwarmAndDropCombo = function () { for (var i = 0; i < 3; i++) { var swarm = new SwarmEnemy(); swarm.x = self.x + (Math.random() - 0.5) * 100; swarm.y = self.y; game.addChild(swarm); enemies.push(swarm); } var combo = new ComboPowerup(); combo.x = self.x; combo.y = self.y; game.addChild(combo); powerups.push(combo); }; return self; }); // --- 41. Add a new asteroid type: ComboSwarmHealthAsteroid (spawns SwarmEnemies, drops combo and health powerups) var ComboSwarmHealthAsteroid = Container.expand(function () { var self = Container.call(this); var asteroidGraphics = self.attachAsset('asteroid', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.speed = 2.5; self.update = function () { self.y += self.speed; }; self.spawnSwarmDropComboHealth = function () { for (var i = 0; i < 3; i++) { var swarm = new SwarmEnemy(); swarm.x = self.x + (Math.random() - 0.5) * 100; swarm.y = self.y; game.addChild(swarm); enemies.push(swarm); } var combo = new ComboPowerup(); combo.x = self.x; combo.y = self.y; game.addChild(combo); powerups.push(combo); var health = new HealthPowerup(); health.x = self.x - 30; health.y = self.y; game.addChild(health); powerups.push(health); }; return self; }); // --- 45. Add a new asteroid type: ComboSwarmHealthScoreMultiplierAsteroid (spawns SwarmEnemies, drops combo, health, and score multiplier powerups) var ComboSwarmHealthScoreMultiplierAsteroid = Container.expand(function () { var self = Container.call(this); var asteroidGraphics = self.attachAsset('asteroid', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.speed = 2.5; self.update = function () { self.y += self.speed; }; self.spawnSwarmDropComboHealthScoreMultiplier = function () { for (var i = 0; i < 3; i++) { var swarm = new SwarmEnemy(); swarm.x = self.x + (Math.random() - 0.5) * 100; swarm.y = self.y; game.addChild(swarm); enemies.push(swarm); } var combo = new ComboPowerup(); combo.x = self.x; combo.y = self.y; game.addChild(combo); powerups.push(combo); var health = new HealthPowerup(); health.x = self.x + 30; health.y = self.y; game.addChild(health); powerups.push(health); var sm = new ScoreMultiplierPowerup(); sm.x = self.x - 30; sm.y = self.y; game.addChild(sm); powerups.push(sm); }; return self; }); // --- 40. Add a new asteroid type: ComboSwarmMagnetAsteroid (spawns SwarmEnemies, drops combo and magnet powerups) var ComboSwarmMagnetAsteroid = Container.expand(function () { var self = Container.call(this); var asteroidGraphics = self.attachAsset('asteroid', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.speed = 2.5; self.update = function () { self.y += self.speed; }; self.spawnSwarmDropComboMagnet = function () { for (var i = 0; i < 3; i++) { var swarm = new SwarmEnemy(); swarm.x = self.x + (Math.random() - 0.5) * 100; swarm.y = self.y; game.addChild(swarm); enemies.push(swarm); } var combo = new ComboPowerup(); combo.x = self.x; combo.y = self.y; game.addChild(combo); powerups.push(combo); var magnet = new MagnetPowerup(); magnet.x = self.x + 30; magnet.y = self.y; game.addChild(magnet); powerups.push(magnet); }; return self; }); // --- 43. Add a new asteroid type: ComboSwarmMagnetHealthAsteroid (spawns SwarmEnemies, drops combo, magnet, and health powerups) var ComboSwarmMagnetHealthAsteroid = Container.expand(function () { var self = Container.call(this); var asteroidGraphics = self.attachAsset('asteroid', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.speed = 2.5; self.update = function () { self.y += self.speed; }; self.spawnSwarmDropComboMagnetHealth = function () { for (var i = 0; i < 3; i++) { var swarm = new SwarmEnemy(); swarm.x = self.x + (Math.random() - 0.5) * 100; swarm.y = self.y; game.addChild(swarm); enemies.push(swarm); } var combo = new ComboPowerup(); combo.x = self.x; combo.y = self.y; game.addChild(combo); powerups.push(combo); var magnet = new MagnetPowerup(); magnet.x = self.x + 30; magnet.y = self.y; game.addChild(magnet); powerups.push(magnet); var health = new HealthPowerup(); health.x = self.x - 30; health.y = self.y; game.addChild(health); powerups.push(health); }; return self; }); // --- 46. Add a new asteroid type: ComboSwarmMagnetHealthScoreMultiplierAsteroid (spawns SwarmEnemies, drops combo, magnet, health, and score multiplier powerups) var ComboSwarmMagnetHealthScoreMultiplierAsteroid = Container.expand(function () { var self = Container.call(this); var asteroidGraphics = self.attachAsset('asteroid', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.speed = 2.5; self.update = function () { self.y += self.speed; }; self.spawnSwarmDropComboMagnetHealthScoreMultiplier = function () { for (var i = 0; i < 3; i++) { var swarm = new SwarmEnemy(); swarm.x = self.x + (Math.random() - 0.5) * 100; swarm.y = self.y; game.addChild(swarm); enemies.push(swarm); } var combo = new ComboPowerup(); combo.x = self.x; combo.y = self.y; game.addChild(combo); powerups.push(combo); var magnet = new MagnetPowerup(); magnet.x = self.x + 30; magnet.y = self.y; game.addChild(magnet); powerups.push(magnet); var health = new HealthPowerup(); health.x = self.x - 30; health.y = self.y; game.addChild(health); powerups.push(health); var sm = new ScoreMultiplierPowerup(); sm.x = self.x + 60; sm.y = self.y; game.addChild(sm); powerups.push(sm); }; return self; }); // --- 47. Add a new asteroid type: ComboSwarmMagnetHealthScoreMultiplierTimeSlowAsteroid (spawns SwarmEnemies, drops combo, magnet, health, score multiplier, and time slow powerups) var ComboSwarmMagnetHealthScoreMultiplierTimeSlowAsteroid = Container.expand(function () { var self = Container.call(this); var asteroidGraphics = self.attachAsset('asteroid', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.speed = 2.5; self.update = function () { self.y += self.speed; }; self.spawnSwarmDropAll = function () { for (var i = 0; i < 3; i++) { var swarm = new SwarmEnemy(); swarm.x = self.x + (Math.random() - 0.5) * 100; swarm.y = self.y; game.addChild(swarm); enemies.push(swarm); } var combo = new ComboPowerup(); combo.x = self.x; combo.y = self.y; game.addChild(combo); powerups.push(combo); var magnet = new MagnetPowerup(); magnet.x = self.x + 30; magnet.y = self.y; game.addChild(magnet); powerups.push(magnet); var health = new HealthPowerup(); health.x = self.x - 30; health.y = self.y; game.addChild(health); powerups.push(health); var sm = new ScoreMultiplierPowerup(); sm.x = self.x + 60; sm.y = self.y; game.addChild(sm); powerups.push(sm); var ts = new TimeSlowPowerup(); ts.x = self.x - 60; ts.y = self.y; game.addChild(ts); powerups.push(ts); }; return self; }); // --- 48. Add a new asteroid type: ComboSwarmMagnetHealthScoreMultiplierTimeSlowHealerAsteroid (spawns SwarmEnemies, drops combo, magnet, health, score multiplier, time slow, and heals player) var ComboSwarmMagnetHealthScoreMultiplierTimeSlowHealerAsteroid = Container.expand(function () { var self = Container.call(this); var asteroidGraphics = self.attachAsset('asteroid', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.speed = 2.5; self.update = function () { self.y += self.speed; }; self.spawnSwarmDropAllHeal = function () { for (var i = 0; i < 3; i++) { var swarm = new SwarmEnemy(); swarm.x = self.x + (Math.random() - 0.5) * 100; swarm.y = self.y; game.addChild(swarm); enemies.push(swarm); } var combo = new ComboPowerup(); combo.x = self.x; combo.y = self.y; game.addChild(combo); powerups.push(combo); var magnet = new MagnetPowerup(); magnet.x = self.x + 30; magnet.y = self.y; game.addChild(magnet); powerups.push(magnet); var health = new HealthPowerup(); health.x = self.x - 30; health.y = self.y; game.addChild(health); powerups.push(health); var sm = new ScoreMultiplierPowerup(); sm.x = self.x + 60; sm.y = self.y; game.addChild(sm); powerups.push(sm); var ts = new TimeSlowPowerup(); ts.x = self.x - 60; ts.y = self.y; game.addChild(ts); powerups.push(ts); if (player) { player.health = Math.min(player.health + 2, 10); updateUI(); } }; return self; }); // --- 49. Add a new asteroid type: ComboSwarmMagnetHealthScoreMultiplierTimeSlowHealerScoreAsteroid (spawns SwarmEnemies, drops combo, magnet, health, score multiplier, time slow, heals player, and gives bonus score) var ComboSwarmMagnetHealthScoreMultiplierTimeSlowHealerScoreAsteroid = Container.expand(function () { var self = Container.call(this); var asteroidGraphics = self.attachAsset('asteroid', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.speed = 2.5; self.update = function () { self.y += self.speed; }; self.spawnSwarmDropAllHealScore = function () { for (var i = 0; i < 3; i++) { var swarm = new SwarmEnemy(); swarm.x = self.x + (Math.random() - 0.5) * 100; swarm.y = self.y; game.addChild(swarm); enemies.push(swarm); } var combo = new ComboPowerup(); combo.x = self.x; combo.y = self.y; game.addChild(combo); powerups.push(combo); var magnet = new MagnetPowerup(); magnet.x = self.x + 30; magnet.y = self.y; game.addChild(magnet); powerups.push(magnet); var health = new HealthPowerup(); health.x = self.x - 30; health.y = self.y; game.addChild(health); powerups.push(health); var sm = new ScoreMultiplierPowerup(); sm.x = self.x + 60; sm.y = self.y; game.addChild(sm); powerups.push(sm); var ts = new TimeSlowPowerup(); ts.x = self.x - 60; ts.y = self.y; game.addChild(ts); powerups.push(ts); if (player) { player.health = Math.min(player.health + 2, 10); updateUI(); } LK.setScore(LK.getScore() + 500); updateUI(); }; return self; }); // --- 50. Add a new asteroid type: ComboSwarmMagnetHealthScoreMultiplierTimeSlowHealerScoreReflectorAsteroid (spawns SwarmEnemies, drops combo, magnet, health, score multiplier, time slow, heals player, gives bonus score, and reflects bullets) var ComboSwarmMagnetHealthScoreMultiplierTimeSlowHealerScoreReflectorAsteroid = Container.expand(function () { var self = Container.call(this); var asteroidGraphics = self.attachAsset('asteroid', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.speed = 2.5; self.reflects = true; self.update = function () { self.y += self.speed; }; self.spawnSwarmDropAllHealScoreReflect = function () { for (var i = 0; i < 3; i++) { var swarm = new SwarmEnemy(); swarm.x = self.x + (Math.random() - 0.5) * 100; swarm.y = self.y; game.addChild(swarm); enemies.push(swarm); } var combo = new ComboPowerup(); combo.x = self.x; combo.y = self.y; game.addChild(combo); powerups.push(combo); var magnet = new MagnetPowerup(); magnet.x = self.x + 30; magnet.y = self.y; game.addChild(magnet); powerups.push(magnet); var health = new HealthPowerup(); health.x = self.x - 30; health.y = self.y; game.addChild(health); powerups.push(health); var sm = new ScoreMultiplierPowerup(); sm.x = self.x + 60; sm.y = self.y; game.addChild(sm); powerups.push(sm); var ts = new TimeSlowPowerup(); ts.x = self.x - 60; ts.y = self.y; game.addChild(ts); powerups.push(ts); if (player) { player.health = Math.min(player.health + 2, 10); updateUI(); } LK.setScore(LK.getScore() + 500); updateUI(); }; return self; }); // --- 44. Add a new asteroid type: ComboSwarmMagnetScoreMultiplierAsteroid (spawns SwarmEnemies, drops combo, magnet, and score multiplier powerups) var ComboSwarmMagnetScoreMultiplierAsteroid = Container.expand(function () { var self = Container.call(this); var asteroidGraphics = self.attachAsset('asteroid', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.speed = 2.5; self.update = function () { self.y += self.speed; }; self.spawnSwarmDropComboMagnetScoreMultiplier = function () { for (var i = 0; i < 3; i++) { var swarm = new SwarmEnemy(); swarm.x = self.x + (Math.random() - 0.5) * 100; swarm.y = self.y; game.addChild(swarm); enemies.push(swarm); } var combo = new ComboPowerup(); combo.x = self.x; combo.y = self.y; game.addChild(combo); powerups.push(combo); var magnet = new MagnetPowerup(); magnet.x = self.x + 30; magnet.y = self.y; game.addChild(magnet); powerups.push(magnet); var sm = new ScoreMultiplierPowerup(); sm.x = self.x - 30; sm.y = self.y; game.addChild(sm); powerups.push(sm); }; return self; }); // --- 42. Add a new asteroid type: ComboSwarmScoreMultiplierAsteroid (spawns SwarmEnemies, drops combo and score multiplier powerups) var ComboSwarmScoreMultiplierAsteroid = Container.expand(function () { var self = Container.call(this); var asteroidGraphics = self.attachAsset('asteroid', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.speed = 2.5; self.update = function () { self.y += self.speed; }; self.spawnSwarmDropComboScoreMultiplier = function () { for (var i = 0; i < 3; i++) { var swarm = new SwarmEnemy(); swarm.x = self.x + (Math.random() - 0.5) * 100; swarm.y = self.y; game.addChild(swarm); enemies.push(swarm); } var combo = new ComboPowerup(); combo.x = self.x; combo.y = self.y; game.addChild(combo); powerups.push(combo); var sm = new ScoreMultiplierPowerup(); sm.x = self.x + 30; sm.y = self.y; game.addChild(sm); powerups.push(sm); }; return self; }); var Enemy = Container.expand(function () { var self = Container.call(this); var enemyGraphics = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.health = 1; self.speed = 2; self.points = 10; self.canShoot = false; self.fireRate = 120; // Frames between shots self.lastFired = Math.floor(Math.random() * 60); // Randomize initial fire time self.movePattern = 'straight'; // Default pattern self.amplitude = 100; // For wave pattern self.frequency = 0.02; // For wave pattern self.startX = 0; // Store initial X position for wave pattern self.direction = 1; // For zigzag pattern self.update = function () { // Basic movement if (self.movePattern === 'straight') { self.y += self.speed; } else if (self.movePattern === 'wave') { self.y += self.speed; self.x = self.startX + Math.sin(self.y * self.frequency) * self.amplitude; } else if (self.movePattern === 'zigzag') { self.y += self.speed; self.x += self.speed * self.direction; // Reverse direction if approaching screen edge if (self.x < 100 || self.x > 2048 - 100) { self.direction *= -1; } } // Enemy shooting logic if (self.canShoot) { self.lastFired++; if (self.lastFired >= self.fireRate) { self.lastFired = 0; return true; // Signal to create a bullet } } return false; }; self.takeDamage = function (amount) { self.health -= amount; return self.health <= 0; }; return self; }); var EnemyBullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('enemyBullet', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.speed = 8; self.update = function () { self.y += self.speed; }; return self; }); // --- 9. Add a new enemy type: ExploderEnemy (explodes on death, damaging nearby) var ExploderEnemy = Container.expand(function () { var self = Container.call(this); var enemyGraphics = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.health = 2; self.speed = 2.5; self.points = 30; self.update = function () { self.y += self.speed; }; self.takeDamage = function (amount) { self.health -= amount; if (self.health <= 0) { // Damage all enemies within 150px for (var i = 0; i < enemies.length; i++) { var e = enemies[i]; if (e !== self && Math.abs(e.x - self.x) < 150 && Math.abs(e.y - self.y) < 150) { e.takeDamage(1); LK.effects.flashObject(e, 0xff8800, 300); } } // Damage player if close if (player && Math.abs(player.x - self.x) < 150 && Math.abs(player.y - self.y) < 150) { player.takeDamage(); updateUI(); handleGameOver(); } return true; } return false; }; return self; }); // --- 21. Add a new asteroid type: ExplodingAsteroid (explodes on death) var ExplodingAsteroid = Container.expand(function () { var self = Container.call(this); var asteroidGraphics = self.attachAsset('asteroid', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.5, scaleY: 2.5 }); self.speed = 2.5; self.update = function () { self.y += self.speed; }; self.explode = function () { // Damage player if close if (player && Math.abs(player.x - self.x) < 200 && Math.abs(player.y - self.y) < 200) { player.takeDamage(); updateUI(); handleGameOver(); } LK.effects.flashScreen(0xff8800, 500); }; return self; }); // --- 18. Add a new asteroid type: FastAsteroid var FastAsteroid = Container.expand(function () { var self = Container.call(this); var asteroidGraphics = self.attachAsset('asteroid', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.0 + Math.random() * 1.5, scaleY: 1.0 + Math.random() * 1.5 }); self.speed = 8 + Math.random() * 4; self.rotationSpeed = (Math.random() - 0.5) * 0.1; self.update = function () { self.y += self.speed; self.rotation += self.rotationSpeed; }; return self; }); // --- 7. Add a new enemy type: FastEnemy (moves very fast, low health) var FastEnemy = Container.expand(function () { var self = Container.call(this); var enemyGraphics = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5 }); self.health = 1; self.speed = 7; self.points = 20; self.update = function () { self.y += self.speed; }; self.takeDamage = function (amount) { self.health -= amount; return self.health <= 0; }; return self; }); // --- 25. Add a new asteroid type: GhostAsteroid (only hit by powerup bullets) var GhostAsteroid = Container.expand(function () { var self = Container.call(this); var asteroidGraphics = self.attachAsset('asteroid', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.speed = 2.5; self.health = 2; self.update = function () { self.y += self.speed; }; self.takeDamage = function (amount, isPowerup) { if (isPowerup) { self.health -= amount; } return self.health <= 0; }; self.isGhost = true; return self; }); // --- 11. Add a new enemy type: GhostEnemy (can phase through player, only hit by powerup bullets) var GhostEnemy = Container.expand(function () { var self = Container.call(this); var enemyGraphics = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.health = 2; self.speed = 2.2; self.points = 40; self.update = function () { self.y += self.speed; }; self.takeDamage = function (amount, isPowerup) { if (isPowerup) { self.health -= amount; } return self.health <= 0; }; self.isGhost = true; return self; }); // --- 19. Add a new asteroid type: GiantAsteroid (splits into smaller asteroids) var GiantAsteroid = Container.expand(function () { var self = Container.call(this); var asteroidGraphics = self.attachAsset('asteroid', { anchorX: 0.5, anchorY: 0.5, scaleX: 4.0, scaleY: 4.0 }); self.speed = 2 + Math.random() * 2; self.rotationSpeed = (Math.random() - 0.5) * 0.05; self.update = function () { self.y += self.speed; self.rotation += self.rotationSpeed; }; self.split = function () { for (var i = 0; i < 3; i++) { var smallAsteroid = new Asteroid(); smallAsteroid.x = self.x + (Math.random() - 0.5) * 100; smallAsteroid.y = self.y; game.addChild(smallAsteroid); asteroids.push(smallAsteroid); } }; return self; }); // --- 27. Add a new asteroid type: HealerAsteroid (heals player on death) var HealerAsteroid = Container.expand(function () { var self = Container.call(this); var asteroidGraphics = self.attachAsset('asteroid', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.speed = 2.5; self.update = function () { self.y += self.speed; }; self.healPlayer = function () { if (player) { player.health = Math.min(player.health + 1, 10); updateUI(); } }; return self; }); // --- 17. Add a new boss: HealerBoss (heals itself and enemies every 8 seconds) var HealerBoss = Container.expand(function () { var self = Container.call(this); var bossGraphics = self.attachAsset('boss', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.health = 80; self.maxHealth = 80; self.speed = 2.0; self.points = 1700; self.phase = 1; self.moveDirection = 1; self.fireRate = 60; self.lastFired = 0; self.healTimer = 0; self.update = function () { self.x += self.speed * self.moveDirection; if (self.x < 300 || self.x > 2048 - 300) { self.moveDirection *= -1; } self.lastFired++; if (self.lastFired >= self.fireRate) { self.lastFired = 0; return true; } self.healTimer++; if (self.healTimer >= 480) { self.healTimer = 0; self.health = Math.min(self.maxHealth, self.health + 10); for (var i = 0; i < enemies.length; i++) { enemies[i].health = Math.min(5, enemies[i].health + 1); LK.effects.flashObject(enemies[i], 0x00ff00, 300); } LK.effects.flashObject(self, 0x00ff00, 1000); } return false; }; self.takeDamage = function (amount) { self.health -= amount; LK.effects.flashObject(self, 0x00ff00, 300); return self.health <= 0; }; return self; }); // --- 8. Add a new enemy type: HealerEnemy (heals other enemies) var HealerEnemy = Container.expand(function () { var self = Container.call(this); var enemyGraphics = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.health = 2; self.speed = 1.5; self.points = 25; self.healRate = 180; self.lastHeal = 0; self.update = function () { self.y += self.speed; self.lastHeal++; if (self.lastHeal >= self.healRate) { self.lastHeal = 0; // Heal a random enemy if (enemies.length > 1) { for (var i = 0; i < 2; i++) { var idx = Math.floor(Math.random() * enemies.length); if (enemies[idx] !== self && enemies[idx].health < 5) { enemies[idx].health++; LK.effects.flashObject(enemies[idx], 0x00ff00, 300); break; } } } } }; self.takeDamage = function (amount) { self.health -= amount; return self.health <= 0; }; return self; }); // --- 3. Health Powerup: Restores 1 health var HealthPowerup = Container.expand(function () { var self = Container.call(this); var powerupGraphics = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5, scaleX: 3.5, scaleY: 3.5 }); self.type = 'health'; self.speed = 3; powerupGraphics.tint = 0x00ff99; // Teal for health self.update = function () { self.y += self.speed; var scale = 1 + Math.sin(LK.ticks * 0.1) * 0.1; powerupGraphics.scale.set(scale, scale); }; return self; }); // --- 33. Add a new asteroid type: HealthPowerupAsteroid (drops health powerup on death) var HealthPowerupAsteroid = Container.expand(function () { var self = Container.call(this); var asteroidGraphics = self.attachAsset('asteroid', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.speed = 2.5; self.update = function () { self.y += self.speed; }; self.dropHealth = function () { var health = new HealthPowerup(); health.x = self.x; health.y = self.y; game.addChild(health); powerups.push(health); }; return self; }); var HeavyEnemy = Container.expand(function () { var self = Container.call(this); var heavyEnemyGraphics = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5, scaleX: 3.0, scaleY: 3.0 }); self.health = 5; self.speed = 1; self.points = 50; self.update = function () { self.y += self.speed; }; self.takeDamage = function (amount) { self.health -= amount; return self.health <= 0; }; return self; }); // --- 20. Add a new asteroid type: HomingAsteroid (follows player) var HomingAsteroid = Container.expand(function () { var self = Container.call(this); var asteroidGraphics = self.attachAsset('asteroid', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.speed = 3; self.update = function () { if (player) { var angle = Math.atan2(player.y - self.y, player.x - self.x); self.x += Math.cos(angle) * self.speed; self.y += Math.sin(angle) * self.speed; } }; return self; }); var KamikazeEnemy = Container.expand(function () { var self = Container.call(this); var enemyGraphics = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.health = 1; self.speed = 4; self.points = 15; self.update = function () { // Move directly towards the player if (player) { var angle = Math.atan2(player.y - self.y, player.x - self.x); self.x += Math.cos(angle) * self.speed; self.y += Math.sin(angle) * self.speed; } }; self.takeDamage = function (amount) { self.health -= amount; return self.health <= 0; }; return self; }); // --- 30. Add a new asteroid type: MagnetAsteroid (attracts all powerups to itself) var MagnetAsteroid = Container.expand(function () { var self = Container.call(this); var asteroidGraphics = self.attachAsset('asteroid', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.speed = 2.5; self.update = function () { self.y += self.speed; // Attract powerups for (var i = 0; i < powerups.length; i++) { var p = powerups[i]; var angle = Math.atan2(self.y - p.y, self.x - p.x); p.x += Math.cos(angle) * 2; p.y += Math.sin(angle) * 2; } }; return self; }); // --- 2. Magnet Powerup: Attracts all powerups to player for 5 seconds var MagnetPowerup = Container.expand(function () { var self = Container.call(this); var powerupGraphics = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5, scaleX: 3.5, scaleY: 3.5 }); self.type = 'magnet'; self.speed = 3; powerupGraphics.tint = 0xffff00; // Yellow for magnet self.update = function () { self.y += self.speed; var scale = 1 + Math.sin(LK.ticks * 0.1) * 0.1; powerupGraphics.scale.set(scale, scale); }; return self; }); // --- 32. Add a new asteroid type: MagnetPowerupAsteroid (drops magnet powerup on death) var MagnetPowerupAsteroid = Container.expand(function () { var self = Container.call(this); var asteroidGraphics = self.attachAsset('asteroid', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.speed = 2.5; self.update = function () { self.y += self.speed; }; self.dropMagnet = function () { var magnet = new MagnetPowerup(); magnet.x = self.x; magnet.y = self.y; game.addChild(magnet); powerups.push(magnet); }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.health = 3; self.fireRate = 20; self.lastFired = 0; self.speed = 10; self.powerupTimer = 0; self.hasPowerup = false; self.takeDamage = function () { if (self.invulnerable) { return; } self.health--; LK.getSound('playerHit').play(); // Flash player to indicate damage self.invulnerable = true; // Blink effect to show invulnerability var blinkCount = 0; var blinkInterval = LK.setInterval(function () { playerGraphics.alpha = playerGraphics.alpha === 1 ? 0.2 : 1; blinkCount++; if (blinkCount >= 10) { LK.clearInterval(blinkInterval); playerGraphics.alpha = 1; self.invulnerable = false; } }, 150); }; self.activatePowerup = function (type) { LK.getSound('powerupCollected').play(); self.hasPowerup = true; self.powerupTimer = 300; // 5 seconds at 60fps if (type === 'fire') { self.fireRate = 10; // Faster fire rate playerGraphics.tint = 0xff0000; } else if (type === 'shield') { self.invulnerable = true; playerGraphics.tint = 0x00ffff; } else if (type === 'timeSlow') { self.timeSlowActive = true; game.setGameSpeed(0.5); // Slow down game speed playerGraphics.tint = 0x00ff00; // Green tint for time slow } }; self.update = function () { // Handle powerup duration if (self.hasPowerup) { self.powerupTimer--; if (self.powerupTimer <= 0) { self.hasPowerup = false; self.fireRate = 20; // Reset to normal self.invulnerable = false; playerGraphics.tint = 0xffffff; // Reset tint if (self.timeSlowActive) { self.timeSlowActive = false; game.setGameSpeed(1); // Reset game speed to normal } } } }; return self; }); var PlayerShip2 = Container.expand(function () { var self = Container.call(this); var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.health = 5; self.fireRate = 15; self.lastFired = 0; self.speed = 12; self.powerupTimer = 0; self.hasPowerup = false; self.takeDamage = function () { if (self.invulnerable) { return; } self.health--; LK.getSound('playerHit').play(); self.invulnerable = true; var blinkCount = 0; var blinkInterval = LK.setInterval(function () { playerGraphics.alpha = playerGraphics.alpha === 1 ? 0.2 : 1; blinkCount++; if (blinkCount >= 10) { LK.clearInterval(blinkInterval); playerGraphics.alpha = 1; self.invulnerable = false; } }, 150); }; self.activatePowerup = function (type) { LK.getSound('powerupCollected').play(); self.hasPowerup = true; self.powerupTimer = 300; if (type === 'fire') { self.fireRate = 8; playerGraphics.tint = 0xff0000; } else if (type === 'shield') { self.invulnerable = true; playerGraphics.tint = 0x00ffff; } else if (type === 'timeSlow') { self.timeSlowActive = true; game.setGameSpeed(0.5); playerGraphics.tint = 0x00ff00; } }; self.update = function () { if (self.hasPowerup) { self.powerupTimer--; if (self.powerupTimer <= 0) { self.hasPowerup = false; self.fireRate = 15; self.invulnerable = false; playerGraphics.tint = 0xffffff; if (self.timeSlowActive) { self.timeSlowActive = false; game.setGameSpeed(1); } } } }; return self; }); var PlayerShip3 = Container.expand(function () { var self = Container.call(this); var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.health = 4; self.fireRate = 18; self.lastFired = 0; self.speed = 10; self.powerupTimer = 0; self.hasPowerup = false; self.teleportCooldown = 300; // Cooldown period for teleport ability self.lastTeleport = 0; self.takeDamage = function () { if (self.invulnerable) { return; } self.health--; LK.getSound('playerHit').play(); self.invulnerable = true; var blinkCount = 0; var blinkInterval = LK.setInterval(function () { playerGraphics.alpha = playerGraphics.alpha === 1 ? 0.2 : 1; blinkCount++; if (blinkCount >= 10) { LK.clearInterval(blinkInterval); playerGraphics.alpha = 1; self.invulnerable = false; } }, 150); }; self.activatePowerup = function (type) { LK.getSound('powerupCollected').play(); self.hasPowerup = true; self.powerupTimer = 300; if (type === 'fire') { self.fireRate = 9; playerGraphics.tint = 0xff0000; } else if (type === 'shield') { self.invulnerable = true; playerGraphics.tint = 0x00ffff; } else if (type === 'timeSlow') { self.timeSlowActive = true; game.setGameSpeed(0.5); playerGraphics.tint = 0x00ff00; } }; self.update = function () { if (self.hasPowerup) { self.powerupTimer--; if (self.powerupTimer <= 0) { self.hasPowerup = false; self.fireRate = 18; self.invulnerable = false; playerGraphics.tint = 0xffffff; if (self.timeSlowActive) { self.timeSlowActive = false; game.setGameSpeed(1); } } } // Teleport ability logic self.lastTeleport++; if (self.lastTeleport >= self.teleportCooldown) { // Teleport to a random position on the screen self.x = Math.random() * GAME_WIDTH; self.y = Math.random() * GAME_HEIGHT; self.lastTeleport = 0; } }; return self; }); var Powerup = Container.expand(function () { var self = Container.call(this); var powerupGraphics = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5, scaleX: 3.5, scaleY: 3.5 }); self.type = Math.random() < 0.5 ? 'fire' : 'shield'; self.speed = 3; // Set color based on type if (self.type === 'fire') { powerupGraphics.tint = 0xff0000; // Red for fire rate } else { powerupGraphics.tint = 0x00ffff; // Cyan for shield } self.update = function () { self.y += self.speed; // Slight pulsing effect var scale = 1 + Math.sin(LK.ticks * 0.1) * 0.1; powerupGraphics.scale.set(scale, scale); }; return self; }); // --- 22. Add a new asteroid type: PowerupAsteroid (drops powerup on death) var PowerupAsteroid = Container.expand(function () { var self = Container.call(this); var asteroidGraphics = self.attachAsset('asteroid', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.speed = 2.5; self.update = function () { self.y += self.speed; }; self.dropPowerup = function () { spawnPowerup(self.x, self.y); }; return self; }); // --- 24. Add a new asteroid type: ReflectorAsteroid (reflects bullets) var ReflectorAsteroid = Container.expand(function () { var self = Container.call(this); var asteroidGraphics = self.attachAsset('asteroid', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.speed = 2.5; self.update = function () { self.y += self.speed; }; self.reflects = true; return self; }); // --- 16. Add a new boss: ReflectorBoss (reflects all bullets for 5 seconds every 15 seconds) var ReflectorBoss = Container.expand(function () { var self = Container.call(this); var bossGraphics = self.attachAsset('boss', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.health = 70; self.maxHealth = 70; self.speed = 2.0; self.points = 1500; self.phase = 1; self.moveDirection = 1; self.fireRate = 50; self.lastFired = 0; self.reflectTimer = 0; self.reflectActive = false; self.update = function () { self.x += self.speed * self.moveDirection; if (self.x < 300 || self.x > 2048 - 300) { self.moveDirection *= -1; } self.lastFired++; if (self.lastFired >= self.fireRate) { self.lastFired = 0; return true; } self.reflectTimer++; if (!self.reflectActive && self.reflectTimer >= 900) { self.reflectActive = true; self.reflectTimer = 0; LK.effects.flashObject(self, 0xffff00, 5000); LK.setTimeout(function () { self.reflectActive = false; }, 5000); } return false; }; self.takeDamage = function (amount) { self.health -= amount; LK.effects.flashObject(self, 0xffff00, 300); return self.health <= 0; }; return self; }); // --- 10. Add a new enemy type: ReflectorEnemy (reflects bullets) var ReflectorEnemy = Container.expand(function () { var self = Container.call(this); var enemyGraphics = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.health = 3; self.speed = 1.8; self.points = 35; self.update = function () { self.y += self.speed; }; self.takeDamage = function (amount) { self.health -= amount; return self.health <= 0; }; self.reflects = true; return self; }); // --- 29. Add a new asteroid type: ScoreAsteroid (gives bonus score on death) var ScoreAsteroid = Container.expand(function () { var self = Container.call(this); var asteroidGraphics = self.attachAsset('asteroid', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.speed = 2.5; self.update = function () { self.y += self.speed; }; self.giveScore = function () { LK.setScore(LK.getScore() + 100); updateUI(); }; return self; }); // --- 4. Score Multiplier Powerup: Doubles score for 10 seconds var ScoreMultiplierPowerup = Container.expand(function () { var self = Container.call(this); var powerupGraphics = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5, scaleX: 3.5, scaleY: 3.5 }); self.type = 'scoreMultiplier'; self.speed = 3; powerupGraphics.tint = 0xffa500; // Orange for score multiplier self.update = function () { self.y += self.speed; var scale = 1 + Math.sin(LK.ticks * 0.1) * 0.1; powerupGraphics.scale.set(scale, scale); }; return self; }); // --- 34. Add a new asteroid type: ScoreMultiplierPowerupAsteroid (drops score multiplier powerup on death) var ScoreMultiplierPowerupAsteroid = Container.expand(function () { var self = Container.call(this); var asteroidGraphics = self.attachAsset('asteroid', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.speed = 2.5; self.update = function () { self.y += self.speed; }; self.dropScoreMultiplier = function () { var sm = new ScoreMultiplierPowerup(); sm.x = self.x; sm.y = self.y; game.addChild(sm); powerups.push(sm); }; return self; }); var ShieldPowerup = Container.expand(function () { var self = Container.call(this); var powerupGraphics = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5, scaleX: 3.5, scaleY: 3.5 }); self.type = 'shield'; self.speed = 3; powerupGraphics.tint = 0x00ffff; // Cyan for shield self.update = function () { self.y += self.speed; var scale = 1 + Math.sin(LK.ticks * 0.1) * 0.1; powerupGraphics.scale.set(scale, scale); }; return self; }); // --- 23. Add a new asteroid type: ShieldedAsteroid (takes half damage) var ShieldedAsteroid = Container.expand(function () { var self = Container.call(this); var asteroidGraphics = self.attachAsset('asteroid', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.5, scaleY: 2.5 }); self.speed = 2.5; self.health = 4; self.update = function () { self.y += self.speed; }; self.takeDamage = function (amount) { self.health -= Math.ceil(amount / 2); return self.health <= 0; }; return self; }); // --- 6. Add a new enemy type: ShieldedEnemy (takes half damage) var ShieldedEnemy = Container.expand(function () { var self = Container.call(this); var enemyGraphics = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.5, scaleY: 2.5 }); self.health = 4; self.speed = 1.2; self.points = 40; self.update = function () { self.y += self.speed; }; self.takeDamage = function (amount) { self.health -= Math.ceil(amount / 2); return self.health <= 0; }; return self; }); // --- 5. Add a new enemy type: SniperEnemy (shoots at player from distance) var SniperEnemy = Container.expand(function () { var self = Container.call(this); var enemyGraphics = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.health = 2; self.speed = 1.5; self.points = 30; self.canShoot = true; self.fireRate = 90; self.lastFired = 0; self.update = function () { self.y += self.speed; self.lastFired++; if (self.lastFired >= self.fireRate && player && Math.abs(self.x - player.x) < 200) { self.lastFired = 0; return true; } return false; }; self.takeDamage = function (amount) { self.health -= amount; return self.health <= 0; }; return self; }); // --- 13. Add a new enemy type: SplitterBoss (splits into two mini-bosses) var SplitterBoss = Container.expand(function () { var self = Container.call(this); var bossGraphics = self.attachAsset('boss', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.health = 40; self.maxHealth = 40; self.speed = 2.5; self.points = 800; self.phase = 1; self.moveDirection = 1; self.fireRate = 50; self.lastFired = 0; self.patternTimer = 0; self.currentPattern = 'move'; self.update = function () { self.patternTimer++; if (self.patternTimer >= 180) { self.patternTimer = 0; self.currentPattern = self.currentPattern === 'move' ? 'attack' : 'move'; } if (self.currentPattern === 'move') { self.x += self.speed * self.moveDirection; if (self.x < 300 || self.x > 2048 - 300) { self.moveDirection *= -1; } } if (self.currentPattern === 'attack') { self.lastFired++; if (self.lastFired >= self.fireRate) { self.lastFired = 0; return true; } } if (self.health <= self.maxHealth * 0.5 && self.phase === 1) { self.phase = 2; // Split into two mini-bosses for (var i = 0; i < 2; i++) { var miniBoss = new Boss(); miniBoss.x = self.x + (i === 0 ? -100 : 100); miniBoss.y = self.y; miniBoss.health = 15; miniBoss.maxHealth = 15; miniBoss.points = 200; game.addChild(miniBoss); boss = miniBoss; } self.destroy(); return false; } return false; }; self.takeDamage = function (amount) { self.health -= amount; LK.effects.flashObject(self, 0xff0000, 300); return self.health <= 0; }; return self; }); var SplittingEnemy = Container.expand(function () { var self = Container.call(this); var enemyGraphics = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.health = 2; self.speed = 2; self.points = 20; self.splitCount = 2; // Number of smaller enemies to spawn self.update = function () { self.y += self.speed; }; self.takeDamage = function (amount) { self.health -= amount; if (self.health <= 0) { // Spawn smaller enemies for (var i = 0; i < self.splitCount; i++) { var smallEnemy = new Enemy(); smallEnemy.x = self.x + (Math.random() - 0.5) * 50; smallEnemy.y = self.y; smallEnemy.health = 1; smallEnemy.speed = 3; game.addChild(smallEnemy); enemies.push(smallEnemy); } return true; } return false; }; return self; }); // --- 26. Add a new asteroid type: SwarmAsteroid (spawns SwarmEnemies on death) var SwarmAsteroid = Container.expand(function () { var self = Container.call(this); var asteroidGraphics = self.attachAsset('asteroid', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.speed = 2.5; self.update = function () { self.y += self.speed; }; self.spawnSwarm = function () { for (var i = 0; i < 5; i++) { var swarm = new SwarmEnemy(); swarm.x = self.x + (Math.random() - 0.5) * 100; swarm.y = self.y; game.addChild(swarm); enemies.push(swarm); } }; return self; }); // --- 15. Add a new boss: SwarmBoss (spawns SwarmEnemies every 2 seconds) var SwarmBoss = Container.expand(function () { var self = Container.call(this); var bossGraphics = self.attachAsset('boss', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.health = 60; self.maxHealth = 60; self.speed = 2.0; self.points = 1200; self.phase = 1; self.moveDirection = 1; self.fireRate = 60; self.lastFired = 0; self.swarmTimer = 0; self.update = function () { self.x += self.speed * self.moveDirection; if (self.x < 300 || self.x > 2048 - 300) { self.moveDirection *= -1; } self.lastFired++; if (self.lastFired >= self.fireRate) { self.lastFired = 0; return true; } self.swarmTimer++; if (self.swarmTimer >= 120) { self.swarmTimer = 0; // Spawn SwarmEnemies for (var i = 0; i < 5; i++) { var swarm = new SwarmEnemy(); swarm.x = self.x + (Math.random() - 0.5) * 200; swarm.y = self.y + 100; game.addChild(swarm); enemies.push(swarm); } } return false; }; self.takeDamage = function (amount) { self.health -= amount; LK.effects.flashObject(self, 0xff00ff, 300); return self.health <= 0; }; return self; }); // --- 12. Add a new enemy type: SwarmEnemy (spawns in groups, low points) var SwarmEnemy = Container.expand(function () { var self = Container.call(this); var enemyGraphics = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.0, scaleY: 1.0 }); self.health = 1; self.speed = 3.5; self.points = 5; self.update = function () { self.y += self.speed; }; self.takeDamage = function (amount) { self.health -= amount; return self.health <= 0; }; return self; }); // --- 35. Add a new asteroid type: SwarmPowerupAsteroid (spawns SwarmEnemies and drops powerup) var SwarmPowerupAsteroid = Container.expand(function () { var self = Container.call(this); var asteroidGraphics = self.attachAsset('asteroid', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.speed = 2.5; self.update = function () { self.y += self.speed; }; self.spawnSwarmAndDrop = function () { for (var i = 0; i < 3; i++) { var swarm = new SwarmEnemy(); swarm.x = self.x + (Math.random() - 0.5) * 100; swarm.y = self.y; game.addChild(swarm); enemies.push(swarm); } spawnPowerup(self.x, self.y); }; return self; }); // --- 28. Add a new asteroid type: TimeSlowAsteroid (slows time on death) var TimeSlowAsteroid = Container.expand(function () { var self = Container.call(this); var asteroidGraphics = self.attachAsset('asteroid', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.speed = 2.5; self.update = function () { self.y += self.speed; }; self.slowTime = function () { game.setGameSpeed(0.5); LK.setTimeout(function () { game.setGameSpeed(1); }, 3000); }; return self; }); var TimeSlowPowerup = Container.expand(function () { var self = Container.call(this); var powerupGraphics = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5, scaleX: 3.5, scaleY: 3.5 }); self.type = 'timeSlow'; self.speed = 3; powerupGraphics.tint = 0x00ff00; // Green for time slow self.update = function () { self.y += self.speed; var scale = 1 + Math.sin(LK.ticks * 0.1) * 0.1; powerupGraphics.scale.set(scale, scale); }; return self; }); // --- 14. Add a new boss: TimeStopBoss (freezes player for 2 seconds every 10 seconds) var TimeStopBoss = Container.expand(function () { var self = Container.call(this); var bossGraphics = self.attachAsset('boss', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.health = 50; self.maxHealth = 50; self.speed = 2.5; self.points = 1000; self.phase = 1; self.moveDirection = 1; self.fireRate = 40; self.lastFired = 0; self.patternTimer = 0; self.freezeTimer = 0; self.update = function () { self.patternTimer++; self.freezeTimer++; if (self.patternTimer >= 180) { self.patternTimer = 0; } self.x += self.speed * self.moveDirection; if (self.x < 300 || self.x > 2048 - 300) { self.moveDirection *= -1; } self.lastFired++; if (self.lastFired >= self.fireRate) { self.lastFired = 0; return true; } if (self.freezeTimer >= 600) { self.freezeTimer = 0; // Freeze player for 2 seconds if (player) { player.frozen = true; LK.setTimeout(function () { player.frozen = false; }, 2000); } } return false; }; self.takeDamage = function (amount) { self.health -= amount; LK.effects.flashObject(self, 0x00ffff, 300); return self.health <= 0; }; return self; }); var UniquePlayerShip = Container.expand(function () { var self = Container.call(this); var uniquePlayerGraphics = self.attachAsset('uniquePlayer', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); self.health = 6; self.fireRate = 12; self.lastFired = 0; self.speed = 14; self.powerupTimer = 0; self.hasPowerup = false; self.uniqueAbilityCooldown = 500; // Cooldown period for unique ability self.lastAbilityUse = 0; self.takeDamage = function () { if (self.invulnerable) { return; } self.health--; LK.getSound('playerHit').play(); self.invulnerable = true; var blinkCount = 0; var blinkInterval = LK.setInterval(function () { uniquePlayerGraphics.alpha = uniquePlayerGraphics.alpha === 1 ? 0.2 : 1; blinkCount++; if (blinkCount >= 10) { LK.clearInterval(blinkInterval); uniquePlayerGraphics.alpha = 1; self.invulnerable = false; } }, 150); }; self.activatePowerup = function (type) { LK.getSound('powerupCollected').play(); self.hasPowerup = true; self.powerupTimer = 300; if (type === 'fire') { self.fireRate = 6; uniquePlayerGraphics.tint = 0xff0000; } else if (type === 'shield') { self.invulnerable = true; uniquePlayerGraphics.tint = 0x00ffff; } else if (type === 'timeSlow') { self.timeSlowActive = true; game.setGameSpeed(0.5); uniquePlayerGraphics.tint = 0x00ff00; } }; self.update = function () { if (self.hasPowerup) { self.powerupTimer--; if (self.powerupTimer <= 0) { self.hasPowerup = false; self.fireRate = 12; self.invulnerable = false; uniquePlayerGraphics.tint = 0xffffff; if (self.timeSlowActive) { self.timeSlowActive = false; game.setGameSpeed(1); } } } // Unique ability logic self.lastAbilityUse++; if (self.lastAbilityUse >= self.uniqueAbilityCooldown) { // Implement unique ability, e.g., temporary invincibility self.invulnerable = true; LK.setTimeout(function () { self.invulnerable = false; }, 2000); // 2 seconds of invincibility self.lastAbilityUse = 0; } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // Create a shop interface for purchasing ships var shopInterface = new Container(); shopInterface.visible = false; // Initially hidden // Create buttons for each ship type var shipButtons = [{ type: 'Player', text: 'Standard Ship', cost: 100 }, { type: 'PlayerShip2', text: 'Advanced Ship', cost: 200 }, { type: 'PlayerShip3', text: 'Teleport Ship', cost: 300 }, { type: 'UniquePlayerShip', text: 'Unique Ship', cost: 500 }]; // Add buttons to the shop interface shipButtons.forEach(function (ship, index) { var button = new Button({ text: ship.text + ' - ' + ship.cost + ' Points', size: 50, fill: 0xFFFFFF, x: GAME_WIDTH / 2, y: 200 + index * 100, anchorX: 0.5, anchorY: 0.5, onDown: function onDown() { if (LK.getScore() >= ship.cost) { LK.setScore(LK.getScore() - ship.cost); updateUI(); // Replace current player with selected ship player.destroy(); player = new window[ship.type](); player.x = GAME_WIDTH / 2; player.y = GAME_HEIGHT - 200; game.addChild(player); shopInterface.visible = false; // Hide shop after purchase } } }); button.on('down', function () { if (LK.getScore() >= ship.cost) { LK.setScore(LK.getScore() - ship.cost); updateUI(); // Replace current player with selected ship player.destroy(); player = new window[ship.type](); player.x = GAME_WIDTH / 2; player.y = GAME_HEIGHT - 200; game.addChild(player); shopInterface.visible = false; // Hide shop after purchase } }); shopInterface.addChild(button); }); // Add the shop interface to the game UI LK.gui.center.addChild(shopInterface); // Function to toggle shop visibility function toggleShop() { shopInterface.visible = !shopInterface.visible; } // Example: Toggle shop with a specific gesture or condition game.down = function (x, y, obj) { // Admin mode toggle with a specific gesture or condition if (x < 100 && y < 100) { adminPowers.toggleAdminMode(); return; } // Shop toggle in top right if (x > GAME_WIDTH - 100 && y < 100) { toggleShop(); } }; // Teleport button removed as requested game.setGameSpeed = function (speed) { // Implement logic to adjust game speed // This could involve adjusting the speed of all game elements player.speed *= speed; playerBullets.forEach(function (bullet) { return bullet.speed *= speed; }); enemies.forEach(function (enemy) { return enemy.speed *= speed; }); enemyBullets.forEach(function (bullet) { return bullet.speed *= speed; }); asteroids.forEach(function (asteroid) { return asteroid.speed *= speed; }); powerups.forEach(function (powerup) { return powerup.speed *= speed; }); if (boss) { boss.speed *= speed; } }; var AdminPowers = function AdminPowers() { var self = this; self.isAdmin = false; self.toggleAdminMode = function () { self.isAdmin = !self.isAdmin; if (self.isAdmin) { console.log("Admin mode activated"); // Additional admin features can be added here } else { console.log("Admin mode deactivated"); } }; self.spawnBoss = function () { if (self.isAdmin) { spawnBoss(); console.log("Boss spawned by admin"); } }; self.increaseScore = function (amount) { if (self.isAdmin) { LK.setScore(LK.getScore() + amount); updateUI(); console.log("Score increased by admin"); } }; return self; }; var adminPowers = new AdminPowers(); var GAME_WIDTH = 2048; var GAME_HEIGHT = 2732; // Game state variables var gameState = "playing"; // playing, paused, over var level = 1; var waveTimer = 0; var nextWaveTime = 180; // 3 seconds at 60fps var wave = 0; var spawnRate = 60; // frames between enemy spawns var lastSpawn = 0; var bossActive = false; var bossDefeated = false; var bossSpawnWave = 5; // Game elements var player; var playerBullets = []; var enemies = []; var enemyBullets = []; var asteroids = []; var powerups = []; var boss = null; // Track dragging var dragging = false; var lastX = 0; var lastY = 0; // Score display var scoreText = new Text2('SCORE: 0', { size: 60, fill: 0xFFFFFF }); scoreText.anchor.set(0, 0); LK.gui.topRight.addChild(scoreText); scoreText.x = -350; // Position from right edge // Wave display var waveText = new Text2('WAVE: 1', { size: 60, fill: 0xFFFFFF }); waveText.anchor.set(0, 0); LK.gui.topRight.addChild(waveText); waveText.x = -350; waveText.y = 70; // Health display var healthText = new Text2('HEALTH: 3', { size: 60, fill: 0xFFFFFF }); healthText.anchor.set(0, 0); LK.gui.topLeft.addChild(healthText); healthText.x = 120; // Avoid the top-left corner as requested healthText.y = 0; // Initialize game elements function initGame() { // Reset game state gameState = "playing"; level = 1; waveTimer = 0; nextWaveTime = 180; wave = 0; spawnRate = 60; lastSpawn = 0; bossActive = false; bossDefeated = false; // Clear all game elements playerBullets = []; enemies = []; enemyBullets = []; asteroids = []; powerups = []; if (boss) { boss.destroy(); boss = null; } // Create player player = new UniquePlayerShip(); player.x = GAME_WIDTH / 2; player.y = GAME_HEIGHT - 200; game.addChild(player); // Update UI LK.setScore(0); updateUI(); // Start background music LK.playMusic('gameMusic'); } // Update UI elements function updateUI() { scoreText.setText('SCORE: ' + LK.getScore()); waveText.setText('WAVE: ' + wave); healthText.setText('HEALTH: ' + player.health); } // Spawn enemies for the current wave function spawnWave() { wave++; waveText.setText('WAVE: ' + wave); // Boss wave if (wave % bossSpawnWave === 0) { spawnBoss(); return; } // Increase difficulty with each wave spawnRate = Math.max(20, 60 - wave * 5); // Faster spawn rate as waves progress // Spawn some initial enemies var initialEnemies = 3 + Math.min(10, Math.floor(wave / 2)); // More enemies as waves progress for (var i = 0; i < initialEnemies; i++) { spawnEnemy(); } // Also spawn some asteroids for (var j = 0; j < Math.min(7, wave); j++) { // More asteroids as waves progress spawnAsteroid(); } // Introduce new enemy types or patterns every few waves if (wave % 3 === 0) { for (var k = 0; k < Math.min(3, wave / 3); k++) { var specialEnemy = new SplittingEnemy(); specialEnemy.x = 200 + Math.random() * (GAME_WIDTH - 400); specialEnemy.y = -100; game.addChild(specialEnemy); enemies.push(specialEnemy); } } } // Spawn a single enemy function spawnEnemy() { var enemy; if (Math.random() < 0.1) { // 10% chance to spawn a KamikazeEnemy enemy = new KamikazeEnemy(); } else if (Math.random() < 0.2) { // 20% chance to spawn a SplittingEnemy enemy = new SplittingEnemy(); } else if (Math.random() < 0.15) { // 15% chance to spawn a HeavyEnemy enemy = new HeavyEnemy(); } else { enemy = new Enemy(); } enemy.x = 200 + Math.random() * (GAME_WIDTH - 400); enemy.y = -100; // Increase health and speed with level enemy.health = 1 + Math.floor(wave / 3); enemy.speed = 2 + Math.min(3, wave * 0.5); enemy.points = 10 * (1 + Math.floor(wave / 2)); // Different enemy types based on wave if (wave > 1) { // Some enemies can shoot enemy.canShoot = Math.random() < 0.3; // Different movement patterns var patterns = ['straight', 'wave', 'zigzag']; enemy.movePattern = patterns[Math.floor(Math.random() * Math.min(patterns.length, 1 + wave / 2))]; enemy.startX = enemy.x; } game.addChild(enemy); enemies.push(enemy); } // Spawn boss function spawnBoss() { LK.getSound('bossAppear').play(); boss = new Boss(); boss.x = GAME_WIDTH / 2; boss.y = 300; // Scale boss difficulty with wave var waveMultiplier = Math.floor(wave / bossSpawnWave); boss.health = boss.maxHealth = 30 + waveMultiplier * 20; boss.points = 500 + waveMultiplier * 200; bossActive = true; game.addChild(boss); // Add warning text var warningText = new Text2('BOSS INCOMING!', { size: 120, fill: 0xFF0000 }); warningText.anchor.set(0.5, 0.5); warningText.x = GAME_WIDTH / 2; warningText.y = GAME_HEIGHT / 2; game.addChild(warningText); // Remove warning after 2 seconds LK.setTimeout(function () { warningText.destroy(); }, 2000); } // Spawn asteroid function spawnAsteroid() { var asteroid = new Asteroid(); asteroid.x = Math.random() * GAME_WIDTH; asteroid.y = -100; game.addChild(asteroid); asteroids.push(asteroid); } // Spawn powerup function spawnPowerup(x, y) { if (Math.random() < 0.2) { // 20% chance to spawn a powerup var powerup; if (Math.random() < 0.1) { // 10% chance for time slow powerup powerup = new TimeSlowPowerup(); } else if (Math.random() < 0.2) { // 10% chance for shield powerup powerup = new ShieldPowerup(); } else { powerup = new Powerup(); } powerup.x = x; powerup.y = y; game.addChild(powerup); powerups.push(powerup); } } // Player shoots a bullet function playerShoot() { var bullet = new Bullet(); bullet.x = player.x; bullet.y = player.y - 40; game.addChild(bullet); playerBullets.push(bullet); LK.getSound('playerShoot').play(); } // Enemy shoots a bullet function enemyShoot(enemy) { var bullet = new EnemyBullet(); bullet.x = enemy.x; bullet.y = enemy.y + 30; game.addChild(bullet); enemyBullets.push(bullet); } // Boss shoots bullets function bossShoot() { // Different attack patterns based on phase if (boss.phase === 1) { // Single bullet var bullet = new EnemyBullet(); bullet.x = boss.x; bullet.y = boss.y + 75; game.addChild(bullet); enemyBullets.push(bullet); } else if (boss.phase === 2) { // Three bullets in spread for (var i = -1; i <= 1; i++) { var bullet = new EnemyBullet(); bullet.x = boss.x + i * 50; bullet.y = boss.y + 75; game.addChild(bullet); enemyBullets.push(bullet); } } else { // Circle of bullets var bulletCount = 8; for (var i = 0; i < bulletCount; i++) { var angle = i / bulletCount * Math.PI * 2; var bullet = new EnemyBullet(); bullet.x = boss.x; bullet.y = boss.y + 75; bullet.speed = 6; // Add velocity components bullet.vx = Math.sin(angle) * bullet.speed; bullet.vy = Math.cos(angle) * bullet.speed; // Override update method for this bullet bullet.update = function () { this.x += this.vx; this.y += this.vy; }; game.addChild(bullet); enemyBullets.push(bullet); } } } // Check if an object is off screen function isOffScreen(obj) { return obj.y < -100 || obj.y > GAME_HEIGHT + 100 || obj.x < -100 || obj.x > GAME_WIDTH + 100; } // Handle game over function handleGameOver() { if (player.health <= 0) { gameState = "over"; LK.effects.flashScreen(0xff0000, 1000); LK.showGameOver(); } } // Handle input events game.down = function (x, y, obj) { dragging = true; lastX = x; lastY = y; // Admin mode toggle with a specific gesture or condition if (x < 100 && y < 100) { // Example condition for toggling admin mode adminPowers.toggleAdminMode(); } }; game.up = function (x, y, obj) { dragging = false; }; game.move = function (x, y, obj) { if (dragging && player) { // Calculate movement var dx = x - lastX; var dy = y - lastY; // Update player position with boundaries player.x = Math.max(50, Math.min(GAME_WIDTH - 50, player.x + dx)); player.y = Math.max(50, Math.min(GAME_HEIGHT - 50, player.y + dy)); // Update last position lastX = x; lastY = y; } }; // Initialize the game initGame(); // Main game loop game.update = function () { if (gameState !== "playing") { return; } // Example admin controls if (adminPowers.isAdmin) { // Admin can spawn a boss at any time if (LK.ticks % 600 === 0) { // Every 10 seconds adminPowers.spawnBoss(); } // Admin can increase score periodically if (LK.ticks % 300 === 0) { // Every 5 seconds adminPowers.increaseScore(100); } } // Update player if (player) { player.update(); // Player shooting player.lastFired++; if (player.lastFired >= player.fireRate) { player.lastFired = 0; playerShoot(); } } // Wave management if (!bossActive) { waveTimer++; if (waveTimer >= nextWaveTime && enemies.length === 0) { waveTimer = 0; spawnWave(); } // Periodic enemy spawning during wave lastSpawn++; if (lastSpawn >= spawnRate && wave > 0 && !bossActive && enemies.length < 10 + wave) { lastSpawn = 0; spawnEnemy(); } } // Update bullets for (var i = playerBullets.length - 1; i >= 0; i--) { var bullet = playerBullets[i]; bullet.update(); // Remove off-screen bullets if (isOffScreen(bullet)) { bullet.destroy(); playerBullets.splice(i, 1); continue; } // Check collision with enemies for (var j = enemies.length - 1; j >= 0; j--) { var enemy = enemies[j]; if (bullet.intersects(enemy)) { var destroyed = enemy.takeDamage(bullet.damage); if (destroyed && enemy instanceof SplittingEnemy) {} ; if (destroyed) { LK.getSound('enemyDestroyed').play(); LK.setScore(LK.getScore() + enemy.points); updateUI(); // Chance to spawn powerup spawnPowerup(enemy.x, enemy.y); enemy.destroy(); enemies.splice(j, 1); } bullet.destroy(); playerBullets.splice(i, 1); break; } if (enemy instanceof KamikazeEnemy && enemy.intersects(player)) { player.takeDamage(); updateUI(); enemy.destroy(); enemies.splice(j, 1); handleGameOver(); } } // Check collision with boss if (boss && bullet.intersects(boss)) { var bossDestroyed = boss.takeDamage(bullet.damage); if (bossDestroyed) { LK.getSound('enemyDestroyed').play(); LK.setScore(LK.getScore() + boss.points); updateUI(); // Multiple powerups when boss is defeated for (var k = 0; k < 3; k++) { spawnPowerup(boss.x + (Math.random() - 0.5) * 100, boss.y + (Math.random() - 0.5) * 100); } boss.destroy(); boss = null; bossActive = false; bossDefeated = true; // Next wave after boss defeat waveTimer = nextWaveTime; } bullet.destroy(); playerBullets.splice(i, 1); } // Check collision with asteroids for (var j = asteroids.length - 1; j >= 0; j--) { var asteroid = asteroids[j]; if (bullet.intersects(asteroid)) { asteroid.destroy(); asteroids.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]; bullet.update(); // Remove off-screen bullets if (isOffScreen(bullet)) { bullet.destroy(); enemyBullets.splice(i, 1); continue; } // Check collision with player if (player && bullet.intersects(player)) { player.takeDamage(); updateUI(); bullet.destroy(); enemyBullets.splice(i, 1); handleGameOver(); } } // Update enemies for (var i = enemies.length - 1; i >= 0; i--) { var enemy = enemies[i]; var shouldShoot = enemy.update(); // Enemy shooting if (shouldShoot) { enemyShoot(enemy); } // Remove off-screen enemies if (enemy.y > GAME_HEIGHT + 100) { enemy.destroy(); enemies.splice(i, 1); continue; } // Check collision with player if (player && enemy.intersects(player)) { player.takeDamage(); updateUI(); enemy.destroy(); enemies.splice(i, 1); handleGameOver(); } } // Update boss if (boss) { var shouldShoot = boss.update(); if (shouldShoot) { bossShoot(); } // Check collision with player if (player && boss.intersects(player)) { player.takeDamage(); updateUI(); handleGameOver(); } } // Update asteroids for (var i = asteroids.length - 1; i >= 0; i--) { var asteroid = asteroids[i]; asteroid.update(); // Remove off-screen asteroids if (asteroid.y > GAME_HEIGHT + 100) { asteroid.destroy(); asteroids.splice(i, 1); continue; } // Check collision with player if (player && asteroid.intersects(player)) { player.takeDamage(); updateUI(); asteroid.destroy(); asteroids.splice(i, 1); handleGameOver(); } } // Update powerups for (var i = powerups.length - 1; i >= 0; i--) { var powerup = powerups[i]; powerup.update(); // Remove off-screen powerups if (powerup.y > GAME_HEIGHT + 100) { powerup.destroy(); powerups.splice(i, 1); continue; } // Check collision with player if (player && powerup.intersects(player)) { player.activatePowerup(powerup.type); powerup.destroy(); powerups.splice(i, 1); } } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Asteroid = Container.expand(function () {
var self = Container.call(this);
var size = 1.0 + Math.random() * 2.0; // Random size between 1.0 and 3.0
var asteroidGraphics = self.attachAsset('asteroid', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: size * 1.5,
scaleY: size * 1.5
});
self.speed = 1 + Math.random() * 4; // Random speed
self.rotationSpeed = (Math.random() - 0.5) * 0.05; // Random rotation
self.update = function () {
self.y += self.speed;
self.rotation += self.rotationSpeed;
};
return self;
});
var Boss = Container.expand(function () {
var self = Container.call(this);
var bossGraphics = self.attachAsset('boss', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.health = 30;
self.maxHealth = 30;
self.speed = 3;
self.points = 500;
self.phase = 1;
self.moveDirection = 1;
self.fireRate = 60;
self.lastFired = 0;
self.patternTimer = 0;
self.currentPattern = 'move';
self.update = function () {
self.patternTimer++;
// Change patterns every few seconds
if (self.patternTimer >= 180) {
self.patternTimer = 0;
self.currentPattern = self.currentPattern === 'move' ? 'attack' : 'move';
}
// Movement pattern
if (self.currentPattern === 'move') {
self.x += self.speed * self.moveDirection;
// Reverse direction if approaching screen edge
if (self.x < 300 || self.x > 2048 - 300) {
self.moveDirection *= -1;
}
}
// Attack pattern
if (self.currentPattern === 'attack') {
self.lastFired++;
if (self.lastFired >= self.fireRate) {
self.lastFired = 0;
return true; // Signal to create bullets
}
}
// Change phase based on health
if (self.health <= self.maxHealth * 0.6 && self.phase === 1) {
self.phase = 2;
self.speed = 4;
self.fireRate = 45;
} else if (self.health <= self.maxHealth * 0.3 && self.phase === 2) {
self.phase = 3;
self.speed = 5;
self.fireRate = 30;
}
return false;
};
self.takeDamage = function (amount) {
self.health -= amount;
// Flash boss red when hit
LK.effects.flashObject(self, 0xff0000, 300);
return self.health <= 0;
};
return self;
});
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.speed = -15; // Negative because bullets move upward
self.damage = 1;
self.update = function () {
self.y += self.speed;
};
return self;
});
var Button = Container.expand(function (options) {
var self = Container.call(this);
var buttonGraphics = self.attachAsset('button', {
anchorX: options.anchorX || 0.5,
anchorY: options.anchorY || 0.5
});
var buttonText = new Text2(options.text, {
size: options.size || 50,
fill: options.fill || 0xFFFFFF
});
buttonText.anchor.set(0.5, 0.5);
self.addChild(buttonText);
self.x = options.x || 0;
self.y = options.y || 0;
self.on('down', options.onDown || function () {});
return self;
});
// --- 31. Add a new asteroid type: ComboAsteroid (drops combo powerup on death)
var ComboAsteroid = Container.expand(function () {
var self = Container.call(this);
var asteroidGraphics = self.attachAsset('asteroid', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.speed = 2.5;
self.update = function () {
self.y += self.speed;
};
self.dropCombo = function () {
var combo = new ComboPowerup();
combo.x = self.x;
combo.y = self.y;
game.addChild(combo);
powerups.push(combo);
};
return self;
});
// --- 38. Add a new asteroid type: ComboHealthAsteroid (drops combo and health powerups)
var ComboHealthAsteroid = Container.expand(function () {
var self = Container.call(this);
var asteroidGraphics = self.attachAsset('asteroid', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.speed = 2.5;
self.update = function () {
self.y += self.speed;
};
self.dropComboAndHealth = function () {
var combo = new ComboPowerup();
combo.x = self.x;
combo.y = self.y;
game.addChild(combo);
powerups.push(combo);
var health = new HealthPowerup();
health.x = self.x - 30;
health.y = self.y;
game.addChild(health);
powerups.push(health);
};
return self;
});
// --- 37. Add a new asteroid type: ComboMagnetAsteroid (drops combo and magnet powerups)
var ComboMagnetAsteroid = Container.expand(function () {
var self = Container.call(this);
var asteroidGraphics = self.attachAsset('asteroid', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.speed = 2.5;
self.update = function () {
self.y += self.speed;
};
self.dropComboAndMagnet = function () {
var combo = new ComboPowerup();
combo.x = self.x;
combo.y = self.y;
game.addChild(combo);
powerups.push(combo);
var magnet = new MagnetPowerup();
magnet.x = self.x + 30;
magnet.y = self.y;
game.addChild(magnet);
powerups.push(magnet);
};
return self;
});
// --- 1. Combo Powerup: Grants both shield and fire rate for 5 seconds
var ComboPowerup = Container.expand(function () {
var self = Container.call(this);
var powerupGraphics = self.attachAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3.5,
scaleY: 3.5
});
self.type = 'combo';
self.speed = 3;
powerupGraphics.tint = 0xff00ff; // Magenta for combo
self.update = function () {
self.y += self.speed;
var scale = 1 + Math.sin(LK.ticks * 0.1) * 0.1;
powerupGraphics.scale.set(scale, scale);
};
return self;
});
// --- 39. Add a new asteroid type: ComboScoreMultiplierAsteroid (drops combo and score multiplier powerups)
var ComboScoreMultiplierAsteroid = Container.expand(function () {
var self = Container.call(this);
var asteroidGraphics = self.attachAsset('asteroid', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.speed = 2.5;
self.update = function () {
self.y += self.speed;
};
self.dropComboAndScoreMultiplier = function () {
var combo = new ComboPowerup();
combo.x = self.x;
combo.y = self.y;
game.addChild(combo);
powerups.push(combo);
var sm = new ScoreMultiplierPowerup();
sm.x = self.x + 30;
sm.y = self.y;
game.addChild(sm);
powerups.push(sm);
};
return self;
});
// --- 36. Add a new asteroid type: ComboSwarmAsteroid (spawns SwarmEnemies and drops combo powerup)
var ComboSwarmAsteroid = Container.expand(function () {
var self = Container.call(this);
var asteroidGraphics = self.attachAsset('asteroid', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.speed = 2.5;
self.update = function () {
self.y += self.speed;
};
self.spawnSwarmAndDropCombo = function () {
for (var i = 0; i < 3; i++) {
var swarm = new SwarmEnemy();
swarm.x = self.x + (Math.random() - 0.5) * 100;
swarm.y = self.y;
game.addChild(swarm);
enemies.push(swarm);
}
var combo = new ComboPowerup();
combo.x = self.x;
combo.y = self.y;
game.addChild(combo);
powerups.push(combo);
};
return self;
});
// --- 41. Add a new asteroid type: ComboSwarmHealthAsteroid (spawns SwarmEnemies, drops combo and health powerups)
var ComboSwarmHealthAsteroid = Container.expand(function () {
var self = Container.call(this);
var asteroidGraphics = self.attachAsset('asteroid', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.speed = 2.5;
self.update = function () {
self.y += self.speed;
};
self.spawnSwarmDropComboHealth = function () {
for (var i = 0; i < 3; i++) {
var swarm = new SwarmEnemy();
swarm.x = self.x + (Math.random() - 0.5) * 100;
swarm.y = self.y;
game.addChild(swarm);
enemies.push(swarm);
}
var combo = new ComboPowerup();
combo.x = self.x;
combo.y = self.y;
game.addChild(combo);
powerups.push(combo);
var health = new HealthPowerup();
health.x = self.x - 30;
health.y = self.y;
game.addChild(health);
powerups.push(health);
};
return self;
});
// --- 45. Add a new asteroid type: ComboSwarmHealthScoreMultiplierAsteroid (spawns SwarmEnemies, drops combo, health, and score multiplier powerups)
var ComboSwarmHealthScoreMultiplierAsteroid = Container.expand(function () {
var self = Container.call(this);
var asteroidGraphics = self.attachAsset('asteroid', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.speed = 2.5;
self.update = function () {
self.y += self.speed;
};
self.spawnSwarmDropComboHealthScoreMultiplier = function () {
for (var i = 0; i < 3; i++) {
var swarm = new SwarmEnemy();
swarm.x = self.x + (Math.random() - 0.5) * 100;
swarm.y = self.y;
game.addChild(swarm);
enemies.push(swarm);
}
var combo = new ComboPowerup();
combo.x = self.x;
combo.y = self.y;
game.addChild(combo);
powerups.push(combo);
var health = new HealthPowerup();
health.x = self.x + 30;
health.y = self.y;
game.addChild(health);
powerups.push(health);
var sm = new ScoreMultiplierPowerup();
sm.x = self.x - 30;
sm.y = self.y;
game.addChild(sm);
powerups.push(sm);
};
return self;
});
// --- 40. Add a new asteroid type: ComboSwarmMagnetAsteroid (spawns SwarmEnemies, drops combo and magnet powerups)
var ComboSwarmMagnetAsteroid = Container.expand(function () {
var self = Container.call(this);
var asteroidGraphics = self.attachAsset('asteroid', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.speed = 2.5;
self.update = function () {
self.y += self.speed;
};
self.spawnSwarmDropComboMagnet = function () {
for (var i = 0; i < 3; i++) {
var swarm = new SwarmEnemy();
swarm.x = self.x + (Math.random() - 0.5) * 100;
swarm.y = self.y;
game.addChild(swarm);
enemies.push(swarm);
}
var combo = new ComboPowerup();
combo.x = self.x;
combo.y = self.y;
game.addChild(combo);
powerups.push(combo);
var magnet = new MagnetPowerup();
magnet.x = self.x + 30;
magnet.y = self.y;
game.addChild(magnet);
powerups.push(magnet);
};
return self;
});
// --- 43. Add a new asteroid type: ComboSwarmMagnetHealthAsteroid (spawns SwarmEnemies, drops combo, magnet, and health powerups)
var ComboSwarmMagnetHealthAsteroid = Container.expand(function () {
var self = Container.call(this);
var asteroidGraphics = self.attachAsset('asteroid', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.speed = 2.5;
self.update = function () {
self.y += self.speed;
};
self.spawnSwarmDropComboMagnetHealth = function () {
for (var i = 0; i < 3; i++) {
var swarm = new SwarmEnemy();
swarm.x = self.x + (Math.random() - 0.5) * 100;
swarm.y = self.y;
game.addChild(swarm);
enemies.push(swarm);
}
var combo = new ComboPowerup();
combo.x = self.x;
combo.y = self.y;
game.addChild(combo);
powerups.push(combo);
var magnet = new MagnetPowerup();
magnet.x = self.x + 30;
magnet.y = self.y;
game.addChild(magnet);
powerups.push(magnet);
var health = new HealthPowerup();
health.x = self.x - 30;
health.y = self.y;
game.addChild(health);
powerups.push(health);
};
return self;
});
// --- 46. Add a new asteroid type: ComboSwarmMagnetHealthScoreMultiplierAsteroid (spawns SwarmEnemies, drops combo, magnet, health, and score multiplier powerups)
var ComboSwarmMagnetHealthScoreMultiplierAsteroid = Container.expand(function () {
var self = Container.call(this);
var asteroidGraphics = self.attachAsset('asteroid', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.speed = 2.5;
self.update = function () {
self.y += self.speed;
};
self.spawnSwarmDropComboMagnetHealthScoreMultiplier = function () {
for (var i = 0; i < 3; i++) {
var swarm = new SwarmEnemy();
swarm.x = self.x + (Math.random() - 0.5) * 100;
swarm.y = self.y;
game.addChild(swarm);
enemies.push(swarm);
}
var combo = new ComboPowerup();
combo.x = self.x;
combo.y = self.y;
game.addChild(combo);
powerups.push(combo);
var magnet = new MagnetPowerup();
magnet.x = self.x + 30;
magnet.y = self.y;
game.addChild(magnet);
powerups.push(magnet);
var health = new HealthPowerup();
health.x = self.x - 30;
health.y = self.y;
game.addChild(health);
powerups.push(health);
var sm = new ScoreMultiplierPowerup();
sm.x = self.x + 60;
sm.y = self.y;
game.addChild(sm);
powerups.push(sm);
};
return self;
});
// --- 47. Add a new asteroid type: ComboSwarmMagnetHealthScoreMultiplierTimeSlowAsteroid (spawns SwarmEnemies, drops combo, magnet, health, score multiplier, and time slow powerups)
var ComboSwarmMagnetHealthScoreMultiplierTimeSlowAsteroid = Container.expand(function () {
var self = Container.call(this);
var asteroidGraphics = self.attachAsset('asteroid', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.speed = 2.5;
self.update = function () {
self.y += self.speed;
};
self.spawnSwarmDropAll = function () {
for (var i = 0; i < 3; i++) {
var swarm = new SwarmEnemy();
swarm.x = self.x + (Math.random() - 0.5) * 100;
swarm.y = self.y;
game.addChild(swarm);
enemies.push(swarm);
}
var combo = new ComboPowerup();
combo.x = self.x;
combo.y = self.y;
game.addChild(combo);
powerups.push(combo);
var magnet = new MagnetPowerup();
magnet.x = self.x + 30;
magnet.y = self.y;
game.addChild(magnet);
powerups.push(magnet);
var health = new HealthPowerup();
health.x = self.x - 30;
health.y = self.y;
game.addChild(health);
powerups.push(health);
var sm = new ScoreMultiplierPowerup();
sm.x = self.x + 60;
sm.y = self.y;
game.addChild(sm);
powerups.push(sm);
var ts = new TimeSlowPowerup();
ts.x = self.x - 60;
ts.y = self.y;
game.addChild(ts);
powerups.push(ts);
};
return self;
});
// --- 48. Add a new asteroid type: ComboSwarmMagnetHealthScoreMultiplierTimeSlowHealerAsteroid (spawns SwarmEnemies, drops combo, magnet, health, score multiplier, time slow, and heals player)
var ComboSwarmMagnetHealthScoreMultiplierTimeSlowHealerAsteroid = Container.expand(function () {
var self = Container.call(this);
var asteroidGraphics = self.attachAsset('asteroid', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.speed = 2.5;
self.update = function () {
self.y += self.speed;
};
self.spawnSwarmDropAllHeal = function () {
for (var i = 0; i < 3; i++) {
var swarm = new SwarmEnemy();
swarm.x = self.x + (Math.random() - 0.5) * 100;
swarm.y = self.y;
game.addChild(swarm);
enemies.push(swarm);
}
var combo = new ComboPowerup();
combo.x = self.x;
combo.y = self.y;
game.addChild(combo);
powerups.push(combo);
var magnet = new MagnetPowerup();
magnet.x = self.x + 30;
magnet.y = self.y;
game.addChild(magnet);
powerups.push(magnet);
var health = new HealthPowerup();
health.x = self.x - 30;
health.y = self.y;
game.addChild(health);
powerups.push(health);
var sm = new ScoreMultiplierPowerup();
sm.x = self.x + 60;
sm.y = self.y;
game.addChild(sm);
powerups.push(sm);
var ts = new TimeSlowPowerup();
ts.x = self.x - 60;
ts.y = self.y;
game.addChild(ts);
powerups.push(ts);
if (player) {
player.health = Math.min(player.health + 2, 10);
updateUI();
}
};
return self;
});
// --- 49. Add a new asteroid type: ComboSwarmMagnetHealthScoreMultiplierTimeSlowHealerScoreAsteroid (spawns SwarmEnemies, drops combo, magnet, health, score multiplier, time slow, heals player, and gives bonus score)
var ComboSwarmMagnetHealthScoreMultiplierTimeSlowHealerScoreAsteroid = Container.expand(function () {
var self = Container.call(this);
var asteroidGraphics = self.attachAsset('asteroid', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.speed = 2.5;
self.update = function () {
self.y += self.speed;
};
self.spawnSwarmDropAllHealScore = function () {
for (var i = 0; i < 3; i++) {
var swarm = new SwarmEnemy();
swarm.x = self.x + (Math.random() - 0.5) * 100;
swarm.y = self.y;
game.addChild(swarm);
enemies.push(swarm);
}
var combo = new ComboPowerup();
combo.x = self.x;
combo.y = self.y;
game.addChild(combo);
powerups.push(combo);
var magnet = new MagnetPowerup();
magnet.x = self.x + 30;
magnet.y = self.y;
game.addChild(magnet);
powerups.push(magnet);
var health = new HealthPowerup();
health.x = self.x - 30;
health.y = self.y;
game.addChild(health);
powerups.push(health);
var sm = new ScoreMultiplierPowerup();
sm.x = self.x + 60;
sm.y = self.y;
game.addChild(sm);
powerups.push(sm);
var ts = new TimeSlowPowerup();
ts.x = self.x - 60;
ts.y = self.y;
game.addChild(ts);
powerups.push(ts);
if (player) {
player.health = Math.min(player.health + 2, 10);
updateUI();
}
LK.setScore(LK.getScore() + 500);
updateUI();
};
return self;
});
// --- 50. Add a new asteroid type: ComboSwarmMagnetHealthScoreMultiplierTimeSlowHealerScoreReflectorAsteroid (spawns SwarmEnemies, drops combo, magnet, health, score multiplier, time slow, heals player, gives bonus score, and reflects bullets)
var ComboSwarmMagnetHealthScoreMultiplierTimeSlowHealerScoreReflectorAsteroid = Container.expand(function () {
var self = Container.call(this);
var asteroidGraphics = self.attachAsset('asteroid', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.speed = 2.5;
self.reflects = true;
self.update = function () {
self.y += self.speed;
};
self.spawnSwarmDropAllHealScoreReflect = function () {
for (var i = 0; i < 3; i++) {
var swarm = new SwarmEnemy();
swarm.x = self.x + (Math.random() - 0.5) * 100;
swarm.y = self.y;
game.addChild(swarm);
enemies.push(swarm);
}
var combo = new ComboPowerup();
combo.x = self.x;
combo.y = self.y;
game.addChild(combo);
powerups.push(combo);
var magnet = new MagnetPowerup();
magnet.x = self.x + 30;
magnet.y = self.y;
game.addChild(magnet);
powerups.push(magnet);
var health = new HealthPowerup();
health.x = self.x - 30;
health.y = self.y;
game.addChild(health);
powerups.push(health);
var sm = new ScoreMultiplierPowerup();
sm.x = self.x + 60;
sm.y = self.y;
game.addChild(sm);
powerups.push(sm);
var ts = new TimeSlowPowerup();
ts.x = self.x - 60;
ts.y = self.y;
game.addChild(ts);
powerups.push(ts);
if (player) {
player.health = Math.min(player.health + 2, 10);
updateUI();
}
LK.setScore(LK.getScore() + 500);
updateUI();
};
return self;
});
// --- 44. Add a new asteroid type: ComboSwarmMagnetScoreMultiplierAsteroid (spawns SwarmEnemies, drops combo, magnet, and score multiplier powerups)
var ComboSwarmMagnetScoreMultiplierAsteroid = Container.expand(function () {
var self = Container.call(this);
var asteroidGraphics = self.attachAsset('asteroid', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.speed = 2.5;
self.update = function () {
self.y += self.speed;
};
self.spawnSwarmDropComboMagnetScoreMultiplier = function () {
for (var i = 0; i < 3; i++) {
var swarm = new SwarmEnemy();
swarm.x = self.x + (Math.random() - 0.5) * 100;
swarm.y = self.y;
game.addChild(swarm);
enemies.push(swarm);
}
var combo = new ComboPowerup();
combo.x = self.x;
combo.y = self.y;
game.addChild(combo);
powerups.push(combo);
var magnet = new MagnetPowerup();
magnet.x = self.x + 30;
magnet.y = self.y;
game.addChild(magnet);
powerups.push(magnet);
var sm = new ScoreMultiplierPowerup();
sm.x = self.x - 30;
sm.y = self.y;
game.addChild(sm);
powerups.push(sm);
};
return self;
});
// --- 42. Add a new asteroid type: ComboSwarmScoreMultiplierAsteroid (spawns SwarmEnemies, drops combo and score multiplier powerups)
var ComboSwarmScoreMultiplierAsteroid = Container.expand(function () {
var self = Container.call(this);
var asteroidGraphics = self.attachAsset('asteroid', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.speed = 2.5;
self.update = function () {
self.y += self.speed;
};
self.spawnSwarmDropComboScoreMultiplier = function () {
for (var i = 0; i < 3; i++) {
var swarm = new SwarmEnemy();
swarm.x = self.x + (Math.random() - 0.5) * 100;
swarm.y = self.y;
game.addChild(swarm);
enemies.push(swarm);
}
var combo = new ComboPowerup();
combo.x = self.x;
combo.y = self.y;
game.addChild(combo);
powerups.push(combo);
var sm = new ScoreMultiplierPowerup();
sm.x = self.x + 30;
sm.y = self.y;
game.addChild(sm);
powerups.push(sm);
};
return self;
});
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.health = 1;
self.speed = 2;
self.points = 10;
self.canShoot = false;
self.fireRate = 120; // Frames between shots
self.lastFired = Math.floor(Math.random() * 60); // Randomize initial fire time
self.movePattern = 'straight'; // Default pattern
self.amplitude = 100; // For wave pattern
self.frequency = 0.02; // For wave pattern
self.startX = 0; // Store initial X position for wave pattern
self.direction = 1; // For zigzag pattern
self.update = function () {
// Basic movement
if (self.movePattern === 'straight') {
self.y += self.speed;
} else if (self.movePattern === 'wave') {
self.y += self.speed;
self.x = self.startX + Math.sin(self.y * self.frequency) * self.amplitude;
} else if (self.movePattern === 'zigzag') {
self.y += self.speed;
self.x += self.speed * self.direction;
// Reverse direction if approaching screen edge
if (self.x < 100 || self.x > 2048 - 100) {
self.direction *= -1;
}
}
// Enemy shooting logic
if (self.canShoot) {
self.lastFired++;
if (self.lastFired >= self.fireRate) {
self.lastFired = 0;
return true; // Signal to create a bullet
}
}
return false;
};
self.takeDamage = function (amount) {
self.health -= amount;
return self.health <= 0;
};
return self;
});
var EnemyBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('enemyBullet', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.speed = 8;
self.update = function () {
self.y += self.speed;
};
return self;
});
// --- 9. Add a new enemy type: ExploderEnemy (explodes on death, damaging nearby)
var ExploderEnemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.health = 2;
self.speed = 2.5;
self.points = 30;
self.update = function () {
self.y += self.speed;
};
self.takeDamage = function (amount) {
self.health -= amount;
if (self.health <= 0) {
// Damage all enemies within 150px
for (var i = 0; i < enemies.length; i++) {
var e = enemies[i];
if (e !== self && Math.abs(e.x - self.x) < 150 && Math.abs(e.y - self.y) < 150) {
e.takeDamage(1);
LK.effects.flashObject(e, 0xff8800, 300);
}
}
// Damage player if close
if (player && Math.abs(player.x - self.x) < 150 && Math.abs(player.y - self.y) < 150) {
player.takeDamage();
updateUI();
handleGameOver();
}
return true;
}
return false;
};
return self;
});
// --- 21. Add a new asteroid type: ExplodingAsteroid (explodes on death)
var ExplodingAsteroid = Container.expand(function () {
var self = Container.call(this);
var asteroidGraphics = self.attachAsset('asteroid', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.5,
scaleY: 2.5
});
self.speed = 2.5;
self.update = function () {
self.y += self.speed;
};
self.explode = function () {
// Damage player if close
if (player && Math.abs(player.x - self.x) < 200 && Math.abs(player.y - self.y) < 200) {
player.takeDamage();
updateUI();
handleGameOver();
}
LK.effects.flashScreen(0xff8800, 500);
};
return self;
});
// --- 18. Add a new asteroid type: FastAsteroid
var FastAsteroid = Container.expand(function () {
var self = Container.call(this);
var asteroidGraphics = self.attachAsset('asteroid', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.0 + Math.random() * 1.5,
scaleY: 1.0 + Math.random() * 1.5
});
self.speed = 8 + Math.random() * 4;
self.rotationSpeed = (Math.random() - 0.5) * 0.1;
self.update = function () {
self.y += self.speed;
self.rotation += self.rotationSpeed;
};
return self;
});
// --- 7. Add a new enemy type: FastEnemy (moves very fast, low health)
var FastEnemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
self.health = 1;
self.speed = 7;
self.points = 20;
self.update = function () {
self.y += self.speed;
};
self.takeDamage = function (amount) {
self.health -= amount;
return self.health <= 0;
};
return self;
});
// --- 25. Add a new asteroid type: GhostAsteroid (only hit by powerup bullets)
var GhostAsteroid = Container.expand(function () {
var self = Container.call(this);
var asteroidGraphics = self.attachAsset('asteroid', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.speed = 2.5;
self.health = 2;
self.update = function () {
self.y += self.speed;
};
self.takeDamage = function (amount, isPowerup) {
if (isPowerup) {
self.health -= amount;
}
return self.health <= 0;
};
self.isGhost = true;
return self;
});
// --- 11. Add a new enemy type: GhostEnemy (can phase through player, only hit by powerup bullets)
var GhostEnemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.health = 2;
self.speed = 2.2;
self.points = 40;
self.update = function () {
self.y += self.speed;
};
self.takeDamage = function (amount, isPowerup) {
if (isPowerup) {
self.health -= amount;
}
return self.health <= 0;
};
self.isGhost = true;
return self;
});
// --- 19. Add a new asteroid type: GiantAsteroid (splits into smaller asteroids)
var GiantAsteroid = Container.expand(function () {
var self = Container.call(this);
var asteroidGraphics = self.attachAsset('asteroid', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4.0,
scaleY: 4.0
});
self.speed = 2 + Math.random() * 2;
self.rotationSpeed = (Math.random() - 0.5) * 0.05;
self.update = function () {
self.y += self.speed;
self.rotation += self.rotationSpeed;
};
self.split = function () {
for (var i = 0; i < 3; i++) {
var smallAsteroid = new Asteroid();
smallAsteroid.x = self.x + (Math.random() - 0.5) * 100;
smallAsteroid.y = self.y;
game.addChild(smallAsteroid);
asteroids.push(smallAsteroid);
}
};
return self;
});
// --- 27. Add a new asteroid type: HealerAsteroid (heals player on death)
var HealerAsteroid = Container.expand(function () {
var self = Container.call(this);
var asteroidGraphics = self.attachAsset('asteroid', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.speed = 2.5;
self.update = function () {
self.y += self.speed;
};
self.healPlayer = function () {
if (player) {
player.health = Math.min(player.health + 1, 10);
updateUI();
}
};
return self;
});
// --- 17. Add a new boss: HealerBoss (heals itself and enemies every 8 seconds)
var HealerBoss = Container.expand(function () {
var self = Container.call(this);
var bossGraphics = self.attachAsset('boss', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.health = 80;
self.maxHealth = 80;
self.speed = 2.0;
self.points = 1700;
self.phase = 1;
self.moveDirection = 1;
self.fireRate = 60;
self.lastFired = 0;
self.healTimer = 0;
self.update = function () {
self.x += self.speed * self.moveDirection;
if (self.x < 300 || self.x > 2048 - 300) {
self.moveDirection *= -1;
}
self.lastFired++;
if (self.lastFired >= self.fireRate) {
self.lastFired = 0;
return true;
}
self.healTimer++;
if (self.healTimer >= 480) {
self.healTimer = 0;
self.health = Math.min(self.maxHealth, self.health + 10);
for (var i = 0; i < enemies.length; i++) {
enemies[i].health = Math.min(5, enemies[i].health + 1);
LK.effects.flashObject(enemies[i], 0x00ff00, 300);
}
LK.effects.flashObject(self, 0x00ff00, 1000);
}
return false;
};
self.takeDamage = function (amount) {
self.health -= amount;
LK.effects.flashObject(self, 0x00ff00, 300);
return self.health <= 0;
};
return self;
});
// --- 8. Add a new enemy type: HealerEnemy (heals other enemies)
var HealerEnemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.health = 2;
self.speed = 1.5;
self.points = 25;
self.healRate = 180;
self.lastHeal = 0;
self.update = function () {
self.y += self.speed;
self.lastHeal++;
if (self.lastHeal >= self.healRate) {
self.lastHeal = 0;
// Heal a random enemy
if (enemies.length > 1) {
for (var i = 0; i < 2; i++) {
var idx = Math.floor(Math.random() * enemies.length);
if (enemies[idx] !== self && enemies[idx].health < 5) {
enemies[idx].health++;
LK.effects.flashObject(enemies[idx], 0x00ff00, 300);
break;
}
}
}
}
};
self.takeDamage = function (amount) {
self.health -= amount;
return self.health <= 0;
};
return self;
});
// --- 3. Health Powerup: Restores 1 health
var HealthPowerup = Container.expand(function () {
var self = Container.call(this);
var powerupGraphics = self.attachAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3.5,
scaleY: 3.5
});
self.type = 'health';
self.speed = 3;
powerupGraphics.tint = 0x00ff99; // Teal for health
self.update = function () {
self.y += self.speed;
var scale = 1 + Math.sin(LK.ticks * 0.1) * 0.1;
powerupGraphics.scale.set(scale, scale);
};
return self;
});
// --- 33. Add a new asteroid type: HealthPowerupAsteroid (drops health powerup on death)
var HealthPowerupAsteroid = Container.expand(function () {
var self = Container.call(this);
var asteroidGraphics = self.attachAsset('asteroid', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.speed = 2.5;
self.update = function () {
self.y += self.speed;
};
self.dropHealth = function () {
var health = new HealthPowerup();
health.x = self.x;
health.y = self.y;
game.addChild(health);
powerups.push(health);
};
return self;
});
var HeavyEnemy = Container.expand(function () {
var self = Container.call(this);
var heavyEnemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3.0,
scaleY: 3.0
});
self.health = 5;
self.speed = 1;
self.points = 50;
self.update = function () {
self.y += self.speed;
};
self.takeDamage = function (amount) {
self.health -= amount;
return self.health <= 0;
};
return self;
});
// --- 20. Add a new asteroid type: HomingAsteroid (follows player)
var HomingAsteroid = Container.expand(function () {
var self = Container.call(this);
var asteroidGraphics = self.attachAsset('asteroid', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.speed = 3;
self.update = function () {
if (player) {
var angle = Math.atan2(player.y - self.y, player.x - self.x);
self.x += Math.cos(angle) * self.speed;
self.y += Math.sin(angle) * self.speed;
}
};
return self;
});
var KamikazeEnemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.health = 1;
self.speed = 4;
self.points = 15;
self.update = function () {
// Move directly towards the player
if (player) {
var angle = Math.atan2(player.y - self.y, player.x - self.x);
self.x += Math.cos(angle) * self.speed;
self.y += Math.sin(angle) * self.speed;
}
};
self.takeDamage = function (amount) {
self.health -= amount;
return self.health <= 0;
};
return self;
});
// --- 30. Add a new asteroid type: MagnetAsteroid (attracts all powerups to itself)
var MagnetAsteroid = Container.expand(function () {
var self = Container.call(this);
var asteroidGraphics = self.attachAsset('asteroid', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.speed = 2.5;
self.update = function () {
self.y += self.speed;
// Attract powerups
for (var i = 0; i < powerups.length; i++) {
var p = powerups[i];
var angle = Math.atan2(self.y - p.y, self.x - p.x);
p.x += Math.cos(angle) * 2;
p.y += Math.sin(angle) * 2;
}
};
return self;
});
// --- 2. Magnet Powerup: Attracts all powerups to player for 5 seconds
var MagnetPowerup = Container.expand(function () {
var self = Container.call(this);
var powerupGraphics = self.attachAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3.5,
scaleY: 3.5
});
self.type = 'magnet';
self.speed = 3;
powerupGraphics.tint = 0xffff00; // Yellow for magnet
self.update = function () {
self.y += self.speed;
var scale = 1 + Math.sin(LK.ticks * 0.1) * 0.1;
powerupGraphics.scale.set(scale, scale);
};
return self;
});
// --- 32. Add a new asteroid type: MagnetPowerupAsteroid (drops magnet powerup on death)
var MagnetPowerupAsteroid = Container.expand(function () {
var self = Container.call(this);
var asteroidGraphics = self.attachAsset('asteroid', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.speed = 2.5;
self.update = function () {
self.y += self.speed;
};
self.dropMagnet = function () {
var magnet = new MagnetPowerup();
magnet.x = self.x;
magnet.y = self.y;
game.addChild(magnet);
powerups.push(magnet);
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.health = 3;
self.fireRate = 20;
self.lastFired = 0;
self.speed = 10;
self.powerupTimer = 0;
self.hasPowerup = false;
self.takeDamage = function () {
if (self.invulnerable) {
return;
}
self.health--;
LK.getSound('playerHit').play();
// Flash player to indicate damage
self.invulnerable = true;
// Blink effect to show invulnerability
var blinkCount = 0;
var blinkInterval = LK.setInterval(function () {
playerGraphics.alpha = playerGraphics.alpha === 1 ? 0.2 : 1;
blinkCount++;
if (blinkCount >= 10) {
LK.clearInterval(blinkInterval);
playerGraphics.alpha = 1;
self.invulnerable = false;
}
}, 150);
};
self.activatePowerup = function (type) {
LK.getSound('powerupCollected').play();
self.hasPowerup = true;
self.powerupTimer = 300; // 5 seconds at 60fps
if (type === 'fire') {
self.fireRate = 10; // Faster fire rate
playerGraphics.tint = 0xff0000;
} else if (type === 'shield') {
self.invulnerable = true;
playerGraphics.tint = 0x00ffff;
} else if (type === 'timeSlow') {
self.timeSlowActive = true;
game.setGameSpeed(0.5); // Slow down game speed
playerGraphics.tint = 0x00ff00; // Green tint for time slow
}
};
self.update = function () {
// Handle powerup duration
if (self.hasPowerup) {
self.powerupTimer--;
if (self.powerupTimer <= 0) {
self.hasPowerup = false;
self.fireRate = 20; // Reset to normal
self.invulnerable = false;
playerGraphics.tint = 0xffffff; // Reset tint
if (self.timeSlowActive) {
self.timeSlowActive = false;
game.setGameSpeed(1); // Reset game speed to normal
}
}
}
};
return self;
});
var PlayerShip2 = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.health = 5;
self.fireRate = 15;
self.lastFired = 0;
self.speed = 12;
self.powerupTimer = 0;
self.hasPowerup = false;
self.takeDamage = function () {
if (self.invulnerable) {
return;
}
self.health--;
LK.getSound('playerHit').play();
self.invulnerable = true;
var blinkCount = 0;
var blinkInterval = LK.setInterval(function () {
playerGraphics.alpha = playerGraphics.alpha === 1 ? 0.2 : 1;
blinkCount++;
if (blinkCount >= 10) {
LK.clearInterval(blinkInterval);
playerGraphics.alpha = 1;
self.invulnerable = false;
}
}, 150);
};
self.activatePowerup = function (type) {
LK.getSound('powerupCollected').play();
self.hasPowerup = true;
self.powerupTimer = 300;
if (type === 'fire') {
self.fireRate = 8;
playerGraphics.tint = 0xff0000;
} else if (type === 'shield') {
self.invulnerable = true;
playerGraphics.tint = 0x00ffff;
} else if (type === 'timeSlow') {
self.timeSlowActive = true;
game.setGameSpeed(0.5);
playerGraphics.tint = 0x00ff00;
}
};
self.update = function () {
if (self.hasPowerup) {
self.powerupTimer--;
if (self.powerupTimer <= 0) {
self.hasPowerup = false;
self.fireRate = 15;
self.invulnerable = false;
playerGraphics.tint = 0xffffff;
if (self.timeSlowActive) {
self.timeSlowActive = false;
game.setGameSpeed(1);
}
}
}
};
return self;
});
var PlayerShip3 = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.health = 4;
self.fireRate = 18;
self.lastFired = 0;
self.speed = 10;
self.powerupTimer = 0;
self.hasPowerup = false;
self.teleportCooldown = 300; // Cooldown period for teleport ability
self.lastTeleport = 0;
self.takeDamage = function () {
if (self.invulnerable) {
return;
}
self.health--;
LK.getSound('playerHit').play();
self.invulnerable = true;
var blinkCount = 0;
var blinkInterval = LK.setInterval(function () {
playerGraphics.alpha = playerGraphics.alpha === 1 ? 0.2 : 1;
blinkCount++;
if (blinkCount >= 10) {
LK.clearInterval(blinkInterval);
playerGraphics.alpha = 1;
self.invulnerable = false;
}
}, 150);
};
self.activatePowerup = function (type) {
LK.getSound('powerupCollected').play();
self.hasPowerup = true;
self.powerupTimer = 300;
if (type === 'fire') {
self.fireRate = 9;
playerGraphics.tint = 0xff0000;
} else if (type === 'shield') {
self.invulnerable = true;
playerGraphics.tint = 0x00ffff;
} else if (type === 'timeSlow') {
self.timeSlowActive = true;
game.setGameSpeed(0.5);
playerGraphics.tint = 0x00ff00;
}
};
self.update = function () {
if (self.hasPowerup) {
self.powerupTimer--;
if (self.powerupTimer <= 0) {
self.hasPowerup = false;
self.fireRate = 18;
self.invulnerable = false;
playerGraphics.tint = 0xffffff;
if (self.timeSlowActive) {
self.timeSlowActive = false;
game.setGameSpeed(1);
}
}
}
// Teleport ability logic
self.lastTeleport++;
if (self.lastTeleport >= self.teleportCooldown) {
// Teleport to a random position on the screen
self.x = Math.random() * GAME_WIDTH;
self.y = Math.random() * GAME_HEIGHT;
self.lastTeleport = 0;
}
};
return self;
});
var Powerup = Container.expand(function () {
var self = Container.call(this);
var powerupGraphics = self.attachAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3.5,
scaleY: 3.5
});
self.type = Math.random() < 0.5 ? 'fire' : 'shield';
self.speed = 3;
// Set color based on type
if (self.type === 'fire') {
powerupGraphics.tint = 0xff0000; // Red for fire rate
} else {
powerupGraphics.tint = 0x00ffff; // Cyan for shield
}
self.update = function () {
self.y += self.speed;
// Slight pulsing effect
var scale = 1 + Math.sin(LK.ticks * 0.1) * 0.1;
powerupGraphics.scale.set(scale, scale);
};
return self;
});
// --- 22. Add a new asteroid type: PowerupAsteroid (drops powerup on death)
var PowerupAsteroid = Container.expand(function () {
var self = Container.call(this);
var asteroidGraphics = self.attachAsset('asteroid', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.speed = 2.5;
self.update = function () {
self.y += self.speed;
};
self.dropPowerup = function () {
spawnPowerup(self.x, self.y);
};
return self;
});
// --- 24. Add a new asteroid type: ReflectorAsteroid (reflects bullets)
var ReflectorAsteroid = Container.expand(function () {
var self = Container.call(this);
var asteroidGraphics = self.attachAsset('asteroid', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.speed = 2.5;
self.update = function () {
self.y += self.speed;
};
self.reflects = true;
return self;
});
// --- 16. Add a new boss: ReflectorBoss (reflects all bullets for 5 seconds every 15 seconds)
var ReflectorBoss = Container.expand(function () {
var self = Container.call(this);
var bossGraphics = self.attachAsset('boss', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.health = 70;
self.maxHealth = 70;
self.speed = 2.0;
self.points = 1500;
self.phase = 1;
self.moveDirection = 1;
self.fireRate = 50;
self.lastFired = 0;
self.reflectTimer = 0;
self.reflectActive = false;
self.update = function () {
self.x += self.speed * self.moveDirection;
if (self.x < 300 || self.x > 2048 - 300) {
self.moveDirection *= -1;
}
self.lastFired++;
if (self.lastFired >= self.fireRate) {
self.lastFired = 0;
return true;
}
self.reflectTimer++;
if (!self.reflectActive && self.reflectTimer >= 900) {
self.reflectActive = true;
self.reflectTimer = 0;
LK.effects.flashObject(self, 0xffff00, 5000);
LK.setTimeout(function () {
self.reflectActive = false;
}, 5000);
}
return false;
};
self.takeDamage = function (amount) {
self.health -= amount;
LK.effects.flashObject(self, 0xffff00, 300);
return self.health <= 0;
};
return self;
});
// --- 10. Add a new enemy type: ReflectorEnemy (reflects bullets)
var ReflectorEnemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.health = 3;
self.speed = 1.8;
self.points = 35;
self.update = function () {
self.y += self.speed;
};
self.takeDamage = function (amount) {
self.health -= amount;
return self.health <= 0;
};
self.reflects = true;
return self;
});
// --- 29. Add a new asteroid type: ScoreAsteroid (gives bonus score on death)
var ScoreAsteroid = Container.expand(function () {
var self = Container.call(this);
var asteroidGraphics = self.attachAsset('asteroid', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.speed = 2.5;
self.update = function () {
self.y += self.speed;
};
self.giveScore = function () {
LK.setScore(LK.getScore() + 100);
updateUI();
};
return self;
});
// --- 4. Score Multiplier Powerup: Doubles score for 10 seconds
var ScoreMultiplierPowerup = Container.expand(function () {
var self = Container.call(this);
var powerupGraphics = self.attachAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3.5,
scaleY: 3.5
});
self.type = 'scoreMultiplier';
self.speed = 3;
powerupGraphics.tint = 0xffa500; // Orange for score multiplier
self.update = function () {
self.y += self.speed;
var scale = 1 + Math.sin(LK.ticks * 0.1) * 0.1;
powerupGraphics.scale.set(scale, scale);
};
return self;
});
// --- 34. Add a new asteroid type: ScoreMultiplierPowerupAsteroid (drops score multiplier powerup on death)
var ScoreMultiplierPowerupAsteroid = Container.expand(function () {
var self = Container.call(this);
var asteroidGraphics = self.attachAsset('asteroid', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.speed = 2.5;
self.update = function () {
self.y += self.speed;
};
self.dropScoreMultiplier = function () {
var sm = new ScoreMultiplierPowerup();
sm.x = self.x;
sm.y = self.y;
game.addChild(sm);
powerups.push(sm);
};
return self;
});
var ShieldPowerup = Container.expand(function () {
var self = Container.call(this);
var powerupGraphics = self.attachAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3.5,
scaleY: 3.5
});
self.type = 'shield';
self.speed = 3;
powerupGraphics.tint = 0x00ffff; // Cyan for shield
self.update = function () {
self.y += self.speed;
var scale = 1 + Math.sin(LK.ticks * 0.1) * 0.1;
powerupGraphics.scale.set(scale, scale);
};
return self;
});
// --- 23. Add a new asteroid type: ShieldedAsteroid (takes half damage)
var ShieldedAsteroid = Container.expand(function () {
var self = Container.call(this);
var asteroidGraphics = self.attachAsset('asteroid', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.5,
scaleY: 2.5
});
self.speed = 2.5;
self.health = 4;
self.update = function () {
self.y += self.speed;
};
self.takeDamage = function (amount) {
self.health -= Math.ceil(amount / 2);
return self.health <= 0;
};
return self;
});
// --- 6. Add a new enemy type: ShieldedEnemy (takes half damage)
var ShieldedEnemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.5,
scaleY: 2.5
});
self.health = 4;
self.speed = 1.2;
self.points = 40;
self.update = function () {
self.y += self.speed;
};
self.takeDamage = function (amount) {
self.health -= Math.ceil(amount / 2);
return self.health <= 0;
};
return self;
});
// --- 5. Add a new enemy type: SniperEnemy (shoots at player from distance)
var SniperEnemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.health = 2;
self.speed = 1.5;
self.points = 30;
self.canShoot = true;
self.fireRate = 90;
self.lastFired = 0;
self.update = function () {
self.y += self.speed;
self.lastFired++;
if (self.lastFired >= self.fireRate && player && Math.abs(self.x - player.x) < 200) {
self.lastFired = 0;
return true;
}
return false;
};
self.takeDamage = function (amount) {
self.health -= amount;
return self.health <= 0;
};
return self;
});
// --- 13. Add a new enemy type: SplitterBoss (splits into two mini-bosses)
var SplitterBoss = Container.expand(function () {
var self = Container.call(this);
var bossGraphics = self.attachAsset('boss', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.health = 40;
self.maxHealth = 40;
self.speed = 2.5;
self.points = 800;
self.phase = 1;
self.moveDirection = 1;
self.fireRate = 50;
self.lastFired = 0;
self.patternTimer = 0;
self.currentPattern = 'move';
self.update = function () {
self.patternTimer++;
if (self.patternTimer >= 180) {
self.patternTimer = 0;
self.currentPattern = self.currentPattern === 'move' ? 'attack' : 'move';
}
if (self.currentPattern === 'move') {
self.x += self.speed * self.moveDirection;
if (self.x < 300 || self.x > 2048 - 300) {
self.moveDirection *= -1;
}
}
if (self.currentPattern === 'attack') {
self.lastFired++;
if (self.lastFired >= self.fireRate) {
self.lastFired = 0;
return true;
}
}
if (self.health <= self.maxHealth * 0.5 && self.phase === 1) {
self.phase = 2;
// Split into two mini-bosses
for (var i = 0; i < 2; i++) {
var miniBoss = new Boss();
miniBoss.x = self.x + (i === 0 ? -100 : 100);
miniBoss.y = self.y;
miniBoss.health = 15;
miniBoss.maxHealth = 15;
miniBoss.points = 200;
game.addChild(miniBoss);
boss = miniBoss;
}
self.destroy();
return false;
}
return false;
};
self.takeDamage = function (amount) {
self.health -= amount;
LK.effects.flashObject(self, 0xff0000, 300);
return self.health <= 0;
};
return self;
});
var SplittingEnemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.health = 2;
self.speed = 2;
self.points = 20;
self.splitCount = 2; // Number of smaller enemies to spawn
self.update = function () {
self.y += self.speed;
};
self.takeDamage = function (amount) {
self.health -= amount;
if (self.health <= 0) {
// Spawn smaller enemies
for (var i = 0; i < self.splitCount; i++) {
var smallEnemy = new Enemy();
smallEnemy.x = self.x + (Math.random() - 0.5) * 50;
smallEnemy.y = self.y;
smallEnemy.health = 1;
smallEnemy.speed = 3;
game.addChild(smallEnemy);
enemies.push(smallEnemy);
}
return true;
}
return false;
};
return self;
});
// --- 26. Add a new asteroid type: SwarmAsteroid (spawns SwarmEnemies on death)
var SwarmAsteroid = Container.expand(function () {
var self = Container.call(this);
var asteroidGraphics = self.attachAsset('asteroid', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.speed = 2.5;
self.update = function () {
self.y += self.speed;
};
self.spawnSwarm = function () {
for (var i = 0; i < 5; i++) {
var swarm = new SwarmEnemy();
swarm.x = self.x + (Math.random() - 0.5) * 100;
swarm.y = self.y;
game.addChild(swarm);
enemies.push(swarm);
}
};
return self;
});
// --- 15. Add a new boss: SwarmBoss (spawns SwarmEnemies every 2 seconds)
var SwarmBoss = Container.expand(function () {
var self = Container.call(this);
var bossGraphics = self.attachAsset('boss', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.health = 60;
self.maxHealth = 60;
self.speed = 2.0;
self.points = 1200;
self.phase = 1;
self.moveDirection = 1;
self.fireRate = 60;
self.lastFired = 0;
self.swarmTimer = 0;
self.update = function () {
self.x += self.speed * self.moveDirection;
if (self.x < 300 || self.x > 2048 - 300) {
self.moveDirection *= -1;
}
self.lastFired++;
if (self.lastFired >= self.fireRate) {
self.lastFired = 0;
return true;
}
self.swarmTimer++;
if (self.swarmTimer >= 120) {
self.swarmTimer = 0;
// Spawn SwarmEnemies
for (var i = 0; i < 5; i++) {
var swarm = new SwarmEnemy();
swarm.x = self.x + (Math.random() - 0.5) * 200;
swarm.y = self.y + 100;
game.addChild(swarm);
enemies.push(swarm);
}
}
return false;
};
self.takeDamage = function (amount) {
self.health -= amount;
LK.effects.flashObject(self, 0xff00ff, 300);
return self.health <= 0;
};
return self;
});
// --- 12. Add a new enemy type: SwarmEnemy (spawns in groups, low points)
var SwarmEnemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.0,
scaleY: 1.0
});
self.health = 1;
self.speed = 3.5;
self.points = 5;
self.update = function () {
self.y += self.speed;
};
self.takeDamage = function (amount) {
self.health -= amount;
return self.health <= 0;
};
return self;
});
// --- 35. Add a new asteroid type: SwarmPowerupAsteroid (spawns SwarmEnemies and drops powerup)
var SwarmPowerupAsteroid = Container.expand(function () {
var self = Container.call(this);
var asteroidGraphics = self.attachAsset('asteroid', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.speed = 2.5;
self.update = function () {
self.y += self.speed;
};
self.spawnSwarmAndDrop = function () {
for (var i = 0; i < 3; i++) {
var swarm = new SwarmEnemy();
swarm.x = self.x + (Math.random() - 0.5) * 100;
swarm.y = self.y;
game.addChild(swarm);
enemies.push(swarm);
}
spawnPowerup(self.x, self.y);
};
return self;
});
// --- 28. Add a new asteroid type: TimeSlowAsteroid (slows time on death)
var TimeSlowAsteroid = Container.expand(function () {
var self = Container.call(this);
var asteroidGraphics = self.attachAsset('asteroid', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.speed = 2.5;
self.update = function () {
self.y += self.speed;
};
self.slowTime = function () {
game.setGameSpeed(0.5);
LK.setTimeout(function () {
game.setGameSpeed(1);
}, 3000);
};
return self;
});
var TimeSlowPowerup = Container.expand(function () {
var self = Container.call(this);
var powerupGraphics = self.attachAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3.5,
scaleY: 3.5
});
self.type = 'timeSlow';
self.speed = 3;
powerupGraphics.tint = 0x00ff00; // Green for time slow
self.update = function () {
self.y += self.speed;
var scale = 1 + Math.sin(LK.ticks * 0.1) * 0.1;
powerupGraphics.scale.set(scale, scale);
};
return self;
});
// --- 14. Add a new boss: TimeStopBoss (freezes player for 2 seconds every 10 seconds)
var TimeStopBoss = Container.expand(function () {
var self = Container.call(this);
var bossGraphics = self.attachAsset('boss', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.health = 50;
self.maxHealth = 50;
self.speed = 2.5;
self.points = 1000;
self.phase = 1;
self.moveDirection = 1;
self.fireRate = 40;
self.lastFired = 0;
self.patternTimer = 0;
self.freezeTimer = 0;
self.update = function () {
self.patternTimer++;
self.freezeTimer++;
if (self.patternTimer >= 180) {
self.patternTimer = 0;
}
self.x += self.speed * self.moveDirection;
if (self.x < 300 || self.x > 2048 - 300) {
self.moveDirection *= -1;
}
self.lastFired++;
if (self.lastFired >= self.fireRate) {
self.lastFired = 0;
return true;
}
if (self.freezeTimer >= 600) {
self.freezeTimer = 0;
// Freeze player for 2 seconds
if (player) {
player.frozen = true;
LK.setTimeout(function () {
player.frozen = false;
}, 2000);
}
}
return false;
};
self.takeDamage = function (amount) {
self.health -= amount;
LK.effects.flashObject(self, 0x00ffff, 300);
return self.health <= 0;
};
return self;
});
var UniquePlayerShip = Container.expand(function () {
var self = Container.call(this);
var uniquePlayerGraphics = self.attachAsset('uniquePlayer', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.health = 6;
self.fireRate = 12;
self.lastFired = 0;
self.speed = 14;
self.powerupTimer = 0;
self.hasPowerup = false;
self.uniqueAbilityCooldown = 500; // Cooldown period for unique ability
self.lastAbilityUse = 0;
self.takeDamage = function () {
if (self.invulnerable) {
return;
}
self.health--;
LK.getSound('playerHit').play();
self.invulnerable = true;
var blinkCount = 0;
var blinkInterval = LK.setInterval(function () {
uniquePlayerGraphics.alpha = uniquePlayerGraphics.alpha === 1 ? 0.2 : 1;
blinkCount++;
if (blinkCount >= 10) {
LK.clearInterval(blinkInterval);
uniquePlayerGraphics.alpha = 1;
self.invulnerable = false;
}
}, 150);
};
self.activatePowerup = function (type) {
LK.getSound('powerupCollected').play();
self.hasPowerup = true;
self.powerupTimer = 300;
if (type === 'fire') {
self.fireRate = 6;
uniquePlayerGraphics.tint = 0xff0000;
} else if (type === 'shield') {
self.invulnerable = true;
uniquePlayerGraphics.tint = 0x00ffff;
} else if (type === 'timeSlow') {
self.timeSlowActive = true;
game.setGameSpeed(0.5);
uniquePlayerGraphics.tint = 0x00ff00;
}
};
self.update = function () {
if (self.hasPowerup) {
self.powerupTimer--;
if (self.powerupTimer <= 0) {
self.hasPowerup = false;
self.fireRate = 12;
self.invulnerable = false;
uniquePlayerGraphics.tint = 0xffffff;
if (self.timeSlowActive) {
self.timeSlowActive = false;
game.setGameSpeed(1);
}
}
}
// Unique ability logic
self.lastAbilityUse++;
if (self.lastAbilityUse >= self.uniqueAbilityCooldown) {
// Implement unique ability, e.g., temporary invincibility
self.invulnerable = true;
LK.setTimeout(function () {
self.invulnerable = false;
}, 2000); // 2 seconds of invincibility
self.lastAbilityUse = 0;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Create a shop interface for purchasing ships
var shopInterface = new Container();
shopInterface.visible = false; // Initially hidden
// Create buttons for each ship type
var shipButtons = [{
type: 'Player',
text: 'Standard Ship',
cost: 100
}, {
type: 'PlayerShip2',
text: 'Advanced Ship',
cost: 200
}, {
type: 'PlayerShip3',
text: 'Teleport Ship',
cost: 300
}, {
type: 'UniquePlayerShip',
text: 'Unique Ship',
cost: 500
}];
// Add buttons to the shop interface
shipButtons.forEach(function (ship, index) {
var button = new Button({
text: ship.text + ' - ' + ship.cost + ' Points',
size: 50,
fill: 0xFFFFFF,
x: GAME_WIDTH / 2,
y: 200 + index * 100,
anchorX: 0.5,
anchorY: 0.5,
onDown: function onDown() {
if (LK.getScore() >= ship.cost) {
LK.setScore(LK.getScore() - ship.cost);
updateUI();
// Replace current player with selected ship
player.destroy();
player = new window[ship.type]();
player.x = GAME_WIDTH / 2;
player.y = GAME_HEIGHT - 200;
game.addChild(player);
shopInterface.visible = false; // Hide shop after purchase
}
}
});
button.on('down', function () {
if (LK.getScore() >= ship.cost) {
LK.setScore(LK.getScore() - ship.cost);
updateUI();
// Replace current player with selected ship
player.destroy();
player = new window[ship.type]();
player.x = GAME_WIDTH / 2;
player.y = GAME_HEIGHT - 200;
game.addChild(player);
shopInterface.visible = false; // Hide shop after purchase
}
});
shopInterface.addChild(button);
});
// Add the shop interface to the game UI
LK.gui.center.addChild(shopInterface);
// Function to toggle shop visibility
function toggleShop() {
shopInterface.visible = !shopInterface.visible;
}
// Example: Toggle shop with a specific gesture or condition
game.down = function (x, y, obj) {
// Admin mode toggle with a specific gesture or condition
if (x < 100 && y < 100) {
adminPowers.toggleAdminMode();
return;
}
// Shop toggle in top right
if (x > GAME_WIDTH - 100 && y < 100) {
toggleShop();
}
};
// Teleport button removed as requested
game.setGameSpeed = function (speed) {
// Implement logic to adjust game speed
// This could involve adjusting the speed of all game elements
player.speed *= speed;
playerBullets.forEach(function (bullet) {
return bullet.speed *= speed;
});
enemies.forEach(function (enemy) {
return enemy.speed *= speed;
});
enemyBullets.forEach(function (bullet) {
return bullet.speed *= speed;
});
asteroids.forEach(function (asteroid) {
return asteroid.speed *= speed;
});
powerups.forEach(function (powerup) {
return powerup.speed *= speed;
});
if (boss) {
boss.speed *= speed;
}
};
var AdminPowers = function AdminPowers() {
var self = this;
self.isAdmin = false;
self.toggleAdminMode = function () {
self.isAdmin = !self.isAdmin;
if (self.isAdmin) {
console.log("Admin mode activated");
// Additional admin features can be added here
} else {
console.log("Admin mode deactivated");
}
};
self.spawnBoss = function () {
if (self.isAdmin) {
spawnBoss();
console.log("Boss spawned by admin");
}
};
self.increaseScore = function (amount) {
if (self.isAdmin) {
LK.setScore(LK.getScore() + amount);
updateUI();
console.log("Score increased by admin");
}
};
return self;
};
var adminPowers = new AdminPowers();
var GAME_WIDTH = 2048;
var GAME_HEIGHT = 2732;
// Game state variables
var gameState = "playing"; // playing, paused, over
var level = 1;
var waveTimer = 0;
var nextWaveTime = 180; // 3 seconds at 60fps
var wave = 0;
var spawnRate = 60; // frames between enemy spawns
var lastSpawn = 0;
var bossActive = false;
var bossDefeated = false;
var bossSpawnWave = 5;
// Game elements
var player;
var playerBullets = [];
var enemies = [];
var enemyBullets = [];
var asteroids = [];
var powerups = [];
var boss = null;
// Track dragging
var dragging = false;
var lastX = 0;
var lastY = 0;
// Score display
var scoreText = new Text2('SCORE: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(0, 0);
LK.gui.topRight.addChild(scoreText);
scoreText.x = -350; // Position from right edge
// Wave display
var waveText = new Text2('WAVE: 1', {
size: 60,
fill: 0xFFFFFF
});
waveText.anchor.set(0, 0);
LK.gui.topRight.addChild(waveText);
waveText.x = -350;
waveText.y = 70;
// Health display
var healthText = new Text2('HEALTH: 3', {
size: 60,
fill: 0xFFFFFF
});
healthText.anchor.set(0, 0);
LK.gui.topLeft.addChild(healthText);
healthText.x = 120; // Avoid the top-left corner as requested
healthText.y = 0;
// Initialize game elements
function initGame() {
// Reset game state
gameState = "playing";
level = 1;
waveTimer = 0;
nextWaveTime = 180;
wave = 0;
spawnRate = 60;
lastSpawn = 0;
bossActive = false;
bossDefeated = false;
// Clear all game elements
playerBullets = [];
enemies = [];
enemyBullets = [];
asteroids = [];
powerups = [];
if (boss) {
boss.destroy();
boss = null;
}
// Create player
player = new UniquePlayerShip();
player.x = GAME_WIDTH / 2;
player.y = GAME_HEIGHT - 200;
game.addChild(player);
// Update UI
LK.setScore(0);
updateUI();
// Start background music
LK.playMusic('gameMusic');
}
// Update UI elements
function updateUI() {
scoreText.setText('SCORE: ' + LK.getScore());
waveText.setText('WAVE: ' + wave);
healthText.setText('HEALTH: ' + player.health);
}
// Spawn enemies for the current wave
function spawnWave() {
wave++;
waveText.setText('WAVE: ' + wave);
// Boss wave
if (wave % bossSpawnWave === 0) {
spawnBoss();
return;
}
// Increase difficulty with each wave
spawnRate = Math.max(20, 60 - wave * 5); // Faster spawn rate as waves progress
// Spawn some initial enemies
var initialEnemies = 3 + Math.min(10, Math.floor(wave / 2)); // More enemies as waves progress
for (var i = 0; i < initialEnemies; i++) {
spawnEnemy();
}
// Also spawn some asteroids
for (var j = 0; j < Math.min(7, wave); j++) {
// More asteroids as waves progress
spawnAsteroid();
}
// Introduce new enemy types or patterns every few waves
if (wave % 3 === 0) {
for (var k = 0; k < Math.min(3, wave / 3); k++) {
var specialEnemy = new SplittingEnemy();
specialEnemy.x = 200 + Math.random() * (GAME_WIDTH - 400);
specialEnemy.y = -100;
game.addChild(specialEnemy);
enemies.push(specialEnemy);
}
}
}
// Spawn a single enemy
function spawnEnemy() {
var enemy;
if (Math.random() < 0.1) {
// 10% chance to spawn a KamikazeEnemy
enemy = new KamikazeEnemy();
} else if (Math.random() < 0.2) {
// 20% chance to spawn a SplittingEnemy
enemy = new SplittingEnemy();
} else if (Math.random() < 0.15) {
// 15% chance to spawn a HeavyEnemy
enemy = new HeavyEnemy();
} else {
enemy = new Enemy();
}
enemy.x = 200 + Math.random() * (GAME_WIDTH - 400);
enemy.y = -100;
// Increase health and speed with level
enemy.health = 1 + Math.floor(wave / 3);
enemy.speed = 2 + Math.min(3, wave * 0.5);
enemy.points = 10 * (1 + Math.floor(wave / 2));
// Different enemy types based on wave
if (wave > 1) {
// Some enemies can shoot
enemy.canShoot = Math.random() < 0.3;
// Different movement patterns
var patterns = ['straight', 'wave', 'zigzag'];
enemy.movePattern = patterns[Math.floor(Math.random() * Math.min(patterns.length, 1 + wave / 2))];
enemy.startX = enemy.x;
}
game.addChild(enemy);
enemies.push(enemy);
}
// Spawn boss
function spawnBoss() {
LK.getSound('bossAppear').play();
boss = new Boss();
boss.x = GAME_WIDTH / 2;
boss.y = 300;
// Scale boss difficulty with wave
var waveMultiplier = Math.floor(wave / bossSpawnWave);
boss.health = boss.maxHealth = 30 + waveMultiplier * 20;
boss.points = 500 + waveMultiplier * 200;
bossActive = true;
game.addChild(boss);
// Add warning text
var warningText = new Text2('BOSS INCOMING!', {
size: 120,
fill: 0xFF0000
});
warningText.anchor.set(0.5, 0.5);
warningText.x = GAME_WIDTH / 2;
warningText.y = GAME_HEIGHT / 2;
game.addChild(warningText);
// Remove warning after 2 seconds
LK.setTimeout(function () {
warningText.destroy();
}, 2000);
}
// Spawn asteroid
function spawnAsteroid() {
var asteroid = new Asteroid();
asteroid.x = Math.random() * GAME_WIDTH;
asteroid.y = -100;
game.addChild(asteroid);
asteroids.push(asteroid);
}
// Spawn powerup
function spawnPowerup(x, y) {
if (Math.random() < 0.2) {
// 20% chance to spawn a powerup
var powerup;
if (Math.random() < 0.1) {
// 10% chance for time slow powerup
powerup = new TimeSlowPowerup();
} else if (Math.random() < 0.2) {
// 10% chance for shield powerup
powerup = new ShieldPowerup();
} else {
powerup = new Powerup();
}
powerup.x = x;
powerup.y = y;
game.addChild(powerup);
powerups.push(powerup);
}
}
// Player shoots a bullet
function playerShoot() {
var bullet = new Bullet();
bullet.x = player.x;
bullet.y = player.y - 40;
game.addChild(bullet);
playerBullets.push(bullet);
LK.getSound('playerShoot').play();
}
// Enemy shoots a bullet
function enemyShoot(enemy) {
var bullet = new EnemyBullet();
bullet.x = enemy.x;
bullet.y = enemy.y + 30;
game.addChild(bullet);
enemyBullets.push(bullet);
}
// Boss shoots bullets
function bossShoot() {
// Different attack patterns based on phase
if (boss.phase === 1) {
// Single bullet
var bullet = new EnemyBullet();
bullet.x = boss.x;
bullet.y = boss.y + 75;
game.addChild(bullet);
enemyBullets.push(bullet);
} else if (boss.phase === 2) {
// Three bullets in spread
for (var i = -1; i <= 1; i++) {
var bullet = new EnemyBullet();
bullet.x = boss.x + i * 50;
bullet.y = boss.y + 75;
game.addChild(bullet);
enemyBullets.push(bullet);
}
} else {
// Circle of bullets
var bulletCount = 8;
for (var i = 0; i < bulletCount; i++) {
var angle = i / bulletCount * Math.PI * 2;
var bullet = new EnemyBullet();
bullet.x = boss.x;
bullet.y = boss.y + 75;
bullet.speed = 6;
// Add velocity components
bullet.vx = Math.sin(angle) * bullet.speed;
bullet.vy = Math.cos(angle) * bullet.speed;
// Override update method for this bullet
bullet.update = function () {
this.x += this.vx;
this.y += this.vy;
};
game.addChild(bullet);
enemyBullets.push(bullet);
}
}
}
// Check if an object is off screen
function isOffScreen(obj) {
return obj.y < -100 || obj.y > GAME_HEIGHT + 100 || obj.x < -100 || obj.x > GAME_WIDTH + 100;
}
// Handle game over
function handleGameOver() {
if (player.health <= 0) {
gameState = "over";
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
}
}
// Handle input events
game.down = function (x, y, obj) {
dragging = true;
lastX = x;
lastY = y;
// Admin mode toggle with a specific gesture or condition
if (x < 100 && y < 100) {
// Example condition for toggling admin mode
adminPowers.toggleAdminMode();
}
};
game.up = function (x, y, obj) {
dragging = false;
};
game.move = function (x, y, obj) {
if (dragging && player) {
// Calculate movement
var dx = x - lastX;
var dy = y - lastY;
// Update player position with boundaries
player.x = Math.max(50, Math.min(GAME_WIDTH - 50, player.x + dx));
player.y = Math.max(50, Math.min(GAME_HEIGHT - 50, player.y + dy));
// Update last position
lastX = x;
lastY = y;
}
};
// Initialize the game
initGame();
// Main game loop
game.update = function () {
if (gameState !== "playing") {
return;
}
// Example admin controls
if (adminPowers.isAdmin) {
// Admin can spawn a boss at any time
if (LK.ticks % 600 === 0) {
// Every 10 seconds
adminPowers.spawnBoss();
}
// Admin can increase score periodically
if (LK.ticks % 300 === 0) {
// Every 5 seconds
adminPowers.increaseScore(100);
}
}
// Update player
if (player) {
player.update();
// Player shooting
player.lastFired++;
if (player.lastFired >= player.fireRate) {
player.lastFired = 0;
playerShoot();
}
}
// Wave management
if (!bossActive) {
waveTimer++;
if (waveTimer >= nextWaveTime && enemies.length === 0) {
waveTimer = 0;
spawnWave();
}
// Periodic enemy spawning during wave
lastSpawn++;
if (lastSpawn >= spawnRate && wave > 0 && !bossActive && enemies.length < 10 + wave) {
lastSpawn = 0;
spawnEnemy();
}
}
// Update bullets
for (var i = playerBullets.length - 1; i >= 0; i--) {
var bullet = playerBullets[i];
bullet.update();
// Remove off-screen bullets
if (isOffScreen(bullet)) {
bullet.destroy();
playerBullets.splice(i, 1);
continue;
}
// Check collision with enemies
for (var j = enemies.length - 1; j >= 0; j--) {
var enemy = enemies[j];
if (bullet.intersects(enemy)) {
var destroyed = enemy.takeDamage(bullet.damage);
if (destroyed && enemy instanceof SplittingEnemy) {}
;
if (destroyed) {
LK.getSound('enemyDestroyed').play();
LK.setScore(LK.getScore() + enemy.points);
updateUI();
// Chance to spawn powerup
spawnPowerup(enemy.x, enemy.y);
enemy.destroy();
enemies.splice(j, 1);
}
bullet.destroy();
playerBullets.splice(i, 1);
break;
}
if (enemy instanceof KamikazeEnemy && enemy.intersects(player)) {
player.takeDamage();
updateUI();
enemy.destroy();
enemies.splice(j, 1);
handleGameOver();
}
}
// Check collision with boss
if (boss && bullet.intersects(boss)) {
var bossDestroyed = boss.takeDamage(bullet.damage);
if (bossDestroyed) {
LK.getSound('enemyDestroyed').play();
LK.setScore(LK.getScore() + boss.points);
updateUI();
// Multiple powerups when boss is defeated
for (var k = 0; k < 3; k++) {
spawnPowerup(boss.x + (Math.random() - 0.5) * 100, boss.y + (Math.random() - 0.5) * 100);
}
boss.destroy();
boss = null;
bossActive = false;
bossDefeated = true;
// Next wave after boss defeat
waveTimer = nextWaveTime;
}
bullet.destroy();
playerBullets.splice(i, 1);
}
// Check collision with asteroids
for (var j = asteroids.length - 1; j >= 0; j--) {
var asteroid = asteroids[j];
if (bullet.intersects(asteroid)) {
asteroid.destroy();
asteroids.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];
bullet.update();
// Remove off-screen bullets
if (isOffScreen(bullet)) {
bullet.destroy();
enemyBullets.splice(i, 1);
continue;
}
// Check collision with player
if (player && bullet.intersects(player)) {
player.takeDamage();
updateUI();
bullet.destroy();
enemyBullets.splice(i, 1);
handleGameOver();
}
}
// Update enemies
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
var shouldShoot = enemy.update();
// Enemy shooting
if (shouldShoot) {
enemyShoot(enemy);
}
// Remove off-screen enemies
if (enemy.y > GAME_HEIGHT + 100) {
enemy.destroy();
enemies.splice(i, 1);
continue;
}
// Check collision with player
if (player && enemy.intersects(player)) {
player.takeDamage();
updateUI();
enemy.destroy();
enemies.splice(i, 1);
handleGameOver();
}
}
// Update boss
if (boss) {
var shouldShoot = boss.update();
if (shouldShoot) {
bossShoot();
}
// Check collision with player
if (player && boss.intersects(player)) {
player.takeDamage();
updateUI();
handleGameOver();
}
}
// Update asteroids
for (var i = asteroids.length - 1; i >= 0; i--) {
var asteroid = asteroids[i];
asteroid.update();
// Remove off-screen asteroids
if (asteroid.y > GAME_HEIGHT + 100) {
asteroid.destroy();
asteroids.splice(i, 1);
continue;
}
// Check collision with player
if (player && asteroid.intersects(player)) {
player.takeDamage();
updateUI();
asteroid.destroy();
asteroids.splice(i, 1);
handleGameOver();
}
}
// Update powerups
for (var i = powerups.length - 1; i >= 0; i--) {
var powerup = powerups[i];
powerup.update();
// Remove off-screen powerups
if (powerup.y > GAME_HEIGHT + 100) {
powerup.destroy();
powerups.splice(i, 1);
continue;
}
// Check collision with player
if (player && powerup.intersects(player)) {
player.activatePowerup(powerup.type);
powerup.destroy();
powerups.splice(i, 1);
}
}
};