User prompt
player can shoot 4 direction
User prompt
repair enemy not shoot
User prompt
fix all enemy can shoot
User prompt
all enemy can shoot four direction exept asteroid
User prompt
enemy can shoot four direction
User prompt
hapus gambar batu hijau di layar
User prompt
buat musuh baru yaitu pesawat alien yang mampu menembak player
User prompt
buat background statik
User prompt
make enemy more hard to destroy
User prompt
create touch screen buttons to control character movement for android device
User prompt
create touch screen buttons to control character movement
User prompt
make touch pad controler
User prompt
make touc pad control
User prompt
Please fix the bug: 'TypeError: Cannot set properties of undefined (setting 'fill')' in or related to this line: 'specialTxt.style.fill = "#ffffff";' Line Number: 556
User prompt
Please fix the bug: 'Cannot set properties of undefined (setting 'fill')' in or related to this line: 'specialTxt.style.fill = "#9b59b6";' Line Number: 567
Code edit (1 edits merged)
Please save this source code
User prompt
Anime Sky Striker
Initial prompt
anime sidescrolling rail shooter game with anime style
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { highScore: 0, lastScore: 0 }); /**** * Classes ****/ var AlienShip = Container.expand(function () { var self = Container.call(this); self.shipGraphics = self.attachAsset('alienShip', { anchorX: 0.5, anchorY: 0.5 }); self.speedX = -3; self.speedY = 2; self.health = 8; self.score = 300; self.shootTimer = 0; self.shootInterval = 90; // 1.5 seconds at 60fps self.directionChangeTimer = 0; self.directionChangeInterval = 120; // 2 seconds self.lastY = 0; self.lastPlayerIntersecting = false; self.update = function () { self.x += self.speedX; self.y += self.speedY; // Change direction periodically self.directionChangeTimer++; if (self.directionChangeTimer >= self.directionChangeInterval) { self.speedY = -self.speedY; self.directionChangeTimer = 0; } // Boundary checking if (self.y <= 200) { self.speedY = Math.abs(self.speedY); } else if (self.y >= 2500) { self.speedY = -Math.abs(self.speedY); } // Shooting logic - aim at player self.shootTimer++; if (self.shootTimer >= self.shootInterval) { self.shootTimer = 0; self.shootAtPlayer(); } // Auto destroy when off screen if (self.x < -150) { self.destroy(); } }; self.shootAtPlayer = function () { if (!game || !game.player) { return; } var speed = 12; // Create bullets in four directions: up, down, left, right var directions = [{ speedX: 0, speedY: -speed }, // Up { speedX: 0, speedY: speed }, // Down { speedX: -speed, speedY: 0 }, // Left { speedX: speed, speedY: 0 } // Right ]; for (var i = 0; i < directions.length; i++) { var bullet = new Bullet(); bullet.x = self.x; bullet.y = self.y; bullet.speed = directions[i].speedX; bullet.speedY = directions[i].speedY; bullet.isPlayerBullet = false; bullet.bulletGraphics.tint = 0x00ff00; // Green alien bullets // Custom update for four-directional movement bullet.update = function () { this.x += this.speed; this.y += this.speedY; // Off screen check if (this.x < -100 || this.y < -100 || this.y > 2832 || this.x > 2148) { this.destroy(); } }; game.addChild(bullet); game.enemyBullets.push(bullet); } LK.getSound('shoot').play(); }; self.takeDamage = function (damage) { self.health -= damage; // Flash red when taking damage LK.effects.flashObject(self, 0xff0000, 200); if (self.health <= 0) { // Explosion effect LK.getSound('explosion').play(); LK.effects.flashObject(self, 0xffffff, 300); // Add score game.increaseScore(self.score); // Potentially drop powerup (25% chance) if (Math.random() < 0.25) { game.spawnPowerup(self.x, self.y); } self.destroy(); } }; return self; }); var Bullet = Container.expand(function () { var self = Container.call(this); self.bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 20; self.damage = 1; self.isPlayerBullet = true; self.update = function () { self.x += self.speed; // Auto destroy when off screen if (self.x > 2148) { self.destroy(); } }; return self; }); var Enemy = Container.expand(function () { var self = Container.call(this); self.enemyGraphics = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5 }); self.speedX = -5; self.speedY = 0; self.health = 5; self.score = 100; self.canShoot = false; self.shootTimer = 0; self.shootInterval = 120; // 2 seconds at 60fps self.update = function () { self.x += self.speedX; self.y += self.speedY; // Simple movement pattern if (self.movePattern === 'sine') { self.y += Math.sin(LK.ticks * 0.05) * 2; } else if (self.movePattern === 'zigzag') { if (LK.ticks % 60 === 0) { self.speedY = -self.speedY || (Math.random() > 0.5 ? 3 : -3); } } // Shooting logic if (self.canShoot) { self.shootTimer++; if (self.shootTimer >= self.shootInterval) { self.shootTimer = 0; self.shoot(); } } // Auto destroy when off screen if (self.x < -100) { self.destroy(); } }; self.shoot = function () { if (!game) { return; } var speed = 12; // Create bullets in four directions: up, down, left, right var directions = [{ speedX: 0, speedY: -speed }, // Up { speedX: 0, speedY: speed }, // Down { speedX: -speed, speedY: 0 }, // Left { speedX: speed, speedY: 0 } // Right ]; for (var i = 0; i < directions.length; i++) { var bullet = new Bullet(); bullet.x = self.x; bullet.y = self.y; bullet.speed = directions[i].speedX; bullet.speedY = directions[i].speedY; bullet.isPlayerBullet = false; bullet.bulletGraphics.tint = 0xff0000; // Red enemy bullets // Custom update for four-directional movement bullet.update = function () { this.x += this.speed; this.y += this.speedY; // Off screen check if (this.x < -100 || this.y < -100 || this.y > 2832 || this.x > 2148) { this.destroy(); } }; game.addChild(bullet); game.enemyBullets.push(bullet); } LK.getSound('shoot').play(); }; self.takeDamage = function (damage) { self.health -= damage; // Flash red when taking damage LK.effects.flashObject(self, 0xff0000, 200); if (self.health <= 0) { // Explosion effect LK.getSound('explosion').play(); LK.effects.flashObject(self, 0xffffff, 300); // Add score game.increaseScore(self.score); // Potentially drop powerup (20% chance) if (Math.random() < 0.2) { game.spawnPowerup(self.x, self.y); } self.destroy(); } }; return self; }); var Boss = Enemy.expand(function () { var self = Enemy.call(this); // Replace graphics with boss graphic self.enemyGraphics.destroy(); self.enemyGraphics = self.attachAsset('boss', { anchorX: 0.5, anchorY: 0.5 }); self.health = 75; self.score = 2000; self.speedX = -2; self.canShoot = true; self.shootInterval = 60; // 1 second at 60fps self.phase = 1; self.phaseTimer = 0; self.isBoss = true; // Override update function self.update = function () { self.phaseTimer++; // Boss movement based on phases if (self.phase === 1) { // Enter the screen if (self.x > 1600) { self.x += self.speedX; } else { self.phase = 2; self.phaseTimer = 0; } } else if (self.phase === 2) { // Move up and down self.y += Math.sin(self.phaseTimer * 0.03) * 4; // Shooting pattern if (self.phaseTimer % 20 === 0) { self.shoot(); } // Phase transition if (self.phaseTimer > 300) { self.phase = 3; self.phaseTimer = 0; } } else if (self.phase === 3) { // Charge at player if (self.phaseTimer < 60) { // Prepare self.speedX = 0; } else if (self.phaseTimer < 120) { // Charge self.x -= 15; } else { // Return to position if (self.x < 1600) { self.x += 5; } else { self.phase = 2; self.phaseTimer = 0; } } } // Health-based phase changes if (self.health < 25 && self.shootInterval > 40) { self.shootInterval = 40; // Shoot faster when at low health } }; // Override shoot function for more complex patterns self.shoot = function () { if (!game) { return; } var speed = 15; // Create bullets in four directions: up, down, left, right var directions = [{ speedX: 0, speedY: -speed }, // Up { speedX: 0, speedY: speed }, // Down { speedX: -speed, speedY: 0 }, // Left { speedX: speed, speedY: 0 } // Right ]; for (var i = 0; i < directions.length; i++) { var bullet = new Bullet(); bullet.x = self.x - 50; bullet.y = self.y; bullet.speed = directions[i].speedX; bullet.speedY = directions[i].speedY; bullet.isPlayerBullet = false; bullet.bulletGraphics.tint = 0xff0000; // Custom update for four-directional movement bullet.update = function () { this.x += this.speed; this.y += this.speedY; // Off screen check if (this.x < -100 || this.y < -100 || this.y > 2832 || this.x > 2148) { this.destroy(); } }; game.addChild(bullet); game.enemyBullets.push(bullet); } LK.getSound('shoot').play(); }; return self; }); var Obstacle = Container.expand(function () { var self = Container.call(this); self.obstacleGraphics = self.attachAsset('obstacle', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -8; self.update = function () { self.x += self.speed; // Auto destroy when off screen if (self.x < -100) { self.destroy(); } }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); self.playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); self.health = 5; self.maxHealth = 5; self.shield = 0; self.weaponLevel = 1; self.specialMeter = 0; self.specialMax = 100; self.shootCooldown = 0; self.invulnerable = 0; self.update = function () { // Shooting cooldown if (self.shootCooldown > 0) { self.shootCooldown--; } // Invulnerability frames if (self.invulnerable > 0) { self.invulnerable--; // Flash effect during invulnerability if (LK.ticks % 5 === 0) { self.playerGraphics.alpha = self.playerGraphics.alpha === 1 ? 0.5 : 1; } } else { self.playerGraphics.alpha = 1; } // Gentle hover effect self.y += Math.sin(LK.ticks * 0.05) * 0.5; }; self.shoot = function () { if (self.shootCooldown > 0) { return; } LK.getSound('shoot').play(); var speed = 20; // Create bullets in four directions: up, down, left, right var directions = [{ speedX: speed, speedY: 0 }, // Right { speedX: 0, speedY: -speed }, // Up { speedX: 0, speedY: speed }, // Down { speedX: -speed, speedY: 0 } // Left ]; for (var i = 0; i < directions.length; i++) { var bullet = new Bullet(); bullet.x = self.x; bullet.y = self.y; bullet.speed = directions[i].speedX; bullet.speedY = directions[i].speedY; bullet.isPlayerBullet = true; // Custom update for four-directional movement bullet.update = function () { this.x += this.speed; this.y += this.speedY; // Off screen check if (this.x < -100 || this.y < -100 || this.y > 2832 || this.x > 2148) { this.destroy(); } }; game.addChild(bullet); game.playerBullets.push(bullet); } self.shootCooldown = 10; // Increase special meter slightly with each shot self.specialMeter = Math.min(self.specialMeter + 1, self.specialMax); game.updateSpecialMeter(); }; self.activateSpecial = function () { if (self.specialMeter < self.specialMax) { return; } LK.getSound('special').play(); // Create special attack var special = new SpecialAttack(); special.x = self.x; special.y = self.y; game.addChild(special); game.specialAttacks.push(special); // Make player briefly invulnerable self.invulnerable = 60; // Reset special meter self.specialMeter = 0; game.updateSpecialMeter(); }; self.takeDamage = function () { if (self.invulnerable > 0) { return; } // Shield absorbs damage first if (self.shield > 0) { self.shield--; LK.getSound('damage').play(); LK.effects.flashObject(self, 0x3498db, 300); // Blue flash for shield hit } else { self.health--; LK.getSound('damage').play(); LK.effects.flashObject(self, 0xff0000, 300); // Red flash for health hit // Set invulnerability frames self.invulnerable = 60; // Game over check if (self.health <= 0) { // Store score storage.lastScore = game.score; if (game.score > storage.highScore) { storage.highScore = game.score; } LK.showGameOver(); } } game.updateHealthDisplay(); }; self.collectPowerup = function (powerup) { LK.getSound('powerup').play(); if (powerup.type === 'health') { self.health = Math.min(self.health + 1, self.maxHealth); } else if (powerup.type === 'shield') { self.shield = Math.min(self.shield + 2, 3); // Max 3 shield points } else if (powerup.type === 'weapon') { self.weaponLevel = Math.min(self.weaponLevel + 1, 3); } else if (powerup.type === 'special') { self.specialMeter = self.specialMax; // Fill special meter } game.updateHealthDisplay(); game.updateSpecialMeter(); // Visual effect LK.effects.flashObject(self, 0xffffff, 300); }; // Touch/mouse controls self.down = function (x, y, obj) { game.isDragging = true; }; return self; }); var PowerUp = Container.expand(function () { var self = Container.call(this); self.powerupGraphics = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -3; self.type = 'health'; // Default power-up type // Set color based on type if (self.type === 'health') { self.powerupGraphics.tint = 0x2ecc71; // Green } else if (self.type === 'shield') { self.powerupGraphics.tint = 0x3498db; // Blue } else if (self.type === 'weapon') { self.powerupGraphics.tint = 0xf1c40f; // Yellow } else if (self.type === 'special') { self.powerupGraphics.tint = 0x9b59b6; // Purple } self.update = function () { self.x += self.speed; // Gentle floating effect self.y += Math.sin(LK.ticks * 0.1) * 0.5; // Auto destroy when off screen if (self.x < -100) { self.destroy(); } }; return self; }); var SpecialAttack = Container.expand(function () { var self = Container.call(this); self.attackGraphics = self.attachAsset('specialAttack', { anchorX: 0.5, anchorY: 0.5, alpha: 0.7 }); self.duration = 60; // 1 second at 60fps self.counter = 0; self.damage = 5; self.update = function () { self.counter++; self.x += 10; // Flash effect if (self.counter % 5 === 0) { self.attackGraphics.alpha = self.attackGraphics.alpha === 0.7 ? 0.9 : 0.7; } // Auto destroy when duration ends if (self.counter >= self.duration) { self.destroy(); } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x0e0e2a }); /**** * Game Code ****/ // Game variables game.score = 0; game.level = 1; game.waveTimer = 0; game.bossActive = false; game.spawnRate = 120; // Enemy spawn rate (frames) game.isDragging = false; game.autoShoot = true; game.autoShootTimer = 0; // Array containers for game objects game.playerBullets = []; game.enemyBullets = []; game.enemies = []; game.alienShips = []; game.powerups = []; game.obstacles = []; game.specialAttacks = []; // Create background var background = game.addChild(LK.getAsset('background', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366 })); // Create player game.player = new Player(); game.player.x = 300; game.player.y = 1366; // Center vertically game.addChild(game.player); // Create UI // Score display var scoreTxt = new Text2('SCORE: 0', { size: 80, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Create touch screen buttons for movement var leftBtn = game.addChild(LK.getAsset('powerup', { anchorX: 0.5, anchorY: 0.5, x: 100, y: 2500, scaleX: 2, scaleY: 2, tint: 0x3498db })); var rightBtn = game.addChild(LK.getAsset('powerup', { anchorX: 0.5, anchorY: 0.5, x: 400, y: 2500, scaleX: 2, scaleY: 2, tint: 0x3498db })); var upBtn = game.addChild(LK.getAsset('powerup', { anchorX: 0.5, anchorY: 0.5, x: 250, y: 2400, scaleX: 2, scaleY: 2, tint: 0x3498db })); var downBtn = game.addChild(LK.getAsset('powerup', { anchorX: 0.5, anchorY: 0.5, x: 250, y: 2600, scaleX: 2, scaleY: 2, tint: 0x3498db })); // Button event handlers leftBtn.down = function () { game.player.x = Math.max(85, game.player.x - 10); }; rightBtn.down = function () { game.player.x = Math.min(1963, game.player.x + 10); }; upBtn.down = function () { game.player.y = Math.max(85, game.player.y - 10); }; downBtn.down = function () { game.player.y = Math.min(2647, game.player.y + 10); }; // Health display var healthTxt = new Text2('HEALTH: 5', { size: 60, fill: 0x2ECC71 }); healthTxt.anchor.set(0, 0); healthTxt.x = 120; healthTxt.y = 100; LK.gui.addChild(healthTxt); // Shield display var shieldTxt = new Text2('SHIELD: 0', { size: 60, fill: 0x3498DB }); shieldTxt.anchor.set(0, 0); shieldTxt.x = 120; shieldTxt.y = 170; LK.gui.addChild(shieldTxt); // Special meter var specialTxt = new Text2('SPECIAL: 0%', { size: 60, fill: 0x9B59B6 }); specialTxt.anchor.set(0, 0); specialTxt.x = 120; specialTxt.y = 240; LK.gui.addChild(specialTxt); // Level display var levelTxt = new Text2('LEVEL 1', { size: 60, fill: 0xF1C40F }); levelTxt.anchor.set(1, 0); levelTxt.x = -120; levelTxt.y = 100; LK.gui.right.addChild(levelTxt); // Special attack button var specialBtn = game.addChild(LK.getAsset('powerup', { anchorX: 0.5, anchorY: 0.5, x: 1900, y: 2500, scaleX: 2, scaleY: 2, tint: 0x9b59b6 })); // Update UI functions game.updateScoreDisplay = function () { scoreTxt.setText('SCORE: ' + game.score); }; game.updateHealthDisplay = function () { healthTxt.setText('HEALTH: ' + game.player.health); shieldTxt.setText('SHIELD: ' + game.player.shield); }; game.updateSpecialMeter = function () { var percentage = Math.floor(game.player.specialMeter / game.player.specialMax * 100); specialTxt.setText('SPECIAL: ' + percentage + '%'); // Visual indication of special readiness if (percentage >= 100) { specialTxt.setStyle({ fill: 0xFFFFFF }); tween(specialTxt, { alpha: 0.5 }, { duration: 500, easing: tween.easeInOut, onFinish: function onFinish() { tween(specialTxt, { alpha: 1 }, { duration: 500, easing: tween.easeInOut }); } }); } else { specialTxt.setStyle({ fill: 0x9B59B6 }); specialTxt.alpha = 1; } }; game.updateLevelDisplay = function () { levelTxt.setText('LEVEL ' + game.level); }; // Spawn functions game.spawnEnemy = function (type) { var enemy = new Enemy(); enemy.x = 2148; // Just off-screen to the right enemy.y = 500 + Math.random() * 1400; // Random y position // Configure enemy type if (type === 'basic') { enemy.movePattern = 'none'; enemy.canShoot = true; // Enable shooting for basic enemies } else if (type === 'shooter') { enemy.movePattern = 'none'; enemy.canShoot = true; enemy.enemyGraphics.tint = 0xe67e22; // Orange } else if (type === 'fast') { enemy.movePattern = 'zigzag'; enemy.speedX = -10; enemy.health = 2; enemy.canShoot = true; // Enable shooting for fast enemies enemy.enemyGraphics.tint = 0xe74c3c; // Red } else if (type === 'tank') { enemy.movePattern = 'sine'; enemy.speedX = -3; enemy.health = 12; enemy.score = 250; enemy.canShoot = true; // Enable shooting for tank enemies enemy.enemyGraphics.scaleX = 1.5; enemy.enemyGraphics.scaleY = 1.5; enemy.enemyGraphics.tint = 0x7f8c8d; // Gray } game.addChild(enemy); game.enemies.push(enemy); return enemy; }; game.spawnBoss = function () { // Only one boss at a time if (game.bossActive) { return; } game.bossActive = true; var boss = new Boss(); boss.x = 2300; // Start off-screen boss.y = 1366; // Center vertically game.addChild(boss); game.enemies.push(boss); return boss; }; game.spawnObstacle = function () { var obstacle = new Obstacle(); obstacle.x = 2148; // Just off-screen to the right obstacle.y = 400 + Math.random() * 1600; // Random y position game.addChild(obstacle); game.obstacles.push(obstacle); return obstacle; }; game.spawnAlienShip = function () { var alienShip = new AlienShip(); alienShip.x = 2148; // Just off-screen to the right alienShip.y = 300 + Math.random() * 1800; // Random y position alienShip.lastY = alienShip.y; alienShip.lastPlayerIntersecting = false; game.addChild(alienShip); game.alienShips.push(alienShip); return alienShip; }; game.spawnPowerup = function (x, y) { var powerup = new PowerUp(); powerup.x = x; powerup.y = y; // Random powerup type var types = ['health', 'shield', 'weapon', 'special']; var weights = [0.3, 0.3, 0.2, 0.2]; // Higher chance for health/shield var total = 0; var random = Math.random(); for (var i = 0; i < types.length; i++) { total += weights[i]; if (random <= total) { powerup.type = types[i]; break; } } // Set color based on type if (powerup.type === 'health') { powerup.powerupGraphics.tint = 0x2ecc71; // Green } else if (powerup.type === 'shield') { powerup.powerupGraphics.tint = 0x3498db; // Blue } else if (powerup.type === 'weapon') { powerup.powerupGraphics.tint = 0xf1c40f; // Yellow } else if (powerup.type === 'special') { powerup.powerupGraphics.tint = 0x9b59b6; // Purple } game.addChild(powerup); game.powerups.push(powerup); return powerup; }; // Score function game.increaseScore = function (amount) { game.score += amount; game.updateScoreDisplay(); // Level up every 5000 points if (game.score > 0 && game.score % 5000 === 0) { game.levelUp(); } }; game.levelUp = function () { game.level++; game.updateLevelDisplay(); // Spawn boss every 3 levels if (game.level % 3 === 0) { game.spawnBoss(); } // Increase difficulty game.spawnRate = Math.max(60, game.spawnRate - 10); // Flash screen LK.effects.flashScreen(0xf1c40f, 500); // Yellow flash }; // Event handlers game.down = function (x, y, obj) { // Special button handling if (obj === specialBtn && game.player.specialMeter >= game.player.specialMax) { game.player.activateSpecial(); return; } // Player shooting game.player.shoot(); // Start dragging game.isDragging = true; }; game.up = function (x, y, obj) { game.isDragging = false; }; game.move = function (x, y, obj) { if (game.isDragging) { // Calculate movement based on touchpad input var deltaX = x - game.player.x; var deltaY = y - game.player.y; // Apply movement with a sensitivity factor game.player.x += deltaX * 0.1; game.player.y += deltaY * 0.1; // Ensure player stays within screen bounds game.player.x = Math.max(85, Math.min(game.player.x, 1963)); game.player.y = Math.max(85, Math.min(game.player.y, 2647)); } }; // Main game update loop game.update = function () { // Auto-shooting if (game.autoShoot) { game.autoShootTimer++; if (game.autoShootTimer >= 15) { // Every 15 frames (4 times per second) game.player.shoot(); game.autoShootTimer = 0; } } // Spawn enemies based on timer game.waveTimer++; if (!game.bossActive && game.waveTimer >= game.spawnRate) { game.waveTimer = 0; // Different enemy types based on level var types = ['basic']; if (game.level >= 2) { types.push('shooter'); } if (game.level >= 3) { types.push('fast'); } if (game.level >= 5) { types.push('tank'); } // Spawn random enemy type var type = types[Math.floor(Math.random() * types.length)]; game.spawnEnemy(type); // Spawn alien ships (15% chance after level 4) if (game.level >= 4 && Math.random() < 0.15) { game.spawnAlienShip(); } // Occasionally spawn obstacles (10% chance) if (Math.random() < 0.1) { game.spawnObstacle(); } } // Check boss status if (game.bossActive) { var bossStillActive = false; for (var i = 0; i < game.enemies.length; i++) { if (game.enemies[i].isBoss) { bossStillActive = true; break; } } game.bossActive = bossStillActive; } // Check collisions // Player bullets vs enemies for (var i = game.playerBullets.length - 1; i >= 0; i--) { var bullet = game.playerBullets[i]; // Skip destroyed bullets if (!bullet.parent) { game.playerBullets.splice(i, 1); continue; } for (var j = game.enemies.length - 1; j >= 0; j--) { var enemy = game.enemies[j]; // Skip destroyed enemies if (!enemy.parent) { game.enemies.splice(j, 1); continue; } if (bullet.intersects(enemy)) { enemy.takeDamage(bullet.damage); bullet.destroy(); game.playerBullets.splice(i, 1); break; } } // Check alien ships for (var j = game.alienShips.length - 1; j >= 0; j--) { var alienShip = game.alienShips[j]; // Skip destroyed alien ships if (!alienShip.parent) { game.alienShips.splice(j, 1); continue; } if (bullet.intersects(alienShip)) { alienShip.takeDamage(bullet.damage); bullet.destroy(); game.playerBullets.splice(i, 1); break; } } } // Special attacks vs enemies for (var i = game.specialAttacks.length - 1; i >= 0; i--) { var special = game.specialAttacks[i]; // Skip destroyed specials if (!special.parent) { game.specialAttacks.splice(i, 1); continue; } for (var j = game.enemies.length - 1; j >= 0; j--) { var enemy = game.enemies[j]; // Skip destroyed enemies if (!enemy.parent) { game.enemies.splice(j, 1); continue; } if (special.intersects(enemy)) { enemy.takeDamage(special.damage); } } // Special vs alien ships for (var j = game.alienShips.length - 1; j >= 0; j--) { var alienShip = game.alienShips[j]; // Skip destroyed alien ships if (!alienShip.parent) { game.alienShips.splice(j, 1); continue; } if (special.intersects(alienShip)) { alienShip.takeDamage(special.damage); } } // Special clears enemy bullets too for (var j = game.enemyBullets.length - 1; j >= 0; j--) { var bullet = game.enemyBullets[j]; // Skip destroyed bullets if (!bullet.parent) { game.enemyBullets.splice(j, 1); continue; } if (special.intersects(bullet)) { bullet.destroy(); game.enemyBullets.splice(j, 1); } } } // Enemy bullets vs player for (var i = game.enemyBullets.length - 1; i >= 0; i--) { var bullet = game.enemyBullets[i]; // Skip destroyed bullets if (!bullet.parent) { game.enemyBullets.splice(i, 1); continue; } if (bullet.intersects(game.player)) { game.player.takeDamage(); bullet.destroy(); game.enemyBullets.splice(i, 1); } } // Obstacles vs player for (var i = game.obstacles.length - 1; i >= 0; i--) { var obstacle = game.obstacles[i]; // Skip destroyed obstacles if (!obstacle.parent) { game.obstacles.splice(i, 1); continue; } if (obstacle.intersects(game.player)) { game.player.takeDamage(); obstacle.destroy(); game.obstacles.splice(i, 1); } } // Powerups vs player for (var i = game.powerups.length - 1; i >= 0; i--) { var powerup = game.powerups[i]; // Skip destroyed powerups if (!powerup.parent) { game.powerups.splice(i, 1); continue; } if (powerup.intersects(game.player)) { game.player.collectPowerup(powerup); powerup.destroy(); game.powerups.splice(i, 1); } } // Remove destroyed enemies from array for (var i = game.enemies.length - 1; i >= 0; i--) { if (!game.enemies[i].parent) { game.enemies.splice(i, 1); } } // Update arrays of objects that might be removed game.playerBullets = game.playerBullets.filter(function (bullet) { return bullet.parent !== null; }); game.enemyBullets = game.enemyBullets.filter(function (bullet) { return bullet.parent !== null; }); game.obstacles = game.obstacles.filter(function (obstacle) { return obstacle.parent !== null; }); game.powerups = game.powerups.filter(function (powerup) { return powerup.parent !== null; }); game.specialAttacks = game.specialAttacks.filter(function (special) { return special.parent !== null; }); game.alienShips = game.alienShips.filter(function (alienShip) { return alienShip.parent !== null; }); // Static background - no scrolling }; // Initialize displays game.updateScoreDisplay(); game.updateHealthDisplay(); game.updateSpecialMeter(); game.updateLevelDisplay(); // Start background music LK.playMusic('bgm');
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
highScore: 0,
lastScore: 0
});
/****
* Classes
****/
var AlienShip = Container.expand(function () {
var self = Container.call(this);
self.shipGraphics = self.attachAsset('alienShip', {
anchorX: 0.5,
anchorY: 0.5
});
self.speedX = -3;
self.speedY = 2;
self.health = 8;
self.score = 300;
self.shootTimer = 0;
self.shootInterval = 90; // 1.5 seconds at 60fps
self.directionChangeTimer = 0;
self.directionChangeInterval = 120; // 2 seconds
self.lastY = 0;
self.lastPlayerIntersecting = false;
self.update = function () {
self.x += self.speedX;
self.y += self.speedY;
// Change direction periodically
self.directionChangeTimer++;
if (self.directionChangeTimer >= self.directionChangeInterval) {
self.speedY = -self.speedY;
self.directionChangeTimer = 0;
}
// Boundary checking
if (self.y <= 200) {
self.speedY = Math.abs(self.speedY);
} else if (self.y >= 2500) {
self.speedY = -Math.abs(self.speedY);
}
// Shooting logic - aim at player
self.shootTimer++;
if (self.shootTimer >= self.shootInterval) {
self.shootTimer = 0;
self.shootAtPlayer();
}
// Auto destroy when off screen
if (self.x < -150) {
self.destroy();
}
};
self.shootAtPlayer = function () {
if (!game || !game.player) {
return;
}
var speed = 12;
// Create bullets in four directions: up, down, left, right
var directions = [{
speedX: 0,
speedY: -speed
},
// Up
{
speedX: 0,
speedY: speed
},
// Down
{
speedX: -speed,
speedY: 0
},
// Left
{
speedX: speed,
speedY: 0
} // Right
];
for (var i = 0; i < directions.length; i++) {
var bullet = new Bullet();
bullet.x = self.x;
bullet.y = self.y;
bullet.speed = directions[i].speedX;
bullet.speedY = directions[i].speedY;
bullet.isPlayerBullet = false;
bullet.bulletGraphics.tint = 0x00ff00; // Green alien bullets
// Custom update for four-directional movement
bullet.update = function () {
this.x += this.speed;
this.y += this.speedY;
// Off screen check
if (this.x < -100 || this.y < -100 || this.y > 2832 || this.x > 2148) {
this.destroy();
}
};
game.addChild(bullet);
game.enemyBullets.push(bullet);
}
LK.getSound('shoot').play();
};
self.takeDamage = function (damage) {
self.health -= damage;
// Flash red when taking damage
LK.effects.flashObject(self, 0xff0000, 200);
if (self.health <= 0) {
// Explosion effect
LK.getSound('explosion').play();
LK.effects.flashObject(self, 0xffffff, 300);
// Add score
game.increaseScore(self.score);
// Potentially drop powerup (25% chance)
if (Math.random() < 0.25) {
game.spawnPowerup(self.x, self.y);
}
self.destroy();
}
};
return self;
});
var Bullet = Container.expand(function () {
var self = Container.call(this);
self.bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 20;
self.damage = 1;
self.isPlayerBullet = true;
self.update = function () {
self.x += self.speed;
// Auto destroy when off screen
if (self.x > 2148) {
self.destroy();
}
};
return self;
});
var Enemy = Container.expand(function () {
var self = Container.call(this);
self.enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.speedX = -5;
self.speedY = 0;
self.health = 5;
self.score = 100;
self.canShoot = false;
self.shootTimer = 0;
self.shootInterval = 120; // 2 seconds at 60fps
self.update = function () {
self.x += self.speedX;
self.y += self.speedY;
// Simple movement pattern
if (self.movePattern === 'sine') {
self.y += Math.sin(LK.ticks * 0.05) * 2;
} else if (self.movePattern === 'zigzag') {
if (LK.ticks % 60 === 0) {
self.speedY = -self.speedY || (Math.random() > 0.5 ? 3 : -3);
}
}
// Shooting logic
if (self.canShoot) {
self.shootTimer++;
if (self.shootTimer >= self.shootInterval) {
self.shootTimer = 0;
self.shoot();
}
}
// Auto destroy when off screen
if (self.x < -100) {
self.destroy();
}
};
self.shoot = function () {
if (!game) {
return;
}
var speed = 12;
// Create bullets in four directions: up, down, left, right
var directions = [{
speedX: 0,
speedY: -speed
},
// Up
{
speedX: 0,
speedY: speed
},
// Down
{
speedX: -speed,
speedY: 0
},
// Left
{
speedX: speed,
speedY: 0
} // Right
];
for (var i = 0; i < directions.length; i++) {
var bullet = new Bullet();
bullet.x = self.x;
bullet.y = self.y;
bullet.speed = directions[i].speedX;
bullet.speedY = directions[i].speedY;
bullet.isPlayerBullet = false;
bullet.bulletGraphics.tint = 0xff0000; // Red enemy bullets
// Custom update for four-directional movement
bullet.update = function () {
this.x += this.speed;
this.y += this.speedY;
// Off screen check
if (this.x < -100 || this.y < -100 || this.y > 2832 || this.x > 2148) {
this.destroy();
}
};
game.addChild(bullet);
game.enemyBullets.push(bullet);
}
LK.getSound('shoot').play();
};
self.takeDamage = function (damage) {
self.health -= damage;
// Flash red when taking damage
LK.effects.flashObject(self, 0xff0000, 200);
if (self.health <= 0) {
// Explosion effect
LK.getSound('explosion').play();
LK.effects.flashObject(self, 0xffffff, 300);
// Add score
game.increaseScore(self.score);
// Potentially drop powerup (20% chance)
if (Math.random() < 0.2) {
game.spawnPowerup(self.x, self.y);
}
self.destroy();
}
};
return self;
});
var Boss = Enemy.expand(function () {
var self = Enemy.call(this);
// Replace graphics with boss graphic
self.enemyGraphics.destroy();
self.enemyGraphics = self.attachAsset('boss', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 75;
self.score = 2000;
self.speedX = -2;
self.canShoot = true;
self.shootInterval = 60; // 1 second at 60fps
self.phase = 1;
self.phaseTimer = 0;
self.isBoss = true;
// Override update function
self.update = function () {
self.phaseTimer++;
// Boss movement based on phases
if (self.phase === 1) {
// Enter the screen
if (self.x > 1600) {
self.x += self.speedX;
} else {
self.phase = 2;
self.phaseTimer = 0;
}
} else if (self.phase === 2) {
// Move up and down
self.y += Math.sin(self.phaseTimer * 0.03) * 4;
// Shooting pattern
if (self.phaseTimer % 20 === 0) {
self.shoot();
}
// Phase transition
if (self.phaseTimer > 300) {
self.phase = 3;
self.phaseTimer = 0;
}
} else if (self.phase === 3) {
// Charge at player
if (self.phaseTimer < 60) {
// Prepare
self.speedX = 0;
} else if (self.phaseTimer < 120) {
// Charge
self.x -= 15;
} else {
// Return to position
if (self.x < 1600) {
self.x += 5;
} else {
self.phase = 2;
self.phaseTimer = 0;
}
}
}
// Health-based phase changes
if (self.health < 25 && self.shootInterval > 40) {
self.shootInterval = 40; // Shoot faster when at low health
}
};
// Override shoot function for more complex patterns
self.shoot = function () {
if (!game) {
return;
}
var speed = 15;
// Create bullets in four directions: up, down, left, right
var directions = [{
speedX: 0,
speedY: -speed
},
// Up
{
speedX: 0,
speedY: speed
},
// Down
{
speedX: -speed,
speedY: 0
},
// Left
{
speedX: speed,
speedY: 0
} // Right
];
for (var i = 0; i < directions.length; i++) {
var bullet = new Bullet();
bullet.x = self.x - 50;
bullet.y = self.y;
bullet.speed = directions[i].speedX;
bullet.speedY = directions[i].speedY;
bullet.isPlayerBullet = false;
bullet.bulletGraphics.tint = 0xff0000;
// Custom update for four-directional movement
bullet.update = function () {
this.x += this.speed;
this.y += this.speedY;
// Off screen check
if (this.x < -100 || this.y < -100 || this.y > 2832 || this.x > 2148) {
this.destroy();
}
};
game.addChild(bullet);
game.enemyBullets.push(bullet);
}
LK.getSound('shoot').play();
};
return self;
});
var Obstacle = Container.expand(function () {
var self = Container.call(this);
self.obstacleGraphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -8;
self.update = function () {
self.x += self.speed;
// Auto destroy when off screen
if (self.x < -100) {
self.destroy();
}
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
self.playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 5;
self.maxHealth = 5;
self.shield = 0;
self.weaponLevel = 1;
self.specialMeter = 0;
self.specialMax = 100;
self.shootCooldown = 0;
self.invulnerable = 0;
self.update = function () {
// Shooting cooldown
if (self.shootCooldown > 0) {
self.shootCooldown--;
}
// Invulnerability frames
if (self.invulnerable > 0) {
self.invulnerable--;
// Flash effect during invulnerability
if (LK.ticks % 5 === 0) {
self.playerGraphics.alpha = self.playerGraphics.alpha === 1 ? 0.5 : 1;
}
} else {
self.playerGraphics.alpha = 1;
}
// Gentle hover effect
self.y += Math.sin(LK.ticks * 0.05) * 0.5;
};
self.shoot = function () {
if (self.shootCooldown > 0) {
return;
}
LK.getSound('shoot').play();
var speed = 20;
// Create bullets in four directions: up, down, left, right
var directions = [{
speedX: speed,
speedY: 0
},
// Right
{
speedX: 0,
speedY: -speed
},
// Up
{
speedX: 0,
speedY: speed
},
// Down
{
speedX: -speed,
speedY: 0
} // Left
];
for (var i = 0; i < directions.length; i++) {
var bullet = new Bullet();
bullet.x = self.x;
bullet.y = self.y;
bullet.speed = directions[i].speedX;
bullet.speedY = directions[i].speedY;
bullet.isPlayerBullet = true;
// Custom update for four-directional movement
bullet.update = function () {
this.x += this.speed;
this.y += this.speedY;
// Off screen check
if (this.x < -100 || this.y < -100 || this.y > 2832 || this.x > 2148) {
this.destroy();
}
};
game.addChild(bullet);
game.playerBullets.push(bullet);
}
self.shootCooldown = 10;
// Increase special meter slightly with each shot
self.specialMeter = Math.min(self.specialMeter + 1, self.specialMax);
game.updateSpecialMeter();
};
self.activateSpecial = function () {
if (self.specialMeter < self.specialMax) {
return;
}
LK.getSound('special').play();
// Create special attack
var special = new SpecialAttack();
special.x = self.x;
special.y = self.y;
game.addChild(special);
game.specialAttacks.push(special);
// Make player briefly invulnerable
self.invulnerable = 60;
// Reset special meter
self.specialMeter = 0;
game.updateSpecialMeter();
};
self.takeDamage = function () {
if (self.invulnerable > 0) {
return;
}
// Shield absorbs damage first
if (self.shield > 0) {
self.shield--;
LK.getSound('damage').play();
LK.effects.flashObject(self, 0x3498db, 300); // Blue flash for shield hit
} else {
self.health--;
LK.getSound('damage').play();
LK.effects.flashObject(self, 0xff0000, 300); // Red flash for health hit
// Set invulnerability frames
self.invulnerable = 60;
// Game over check
if (self.health <= 0) {
// Store score
storage.lastScore = game.score;
if (game.score > storage.highScore) {
storage.highScore = game.score;
}
LK.showGameOver();
}
}
game.updateHealthDisplay();
};
self.collectPowerup = function (powerup) {
LK.getSound('powerup').play();
if (powerup.type === 'health') {
self.health = Math.min(self.health + 1, self.maxHealth);
} else if (powerup.type === 'shield') {
self.shield = Math.min(self.shield + 2, 3); // Max 3 shield points
} else if (powerup.type === 'weapon') {
self.weaponLevel = Math.min(self.weaponLevel + 1, 3);
} else if (powerup.type === 'special') {
self.specialMeter = self.specialMax; // Fill special meter
}
game.updateHealthDisplay();
game.updateSpecialMeter();
// Visual effect
LK.effects.flashObject(self, 0xffffff, 300);
};
// Touch/mouse controls
self.down = function (x, y, obj) {
game.isDragging = true;
};
return self;
});
var PowerUp = Container.expand(function () {
var self = Container.call(this);
self.powerupGraphics = self.attachAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -3;
self.type = 'health'; // Default power-up type
// Set color based on type
if (self.type === 'health') {
self.powerupGraphics.tint = 0x2ecc71; // Green
} else if (self.type === 'shield') {
self.powerupGraphics.tint = 0x3498db; // Blue
} else if (self.type === 'weapon') {
self.powerupGraphics.tint = 0xf1c40f; // Yellow
} else if (self.type === 'special') {
self.powerupGraphics.tint = 0x9b59b6; // Purple
}
self.update = function () {
self.x += self.speed;
// Gentle floating effect
self.y += Math.sin(LK.ticks * 0.1) * 0.5;
// Auto destroy when off screen
if (self.x < -100) {
self.destroy();
}
};
return self;
});
var SpecialAttack = Container.expand(function () {
var self = Container.call(this);
self.attackGraphics = self.attachAsset('specialAttack', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.7
});
self.duration = 60; // 1 second at 60fps
self.counter = 0;
self.damage = 5;
self.update = function () {
self.counter++;
self.x += 10;
// Flash effect
if (self.counter % 5 === 0) {
self.attackGraphics.alpha = self.attackGraphics.alpha === 0.7 ? 0.9 : 0.7;
}
// Auto destroy when duration ends
if (self.counter >= self.duration) {
self.destroy();
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x0e0e2a
});
/****
* Game Code
****/
// Game variables
game.score = 0;
game.level = 1;
game.waveTimer = 0;
game.bossActive = false;
game.spawnRate = 120; // Enemy spawn rate (frames)
game.isDragging = false;
game.autoShoot = true;
game.autoShootTimer = 0;
// Array containers for game objects
game.playerBullets = [];
game.enemyBullets = [];
game.enemies = [];
game.alienShips = [];
game.powerups = [];
game.obstacles = [];
game.specialAttacks = [];
// Create background
var background = game.addChild(LK.getAsset('background', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366
}));
// Create player
game.player = new Player();
game.player.x = 300;
game.player.y = 1366; // Center vertically
game.addChild(game.player);
// Create UI
// Score display
var scoreTxt = new Text2('SCORE: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Create touch screen buttons for movement
var leftBtn = game.addChild(LK.getAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5,
x: 100,
y: 2500,
scaleX: 2,
scaleY: 2,
tint: 0x3498db
}));
var rightBtn = game.addChild(LK.getAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5,
x: 400,
y: 2500,
scaleX: 2,
scaleY: 2,
tint: 0x3498db
}));
var upBtn = game.addChild(LK.getAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5,
x: 250,
y: 2400,
scaleX: 2,
scaleY: 2,
tint: 0x3498db
}));
var downBtn = game.addChild(LK.getAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5,
x: 250,
y: 2600,
scaleX: 2,
scaleY: 2,
tint: 0x3498db
}));
// Button event handlers
leftBtn.down = function () {
game.player.x = Math.max(85, game.player.x - 10);
};
rightBtn.down = function () {
game.player.x = Math.min(1963, game.player.x + 10);
};
upBtn.down = function () {
game.player.y = Math.max(85, game.player.y - 10);
};
downBtn.down = function () {
game.player.y = Math.min(2647, game.player.y + 10);
};
// Health display
var healthTxt = new Text2('HEALTH: 5', {
size: 60,
fill: 0x2ECC71
});
healthTxt.anchor.set(0, 0);
healthTxt.x = 120;
healthTxt.y = 100;
LK.gui.addChild(healthTxt);
// Shield display
var shieldTxt = new Text2('SHIELD: 0', {
size: 60,
fill: 0x3498DB
});
shieldTxt.anchor.set(0, 0);
shieldTxt.x = 120;
shieldTxt.y = 170;
LK.gui.addChild(shieldTxt);
// Special meter
var specialTxt = new Text2('SPECIAL: 0%', {
size: 60,
fill: 0x9B59B6
});
specialTxt.anchor.set(0, 0);
specialTxt.x = 120;
specialTxt.y = 240;
LK.gui.addChild(specialTxt);
// Level display
var levelTxt = new Text2('LEVEL 1', {
size: 60,
fill: 0xF1C40F
});
levelTxt.anchor.set(1, 0);
levelTxt.x = -120;
levelTxt.y = 100;
LK.gui.right.addChild(levelTxt);
// Special attack button
var specialBtn = game.addChild(LK.getAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5,
x: 1900,
y: 2500,
scaleX: 2,
scaleY: 2,
tint: 0x9b59b6
}));
// Update UI functions
game.updateScoreDisplay = function () {
scoreTxt.setText('SCORE: ' + game.score);
};
game.updateHealthDisplay = function () {
healthTxt.setText('HEALTH: ' + game.player.health);
shieldTxt.setText('SHIELD: ' + game.player.shield);
};
game.updateSpecialMeter = function () {
var percentage = Math.floor(game.player.specialMeter / game.player.specialMax * 100);
specialTxt.setText('SPECIAL: ' + percentage + '%');
// Visual indication of special readiness
if (percentage >= 100) {
specialTxt.setStyle({
fill: 0xFFFFFF
});
tween(specialTxt, {
alpha: 0.5
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(specialTxt, {
alpha: 1
}, {
duration: 500,
easing: tween.easeInOut
});
}
});
} else {
specialTxt.setStyle({
fill: 0x9B59B6
});
specialTxt.alpha = 1;
}
};
game.updateLevelDisplay = function () {
levelTxt.setText('LEVEL ' + game.level);
};
// Spawn functions
game.spawnEnemy = function (type) {
var enemy = new Enemy();
enemy.x = 2148; // Just off-screen to the right
enemy.y = 500 + Math.random() * 1400; // Random y position
// Configure enemy type
if (type === 'basic') {
enemy.movePattern = 'none';
enemy.canShoot = true; // Enable shooting for basic enemies
} else if (type === 'shooter') {
enemy.movePattern = 'none';
enemy.canShoot = true;
enemy.enemyGraphics.tint = 0xe67e22; // Orange
} else if (type === 'fast') {
enemy.movePattern = 'zigzag';
enemy.speedX = -10;
enemy.health = 2;
enemy.canShoot = true; // Enable shooting for fast enemies
enemy.enemyGraphics.tint = 0xe74c3c; // Red
} else if (type === 'tank') {
enemy.movePattern = 'sine';
enemy.speedX = -3;
enemy.health = 12;
enemy.score = 250;
enemy.canShoot = true; // Enable shooting for tank enemies
enemy.enemyGraphics.scaleX = 1.5;
enemy.enemyGraphics.scaleY = 1.5;
enemy.enemyGraphics.tint = 0x7f8c8d; // Gray
}
game.addChild(enemy);
game.enemies.push(enemy);
return enemy;
};
game.spawnBoss = function () {
// Only one boss at a time
if (game.bossActive) {
return;
}
game.bossActive = true;
var boss = new Boss();
boss.x = 2300; // Start off-screen
boss.y = 1366; // Center vertically
game.addChild(boss);
game.enemies.push(boss);
return boss;
};
game.spawnObstacle = function () {
var obstacle = new Obstacle();
obstacle.x = 2148; // Just off-screen to the right
obstacle.y = 400 + Math.random() * 1600; // Random y position
game.addChild(obstacle);
game.obstacles.push(obstacle);
return obstacle;
};
game.spawnAlienShip = function () {
var alienShip = new AlienShip();
alienShip.x = 2148; // Just off-screen to the right
alienShip.y = 300 + Math.random() * 1800; // Random y position
alienShip.lastY = alienShip.y;
alienShip.lastPlayerIntersecting = false;
game.addChild(alienShip);
game.alienShips.push(alienShip);
return alienShip;
};
game.spawnPowerup = function (x, y) {
var powerup = new PowerUp();
powerup.x = x;
powerup.y = y;
// Random powerup type
var types = ['health', 'shield', 'weapon', 'special'];
var weights = [0.3, 0.3, 0.2, 0.2]; // Higher chance for health/shield
var total = 0;
var random = Math.random();
for (var i = 0; i < types.length; i++) {
total += weights[i];
if (random <= total) {
powerup.type = types[i];
break;
}
}
// Set color based on type
if (powerup.type === 'health') {
powerup.powerupGraphics.tint = 0x2ecc71; // Green
} else if (powerup.type === 'shield') {
powerup.powerupGraphics.tint = 0x3498db; // Blue
} else if (powerup.type === 'weapon') {
powerup.powerupGraphics.tint = 0xf1c40f; // Yellow
} else if (powerup.type === 'special') {
powerup.powerupGraphics.tint = 0x9b59b6; // Purple
}
game.addChild(powerup);
game.powerups.push(powerup);
return powerup;
};
// Score function
game.increaseScore = function (amount) {
game.score += amount;
game.updateScoreDisplay();
// Level up every 5000 points
if (game.score > 0 && game.score % 5000 === 0) {
game.levelUp();
}
};
game.levelUp = function () {
game.level++;
game.updateLevelDisplay();
// Spawn boss every 3 levels
if (game.level % 3 === 0) {
game.spawnBoss();
}
// Increase difficulty
game.spawnRate = Math.max(60, game.spawnRate - 10);
// Flash screen
LK.effects.flashScreen(0xf1c40f, 500); // Yellow flash
};
// Event handlers
game.down = function (x, y, obj) {
// Special button handling
if (obj === specialBtn && game.player.specialMeter >= game.player.specialMax) {
game.player.activateSpecial();
return;
}
// Player shooting
game.player.shoot();
// Start dragging
game.isDragging = true;
};
game.up = function (x, y, obj) {
game.isDragging = false;
};
game.move = function (x, y, obj) {
if (game.isDragging) {
// Calculate movement based on touchpad input
var deltaX = x - game.player.x;
var deltaY = y - game.player.y;
// Apply movement with a sensitivity factor
game.player.x += deltaX * 0.1;
game.player.y += deltaY * 0.1;
// Ensure player stays within screen bounds
game.player.x = Math.max(85, Math.min(game.player.x, 1963));
game.player.y = Math.max(85, Math.min(game.player.y, 2647));
}
};
// Main game update loop
game.update = function () {
// Auto-shooting
if (game.autoShoot) {
game.autoShootTimer++;
if (game.autoShootTimer >= 15) {
// Every 15 frames (4 times per second)
game.player.shoot();
game.autoShootTimer = 0;
}
}
// Spawn enemies based on timer
game.waveTimer++;
if (!game.bossActive && game.waveTimer >= game.spawnRate) {
game.waveTimer = 0;
// Different enemy types based on level
var types = ['basic'];
if (game.level >= 2) {
types.push('shooter');
}
if (game.level >= 3) {
types.push('fast');
}
if (game.level >= 5) {
types.push('tank');
}
// Spawn random enemy type
var type = types[Math.floor(Math.random() * types.length)];
game.spawnEnemy(type);
// Spawn alien ships (15% chance after level 4)
if (game.level >= 4 && Math.random() < 0.15) {
game.spawnAlienShip();
}
// Occasionally spawn obstacles (10% chance)
if (Math.random() < 0.1) {
game.spawnObstacle();
}
}
// Check boss status
if (game.bossActive) {
var bossStillActive = false;
for (var i = 0; i < game.enemies.length; i++) {
if (game.enemies[i].isBoss) {
bossStillActive = true;
break;
}
}
game.bossActive = bossStillActive;
}
// Check collisions
// Player bullets vs enemies
for (var i = game.playerBullets.length - 1; i >= 0; i--) {
var bullet = game.playerBullets[i];
// Skip destroyed bullets
if (!bullet.parent) {
game.playerBullets.splice(i, 1);
continue;
}
for (var j = game.enemies.length - 1; j >= 0; j--) {
var enemy = game.enemies[j];
// Skip destroyed enemies
if (!enemy.parent) {
game.enemies.splice(j, 1);
continue;
}
if (bullet.intersects(enemy)) {
enemy.takeDamage(bullet.damage);
bullet.destroy();
game.playerBullets.splice(i, 1);
break;
}
}
// Check alien ships
for (var j = game.alienShips.length - 1; j >= 0; j--) {
var alienShip = game.alienShips[j];
// Skip destroyed alien ships
if (!alienShip.parent) {
game.alienShips.splice(j, 1);
continue;
}
if (bullet.intersects(alienShip)) {
alienShip.takeDamage(bullet.damage);
bullet.destroy();
game.playerBullets.splice(i, 1);
break;
}
}
}
// Special attacks vs enemies
for (var i = game.specialAttacks.length - 1; i >= 0; i--) {
var special = game.specialAttacks[i];
// Skip destroyed specials
if (!special.parent) {
game.specialAttacks.splice(i, 1);
continue;
}
for (var j = game.enemies.length - 1; j >= 0; j--) {
var enemy = game.enemies[j];
// Skip destroyed enemies
if (!enemy.parent) {
game.enemies.splice(j, 1);
continue;
}
if (special.intersects(enemy)) {
enemy.takeDamage(special.damage);
}
}
// Special vs alien ships
for (var j = game.alienShips.length - 1; j >= 0; j--) {
var alienShip = game.alienShips[j];
// Skip destroyed alien ships
if (!alienShip.parent) {
game.alienShips.splice(j, 1);
continue;
}
if (special.intersects(alienShip)) {
alienShip.takeDamage(special.damage);
}
}
// Special clears enemy bullets too
for (var j = game.enemyBullets.length - 1; j >= 0; j--) {
var bullet = game.enemyBullets[j];
// Skip destroyed bullets
if (!bullet.parent) {
game.enemyBullets.splice(j, 1);
continue;
}
if (special.intersects(bullet)) {
bullet.destroy();
game.enemyBullets.splice(j, 1);
}
}
}
// Enemy bullets vs player
for (var i = game.enemyBullets.length - 1; i >= 0; i--) {
var bullet = game.enemyBullets[i];
// Skip destroyed bullets
if (!bullet.parent) {
game.enemyBullets.splice(i, 1);
continue;
}
if (bullet.intersects(game.player)) {
game.player.takeDamage();
bullet.destroy();
game.enemyBullets.splice(i, 1);
}
}
// Obstacles vs player
for (var i = game.obstacles.length - 1; i >= 0; i--) {
var obstacle = game.obstacles[i];
// Skip destroyed obstacles
if (!obstacle.parent) {
game.obstacles.splice(i, 1);
continue;
}
if (obstacle.intersects(game.player)) {
game.player.takeDamage();
obstacle.destroy();
game.obstacles.splice(i, 1);
}
}
// Powerups vs player
for (var i = game.powerups.length - 1; i >= 0; i--) {
var powerup = game.powerups[i];
// Skip destroyed powerups
if (!powerup.parent) {
game.powerups.splice(i, 1);
continue;
}
if (powerup.intersects(game.player)) {
game.player.collectPowerup(powerup);
powerup.destroy();
game.powerups.splice(i, 1);
}
}
// Remove destroyed enemies from array
for (var i = game.enemies.length - 1; i >= 0; i--) {
if (!game.enemies[i].parent) {
game.enemies.splice(i, 1);
}
}
// Update arrays of objects that might be removed
game.playerBullets = game.playerBullets.filter(function (bullet) {
return bullet.parent !== null;
});
game.enemyBullets = game.enemyBullets.filter(function (bullet) {
return bullet.parent !== null;
});
game.obstacles = game.obstacles.filter(function (obstacle) {
return obstacle.parent !== null;
});
game.powerups = game.powerups.filter(function (powerup) {
return powerup.parent !== null;
});
game.specialAttacks = game.specialAttacks.filter(function (special) {
return special.parent !== null;
});
game.alienShips = game.alienShips.filter(function (alienShip) {
return alienShip.parent !== null;
});
// Static background - no scrolling
};
// Initialize displays
game.updateScoreDisplay();
game.updateHealthDisplay();
game.updateSpecialMeter();
game.updateLevelDisplay();
// Start background music
LK.playMusic('bgm');
red robot look like gundam shoot enemy. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
amazing gold stone. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
horizontal branch of red light thunder anime style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
black hole with evil face. anime style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
green crab style alien ship. side scroller image. In-Game asset. 2d. High contrast. No shadows
panorame wied gambar hutan tropis pegunungan dan langit biru cerah gaya anime vinland saga
bio green living asteroid. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
ancient flyng red slime with talasophobia texture