User prompt
Double the player's health.
User prompt
When you kill an enemy it gives you 10 coins ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Delete the attack button. When you move, it makes you attack.
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'if (player.isMoving && x < 2048 / 2) {' Line Number: 1031
User prompt
Show a health bar on the top of your screen and add waves. After you defeat 5 waves, you win the game.
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'shootButton.up();' Line Number: 994
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'player.targetX = x;' Line Number: 958
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'shootButton.down(x, y);' Line Number: 964
User prompt
Please fix the bug: 'TypeError: undefined is not an object (evaluating 'player.update')' in or related to this line: 'player.update();' Line Number: 1002
User prompt
Make a home screen with a start button and a shop. Each time you kill an enemy, it gives you 2 points. ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Use your finger to move the player and delete the joystick.
User prompt
Make the joystick move the player.
Code edit (1 edits merged)
Please save this source code
User prompt
Space Defender
Initial prompt
Add a joystick and a shoot button, player and a gun.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Asteroid = Container.expand(function () { var self = Container.call(this); var size = 60 + Math.floor(Math.random() * 60); var asteroidGraphics = self.attachAsset('asteroid', { anchorX: 0.5, anchorY: 0.5, scaleX: size / 60, scaleY: size / 60 }); self.health = 20 + Math.floor(size / 10); self.speed = 1 + Math.random() * 3; self.rotationSpeed = (Math.random() - 0.5) * 0.05; self.points = 50; self.update = function () { self.y += self.speed; asteroidGraphics.rotation += self.rotationSpeed; // Check if asteroid is off-screen if (self.y > 2832) { return true; // Mark for removal } return false; }; self.damage = function (amount) { self.health -= amount; LK.effects.flashObject(self, 0xffffff, 100); if (self.health <= 0) { LK.getSound('explosion').play(); return true; // Asteroid destroyed } return false; }; 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.update = function () { self.y += self.speed; // Check if bullet is off-screen if (self.y > 2832) { return true; // Mark for removal } return false; }; return self; }); var EnemyShip = Container.expand(function () { var self = Container.call(this); var shipGraphics = self.attachAsset('enemyShip', { anchorX: 0.5, anchorY: 0.5 }); self.health = 30; self.type = 'standard'; self.speed = 2 + Math.random() * 2; self.points = 100; self.fireRate = 120; // Frames between shots self.fireCooldown = Math.floor(Math.random() * 60); self.update = function () { self.y += self.speed; // Check if enemy is off-screen if (self.y > 2832) { return true; // Mark for removal } // Random movement if (Math.random() < 0.02) { self.direction = Math.random() > 0.5 ? 1 : -1; } if (self.direction) { self.x += self.direction * (self.speed * 0.8); // Keep within bounds if (self.x < 100) { self.x = 100; self.direction = 1; } else if (self.x > 2048 - 100) { self.x = 2048 - 100; self.direction = -1; } } // Shooting if (self.fireCooldown <= 0) { self.fireCooldown = self.fireRate; self.shoot(); } else { self.fireCooldown--; } return false; }; self.shoot = function () { var bullet = new EnemyBullet(); bullet.x = self.x; bullet.y = self.y + 40; enemyBullets.push(bullet); game.addChild(bullet); LK.getSound('enemyShoot').play(); }; self.damage = function (amount) { self.health -= amount; LK.effects.flashObject(self, 0xffffff, 100); if (self.health <= 0) { LK.getSound('explosion').play(); return true; // Enemy destroyed } return false; }; 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; self.power = 10; self.update = function () { self.y -= self.speed; // Check if bullet is off-screen if (self.y < -50) { return true; // Mark for removal } return false; }; return self; }); var PlayerShip = Container.expand(function () { var self = Container.call(this); var shipGraphics = self.attachAsset('playerShip', { anchorX: 0.5, anchorY: 0.5 }); self.health = 100; self.fireRate = 20; // Frames between shots self.fireCooldown = 0; self.bulletSpeed = 15; self.speed = 8; self.powerLevel = 1; self.update = function () { if (self.fireCooldown > 0) { self.fireCooldown--; } }; self.damage = function (amount) { self.health -= amount; LK.effects.flashObject(self, 0xff0000, 300); if (self.health <= 0) { self.health = 0; return true; // Ship destroyed } return false; }; self.shoot = function () { if (self.fireCooldown <= 0) { self.fireCooldown = self.fireRate; LK.getSound('playerShoot').play(); // Create bullets based on power level if (self.powerLevel === 1) { // Single bullet createBullet(self.x, self.y - 40); } else if (self.powerLevel === 2) { // Double bullets createBullet(self.x - 20, self.y - 30); createBullet(self.x + 20, self.y - 30); } else { // Triple bullets createBullet(self.x, self.y - 40); createBullet(self.x - 25, self.y - 30); createBullet(self.x + 25, self.y - 30); } } }; // Helper function to create a bullet function createBullet(x, y) { var bullet = new PlayerBullet(); bullet.x = x; bullet.y = y; playerBullets.push(bullet); game.addChild(bullet); } return self; }); var PowerUp = Container.expand(function () { var self = Container.call(this); var powerUpGraphics = self.attachAsset('powerUp', { anchorX: 0.5, anchorY: 0.5 }); self.type = Math.random() < 0.7 ? 'weapon' : 'health'; self.speed = 3; // Change color based on type if (self.type === 'health') { powerUpGraphics.tint = 0x33ff33; // Green for health } else { powerUpGraphics.tint = 0xffcc33; // Yellow for weapon } self.update = function () { self.y += self.speed; // Slight bobbing motion self.x += Math.sin(LK.ticks * 0.05) * 0.5; // Check if power-up is off-screen if (self.y > 2832) { return true; // Mark for removal } return false; }; return self; }); var ShootButton = Container.expand(function () { var self = Container.call(this); var buttonGraphics = self.attachAsset('shootButton', { anchorX: 0.5, anchorY: 0.5, alpha: 0.6 }); self.pressed = false; self.down = function () { self.pressed = true; buttonGraphics.alpha = 0.9; buttonGraphics.scale.set(0.9); }; self.up = function () { self.pressed = false; buttonGraphics.alpha = 0.6; buttonGraphics.scale.set(1); }; return self; }); var VirtualJoystick = Container.expand(function () { var self = Container.call(this); var baseGraphics = self.attachAsset('joystick', { anchorX: 0.5, anchorY: 0.5, alpha: 0.6 }); var knobGraphics = self.attachAsset('joystickKnob', { anchorX: 0.5, anchorY: 0.5, alpha: 0.8 }); self.maxDistance = 80; self.active = false; self.dx = 0; self.dy = 0; self.down = function (x, y) { var localPos = self.toLocal({ x: x, y: y }); if (Math.sqrt(Math.pow(localPos.x, 2) + Math.pow(localPos.y, 2)) <= baseGraphics.width / 2) { self.active = true; self.moveKnob(localPos.x, localPos.y); } }; self.moveKnob = function (x, y) { var dist = Math.sqrt(x * x + y * y); if (dist > self.maxDistance) { x = x / dist * self.maxDistance; y = y / dist * self.maxDistance; } knobGraphics.x = x; knobGraphics.y = y; // Normalize to -1 to 1 range for movement self.dx = x / self.maxDistance; self.dy = y / self.maxDistance; }; self.move = function (x, y) { if (self.active) { var localPos = self.toLocal({ x: x, y: y }); self.moveKnob(localPos.x, localPos.y); } }; self.up = function () { self.active = false; knobGraphics.x = 0; knobGraphics.y = 0; self.dx = 0; self.dy = 0; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // Game state var gameState = 'playing'; var wave = 1; var enemySpawnTimer = 0; var asteroidSpawnTimer = 0; var waveEnemyCount = 0; var waveMaxEnemies = 10; var powerUpChance = 0.2; var touchIdentifiers = {}; // Game elements var player; var joystick; var shootButton; var playerBullets = []; var enemies = []; var enemyBullets = []; var asteroids = []; var powerUps = []; var stars = []; // UI elements var scoreText; var healthBar; var waveText; // Initialize game function initGame() { // Reset game state gameState = 'playing'; wave = 1; enemySpawnTimer = 0; asteroidSpawnTimer = 0; waveEnemyCount = 0; waveMaxEnemies = 5 + wave * 5; playerBullets = []; enemies = []; enemyBullets = []; asteroids = []; powerUps = []; touchIdentifiers = {}; // Set background game.setBackgroundColor(0x000022); // Create starfield background createStarfield(); // Create player player = new PlayerShip(); player.x = 2048 / 2; player.y = 2732 - 300; game.addChild(player); // Create controls joystick = new VirtualJoystick(); joystick.x = 300; joystick.y = 2732 - 300; game.addChild(joystick); shootButton = new ShootButton(); shootButton.x = 2048 - 300; shootButton.y = 2732 - 300; game.addChild(shootButton); // Create UI createUI(); // Start music LK.playMusic('gameMusic'); } // Create starfield background function createStarfield() { for (var i = 0; i < 100; i++) { var star = LK.getAsset('joystickKnob', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.1 + Math.random() * 0.2, scaleY: 0.1 + Math.random() * 0.2, alpha: 0.1 + Math.random() * 0.5, tint: 0xffffff }); star.x = Math.random() * 2048; star.y = Math.random() * 2732; star.speed = 0.5 + Math.random() * 2; stars.push(star); game.addChild(star); } } // Create UI elements function createUI() { // Score text scoreText = new Text2('SCORE: 0', { size: 60, fill: 0xFFFFFF }); scoreText.anchor.set(0, 0); scoreText.x = 30; scoreText.y = 30; LK.gui.addChild(scoreText); // Health bar background var healthBarBg = LK.getAsset('playerBullet', { anchorX: 0, anchorY: 0.5, scaleX: 3, scaleY: 0.5, tint: 0x444444 }); healthBarBg.x = 30; healthBarBg.y = 100; LK.gui.addChild(healthBarBg); // Health bar healthBar = LK.getAsset('playerBullet', { anchorX: 0, anchorY: 0.5, scaleX: 3, scaleY: 0.5, tint: 0x33ff33 }); healthBar.x = 30; healthBar.y = 100; LK.gui.addChild(healthBar); // Wave text waveText = new Text2('WAVE: 1', { size: 60, fill: 0xFFFFFF }); waveText.anchor.set(1, 0); waveText.x = 2048 - 30; waveText.y = 30; LK.gui.addChild(waveText); } // Spawn enemy function spawnEnemy() { var enemy = new EnemyShip(); enemy.x = 100 + Math.random() * (2048 - 200); enemy.y = -100; enemy.direction = Math.random() > 0.5 ? 1 : -1; // Adjust enemy stats based on wave enemy.health = 30 + wave * 5; enemy.speed = 2 + Math.min(wave * 0.3, 3); enemy.fireRate = Math.max(120 - wave * 5, 60); enemy.points = 100 + wave * 10; enemies.push(enemy); game.addChild(enemy); waveEnemyCount++; } // Spawn asteroid function spawnAsteroid() { var asteroid = new Asteroid(); asteroid.x = 100 + Math.random() * (2048 - 200); asteroid.y = -100; asteroids.push(asteroid); game.addChild(asteroid); } // Spawn power-up function spawnPowerUp(x, y) { var powerUp = new PowerUp(); powerUp.x = x; powerUp.y = y; powerUps.push(powerUp); game.addChild(powerUp); } // Check collisions function checkCollisions() { // Player bullets vs enemies for (var i = playerBullets.length - 1; i >= 0; i--) { var bullet = playerBullets[i]; var hitEnemy = false; // Check against enemies for (var j = enemies.length - 1; j >= 0; j--) { var enemy = enemies[j]; if (bullet.intersects(enemy)) { hitEnemy = true; if (enemy.damage(player.powerLevel * 10)) { // Enemy destroyed LK.setScore(LK.getScore() + enemy.points); scoreText.setText('SCORE: ' + LK.getScore()); // Chance to spawn power-up if (Math.random() < powerUpChance) { spawnPowerUp(enemy.x, enemy.y); } enemy.destroy(); enemies.splice(j, 1); } break; } } // Check against asteroids if bullet didn't hit an enemy if (!hitEnemy) { for (var j = asteroids.length - 1; j >= 0; j--) { var asteroid = asteroids[j]; if (bullet.intersects(asteroid)) { hitEnemy = true; if (asteroid.damage(player.powerLevel * 10)) { // Asteroid destroyed LK.setScore(LK.getScore() + asteroid.points); scoreText.setText('SCORE: ' + LK.getScore()); // Small chance to spawn power-up if (Math.random() < powerUpChance * 0.5) { spawnPowerUp(asteroid.x, asteroid.y); } asteroid.destroy(); asteroids.splice(j, 1); } break; } } } // Remove bullet if it hit something or went off-screen if (hitEnemy || bullet.update()) { bullet.destroy(); playerBullets.splice(i, 1); } } // Enemy bullets vs player for (var i = enemyBullets.length - 1; i >= 0; i--) { var bullet = enemyBullets[i]; // Check if bullet should be removed if (bullet.update()) { bullet.destroy(); enemyBullets.splice(i, 1); continue; } // Check against player if (gameState === 'playing' && bullet.intersects(player)) { if (player.damage(bullet.damage)) { // Player destroyed gameOver(); } // Update health bar updateHealthBar(); // Remove bullet bullet.destroy(); enemyBullets.splice(i, 1); } } // Enemies vs player for (var i = enemies.length - 1; i >= 0; i--) { var enemy = enemies[i]; // Check if enemy should be removed if (enemy.update()) { enemy.destroy(); enemies.splice(i, 1); continue; } // Check against player if (gameState === 'playing' && enemy.intersects(player)) { if (player.damage(30)) { // Player destroyed gameOver(); } // Update health bar updateHealthBar(); // Destroy enemy enemy.destroy(); enemies.splice(i, 1); } } // Asteroids vs player for (var i = asteroids.length - 1; i >= 0; i--) { var asteroid = asteroids[i]; // Check if asteroid should be removed if (asteroid.update()) { asteroid.destroy(); asteroids.splice(i, 1); continue; } // Check against player if (gameState === 'playing' && asteroid.intersects(player)) { if (player.damage(20)) { // Player destroyed gameOver(); } // Update health bar updateHealthBar(); // Destroy asteroid asteroid.destroy(); asteroids.splice(i, 1); } } // Power-ups vs player for (var i = powerUps.length - 1; i >= 0; i--) { var powerUp = powerUps[i]; // Check if power-up should be removed if (powerUp.update()) { powerUp.destroy(); powerUps.splice(i, 1); continue; } // Check against player if (gameState === 'playing' && powerUp.intersects(player)) { // Apply power-up effect if (powerUp.type === 'health') { player.health = Math.min(player.health + 30, 100); updateHealthBar(); } else if (powerUp.type === 'weapon') { player.powerLevel = Math.min(player.powerLevel + 1, 3); } // Play sound LK.getSound('powerUpCollect').play(); // Remove power-up powerUp.destroy(); powerUps.splice(i, 1); } } } // Update health bar function updateHealthBar() { healthBar.scale.x = 3 * (player.health / 100); // Change color based on health if (player.health > 60) { healthBar.tint = 0x33ff33; // Green } else if (player.health > 30) { healthBar.tint = 0xffcc33; // Yellow } else { healthBar.tint = 0xff3333; // Red } } // Game over function gameOver() { gameState = 'gameover'; LK.effects.flashScreen(0xff0000, 500); LK.showGameOver(); } // Handle input game.down = function (x, y, obj) { // Store touch identifier to track multiple touches if (obj.identifier !== undefined) { touchIdentifiers[obj.identifier] = { x: x, y: y }; } // Check joystick if (x < 2048 / 2) { joystick.down(x, y); } // Check shoot button if (x > 2048 / 2) { shootButton.down(x, y); player.shoot(); } }; game.move = function (x, y, obj) { // Update stored touch position if (obj.identifier !== undefined && touchIdentifiers[obj.identifier]) { touchIdentifiers[obj.identifier] = { x: x, y: y }; } // Update joystick if it's active if (joystick.active) { joystick.move(x, y); } }; game.up = function (x, y, obj) { // Remove touch identifier if (obj.identifier !== undefined) { delete touchIdentifiers[obj.identifier]; } // Release joystick and shoot button joystick.up(); shootButton.up(); }; // Main game loop game.update = function () { // Skip if game hasn't been initialized if (!player) { initGame(); return; } // Update player player.update(); // Move player based on joystick input if (joystick.active) { // Calculate the new position based on joystick input var newX = player.x + joystick.dx * player.speed; var newY = player.y + joystick.dy * player.speed; // Keep player in bounds player.x = Math.max(50, Math.min(newX, 2048 - 50)); player.y = Math.max(50, Math.min(newY, 2732 - 50)); } // Auto-fire if shoot button is pressed if (shootButton.pressed && LK.ticks % player.fireRate === 0) { player.shoot(); } // Spawn enemies if (gameState === 'playing') { // Check if wave is complete if (waveEnemyCount >= waveMaxEnemies && enemies.length === 0) { // Start new wave wave++; waveEnemyCount = 0; waveMaxEnemies = 5 + wave * 5; waveText.setText('WAVE: ' + wave); // Flash wave text tween(waveText, { scale: 1.5 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { tween(waveText, { scale: 1 }, { duration: 300, easing: tween.easeIn }); } }); } // Spawn enemies if (waveEnemyCount < waveMaxEnemies) { enemySpawnTimer++; if (enemySpawnTimer > Math.max(120 - wave * 5, 30)) { enemySpawnTimer = 0; spawnEnemy(); } } // Spawn asteroids asteroidSpawnTimer++; if (asteroidSpawnTimer > Math.max(180 - wave * 3, 60)) { asteroidSpawnTimer = 0; spawnAsteroid(); } } // Check collisions checkCollisions(); // Update starfield for (var i = 0; i < stars.length; i++) { var star = stars[i]; star.y += star.speed; if (star.y > 2732) { star.y = 0; star.x = Math.random() * 2048; } } }; // Initialize game at startup initGame();
===================================================================
--- original.js
+++ change.js
@@ -672,13 +672,14 @@
// Update player
player.update();
// Move player based on joystick input
if (joystick.active) {
- player.x += joystick.dx * player.speed;
- player.y += joystick.dy * player.speed;
+ // Calculate the new position based on joystick input
+ var newX = player.x + joystick.dx * player.speed;
+ var newY = player.y + joystick.dy * player.speed;
// Keep player in bounds
- player.x = Math.max(50, Math.min(player.x, 2048 - 50));
- player.y = Math.max(50, Math.min(player.y, 2732 - 50));
+ player.x = Math.max(50, Math.min(newX, 2048 - 50));
+ player.y = Math.max(50, Math.min(newY, 2732 - 50));
}
// Auto-fire if shoot button is pressed
if (shootButton.pressed && LK.ticks % player.fireRate === 0) {
player.shoot();