User prompt
Make alien warships work as AI
User prompt
Make alien warships work as AI
User prompt
Decrease the bullet speed of the alien warships. Every 10 seconds, a bomb will come from where the alien warships are coming from. When the bomb is detonated, the alien warships in the 0.5 cm area will be destroyed. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Slow down the tracking system of incoming fighter jets against alien ships a little more. Increase the bullet speed of alien warships more.
User prompt
Increase the movement of enemy warships according to the movement of the fighter plane, increase the speed of the projectiles of the war alien warships by 5 times
User prompt
Increase the precision of spaceships and our fighter jets and increase the speed of their projectiles
Code edit (1 edits merged)
Please save this source code
User prompt
Space Fighter Squadron
Initial prompt
There should be a war with alien warships in space with fighter jets that we can control up to half of the screen. Each alien warship we destroy should have a size scale between 1 and 5, and we should get 5 points per size. There should be a reward system that gives faster fire and more weapons when we blow up some ships that are on the 5 size scale.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { volume: 1 }); /**** * Classes ****/ var Alien = Container.expand(function (size) { var self = Container.call(this); self.size = size || 1; self.health = size; self.maxHealth = size; var assetName = 'alien' + size; var alienGraphics = self.attachAsset(assetName, { anchorX: 0.5, anchorY: 0.5 }); self.speed = Math.random() * 3 + 2; self.lastShot = 0; self.shootDelay = 60 + Math.random() * 120; // AI behavior properties self.aiType = Math.floor(Math.random() * 4); // 0: aggressive, 1: evasive, 2: patrol, 3: formation self.baseX = self.x; self.patrolDirection = Math.random() < 0.5 ? -1 : 1; self.evasionTimer = 0; self.formationOffset = Math.random() * Math.PI * 2; self.aggressionLevel = Math.random() * 0.5 + 0.5; // 0.5 to 1.0 self.update = function () { self.y += self.speed; // AI Movement Behaviors if (self.aiType === 0) { // Aggressive: Move directly toward player with increasing speed var playerDistance = player.x - self.x; var horizontalSpeed = Math.min(Math.abs(playerDistance) * 0.02 * self.aggressionLevel, 2.5); if (playerDistance > 0) { self.x += horizontalSpeed; } else if (playerDistance < 0) { self.x -= horizontalSpeed; } // Increase speed when close to player if (Math.abs(playerDistance) < 200) { self.speed += 0.1; } } else if (self.aiType === 1) { // Evasive: Move away from player bullets and use unpredictable movement self.evasionTimer++; var nearbyBullet = false; for (var b = 0; b < playerBullets.length; b++) { var bullet = playerBullets[b]; var bulletDistance = Math.sqrt(Math.pow(bullet.x - self.x, 2) + Math.pow(bullet.y - self.y, 2)); if (bulletDistance < 150) { nearbyBullet = true; // Evade away from bullet if (bullet.x < self.x) { self.x += 3; } else { self.x -= 3; } break; } } // Random evasive movement when no immediate threat if (!nearbyBullet && self.evasionTimer % 60 === 0) { self.x += (Math.random() - 0.5) * 100; } } else if (self.aiType === 2) { // Patrol: Move in horizontal patterns while slowly tracking player var patrolSpeed = 1.5; self.x += self.patrolDirection * patrolSpeed; if (self.x < 200 || self.x > 1848) { self.patrolDirection *= -1; } // Slight player tracking var playerDistance = player.x - self.x; var trackingSpeed = Math.min(Math.abs(playerDistance) * 0.005, 0.5); if (playerDistance > 0) { self.x += trackingSpeed; } else if (playerDistance < 0) { self.x -= trackingSpeed; } } else if (self.aiType === 3) { // Formation: Move in coordinated patterns with other aliens var formationSpeed = Math.sin((LK.ticks + self.formationOffset) * 0.05) * 2; self.x += formationSpeed; // Maintain formation spacing for (var a = 0; a < aliens.length; a++) { var otherAlien = aliens[a]; if (otherAlien !== self && otherAlien.aiType === 3) { var distance = Math.abs(otherAlien.x - self.x); if (distance < 120 && distance > 0) { if (otherAlien.x > self.x) { self.x -= 1; } else { self.x += 1; } } } } } // Keep aliens within screen bounds self.x = Math.max(50, Math.min(1998, self.x)); // AI Shooting Behavior self.lastShot++; var shootChance = 1.0; var playerDistance = Math.sqrt(Math.pow(player.x - self.x, 2) + Math.pow(player.y - self.y, 2)); // Adjust shooting based on AI type and player proximity if (self.aiType === 0) { // Aggressive aliens shoot more frequently when close to player if (playerDistance < 300) { shootChance = 1.5; self.shootDelay = 40 + Math.random() * 60; } } else if (self.aiType === 1) { // Evasive aliens shoot less frequently but more accurately shootChance = 0.7; self.shootDelay = 80 + Math.random() * 100; } else if (self.aiType === 2) { // Patrol aliens have steady firing rate shootChance = 0.9; } else if (self.aiType === 3) { // Formation aliens coordinate volleys if (LK.ticks % 120 < 20) { shootChance = 2.0; // Synchronized bursts } else { shootChance = 0.3; } } if (self.lastShot >= self.shootDelay * (1 / shootChance) && self.y > 100 && self.y < 2000) { self.lastShot = 0; self.shootDelay = 60 + Math.random() * 120; // Smart targeting for larger aliens if (self.size >= 3) { // Predictive shooting - aim where player will be var bulletSpeed = 20; var timeToReach = Math.abs(self.y - player.y) / bulletSpeed; var predictedPlayerX = player.x; if (dragNode) { // If player is moving, predict movement var playerVelocity = player.x - (player.lastX || player.x) || 0; predictedPlayerX = player.x + playerVelocity * timeToReach; } var bullet = new AlienBullet(); bullet.x = self.x; bullet.y = self.y + 30; // Add slight targeting adjustment var targetOffset = (predictedPlayerX - self.x) * 0.1; bullet.targetOffsetX = Math.max(-2, Math.min(2, targetOffset)); alienBullets.push(bullet); game.addChild(bullet); } else { // Regular shooting for smaller aliens var bullet = new AlienBullet(); bullet.x = self.x; bullet.y = self.y + 30; alienBullets.push(bullet); game.addChild(bullet); } } // Store last position for movement prediction self.lastX = self.x; }; self.takeDamage = function () { self.health--; if (self.health <= 0) { return true; // Destroyed } return false; }; return self; }); var AlienBullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('alienBullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 20; self.targetOffsetX = 0; // For smart targeting self.homingStrength = 0; // For advanced bullets self.update = function () { self.y += self.speed; // Apply horizontal targeting offset for smart bullets if (self.targetOffsetX !== 0) { self.x += self.targetOffsetX; self.targetOffsetX *= 0.95; // Gradually reduce offset } // Light homing behavior for bullets from larger aliens if (self.homingStrength > 0) { var playerDistance = player.x - self.x; var homingForce = Math.sign(playerDistance) * Math.min(Math.abs(playerDistance) * 0.01, 1) * self.homingStrength; self.x += homingForce; self.homingStrength *= 0.98; // Gradually reduce homing } }; return self; }); var Bomb = Container.expand(function () { var self = Container.call(this); var bombGraphics = self.attachAsset('bomb', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 8; self.explosionRadius = 250; // 0.5cm area converted to pixels self.fuseTime = 180; // 3 seconds at 60fps self.currentFuse = 0; self.hasExploded = false; self.update = function () { self.y += self.speed; self.currentFuse++; // Pulsing animation as fuse burns down var pulseScale = 1 + Math.sin(self.currentFuse * 0.3) * 0.2; bombGraphics.scaleX = pulseScale; bombGraphics.scaleY = pulseScale; // Explode after fuse time if (self.currentFuse >= self.fuseTime && !self.hasExploded) { self.explode(); } }; self.explode = function () { self.hasExploded = true; // Flash explosion effect LK.effects.flashScreen(0xffa500, 300); // Destroy all aliens within explosion radius for (var i = aliens.length - 1; i >= 0; i--) { var alien = aliens[i]; var distance = Math.sqrt(Math.pow(alien.x - self.x, 2) + Math.pow(alien.y - self.y, 2)); if (distance <= self.explosionRadius) { LK.setScore(LK.getScore() + alien.size * 5); alien.destroy(); aliens.splice(i, 1); } } // Create explosion visual effect using tween tween(bombGraphics, { scaleX: 5, scaleY: 5, alpha: 0 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { // Remove bomb after explosion animation for (var i = bombs.length - 1; i >= 0; i--) { if (bombs[i] === self) { self.destroy(); bombs.splice(i, 1); break; } } } }); }; return self; }); var MenuButton = Container.expand(function (text, width, height) { var self = Container.call(this); // Create button background self.background = LK.getAsset('button', { width: width || 400, height: height || 100, color: 0x4444ff, shape: 'box', anchorX: 0.5, anchorY: 0.5 }); self.addChild(self.background); // Create button text self.buttonText = new Text2(text || 'Button', { size: 50, fill: 0xffffff }); self.buttonText.anchor.set(0.5, 0.5); self.addChild(self.buttonText); // Button states self.isPressed = false; self.down = function (x, y, obj) { self.isPressed = true; self.background.tint = 0x6666ff; self.scaleX = 0.95; self.scaleY = 0.95; }; self.up = function (x, y, obj) { if (self.isPressed) { self.isPressed = false; self.background.tint = 0xffffff; self.scaleX = 1.0; self.scaleY = 1.0; if (self.onClick) { self.onClick(); } } }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); self.fireRate = 15; self.weaponLevel = 1; self.lastShot = 0; return self; }); var PlayerBullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('playerBullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -18; self.update = function () { self.y += self.speed; }; return self; }); var PowerUp = Container.expand(function () { var self = Container.call(this); var powerupGraphics = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 3; self.bobOffset = Math.random() * Math.PI * 2; self.update = function () { self.y += self.speed; self.x += Math.sin((LK.ticks + self.bobOffset) * 0.1) * 2; powerupGraphics.rotation += 0.05; }; return self; }); var VolumeSlider = Container.expand(function () { var self = Container.call(this); // Slider track self.track = LK.getAsset('sliderTrack', { width: 300, height: 20, color: 0x333333, shape: 'box', anchorX: 0.5, anchorY: 0.5 }); self.addChild(self.track); // Slider handle self.handle = LK.getAsset('sliderHandle', { width: 40, height: 40, color: 0x4444ff, shape: 'ellipse', anchorX: 0.5, anchorY: 0.5 }); self.addChild(self.handle); // Initialize handle position based on stored volume self.value = storage.volume || 1.0; self.handle.x = (self.value - 0.5) * 260; // Map 0-1 to -130 to 130 self.isDragging = false; self.down = function (x, y, obj) { self.isDragging = true; self.updateSlider(x); }; self.move = function (x, y, obj) { if (self.isDragging) { self.updateSlider(x); } }; self.up = function (x, y, obj) { self.isDragging = false; }; self.updateSlider = function (x) { // Convert global x to local slider position var localX = x - self.x; localX = Math.max(-130, Math.min(130, localX)); self.handle.x = localX; self.value = (localX + 130) / 260; // Map -130 to 130 back to 0-1 // Save to storage storage.volume = self.value; // Update actual game volume if applicable if (self.onVolumeChange) { self.onVolumeChange(self.value); } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000033 }); /**** * Game Code ****/ // Game state management var gameState = 'menu'; // 'menu', 'playing', 'settings' var mainMenu; var settingsMenu; var gameVolume = storage.volume || 1.0; var player = game.addChild(new Player()); player.x = 2048 / 2; player.y = 2400; player.lastX = player.x; var playerBullets = []; var aliens = []; var alienBullets = []; var powerups = []; var bombs = []; var waveTimer = 0; var difficultyLevel = 1; var alienSpawnRate = 180; var bombTimer = 0; var bombSpawnRate = 600; // 10 seconds at 60fps // Create Main Menu function createMainMenu() { mainMenu = new Container(); // Title var titleText = new Text2('ALIEN FIGHTER', { size: 120, fill: 0xffffff }); titleText.anchor.set(0.5, 0.5); titleText.x = 2048 / 2; titleText.y = 600; mainMenu.addChild(titleText); // Start Game Button var startButton = new MenuButton('START GAME', 400, 100); startButton.x = 2048 / 2; startButton.y = 1200; startButton.onClick = function () { startGame(); }; mainMenu.addChild(startButton); // Settings Button var settingsButton = new MenuButton('SETTINGS', 400, 100); settingsButton.x = 2048 / 2; settingsButton.y = 1400; settingsButton.onClick = function () { showSettings(); }; mainMenu.addChild(settingsButton); game.addChild(mainMenu); } // Create Settings Menu function createSettingsMenu() { settingsMenu = new Container(); settingsMenu.visible = false; // Settings Title var settingsTitle = new Text2('SETTINGS', { size: 100, fill: 0xffffff }); settingsTitle.anchor.set(0.5, 0.5); settingsTitle.x = 2048 / 2; settingsTitle.y = 600; settingsMenu.addChild(settingsTitle); // Volume Label var volumeLabel = new Text2('VOLUME', { size: 60, fill: 0xffffff }); volumeLabel.anchor.set(0.5, 0.5); volumeLabel.x = 2048 / 2; volumeLabel.y = 1000; settingsMenu.addChild(volumeLabel); // Volume Slider var volumeSlider = new VolumeSlider(); volumeSlider.x = 2048 / 2; volumeSlider.y = 1150; volumeSlider.onVolumeChange = function (volume) { gameVolume = volume; // Update volume display volumeValueText.setText(Math.round(volume * 100) + '%'); }; settingsMenu.addChild(volumeSlider); // Volume Value Display var volumeValueText = new Text2(Math.round(gameVolume * 100) + '%', { size: 50, fill: 0x00ff00 }); volumeValueText.anchor.set(0.5, 0.5); volumeValueText.x = 2048 / 2; volumeValueText.y = 1300; settingsMenu.addChild(volumeValueText); // Back Button var backButton = new MenuButton('BACK', 300, 80); backButton.x = 2048 / 2; backButton.y = 1600; backButton.onClick = function () { showMainMenu(); }; settingsMenu.addChild(backButton); game.addChild(settingsMenu); } function startGame() { gameState = 'playing'; mainMenu.visible = false; settingsMenu.visible = false; // Reset game state resetGameState(); } function showSettings() { gameState = 'settings'; mainMenu.visible = false; settingsMenu.visible = true; } function showMainMenu() { gameState = 'menu'; mainMenu.visible = true; settingsMenu.visible = false; } function resetGameState() { // Clear all game objects for (var i = playerBullets.length - 1; i >= 0; i--) { playerBullets[i].destroy(); } playerBullets = []; for (var i = aliens.length - 1; i >= 0; i--) { aliens[i].destroy(); } aliens = []; for (var i = alienBullets.length - 1; i >= 0; i--) { alienBullets[i].destroy(); } alienBullets = []; for (var i = powerups.length - 1; i >= 0; i--) { powerups[i].destroy(); } powerups = []; for (var i = bombs.length - 1; i >= 0; i--) { bombs[i].destroy(); } bombs = []; // Reset player player.x = 2048 / 2; player.y = 2400; player.weaponLevel = 1; player.fireRate = 15; player.lastShot = 0; // Reset game variables playerHealth = 3; // Reset health hearts display for (var h = 0; h < healthHearts.length; h++) { healthHearts[h].visible = h < playerHealth; } waveTimer = 0; difficultyLevel = 1; alienSpawnRate = 180; bombTimer = 0; invulnerabilityTime = 0; LK.setScore(0); } // Initialize menus createMainMenu(); createSettingsMenu(); // Health system var playerHealth = 3; var maxHealth = 3; var invulnerabilityTime = 0; var invulnerabilityDuration = 120; // 2 seconds at 60fps // UI Elements var scoreTxt = new Text2('0', { size: 80, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); scoreTxt.y = 100; var weaponTxt = new Text2('Weapon Level: 1', { size: 50, fill: 0x00FF00 }); weaponTxt.anchor.set(0, 0); LK.gui.topRight.addChild(weaponTxt); weaponTxt.x = -350; weaponTxt.y = 50; // Health hearts display var healthHearts = []; for (var h = 0; h < maxHealth; h++) { var heart = LK.getAsset('heart', { anchorX: 0.5, anchorY: 0.5 }); heart.x = 150 + h * 60; heart.y = 80; healthHearts.push(heart); LK.gui.topLeft.addChild(heart); } // Player controls var playerControls = { moveLeft: false, moveRight: false, moveUp: false, moveDown: false, speed: 8 }; var controlZones = { left: { x: 0, y: 0, width: 512, height: 2732 }, right: { x: 1536, y: 0, width: 512, height: 2732 }, up: { x: 512, y: 0, width: 1024, height: 1366 }, down: { x: 512, y: 1366, width: 1024, height: 1366 } }; function isInZone(x, y, zone) { return x >= zone.x && x <= zone.x + zone.width && y >= zone.y && y <= zone.y + zone.height; } function handleMove(x, y, obj) { // Reset all controls playerControls.moveLeft = false; playerControls.moveRight = false; playerControls.moveUp = false; playerControls.moveDown = false; // Check which control zone is being touched if (isInZone(x, y, controlZones.left)) { playerControls.moveLeft = true; } if (isInZone(x, y, controlZones.right)) { playerControls.moveRight = true; } if (isInZone(x, y, controlZones.up)) { playerControls.moveUp = true; } if (isInZone(x, y, controlZones.down)) { playerControls.moveDown = true; } } game.move = handleMove; game.down = function (x, y, obj) { handleMove(x, y, obj); }; game.up = function (x, y, obj) { // Reset all controls when touch is released playerControls.moveLeft = false; playerControls.moveRight = false; playerControls.moveUp = false; playerControls.moveDown = false; }; // Spawn alien function function spawnAlien() { var size = 1; var rand = Math.random(); if (difficultyLevel >= 3 && rand < 0.1) size = 5;else if (difficultyLevel >= 2 && rand < 0.2) size = 4;else if (difficultyLevel >= 2 && rand < 0.35) size = 3;else if (rand < 0.5) size = 2; var alien = new Alien(size); alien.x = Math.random() * 1800 + 124; alien.y = -100; alien.baseX = alien.x; // Set initial base position for AI // Set AI type based on difficulty and alien size if (difficultyLevel >= 4) { // Higher difficulty: more aggressive and formation AI if (size >= 4) { alien.aiType = Math.random() < 0.4 ? 0 : 3; // Aggressive or Formation } else { alien.aiType = Math.floor(Math.random() * 4); // All types available } } else if (difficultyLevel >= 2) { // Medium difficulty: introduce evasive and patrol alien.aiType = Math.floor(Math.random() * 3); // No formation yet } else { // Low difficulty: mostly aggressive and patrol alien.aiType = Math.random() < 0.7 ? 0 : 2; // Aggressive or Patrol } // Larger aliens get enhanced capabilities if (size >= 3) { alien.aggressionLevel = Math.min(1.0, alien.aggressionLevel + 0.3); } aliens.push(alien); game.addChild(alien); } // Player shooting function playerShoot() { if (LK.ticks - player.lastShot >= player.fireRate) { player.lastShot = LK.ticks; // Gun positions on left and right sides of fighter plane var leftGunX = player.x - 80; var rightGunX = player.x + 80; var gunY = player.y - 60; if (player.weaponLevel === 1) { // Basic dual gun setup - left and right guns fire simultaneously var bullet1 = new PlayerBullet(); bullet1.x = leftGunX; bullet1.y = gunY; playerBullets.push(bullet1); game.addChild(bullet1); var bullet2 = new PlayerBullet(); bullet2.x = rightGunX; bullet2.y = gunY; playerBullets.push(bullet2); game.addChild(bullet2); } else if (player.weaponLevel === 2) { // Enhanced dual shot - two bullets from each gun var bullet1 = new PlayerBullet(); bullet1.x = leftGunX - 10; bullet1.y = gunY; playerBullets.push(bullet1); game.addChild(bullet1); var bullet2 = new PlayerBullet(); bullet2.x = leftGunX + 10; bullet2.y = gunY; playerBullets.push(bullet2); game.addChild(bullet2); var bullet3 = new PlayerBullet(); bullet3.x = rightGunX - 10; bullet3.y = gunY; playerBullets.push(bullet3); game.addChild(bullet3); var bullet4 = new PlayerBullet(); bullet4.x = rightGunX + 10; bullet4.y = gunY; playerBullets.push(bullet4); game.addChild(bullet4); } else if (player.weaponLevel >= 3) { // Triple shot from each gun plus center var bullet1 = new PlayerBullet(); bullet1.x = leftGunX - 15; bullet1.y = gunY; playerBullets.push(bullet1); game.addChild(bullet1); var bullet2 = new PlayerBullet(); bullet2.x = leftGunX; bullet2.y = gunY; playerBullets.push(bullet2); game.addChild(bullet2); var bullet3 = new PlayerBullet(); bullet3.x = leftGunX + 15; bullet3.y = gunY; playerBullets.push(bullet3); game.addChild(bullet3); var bullet4 = new PlayerBullet(); bullet4.x = rightGunX - 15; bullet4.y = gunY; playerBullets.push(bullet4); game.addChild(bullet4); var bullet5 = new PlayerBullet(); bullet5.x = rightGunX; bullet5.y = gunY; playerBullets.push(bullet5); game.addChild(bullet5); var bullet6 = new PlayerBullet(); bullet6.x = rightGunX + 15; bullet6.y = gunY; playerBullets.push(bullet6); game.addChild(bullet6); } var shootSound = LK.getSound('shoot'); shootSound.volume = gameVolume; shootSound.play(); } } game.update = function () { // Only update game logic when playing if (gameState !== 'playing') { return; } scoreTxt.setText(LK.getScore()); weaponTxt.setText('Weapon Level: ' + player.weaponLevel); // Update heart visibility based on current health for (var h = 0; h < healthHearts.length; h++) { healthHearts[h].visible = h < playerHealth; } // Handle invulnerability timer if (invulnerabilityTime > 0) { invulnerabilityTime--; // Make player flash during invulnerability if (Math.floor(invulnerabilityTime / 10) % 2 === 0) { player.alpha = 0.5; } else { player.alpha = 1.0; } } else { player.alpha = 1.0; } // Handle player movement based on controls player.lastX = player.x; if (playerControls.moveLeft) { player.x -= playerControls.speed; } if (playerControls.moveRight) { player.x += playerControls.speed; } if (playerControls.moveUp) { player.y -= playerControls.speed; } if (playerControls.moveDown) { player.y += playerControls.speed; } // Keep player within bounds player.x = Math.max(50, Math.min(1998, player.x)); player.y = Math.max(100, Math.min(2600, player.y)); // Player auto-shooting playerShoot(); // Wave management waveTimer++; if (waveTimer >= alienSpawnRate) { waveTimer = 0; spawnAlien(); // Increase difficulty over time if (LK.getScore() > difficultyLevel * 100) { difficultyLevel++; alienSpawnRate = Math.max(60, alienSpawnRate - 10); } } // Bomb spawning every 10 seconds bombTimer++; if (bombTimer >= bombSpawnRate) { bombTimer = 0; var bomb = new Bomb(); bomb.x = Math.random() * 1800 + 124; bomb.y = -100; bombs.push(bomb); game.addChild(bomb); } // Update and cleanup bombs for (var i = bombs.length - 1; i >= 0; i--) { var bomb = bombs[i]; if (bomb.y > 2800 && !bomb.hasExploded) { bomb.destroy(); bombs.splice(i, 1); continue; } } // Update and cleanup player bullets for (var i = playerBullets.length - 1; i >= 0; i--) { var bullet = playerBullets[i]; if (bullet.y < -50) { bullet.destroy(); playerBullets.splice(i, 1); continue; } // Check collision with aliens for (var j = aliens.length - 1; j >= 0; j--) { var alien = aliens[j]; if (bullet.intersects(alien)) { if (alien.takeDamage()) { // Alien destroyed LK.setScore(LK.getScore() + alien.size * 5); // Drop powerup from size 5 aliens if (alien.size === 5 && Math.random() < 0.7) { var powerup = new PowerUp(); powerup.x = alien.x; powerup.y = alien.y; powerups.push(powerup); game.addChild(powerup); } var enemyHitSound = LK.getSound('enemyHit'); enemyHitSound.volume = gameVolume; enemyHitSound.play(); alien.destroy(); aliens.splice(j, 1); } bullet.destroy(); playerBullets.splice(i, 1); break; } } } // Update and cleanup aliens for (var i = aliens.length - 1; i >= 0; i--) { var alien = aliens[i]; if (alien.y > 2800) { alien.destroy(); aliens.splice(i, 1); continue; } // Check collision with player if (alien.intersects(player) && invulnerabilityTime <= 0) { playerHealth--; invulnerabilityTime = invulnerabilityDuration; LK.effects.flashScreen(0xff0000, 500); LK.effects.flashObject(player, 0xff0000, 500); if (playerHealth <= 0) { LK.showGameOver(); // Return to main menu after game over LK.setTimeout(function () { showMainMenu(); }, 3000); return; } } } // Update and cleanup alien bullets for (var i = alienBullets.length - 1; i >= 0; i--) { var bullet = alienBullets[i]; if (bullet.y > 2800) { bullet.destroy(); alienBullets.splice(i, 1); continue; } // Check collision with player if (bullet.intersects(player) && invulnerabilityTime <= 0) { playerHealth--; invulnerabilityTime = invulnerabilityDuration; LK.effects.flashScreen(0xff0000, 500); LK.effects.flashObject(player, 0xff0000, 500); bullet.destroy(); alienBullets.splice(i, 1); if (playerHealth <= 0) { LK.showGameOver(); // Return to main menu after game over LK.setTimeout(function () { showMainMenu(); }, 3000); return; } } } // Update and cleanup powerups for (var i = powerups.length - 1; i >= 0; i--) { var powerup = powerups[i]; if (powerup.y > 2800) { powerup.destroy(); powerups.splice(i, 1); continue; } // Check collision with player if (powerup.intersects(player)) { player.weaponLevel = Math.min(3, player.weaponLevel + 1); player.fireRate = Math.max(8, player.fireRate - 3); var powerupSound = LK.getSound('powerupCollect'); powerupSound.volume = gameVolume; powerupSound.play(); LK.effects.flashObject(player, 0x00ffff, 500); powerup.destroy(); powerups.splice(i, 1); } } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
volume: 1
});
/****
* Classes
****/
var Alien = Container.expand(function (size) {
var self = Container.call(this);
self.size = size || 1;
self.health = size;
self.maxHealth = size;
var assetName = 'alien' + size;
var alienGraphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = Math.random() * 3 + 2;
self.lastShot = 0;
self.shootDelay = 60 + Math.random() * 120;
// AI behavior properties
self.aiType = Math.floor(Math.random() * 4); // 0: aggressive, 1: evasive, 2: patrol, 3: formation
self.baseX = self.x;
self.patrolDirection = Math.random() < 0.5 ? -1 : 1;
self.evasionTimer = 0;
self.formationOffset = Math.random() * Math.PI * 2;
self.aggressionLevel = Math.random() * 0.5 + 0.5; // 0.5 to 1.0
self.update = function () {
self.y += self.speed;
// AI Movement Behaviors
if (self.aiType === 0) {
// Aggressive: Move directly toward player with increasing speed
var playerDistance = player.x - self.x;
var horizontalSpeed = Math.min(Math.abs(playerDistance) * 0.02 * self.aggressionLevel, 2.5);
if (playerDistance > 0) {
self.x += horizontalSpeed;
} else if (playerDistance < 0) {
self.x -= horizontalSpeed;
}
// Increase speed when close to player
if (Math.abs(playerDistance) < 200) {
self.speed += 0.1;
}
} else if (self.aiType === 1) {
// Evasive: Move away from player bullets and use unpredictable movement
self.evasionTimer++;
var nearbyBullet = false;
for (var b = 0; b < playerBullets.length; b++) {
var bullet = playerBullets[b];
var bulletDistance = Math.sqrt(Math.pow(bullet.x - self.x, 2) + Math.pow(bullet.y - self.y, 2));
if (bulletDistance < 150) {
nearbyBullet = true;
// Evade away from bullet
if (bullet.x < self.x) {
self.x += 3;
} else {
self.x -= 3;
}
break;
}
}
// Random evasive movement when no immediate threat
if (!nearbyBullet && self.evasionTimer % 60 === 0) {
self.x += (Math.random() - 0.5) * 100;
}
} else if (self.aiType === 2) {
// Patrol: Move in horizontal patterns while slowly tracking player
var patrolSpeed = 1.5;
self.x += self.patrolDirection * patrolSpeed;
if (self.x < 200 || self.x > 1848) {
self.patrolDirection *= -1;
}
// Slight player tracking
var playerDistance = player.x - self.x;
var trackingSpeed = Math.min(Math.abs(playerDistance) * 0.005, 0.5);
if (playerDistance > 0) {
self.x += trackingSpeed;
} else if (playerDistance < 0) {
self.x -= trackingSpeed;
}
} else if (self.aiType === 3) {
// Formation: Move in coordinated patterns with other aliens
var formationSpeed = Math.sin((LK.ticks + self.formationOffset) * 0.05) * 2;
self.x += formationSpeed;
// Maintain formation spacing
for (var a = 0; a < aliens.length; a++) {
var otherAlien = aliens[a];
if (otherAlien !== self && otherAlien.aiType === 3) {
var distance = Math.abs(otherAlien.x - self.x);
if (distance < 120 && distance > 0) {
if (otherAlien.x > self.x) {
self.x -= 1;
} else {
self.x += 1;
}
}
}
}
}
// Keep aliens within screen bounds
self.x = Math.max(50, Math.min(1998, self.x));
// AI Shooting Behavior
self.lastShot++;
var shootChance = 1.0;
var playerDistance = Math.sqrt(Math.pow(player.x - self.x, 2) + Math.pow(player.y - self.y, 2));
// Adjust shooting based on AI type and player proximity
if (self.aiType === 0) {
// Aggressive aliens shoot more frequently when close to player
if (playerDistance < 300) {
shootChance = 1.5;
self.shootDelay = 40 + Math.random() * 60;
}
} else if (self.aiType === 1) {
// Evasive aliens shoot less frequently but more accurately
shootChance = 0.7;
self.shootDelay = 80 + Math.random() * 100;
} else if (self.aiType === 2) {
// Patrol aliens have steady firing rate
shootChance = 0.9;
} else if (self.aiType === 3) {
// Formation aliens coordinate volleys
if (LK.ticks % 120 < 20) {
shootChance = 2.0; // Synchronized bursts
} else {
shootChance = 0.3;
}
}
if (self.lastShot >= self.shootDelay * (1 / shootChance) && self.y > 100 && self.y < 2000) {
self.lastShot = 0;
self.shootDelay = 60 + Math.random() * 120;
// Smart targeting for larger aliens
if (self.size >= 3) {
// Predictive shooting - aim where player will be
var bulletSpeed = 20;
var timeToReach = Math.abs(self.y - player.y) / bulletSpeed;
var predictedPlayerX = player.x;
if (dragNode) {
// If player is moving, predict movement
var playerVelocity = player.x - (player.lastX || player.x) || 0;
predictedPlayerX = player.x + playerVelocity * timeToReach;
}
var bullet = new AlienBullet();
bullet.x = self.x;
bullet.y = self.y + 30;
// Add slight targeting adjustment
var targetOffset = (predictedPlayerX - self.x) * 0.1;
bullet.targetOffsetX = Math.max(-2, Math.min(2, targetOffset));
alienBullets.push(bullet);
game.addChild(bullet);
} else {
// Regular shooting for smaller aliens
var bullet = new AlienBullet();
bullet.x = self.x;
bullet.y = self.y + 30;
alienBullets.push(bullet);
game.addChild(bullet);
}
}
// Store last position for movement prediction
self.lastX = self.x;
};
self.takeDamage = function () {
self.health--;
if (self.health <= 0) {
return true; // Destroyed
}
return false;
};
return self;
});
var AlienBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('alienBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 20;
self.targetOffsetX = 0; // For smart targeting
self.homingStrength = 0; // For advanced bullets
self.update = function () {
self.y += self.speed;
// Apply horizontal targeting offset for smart bullets
if (self.targetOffsetX !== 0) {
self.x += self.targetOffsetX;
self.targetOffsetX *= 0.95; // Gradually reduce offset
}
// Light homing behavior for bullets from larger aliens
if (self.homingStrength > 0) {
var playerDistance = player.x - self.x;
var homingForce = Math.sign(playerDistance) * Math.min(Math.abs(playerDistance) * 0.01, 1) * self.homingStrength;
self.x += homingForce;
self.homingStrength *= 0.98; // Gradually reduce homing
}
};
return self;
});
var Bomb = Container.expand(function () {
var self = Container.call(this);
var bombGraphics = self.attachAsset('bomb', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.explosionRadius = 250; // 0.5cm area converted to pixels
self.fuseTime = 180; // 3 seconds at 60fps
self.currentFuse = 0;
self.hasExploded = false;
self.update = function () {
self.y += self.speed;
self.currentFuse++;
// Pulsing animation as fuse burns down
var pulseScale = 1 + Math.sin(self.currentFuse * 0.3) * 0.2;
bombGraphics.scaleX = pulseScale;
bombGraphics.scaleY = pulseScale;
// Explode after fuse time
if (self.currentFuse >= self.fuseTime && !self.hasExploded) {
self.explode();
}
};
self.explode = function () {
self.hasExploded = true;
// Flash explosion effect
LK.effects.flashScreen(0xffa500, 300);
// Destroy all aliens within explosion radius
for (var i = aliens.length - 1; i >= 0; i--) {
var alien = aliens[i];
var distance = Math.sqrt(Math.pow(alien.x - self.x, 2) + Math.pow(alien.y - self.y, 2));
if (distance <= self.explosionRadius) {
LK.setScore(LK.getScore() + alien.size * 5);
alien.destroy();
aliens.splice(i, 1);
}
}
// Create explosion visual effect using tween
tween(bombGraphics, {
scaleX: 5,
scaleY: 5,
alpha: 0
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
// Remove bomb after explosion animation
for (var i = bombs.length - 1; i >= 0; i--) {
if (bombs[i] === self) {
self.destroy();
bombs.splice(i, 1);
break;
}
}
}
});
};
return self;
});
var MenuButton = Container.expand(function (text, width, height) {
var self = Container.call(this);
// Create button background
self.background = LK.getAsset('button', {
width: width || 400,
height: height || 100,
color: 0x4444ff,
shape: 'box',
anchorX: 0.5,
anchorY: 0.5
});
self.addChild(self.background);
// Create button text
self.buttonText = new Text2(text || 'Button', {
size: 50,
fill: 0xffffff
});
self.buttonText.anchor.set(0.5, 0.5);
self.addChild(self.buttonText);
// Button states
self.isPressed = false;
self.down = function (x, y, obj) {
self.isPressed = true;
self.background.tint = 0x6666ff;
self.scaleX = 0.95;
self.scaleY = 0.95;
};
self.up = function (x, y, obj) {
if (self.isPressed) {
self.isPressed = false;
self.background.tint = 0xffffff;
self.scaleX = 1.0;
self.scaleY = 1.0;
if (self.onClick) {
self.onClick();
}
}
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.fireRate = 15;
self.weaponLevel = 1;
self.lastShot = 0;
return self;
});
var PlayerBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('playerBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -18;
self.update = function () {
self.y += self.speed;
};
return self;
});
var PowerUp = Container.expand(function () {
var self = Container.call(this);
var powerupGraphics = self.attachAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 3;
self.bobOffset = Math.random() * Math.PI * 2;
self.update = function () {
self.y += self.speed;
self.x += Math.sin((LK.ticks + self.bobOffset) * 0.1) * 2;
powerupGraphics.rotation += 0.05;
};
return self;
});
var VolumeSlider = Container.expand(function () {
var self = Container.call(this);
// Slider track
self.track = LK.getAsset('sliderTrack', {
width: 300,
height: 20,
color: 0x333333,
shape: 'box',
anchorX: 0.5,
anchorY: 0.5
});
self.addChild(self.track);
// Slider handle
self.handle = LK.getAsset('sliderHandle', {
width: 40,
height: 40,
color: 0x4444ff,
shape: 'ellipse',
anchorX: 0.5,
anchorY: 0.5
});
self.addChild(self.handle);
// Initialize handle position based on stored volume
self.value = storage.volume || 1.0;
self.handle.x = (self.value - 0.5) * 260; // Map 0-1 to -130 to 130
self.isDragging = false;
self.down = function (x, y, obj) {
self.isDragging = true;
self.updateSlider(x);
};
self.move = function (x, y, obj) {
if (self.isDragging) {
self.updateSlider(x);
}
};
self.up = function (x, y, obj) {
self.isDragging = false;
};
self.updateSlider = function (x) {
// Convert global x to local slider position
var localX = x - self.x;
localX = Math.max(-130, Math.min(130, localX));
self.handle.x = localX;
self.value = (localX + 130) / 260; // Map -130 to 130 back to 0-1
// Save to storage
storage.volume = self.value;
// Update actual game volume if applicable
if (self.onVolumeChange) {
self.onVolumeChange(self.value);
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000033
});
/****
* Game Code
****/
// Game state management
var gameState = 'menu'; // 'menu', 'playing', 'settings'
var mainMenu;
var settingsMenu;
var gameVolume = storage.volume || 1.0;
var player = game.addChild(new Player());
player.x = 2048 / 2;
player.y = 2400;
player.lastX = player.x;
var playerBullets = [];
var aliens = [];
var alienBullets = [];
var powerups = [];
var bombs = [];
var waveTimer = 0;
var difficultyLevel = 1;
var alienSpawnRate = 180;
var bombTimer = 0;
var bombSpawnRate = 600; // 10 seconds at 60fps
// Create Main Menu
function createMainMenu() {
mainMenu = new Container();
// Title
var titleText = new Text2('ALIEN FIGHTER', {
size: 120,
fill: 0xffffff
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 2048 / 2;
titleText.y = 600;
mainMenu.addChild(titleText);
// Start Game Button
var startButton = new MenuButton('START GAME', 400, 100);
startButton.x = 2048 / 2;
startButton.y = 1200;
startButton.onClick = function () {
startGame();
};
mainMenu.addChild(startButton);
// Settings Button
var settingsButton = new MenuButton('SETTINGS', 400, 100);
settingsButton.x = 2048 / 2;
settingsButton.y = 1400;
settingsButton.onClick = function () {
showSettings();
};
mainMenu.addChild(settingsButton);
game.addChild(mainMenu);
}
// Create Settings Menu
function createSettingsMenu() {
settingsMenu = new Container();
settingsMenu.visible = false;
// Settings Title
var settingsTitle = new Text2('SETTINGS', {
size: 100,
fill: 0xffffff
});
settingsTitle.anchor.set(0.5, 0.5);
settingsTitle.x = 2048 / 2;
settingsTitle.y = 600;
settingsMenu.addChild(settingsTitle);
// Volume Label
var volumeLabel = new Text2('VOLUME', {
size: 60,
fill: 0xffffff
});
volumeLabel.anchor.set(0.5, 0.5);
volumeLabel.x = 2048 / 2;
volumeLabel.y = 1000;
settingsMenu.addChild(volumeLabel);
// Volume Slider
var volumeSlider = new VolumeSlider();
volumeSlider.x = 2048 / 2;
volumeSlider.y = 1150;
volumeSlider.onVolumeChange = function (volume) {
gameVolume = volume;
// Update volume display
volumeValueText.setText(Math.round(volume * 100) + '%');
};
settingsMenu.addChild(volumeSlider);
// Volume Value Display
var volumeValueText = new Text2(Math.round(gameVolume * 100) + '%', {
size: 50,
fill: 0x00ff00
});
volumeValueText.anchor.set(0.5, 0.5);
volumeValueText.x = 2048 / 2;
volumeValueText.y = 1300;
settingsMenu.addChild(volumeValueText);
// Back Button
var backButton = new MenuButton('BACK', 300, 80);
backButton.x = 2048 / 2;
backButton.y = 1600;
backButton.onClick = function () {
showMainMenu();
};
settingsMenu.addChild(backButton);
game.addChild(settingsMenu);
}
function startGame() {
gameState = 'playing';
mainMenu.visible = false;
settingsMenu.visible = false;
// Reset game state
resetGameState();
}
function showSettings() {
gameState = 'settings';
mainMenu.visible = false;
settingsMenu.visible = true;
}
function showMainMenu() {
gameState = 'menu';
mainMenu.visible = true;
settingsMenu.visible = false;
}
function resetGameState() {
// Clear all game objects
for (var i = playerBullets.length - 1; i >= 0; i--) {
playerBullets[i].destroy();
}
playerBullets = [];
for (var i = aliens.length - 1; i >= 0; i--) {
aliens[i].destroy();
}
aliens = [];
for (var i = alienBullets.length - 1; i >= 0; i--) {
alienBullets[i].destroy();
}
alienBullets = [];
for (var i = powerups.length - 1; i >= 0; i--) {
powerups[i].destroy();
}
powerups = [];
for (var i = bombs.length - 1; i >= 0; i--) {
bombs[i].destroy();
}
bombs = [];
// Reset player
player.x = 2048 / 2;
player.y = 2400;
player.weaponLevel = 1;
player.fireRate = 15;
player.lastShot = 0;
// Reset game variables
playerHealth = 3;
// Reset health hearts display
for (var h = 0; h < healthHearts.length; h++) {
healthHearts[h].visible = h < playerHealth;
}
waveTimer = 0;
difficultyLevel = 1;
alienSpawnRate = 180;
bombTimer = 0;
invulnerabilityTime = 0;
LK.setScore(0);
}
// Initialize menus
createMainMenu();
createSettingsMenu();
// Health system
var playerHealth = 3;
var maxHealth = 3;
var invulnerabilityTime = 0;
var invulnerabilityDuration = 120; // 2 seconds at 60fps
// UI Elements
var scoreTxt = new Text2('0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
scoreTxt.y = 100;
var weaponTxt = new Text2('Weapon Level: 1', {
size: 50,
fill: 0x00FF00
});
weaponTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(weaponTxt);
weaponTxt.x = -350;
weaponTxt.y = 50;
// Health hearts display
var healthHearts = [];
for (var h = 0; h < maxHealth; h++) {
var heart = LK.getAsset('heart', {
anchorX: 0.5,
anchorY: 0.5
});
heart.x = 150 + h * 60;
heart.y = 80;
healthHearts.push(heart);
LK.gui.topLeft.addChild(heart);
}
// Player controls
var playerControls = {
moveLeft: false,
moveRight: false,
moveUp: false,
moveDown: false,
speed: 8
};
var controlZones = {
left: {
x: 0,
y: 0,
width: 512,
height: 2732
},
right: {
x: 1536,
y: 0,
width: 512,
height: 2732
},
up: {
x: 512,
y: 0,
width: 1024,
height: 1366
},
down: {
x: 512,
y: 1366,
width: 1024,
height: 1366
}
};
function isInZone(x, y, zone) {
return x >= zone.x && x <= zone.x + zone.width && y >= zone.y && y <= zone.y + zone.height;
}
function handleMove(x, y, obj) {
// Reset all controls
playerControls.moveLeft = false;
playerControls.moveRight = false;
playerControls.moveUp = false;
playerControls.moveDown = false;
// Check which control zone is being touched
if (isInZone(x, y, controlZones.left)) {
playerControls.moveLeft = true;
}
if (isInZone(x, y, controlZones.right)) {
playerControls.moveRight = true;
}
if (isInZone(x, y, controlZones.up)) {
playerControls.moveUp = true;
}
if (isInZone(x, y, controlZones.down)) {
playerControls.moveDown = true;
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
handleMove(x, y, obj);
};
game.up = function (x, y, obj) {
// Reset all controls when touch is released
playerControls.moveLeft = false;
playerControls.moveRight = false;
playerControls.moveUp = false;
playerControls.moveDown = false;
};
// Spawn alien function
function spawnAlien() {
var size = 1;
var rand = Math.random();
if (difficultyLevel >= 3 && rand < 0.1) size = 5;else if (difficultyLevel >= 2 && rand < 0.2) size = 4;else if (difficultyLevel >= 2 && rand < 0.35) size = 3;else if (rand < 0.5) size = 2;
var alien = new Alien(size);
alien.x = Math.random() * 1800 + 124;
alien.y = -100;
alien.baseX = alien.x; // Set initial base position for AI
// Set AI type based on difficulty and alien size
if (difficultyLevel >= 4) {
// Higher difficulty: more aggressive and formation AI
if (size >= 4) {
alien.aiType = Math.random() < 0.4 ? 0 : 3; // Aggressive or Formation
} else {
alien.aiType = Math.floor(Math.random() * 4); // All types available
}
} else if (difficultyLevel >= 2) {
// Medium difficulty: introduce evasive and patrol
alien.aiType = Math.floor(Math.random() * 3); // No formation yet
} else {
// Low difficulty: mostly aggressive and patrol
alien.aiType = Math.random() < 0.7 ? 0 : 2; // Aggressive or Patrol
}
// Larger aliens get enhanced capabilities
if (size >= 3) {
alien.aggressionLevel = Math.min(1.0, alien.aggressionLevel + 0.3);
}
aliens.push(alien);
game.addChild(alien);
}
// Player shooting
function playerShoot() {
if (LK.ticks - player.lastShot >= player.fireRate) {
player.lastShot = LK.ticks;
// Gun positions on left and right sides of fighter plane
var leftGunX = player.x - 80;
var rightGunX = player.x + 80;
var gunY = player.y - 60;
if (player.weaponLevel === 1) {
// Basic dual gun setup - left and right guns fire simultaneously
var bullet1 = new PlayerBullet();
bullet1.x = leftGunX;
bullet1.y = gunY;
playerBullets.push(bullet1);
game.addChild(bullet1);
var bullet2 = new PlayerBullet();
bullet2.x = rightGunX;
bullet2.y = gunY;
playerBullets.push(bullet2);
game.addChild(bullet2);
} else if (player.weaponLevel === 2) {
// Enhanced dual shot - two bullets from each gun
var bullet1 = new PlayerBullet();
bullet1.x = leftGunX - 10;
bullet1.y = gunY;
playerBullets.push(bullet1);
game.addChild(bullet1);
var bullet2 = new PlayerBullet();
bullet2.x = leftGunX + 10;
bullet2.y = gunY;
playerBullets.push(bullet2);
game.addChild(bullet2);
var bullet3 = new PlayerBullet();
bullet3.x = rightGunX - 10;
bullet3.y = gunY;
playerBullets.push(bullet3);
game.addChild(bullet3);
var bullet4 = new PlayerBullet();
bullet4.x = rightGunX + 10;
bullet4.y = gunY;
playerBullets.push(bullet4);
game.addChild(bullet4);
} else if (player.weaponLevel >= 3) {
// Triple shot from each gun plus center
var bullet1 = new PlayerBullet();
bullet1.x = leftGunX - 15;
bullet1.y = gunY;
playerBullets.push(bullet1);
game.addChild(bullet1);
var bullet2 = new PlayerBullet();
bullet2.x = leftGunX;
bullet2.y = gunY;
playerBullets.push(bullet2);
game.addChild(bullet2);
var bullet3 = new PlayerBullet();
bullet3.x = leftGunX + 15;
bullet3.y = gunY;
playerBullets.push(bullet3);
game.addChild(bullet3);
var bullet4 = new PlayerBullet();
bullet4.x = rightGunX - 15;
bullet4.y = gunY;
playerBullets.push(bullet4);
game.addChild(bullet4);
var bullet5 = new PlayerBullet();
bullet5.x = rightGunX;
bullet5.y = gunY;
playerBullets.push(bullet5);
game.addChild(bullet5);
var bullet6 = new PlayerBullet();
bullet6.x = rightGunX + 15;
bullet6.y = gunY;
playerBullets.push(bullet6);
game.addChild(bullet6);
}
var shootSound = LK.getSound('shoot');
shootSound.volume = gameVolume;
shootSound.play();
}
}
game.update = function () {
// Only update game logic when playing
if (gameState !== 'playing') {
return;
}
scoreTxt.setText(LK.getScore());
weaponTxt.setText('Weapon Level: ' + player.weaponLevel);
// Update heart visibility based on current health
for (var h = 0; h < healthHearts.length; h++) {
healthHearts[h].visible = h < playerHealth;
}
// Handle invulnerability timer
if (invulnerabilityTime > 0) {
invulnerabilityTime--;
// Make player flash during invulnerability
if (Math.floor(invulnerabilityTime / 10) % 2 === 0) {
player.alpha = 0.5;
} else {
player.alpha = 1.0;
}
} else {
player.alpha = 1.0;
}
// Handle player movement based on controls
player.lastX = player.x;
if (playerControls.moveLeft) {
player.x -= playerControls.speed;
}
if (playerControls.moveRight) {
player.x += playerControls.speed;
}
if (playerControls.moveUp) {
player.y -= playerControls.speed;
}
if (playerControls.moveDown) {
player.y += playerControls.speed;
}
// Keep player within bounds
player.x = Math.max(50, Math.min(1998, player.x));
player.y = Math.max(100, Math.min(2600, player.y));
// Player auto-shooting
playerShoot();
// Wave management
waveTimer++;
if (waveTimer >= alienSpawnRate) {
waveTimer = 0;
spawnAlien();
// Increase difficulty over time
if (LK.getScore() > difficultyLevel * 100) {
difficultyLevel++;
alienSpawnRate = Math.max(60, alienSpawnRate - 10);
}
}
// Bomb spawning every 10 seconds
bombTimer++;
if (bombTimer >= bombSpawnRate) {
bombTimer = 0;
var bomb = new Bomb();
bomb.x = Math.random() * 1800 + 124;
bomb.y = -100;
bombs.push(bomb);
game.addChild(bomb);
}
// Update and cleanup bombs
for (var i = bombs.length - 1; i >= 0; i--) {
var bomb = bombs[i];
if (bomb.y > 2800 && !bomb.hasExploded) {
bomb.destroy();
bombs.splice(i, 1);
continue;
}
}
// Update and cleanup player bullets
for (var i = playerBullets.length - 1; i >= 0; i--) {
var bullet = playerBullets[i];
if (bullet.y < -50) {
bullet.destroy();
playerBullets.splice(i, 1);
continue;
}
// Check collision with aliens
for (var j = aliens.length - 1; j >= 0; j--) {
var alien = aliens[j];
if (bullet.intersects(alien)) {
if (alien.takeDamage()) {
// Alien destroyed
LK.setScore(LK.getScore() + alien.size * 5);
// Drop powerup from size 5 aliens
if (alien.size === 5 && Math.random() < 0.7) {
var powerup = new PowerUp();
powerup.x = alien.x;
powerup.y = alien.y;
powerups.push(powerup);
game.addChild(powerup);
}
var enemyHitSound = LK.getSound('enemyHit');
enemyHitSound.volume = gameVolume;
enemyHitSound.play();
alien.destroy();
aliens.splice(j, 1);
}
bullet.destroy();
playerBullets.splice(i, 1);
break;
}
}
}
// Update and cleanup aliens
for (var i = aliens.length - 1; i >= 0; i--) {
var alien = aliens[i];
if (alien.y > 2800) {
alien.destroy();
aliens.splice(i, 1);
continue;
}
// Check collision with player
if (alien.intersects(player) && invulnerabilityTime <= 0) {
playerHealth--;
invulnerabilityTime = invulnerabilityDuration;
LK.effects.flashScreen(0xff0000, 500);
LK.effects.flashObject(player, 0xff0000, 500);
if (playerHealth <= 0) {
LK.showGameOver();
// Return to main menu after game over
LK.setTimeout(function () {
showMainMenu();
}, 3000);
return;
}
}
}
// Update and cleanup alien bullets
for (var i = alienBullets.length - 1; i >= 0; i--) {
var bullet = alienBullets[i];
if (bullet.y > 2800) {
bullet.destroy();
alienBullets.splice(i, 1);
continue;
}
// Check collision with player
if (bullet.intersects(player) && invulnerabilityTime <= 0) {
playerHealth--;
invulnerabilityTime = invulnerabilityDuration;
LK.effects.flashScreen(0xff0000, 500);
LK.effects.flashObject(player, 0xff0000, 500);
bullet.destroy();
alienBullets.splice(i, 1);
if (playerHealth <= 0) {
LK.showGameOver();
// Return to main menu after game over
LK.setTimeout(function () {
showMainMenu();
}, 3000);
return;
}
}
}
// Update and cleanup powerups
for (var i = powerups.length - 1; i >= 0; i--) {
var powerup = powerups[i];
if (powerup.y > 2800) {
powerup.destroy();
powerups.splice(i, 1);
continue;
}
// Check collision with player
if (powerup.intersects(player)) {
player.weaponLevel = Math.min(3, player.weaponLevel + 1);
player.fireRate = Math.max(8, player.fireRate - 3);
var powerupSound = LK.getSound('powerupCollect');
powerupSound.volume = gameVolume;
powerupSound.play();
LK.effects.flashObject(player, 0x00ffff, 500);
powerup.destroy();
powerups.splice(i, 1);
}
}
};