Code edit (1 edits merged)
Please save this source code
User prompt
add sound for each event.
User prompt
write a small orange “Glaud” in a logical place on the screen.
User prompt
Make the text visible on the screen. The design should be good.
User prompt
Identify and solve some basic logic errors in the game.
User prompt
Identify and solve some basic logic errors in the game.
User prompt
Identify the features that will make it better and implement them in an optimized way, don't make any mistakes, it's clean and playable. Make it a user-friendly game. ↪💡 Consider importing and using the following plugins: @upit/tween.v1, @upit/storage.v1
User prompt
Identify the features that will make it better and implement them in an optimized way, don't make any mistakes, it's clean and playable. Make it a user-friendly game.
User prompt
Identify the features that will make it better and implement them in an optimized way, don't make any mistakes, it's clean and playable. Make it a user-friendly game. ↪💡 Consider importing and using the following plugins: @upit/tween.v1, @upit/storage.v1
User prompt
Identify the features that will make it better and implement them in an optimized way, don't make any mistakes, it's clean and playable. Make it a user-friendly game. ↪💡 Consider importing and using the following plugins: @upit/tween.v1, @upit/storage.v1
Code edit (1 edits merged)
Please save this source code
User prompt
Space Defender
Initial prompt
game
/**** * 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); 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); 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); // Stagger the bullets slightly (function (b, delay) { LK.setTimeout(function () { game.addChild(b); enemyBullets.push(b); }, delay * 100); })(bullet, i); } } 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); 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++; // Check if should drop powerup (20% chance) 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 var index = enemies.indexOf(self); if (index > -1) { enemies.splice(index, 1); 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 }); 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; 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 self.powerupAuraTime = 0; // Remove powerup aura if (self.powerupAura) { self.powerupAura.destroy(); self.powerupAura = null; } } } }; return self; }); var PlayerBullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('playerBullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -15; // 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(); } }; 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(0, 0); LK.gui.topRight.addChild(scoreTxt); var highScoreTxt = new Text2('High Score: ' + storage.highScore, { size: 50, fill: 0xFFFFFF }); highScoreTxt.anchor.set(0, 0); highScoreTxt.y = 80; LK.gui.topRight.addChild(highScoreTxt); var levelTxt = new Text2('Level: ' + level, { size: 70, fill: 0xFFFFFF }); levelTxt.anchor.set(1, 0); LK.gui.topLeft.addChild(levelTxt); levelTxt.x = 250; // Make sure it's not in the top-left corner levelTxt.y = 50; // Adjust Y position as well var healthBar = LK.getAsset('healthBar', { anchorX: 0, anchorY: 0.5, scaleX: 1, scaleY: 0.6 }); healthBar.x = 200; LK.gui.bottom.addChild(healthBar); var healthTxt = new Text2('Health', { size: 60, fill: 0xFFFFFF }); healthTxt.anchor.set(0.5, 0.5); healthTxt.x = 100; 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: 40, fill: 0xFFFFFF }); progressTxt.anchor.set(0.5, 0.5); progressTxt.x = 2048 / 2; progressTxt.y = 40; 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); // 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)) { player.applyPowerup(); powerup.removeFromGame(); } } } // 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) { 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
@@ -26,8 +26,16 @@
self.points = Math.floor(50 * size);
self.takeDamage = function (amount) {
self.health -= amount;
LK.effects.flashObject(self, 0x888888, 200);
+ tween(asteroidGraphics, {
+ tint: 0xFFFFFF
+ }, {
+ duration: 50,
+ onFinish: function onFinish() {
+ asteroidGraphics.tint = 0x999999;
+ }
+ });
if (self.health <= 0) {
self.onDestroyed();
}
};
@@ -82,8 +90,16 @@
});
self.takeDamage = function (amount) {
self.health -= amount;
LK.effects.flashObject(self, 0xff0000, 200);
+ 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) {
@@ -227,8 +243,16 @@
self.directionChangeTimer = 0;
self.takeDamage = function (amount) {
self.health -= amount;
LK.effects.flashObject(self, 0xff0000, 200);
+ tween(enemyGraphics, {
+ tint: 0xFFFFFF
+ }, {
+ duration: 50,
+ onFinish: function onFinish() {
+ enemyGraphics.tint = 0xff0000;
+ }
+ });
if (self.health <= 0) {
self.onDestroyed();
}
};
@@ -415,17 +439,8 @@
var explosionY = self.y + (Math.random() * 150 - 75);
var smallExplosion = new Explosion(explosionX, explosionY, 0.5);
game.addChild(smallExplosion);
}
- // Add a brief visual impact to the player graphic itself
- tween(playerGraphics, {
- tint: 0xFF0000
- }, {
- duration: 100,
- onFinish: function onFinish() {
- playerGraphics.tint = 0xFFFFFF;
- }
- });
LK.setTimeout(function () {
self.invulnerable = false;
}, 1000);
}
@@ -520,15 +535,21 @@
playerGraphics.alpha = 0.5 + Math.sin(self.powerupTimer * 0.2) * 0.5;
}
if (self.powerupTimer <= 0) {
self.powerupActive = false;
- playerGraphics.tint = 0xffffff; // Reset tint
playerGraphics.alpha = 1;
// Remove powerup aura
if (self.powerupAura) {
self.powerupAura.destroy();
self.powerupAura = null;
}
+ // Reset powerup aura animation timer
+ self.powerupAuraTime = 0;
+ // Remove powerup aura
+ if (self.powerupAura) {
+ self.powerupAura.destroy();
+ self.powerupAura = null;
+ }
}
}
};
return self;
@@ -571,8 +592,9 @@
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();
}
@@ -682,10 +704,18 @@
// Initialize player
function initPlayer() {
player = new Player();
player.x = 2048 / 2;
- player.y = 2732 - 200;
+ 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
@@ -716,8 +746,16 @@
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
@@ -803,17 +841,8 @@
impact.duration = 15; // Shorter duration for impact
game.addChild(impact);
enemy.takeDamage(bullet.damage);
bullet.removeFromGame();
- // Add a brief visual impact to the enemy
- tween(enemy, {
- tint: 0xFFFFFF
- }, {
- duration: 50,
- onFinish: function onFinish() {
- enemy.tint = 0xFF0000;
- }
- });
break;
}
}
// Check against asteroids
@@ -825,17 +854,8 @@
impact.duration = 15; // Shorter duration for impact
game.addChild(impact);
asteroid.takeDamage(bullet.damage);
bullet.removeFromGame();
- // Add a brief visual impact to the asteroid
- tween(asteroid, {
- tint: 0xFFFFFF
- }, {
- duration: 50,
- onFinish: function onFinish() {
- asteroid.tint = 0x999999;
- }
- });
break;
}
}
// Check against bosses
@@ -847,17 +867,8 @@
impact.duration = 15; // Shorter duration for impact
game.addChild(impact);
boss.takeDamage(bullet.damage);
bullet.removeFromGame();
- // Add a brief visual impact to the boss
- tween(boss, {
- tint: 0xFFFFFF
- }, {
- duration: 50,
- onFinish: function onFinish() {
- boss.tint = 0xff3300;
- }
- });
break;
}
}
}
@@ -1015,9 +1026,8 @@
} else {
progressTxt.setText('BOSS FIGHT!');
if (!progressTxt.pulsating) {
progressTxt.pulsating = true;
- progressTxt.pulseValue = 0;
tween(progressTxt.scale, {
x: 1.2,
y: 1.2
}, {
@@ -1025,8 +1035,16 @@
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;
}
asteroid. In-Game asset. 2d. High contrast. No shadows
spaceship enemy. In-Game asset. 2d. High contrast. No shadows
enemyBullet. In-Game asset. 2d. High contrast. No shadows
playerBullet. In-Game asset. 2d. High contrast. No shadows
explosion. In-Game asset. 2d. High contrast. No shadows
powerup. In-Game asset. 2d. High contrast. No shadows
boss spaceship. In-Game asset. 2d. High contrast. No shadows