User prompt
"Rotate the playerBullet's sprite/image to face left."
User prompt
undo
User prompt
"Rotate the playerBullet's sprite/image to face right."
User prompt
Rotate the enemyBullet's sprite/image to face left."
User prompt
undo
User prompt
"Rotate the enemyBullet's sprite/image to face right."
User prompt
undo
User prompt
"Rotate the enemyBullet direction to the right."
Remix started
Copy Space Defender
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { highScore: 0, level: 1 }); /**** * Classes ****/ var Asteroid = Container.expand(function () { var self = Container.call(this); // Random size asteroid var size = Math.random() * 0.7 + 0.7; // 0.7 to 1.4 var asteroidGraphics = self.attachAsset('asteroid', { anchorX: 0.5, anchorY: 0.5, scaleX: size, scaleY: size }); self.health = 30 * size; self.speed = 3 / size; // Bigger asteroids move slower self.rotationSpeed = (Math.random() - 0.5) * 0.05; self.points = Math.floor(50 * size); self.takeDamage = function (amount) { self.health -= amount; LK.effects.flashObject(self, 0x888888, 200); LK.getSound('enemyShoot', { volume: 0.5 }).play(); // Play hit sound tween(asteroidGraphics, { tint: 0xFFFFFF }, { duration: 50, onFinish: function onFinish() { asteroidGraphics.tint = 0x999999; } }); if (self.health <= 0) { self.onDestroyed(); } }; self.onDestroyed = function () { // Add points to score LK.setScore(LK.getScore() + self.points); // Create explosion var explosion = new Explosion(self.x, self.y, size); game.addChild(explosion); LK.getSound('explosion').play(); // Remove from game var index = asteroids.indexOf(self); if (index > -1) { asteroids.splice(index, 1); self.destroy(); } }; self.update = function () { self.y += self.speed; asteroidGraphics.rotation += self.rotationSpeed; // Check if asteroid is off-screen if (self.y > 2732 + 100) { var index = asteroids.indexOf(self); if (index > -1) { asteroids.splice(index, 1); self.destroy(); } } }; return self; }); var Boss = Container.expand(function () { var self = Container.call(this); var bossGraphics = self.attachAsset('boss', { anchorX: 0.5, anchorY: 0.5 }); self.health = 500; self.maxHealth = 500; self.speed = 2; self.points = 2000; self.active = false; self.phase = 1; self.directionX = 1; self.shootCooldown = 30; self.specialAttackCooldown = 300; // Health bar self.healthBar = self.attachAsset('healthBar', { anchorX: 0.5, anchorY: 0.5, y: -150 }); self.takeDamage = function (amount) { self.health -= amount; LK.effects.flashObject(self, 0xff0000, 200); LK.getSound('enemyShoot', { volume: 0.5 }).play(); // Play hit sound tween(bossGraphics, { tint: 0xFFFFFF }, { duration: 50, onFinish: function onFinish() { bossGraphics.tint = 0xff3300; } }); // Update health bar scale self.healthBar.scaleX = Math.max(0, self.health / self.maxHealth); // Phase transition at 50% health if (self.health <= self.maxHealth / 2 && self.phase === 1) { self.phase = 2; self.speed = 4; LK.effects.flashObject(self, 0xff00ff, 1000); // Purple flash for phase transition } if (self.health <= 0) { self.onDestroyed(); } }; self.onDestroyed = function () { // Add points to score LK.setScore(LK.getScore() + self.points); // Create multiple explosions for (var i = 0; i < 8; i++) { var explosionX = self.x + (Math.random() * 300 - 150); var explosionY = self.y + (Math.random() * 200 - 100); var explosion = new Explosion(explosionX, explosionY, 2); game.addChild(explosion); // Stagger the explosions (function (delay) { LK.setTimeout(function () { LK.getSound('explosion').play(); }, delay * 200); })(i); } // Complete level level++; if (level > storage.level) { storage.level = level; } // Check high score if (LK.getScore() > storage.highScore) { storage.highScore = LK.getScore(); } // Show win screen LK.showYouWin(); // Remove from game var index = bosses.indexOf(self); if (index > -1) { bosses.splice(index, 1); self.destroy(); } }; self.shoot = function () { // Basic attack - 3 bullets for (var i = -1; i <= 1; i++) { var bullet = new EnemyBullet(); bullet.x = self.x + i * 80; bullet.y = self.y + 100; game.addChild(bullet); enemyBullets.push(bullet); } LK.getSound('enemyShoot').play(); }; self.specialAttack = function () { // Special attack based on phase if (self.phase === 1) { // Phase 1: Circle of 8 bullets for (var i = 0; i < 8; i++) { var angle = i / 8 * Math.PI * 2; var bullet = new EnemyBullet(); bullet.x = self.x + Math.cos(angle) * 100; bullet.y = self.y + Math.sin(angle) * 100; bullet.directionX = Math.cos(angle); bullet.directionY = Math.sin(angle); game.addChild(bullet); enemyBullets.push(bullet); } } else { // Phase 2: Targeted volley at player for (var i = 0; i < 5; i++) { var bullet = new EnemyBullet(); bullet.x = self.x; bullet.y = self.y + 100; // Target the player var dx = player.x - bullet.x; var dy = player.y - bullet.y; var dist = Math.sqrt(dx * dx + dy * dy); bullet.directionX = dx / dist; bullet.directionY = dy / dist; bullet.speed = 8 + i; game.addChild(bullet); enemyBullets.push(bullet); // Timeout was empty and served no purpose, bullet already added. } } LK.getSound('enemyShoot').play(); }; self.update = function () { if (!self.active) { return; } // Movement self.x += self.speed * self.directionX; // Bounce at screen edges if (self.x < 300) { self.x = 300; self.directionX = 1; } else if (self.x > 2048 - 300) { self.x = 2048 - 300; self.directionX = -1; } // Regular attacks self.shootCooldown--; if (self.shootCooldown <= 0) { self.shoot(); self.shootCooldown = self.phase === 1 ? 60 : 40; } // Special attacks self.specialAttackCooldown--; if (self.specialAttackCooldown <= 0) { self.specialAttack(); self.specialAttackCooldown = 300; } }; self.activate = function () { self.active = true; }; return self; }); var Enemy = Container.expand(function () { var self = Container.call(this); var enemyGraphics = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5 }); self.health = 20; self.speed = 2; self.shootCooldown = Math.floor(Math.random() * 120) + 60; self.points = 100; self.movementPattern = "straight"; // Default movement pattern self.directionX = 0; self.directionChangeTimer = 0; self.takeDamage = function (amount) { self.health -= amount; LK.effects.flashObject(self, 0xff0000, 200); LK.getSound('enemyShoot', { volume: 0.5 }).play(); // Play hit sound tween(enemyGraphics, { tint: 0xFFFFFF }, { duration: 50, onFinish: function onFinish() { enemyGraphics.tint = 0xff0000; } }); if (self.health <= 0) { self.onDestroyed(); } }; self.onDestroyed = function () { // Add points to score LK.setScore(LK.getScore() + self.points); // Create explosion var explosion = new Explosion(self.x, self.y, 1); game.addChild(explosion); LK.getSound('explosion').play(); // Increment enemies defeated count for level progression enemiesDefeated++; // Remove from game first var index = enemies.indexOf(self); if (index > -1) { enemies.splice(index, 1); // Check if should drop powerup (20% chance) after removal is confirmed if (Math.random() < 0.2) { var powerup = new Powerup(); powerup.x = self.x; powerup.y = self.y; game.addChild(powerup); powerups.push(powerup); } // Remove from game self.destroy(); } }; self.shoot = function () { var bullet = new EnemyBullet(); bullet.x = self.x; bullet.y = self.y + 50; game.addChild(bullet); enemyBullets.push(bullet); LK.getSound('enemyShoot').play(); }; self.setMovementPattern = function (pattern) { self.movementPattern = pattern; if (pattern === "zigzag") { self.directionX = Math.random() < 0.5 ? -1 : 1; self.speed = 3; } else if (pattern === "circle") { self.angle = Math.random() * Math.PI * 2; self.centerX = self.x; self.centerY = self.y; self.radius = 100; self.speed = 0.02; } else if (pattern === "sine") { self.startX = self.x; self.amplitude = 150; self.frequency = 0.01; self.angle = Math.random() * Math.PI * 2; } }; self.update = function () { // Movement based on pattern if (self.movementPattern === "straight") { self.y += self.speed; } else if (self.movementPattern === "zigzag") { self.y += self.speed; self.x += self.speed * 2 * self.directionX; self.directionChangeTimer++; if (self.directionChangeTimer > 60) { self.directionX *= -1; self.directionChangeTimer = 0; } // Bounce off screen edges if (self.x < 50) { self.x = 50; self.directionX = 1; } else if (self.x > 2048 - 50) { self.x = 2048 - 50; self.directionX = -1; } } else if (self.movementPattern === "circle") { self.angle += self.speed; self.x = self.centerX + Math.cos(self.angle) * self.radius; self.y = self.centerY + Math.sin(self.angle) * self.radius + self.speed * 20; } else if (self.movementPattern === "sine") { self.y += self.speed * 2; self.angle += self.frequency; self.x = self.startX + Math.sin(self.angle) * self.amplitude; } // Shooting self.shootCooldown--; if (self.shootCooldown <= 0) { self.shoot(); self.shootCooldown = Math.floor(Math.random() * 120) + 120; } // Remove if off screen if (self.y > 2732 + 100) { var index = enemies.indexOf(self); if (index > -1) { enemies.splice(index, 1); self.destroy(); } } }; return self; }); var EnemyBullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('enemyBullet', { anchorX: 0.5, anchorY: 0.5 }); bulletGraphics.rotation = Math.PI * 1.5; self.speed = 8; self.damage = 10; self.directionX = 0; self.directionY = 1; self.update = function () { // Move based on direction self.x += self.directionX * self.speed; self.y += self.directionY * self.speed; // Check if bullet is off-screen if (self.y > 2732 + 50 || self.y < -50 || self.x < -50 || self.x > 2048 + 50) { self.removeFromGame(); } }; self.removeFromGame = function () { var index = enemyBullets.indexOf(self); if (index > -1) { enemyBullets.splice(index, 1); self.destroy(); } }; return self; }); var Explosion = Container.expand(function (x, y, size) { var self = Container.call(this); self.x = x; self.y = y; var explosionGraphics = self.attachAsset('explosion', { anchorX: 0.5, anchorY: 0.5, scaleX: size || 1, scaleY: size || 1, alpha: 0.9 }); // Animation for explosion self.duration = 30; // 0.5 seconds at 60fps self.timer = 0; self.update = function () { self.timer++; // Scale up and fade out var progress = self.timer / self.duration; explosionGraphics.scaleX = (size || 1) * (1 + progress); explosionGraphics.scaleY = (size || 1) * (1 + progress); explosionGraphics.alpha = 1 - progress; if (self.timer >= self.duration) { self.destroy(); } }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); self.health = 100; self.speed = 15; self.shootCooldown = 0; self.invulnerable = false; self.powerupTimer = 0; self.powerupActive = false; self.takeDamage = function (amount) { if (self.invulnerable) { return; } self.health -= amount; LK.getSound('enemyShoot', { volume: 0.7 }).play(); // Play player hit sound if (self.health <= 0) { self.health = 0; self.onDestroyed(); } else { // Flash player when hit self.invulnerable = true; LK.effects.flashObject(self, 0xffffff, 500); // Screen shake on hit LK.effects.flashScreen(0xFF0000, 300); // Create small explosions around player for visual feedback for (var i = 0; i < 3; i++) { var explosionX = self.x + (Math.random() * 150 - 75); var explosionY = self.y + (Math.random() * 150 - 75); var smallExplosion = new Explosion(explosionX, explosionY, 0.5); game.addChild(smallExplosion); } LK.setTimeout(function () { self.invulnerable = false; }, 1000); } }; self.applyPowerup = function () { self.powerupActive = true; self.powerupTimer = 300; // 5 seconds at 60fps playerGraphics.tint = 0x00ff00; // Green tint for powered up LK.getSound('powerup').play(); // Visual effect for power-up tween(playerGraphics, { alpha: 0.5, scaleX: 1.2, scaleY: 1.2 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(playerGraphics, { alpha: 1, scaleX: 1, scaleY: 1 }, { duration: 200, easing: tween.easeOut }); } }); // Create a powerup aura if (!self.powerupAura) { self.powerupAura = LK.getAsset('powerup', { anchorX: 0.5, anchorY: 0.5, scaleX: 2, scaleY: 2, alpha: 0.3, tint: 0x00FFAA }); self.addChild(self.powerupAura); } else { self.powerupAura.alpha = 0.3; } }; self.shoot = function () { if (self.shootCooldown <= 0) { var bullet = new PlayerBullet(); bullet.x = self.x; bullet.y = self.y - 70; game.addChild(bullet); bullets.push(bullet); LK.getSound('playerShoot').play(); // If powered up, shoot 3 bullets instead of 1 if (self.powerupActive) { var bulletLeft = new PlayerBullet(); bulletLeft.x = self.x - 40; bulletLeft.y = self.y - 50; var bulletRight = new PlayerBullet(); bulletRight.x = self.x + 40; bulletRight.y = self.y - 50; game.addChild(bulletLeft); game.addChild(bulletRight); bullets.push(bulletLeft); bullets.push(bulletRight); } self.shootCooldown = self.powerupActive ? 10 : 15; } }; self.onDestroyed = function () { var explosion = new Explosion(self.x, self.y, 2); game.addChild(explosion); LK.getSound('explosion').play(); // Show game over LK.showGameOver(); }; self.update = function () { if (self.shootCooldown > 0) { self.shootCooldown--; } if (self.powerupActive) { self.powerupTimer--; // Animate the powerup aura if (self.powerupAura) { self.powerupAura.rotation += 0.02; // Pulse the aura self.powerupAuraTime = (self.powerupAuraTime || 0) + 0.05; self.powerupAura.alpha = 0.2 + Math.sin(self.powerupAuraTime) * 0.1; self.powerupAura.scale.set(1.8 + Math.sin(self.powerupAuraTime) * 0.2); } // Warning animation when powerup is about to expire if (self.powerupTimer < 60) { // Flash the player when powerup is about to end playerGraphics.alpha = 0.5 + Math.sin(self.powerupTimer * 0.2) * 0.5; } if (self.powerupTimer <= 0) { self.powerupActive = false; playerGraphics.alpha = 1; // Remove powerup aura if (self.powerupAura) { self.powerupAura.destroy(); self.powerupAura = null; } // Reset powerup aura animation timer - Redundant as aura is destroyed // self.powerupAuraTime = 0; // The aura is already destroyed above, removing duplicate block. } } }; return self; }); var PlayerBullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('playerBullet', { anchorX: 0.5, anchorY: 0.5 }); bulletGraphics.rotation = Math.PI / 2; self.speed = -15; // Move upwards self.damage = 10; self.update = function () { self.y += self.speed; // Check if bullet is off-screen if (self.y < -50) { self.removeFromGame(); } }; self.removeFromGame = function () { var index = bullets.indexOf(self); if (index > -1) { bullets.splice(index, 1); self.destroy(); } }; 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.pulsateTimer = 0; self.update = function () { self.y += self.speed; // Pulsate effect self.pulsateTimer += 0.05; var scale = 1 + Math.sin(self.pulsateTimer) * 0.2; powerupGraphics.scaleX = scale; powerupGraphics.scaleY = scale; powerupGraphics.alpha = 0.7 + Math.sin(self.pulsateTimer) * 0.3; // Pulsate alpha // Remove if off screen if (self.y > 2732 + 50) { self.removeFromGame(); } }; self.removeFromGame = function () { var index = powerups.indexOf(self); if (index > -1) { powerups.splice(index, 1); self.destroy(); } }; self.alpha = 0; self.scale.set(0.5); tween(self, { alpha: 1, scaleX: 1, scaleY: 1 }, { duration: 300, easing: tween.easeOut }); return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000011 // Deep space blue }); /**** * Game Code ****/ // Game state variables var player; var bullets = []; var enemies = []; var enemyBullets = []; var asteroids = []; var powerups = []; var bosses = []; var level = storage.level || 1; var enemySpawnTimer = 0; var asteroidSpawnTimer = 0; var bossSpawned = false; var gameStarted = false; var levelEnemiesRequired; var enemiesDefeated = 0; var dragNode = null; // Set up UI var scoreTxt = new Text2('Score: 0', { size: 70, fill: 0xFFFFFF }); scoreTxt.anchor.set(1, 0); // Anchor top-right scoreTxt.x = -20; // Padding from right edge scoreTxt.y = 20; // Padding from top edge LK.gui.topRight.addChild(scoreTxt); var highScoreTxt = new Text2('High Score: ' + storage.highScore, { size: 60, // Increased size fill: 0xFFFFFF }); highScoreTxt.anchor.set(1, 0); // Anchor top-right highScoreTxt.x = -20; // Align with scoreTxt padding highScoreTxt.y = scoreTxt.y + scoreTxt.height + 10; // Position below scoreTxt LK.gui.topRight.addChild(highScoreTxt); var levelTxt = new Text2('Level: ' + level, { size: 70, fill: 0xFFFFFF }); levelTxt.anchor.set(0, 0); // Anchor top-left now LK.gui.topLeft.addChild(levelTxt); levelTxt.x = 120; // Move slightly right from absolute left levelTxt.y = 20; // Move slightly down from absolute top, matching score padding // Add Glaud text var glaudTxt = new Text2('Glaud', { size: 40, // Small size fill: 0xFF8C00 // Orange color }); glaudTxt.anchor.set(0, 0); // Anchor top-left // Position below levelTxt glaudTxt.x = levelTxt.x; glaudTxt.y = levelTxt.y + levelTxt.height + 10; // 10px padding below LK.gui.topLeft.addChild(glaudTxt); var healthBar = LK.getAsset('healthBar', { anchorX: 0, anchorY: 0.5, scaleX: 1, scaleY: 0.6 }); // Center the health bar horizontally relative to the bottom-center anchor healthBar.x = 0; // Position the bar slightly up from the absolute bottom edge healthBar.y = -50; LK.gui.bottom.addChild(healthBar); var healthTxt = new Text2('Health', { size: 60, fill: 0xFFFFFF }); healthTxt.anchor.set(0.5, 1); // Anchor bottom-center // Position text centered horizontally, just above the health bar healthTxt.x = healthBar.x; healthTxt.y = healthBar.y - healthBar.height * healthBar.scaleY / 2 - 10; LK.gui.bottom.addChild(healthTxt); // Progress bar for level completion var progressBarBg = LK.getAsset('healthBar', { anchorX: 0.5, anchorY: 0.5, scaleX: 1, scaleY: 0.4, tint: 0x555555 }); progressBarBg.x = 2048 / 2; progressBarBg.y = 100; LK.gui.top.addChild(progressBarBg); var progressBar = LK.getAsset('healthBar', { anchorX: 0, anchorY: 0.5, scaleX: 0, scaleY: 0.3, tint: 0x00FFFF }); progressBar.x = 2048 / 2 - progressBarBg.width / 2; progressBar.y = 100; LK.gui.top.addChild(progressBar); var progressTxt = new Text2('Progress', { size: 50, // Increased size fill: 0xFFFFFF }); progressTxt.anchor.set(0.5, 1); // Anchor bottom-center progressTxt.x = progressBarBg.x; // Position text above the background bar progressTxt.y = progressBarBg.y - progressBarBg.height * progressBarBg.scaleY / 2 - 15; LK.gui.top.addChild(progressTxt); // Initialize player function initPlayer() { player = new Player(); player.x = 2048 / 2; player.y = 2732 + 100; // Start off-screen game.addChild(player); // Animate player entrance tween(player, { y: 2732 - 200, alpha: 1 }, { duration: 1000, easing: tween.easeOutBack }); } // Initialize level function initLevel() { // Clear any existing enemies and bullets for (var i = enemies.length - 1; i >= 0; i--) { enemies[i].destroy(); } for (var i = enemyBullets.length - 1; i >= 0; i--) { enemyBullets[i].destroy(); } for (var i = asteroids.length - 1; i >= 0; i--) { asteroids[i].destroy(); } for (var i = powerups.length - 1; i >= 0; i--) { powerups[i].destroy(); } for (var i = bosses.length - 1; i >= 0; i--) { bosses[i].destroy(); } enemies = []; enemyBullets = []; asteroids = []; powerups = []; bosses = []; bossSpawned = false; enemiesDefeated = 0; // Set level difficulty levelEnemiesRequired = level * 15; enemySpawnTimer = 60; asteroidSpawnTimer = 180; // Update UI levelTxt.setText('Level: ' + level); // Stop pulsating effect on progress text if active if (progressTxt.pulsating) { tween.cancel(progressTxt.scale); tween.cancel(progressTxt); progressTxt.scale.set(1); progressTxt.alpha = 1; progressTxt.pulsating = false; } // Start music LK.playMusic('bgMusic'); } // Spawn enemy with random pattern function spawnEnemy() { var enemy = new Enemy(); // Random x position enemy.x = Math.random() * (2048 - 200) + 100; enemy.y = -100; // Set health and pattern based on level enemy.health = 20 + level * 5; // Choose movement pattern var patterns = ["straight", "zigzag", "sine"]; if (level >= 3) { patterns.push("circle"); } var pattern = patterns[Math.floor(Math.random() * patterns.length)]; enemy.setMovementPattern(pattern); // Add spawn animation enemy.alpha = 0; enemy.scale.set(0.5); game.addChild(enemy); enemies.push(enemy); // Animate entrance tween(enemy, { alpha: 1, scaleX: 1, scaleY: 1 }, { duration: 500, easing: tween.easeOutBack }); } // Spawn asteroid function spawnAsteroid() { var asteroid = new Asteroid(); // Random x position asteroid.x = Math.random() * (2048 - 200) + 100; asteroid.y = -100; game.addChild(asteroid); asteroids.push(asteroid); // Add entry animation asteroid.alpha = 0.5; tween(asteroid, { alpha: 1, rotation: Math.random() * Math.PI * 2 }, { duration: 800, easing: tween.easeOut }); } // Spawn boss function spawnBoss() { var boss = new Boss(); boss.x = 2048 / 2; boss.y = 300; // Adjust boss health based on level boss.health = 500 + level * 100; boss.maxHealth = boss.health; game.addChild(boss); bosses.push(boss); LK.getSound('explosion', { volume: 0.8 }).play(); // Play boss spawn sound // Activate boss after entrance animation tween(boss, { y: 300 }, { duration: 2000, easing: tween.easeOutBack, onFinish: function onFinish() { boss.activate(); } }); } // Check collisions function checkCollisions() { // Player bullets vs enemies for (var i = bullets.length - 1; i >= 0; i--) { var bullet = bullets[i]; // Check against enemies for (var j = enemies.length - 1; j >= 0; j--) { var enemy = enemies[j]; if (bullet.intersects(enemy)) { // Create small impact effect var impact = new Explosion(bullet.x, bullet.y, 0.3); impact.duration = 15; // Shorter duration for impact game.addChild(impact); enemy.takeDamage(bullet.damage); bullet.removeFromGame(); break; } } // Check against asteroids for (var j = asteroids.length - 1; j >= 0; j--) { var asteroid = asteroids[j]; if (bullet.intersects(asteroid)) { // Create small impact effect var impact = new Explosion(bullet.x, bullet.y, 0.3); impact.duration = 15; // Shorter duration for impact game.addChild(impact); asteroid.takeDamage(bullet.damage); bullet.removeFromGame(); break; } } // Check against bosses for (var j = bosses.length - 1; j >= 0; j--) { var boss = bosses[j]; if (bullet.intersects(boss) && boss.active) { // Create small impact effect var impact = new Explosion(bullet.x, bullet.y, 0.3); impact.duration = 15; // Shorter duration for impact game.addChild(impact); boss.takeDamage(bullet.damage); bullet.removeFromGame(); break; } } } // Enemy bullets vs player for (var i = enemyBullets.length - 1; i >= 0; i--) { var bullet = enemyBullets[i]; if (bullet.intersects(player)) { player.takeDamage(bullet.damage); bullet.removeFromGame(); } } // Player vs enemies for (var i = enemies.length - 1; i >= 0; i--) { var enemy = enemies[i]; if (player.intersects(enemy)) { player.takeDamage(20); enemy.takeDamage(enemy.health); // Destroy enemy } } // Player vs asteroids for (var i = asteroids.length - 1; i >= 0; i--) { var asteroid = asteroids[i]; if (player.intersects(asteroid)) { player.takeDamage(30); asteroid.takeDamage(asteroid.health); // Destroy asteroid } } // Player vs powerups for (var i = powerups.length - 1; i >= 0; i--) { var powerup = powerups[i]; if (player.intersects(powerup)) { // Remove the powerup first to prevent potential multiple applications powerup.removeFromGame(); // Then apply the effect player.applyPowerup(); } } } // Handle player movement function handleDrag(x, y) { if (dragNode) { dragNode.x = x; dragNode.y = y; // Constrain player to screen bounds if (dragNode.x < 50) { dragNode.x = 50; } if (dragNode.x > 2048 - 50) { dragNode.x = 2048 - 50; } if (dragNode.y < 50) { dragNode.y = 50; } if (dragNode.y > 2732 - 50) { dragNode.y = 2732 - 50; } } } // Event handlers game.down = function (x, y, obj) { // Only set drag if we're started if (gameStarted) { dragNode = player; handleDrag(x, y); } else { // Start game on first touch gameStarted = true; initPlayer(); initLevel(); } }; game.up = function (x, y, obj) { dragNode = null; }; game.move = function (x, y, obj) { handleDrag(x, y); }; // Main game update loop game.update = function () { if (!gameStarted) { // Show start screen text if (!game.startText) { game.startText = new Text2('Tap to Start\nSpace Defender', { size: 150, fill: 0xFFFFFF }); game.startText.anchor.set(0.5, 0.5); game.startText.x = 2048 / 2; game.startText.y = 2732 / 2; game.addChild(game.startText); // Add background stars for start screen game.stars = []; for (var i = 0; i < 50; i++) { var star = LK.getAsset('playerBullet', { anchorX: 0.5, anchorY: 0.5, scaleX: Math.random() * 0.3 + 0.1, scaleY: Math.random() * 0.3 + 0.1, alpha: Math.random() * 0.7 + 0.3, tint: 0xFFFFFF }); star.x = Math.random() * 2048; star.y = Math.random() * 2732; star.speed = Math.random() * 2 + 1; game.addChild(star); game.stars.push(star); } // Add pulsating effect to start text game.pulseValue = 0; // Add pulsing to the start text using tween tween(game.startText, { alpha: 0.5 }, { duration: 1000, easing: tween.easeInOut, loop: true, yoyo: true }); } // Animate stars in start screen if (game.stars) { // Manual scaling removed, handled by tween animation // game.pulseValue += 0.05; // game.startText.scale.set(1 + Math.sin(game.pulseValue) * 0.05); for (var i = 0; i < game.stars.length; i++) { var star = game.stars[i]; star.y += star.speed; if (star.y > 2732) { star.y = 0; star.x = Math.random() * 2048; } } } return; } else if (game.startText) { game.startText.destroy(); game.startText = null; // Clean up stars if (game.stars) { for (var i = 0; i < game.stars.length; i++) { game.stars[i].destroy(); } game.stars = null; } } // Update UI scoreTxt.setText('Score: ' + LK.getScore()); // Update high score if needed if (LK.getScore() > storage.highScore) { storage.highScore = LK.getScore(); highScoreTxt.setText('High Score: ' + storage.highScore); } // Update progress bar if (!bossSpawned) { var progress = enemiesDefeated / levelEnemiesRequired; progressBar.scaleX = progress; progressTxt.setText('Level Progress: ' + Math.floor(progress * 100) + '%'); } else { progressTxt.setText('BOSS FIGHT!'); if (!progressTxt.pulsating) { progressTxt.pulsating = true; tween(progressTxt.scale, { x: 1.2, y: 1.2 }, { duration: 300, easing: tween.easeInOut, loop: true, yoyo: true }); tween(progressTxt, { alpha: 0.5 }, { duration: 300, easing: tween.easeInOut, loop: true, yoyo: true }); } progressBar.tint = 0xFF0000; progressBar.scaleX = 1; } if (player) { // Update health bar healthBar.scaleX = Math.max(0, player.health / 100); // Auto-fire player.shoot(); } // Spawn enemies if (!bossSpawned) { enemySpawnTimer--; if (enemySpawnTimer <= 0) { spawnEnemy(); // Spawn rate increases with level enemySpawnTimer = Math.max(20, 100 - level * 10); } // Spawn asteroids asteroidSpawnTimer--; if (asteroidSpawnTimer <= 0) { spawnAsteroid(); asteroidSpawnTimer = Math.max(60, 300 - level * 20); } // Check if we should spawn boss if (enemiesDefeated >= levelEnemiesRequired) { bossSpawned = true; spawnBoss(); } } // Update all game objects for (var i = bullets.length - 1; i >= 0; i--) { bullets[i].update(); } for (var i = enemies.length - 1; i >= 0; i--) { enemies[i].update(); } for (var i = enemyBullets.length - 1; i >= 0; i--) { enemyBullets[i].update(); } for (var i = asteroids.length - 1; i >= 0; i--) { asteroids[i].update(); } for (var i = powerups.length - 1; i >= 0; i--) { powerups[i].update(); } for (var i = bosses.length - 1; i >= 0; i--) { bosses[i].update(); } // Check for collisions checkCollisions(); }; // Start game music LK.playMusic('bgMusic', { fade: { start: 0, end: 0.3, duration: 1000 } });
===================================================================
--- original.js
+++ change.js
@@ -563,8 +563,9 @@
var bulletGraphics = self.attachAsset('playerBullet', {
anchorX: 0.5,
anchorY: 0.5
});
+ bulletGraphics.rotation = Math.PI / 2;
self.speed = -15; // Move upwards
self.damage = 10;
self.update = function () {
self.y += self.speed;
enemyBullet. In-Game asset. 2d. High contrast. No shadows
playerBullet. In-Game asset. 2d. High contrast. No shadows
powerup. In-Game asset. 2d. High contrast. No shadows
asteroid. In-Game asset. 2d. High contrast. No shadows
big boss spaceship. In-Game asset. 2d. High contrast. No shadows. In-Game asset. 2d. High contrast. No shadows
explosion. In-Game asset. 2d. High contrast. No shadows. In-Game asset. 2d. High contrast. No shadows
spaceship enemy. In-Game asset. 2d. High contrast. No shadows. In-Game asset. 2d. High contrast. No shadows