User prompt
each hits removes one life
User prompt
tap to start at the begining
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'setText')' in or related to this line: 'scoreTxt.setText(LK.getScore());' Line Number: 404
User prompt
Please fix the bug: 'Uncaught ReferenceError: dragNode is not defined' in or related to this line: 'if (dragNode === player) {' Line Number: 268
User prompt
Please fix the bug: 'ReferenceError: enemyShootingEnabled is not defined' in or related to this line: 'enemy.shootCooldown = enemyShootingEnabled ? enemyShootInterval + Math.floor(Math.random() * 30) : 120 + Math.floor(Math.random() * 60);' Line Number: 322
User prompt
Please fix the bug: 'ReferenceError: spawnTimer is not defined' in or related to this line: 'spawnTimer--;' Line Number: 533
User prompt
Please fix the bug: 'ReferenceError: playerBullets is not defined' in or related to this line: 'for (var i = playerBullets.length - 1; i >= 0; i--) {' Line Number: 354
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'setText')' in or related to this line: 'powerupCountdownTxt.setText('');' Line Number: 345
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'setText')' in or related to this line: 'livesTxt.setText(livesStr);' Line Number: 336
User prompt
put a logo at the begining and press mouse to start
User prompt
ship not visible
User prompt
ı cant see my ship
User prompt
put a logo in begining
User prompt
each hit takes one life
User prompt
game ends when three lives gone
User prompt
each enemy shall decrease only one life
User prompt
there shall be three lives
User prompt
enemies shoot after 200 points
User prompt
Please fix the bug: 'TypeError: tween.to is not a function' in or related to this line: 'tween.to(explosion, {' Line Number: 311 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
expolsion when hit
User prompt
spawn new ship after 600
User prompt
no need for pressing mouse button
User prompt
Please fix the bug: 'storage.getItem is not a function' in or related to this line: 'var highscore = storage.getItem("highscore") || 0;' Line Number: 158 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Please fix the bug: 'storage.get is not a function' in or related to this line: 'var highscore = storage.get("highscore") || 0;' Line Number: 158
User prompt
keep highscore
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ // Enemy Bullet var EnemyBullet = Container.expand(function () { var self = Container.call(this); var bullet = self.attachAsset('enemyBullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 18; self.update = function () { self.y += self.speed; }; return self; }); // Enemy Ship var EnemyShip = Container.expand(function () { var self = Container.call(this); var ship = self.attachAsset('enemyShip', { anchorX: 0.5, anchorY: 0.5 }); self.width = ship.width; self.height = ship.height; self.speed = 4 + Math.random() * 2; self.shootCooldown = 60 + Math.floor(Math.random() * 60); self.shootTimer = Math.floor(Math.random() * self.shootCooldown); self.hp = 1; self.update = function () { self.y += self.speed; if (self.shootTimer > 0) { self.shootTimer--; } }; return self; }); // Player Bullet var PlayerBullet = Container.expand(function () { var self = Container.call(this); var bullet = self.attachAsset('playerBullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -32; self.update = function () { self.y += self.speed; }; return self; }); // Player Ship var PlayerShip = Container.expand(function () { var self = Container.call(this); var ship = self.attachAsset('playerShip', { anchorX: 0.5, anchorY: 0.5 }); self.width = ship.width; self.height = ship.height; self.canShoot = true; self.shootCooldown = 24; // frames between shots (reduced fire rate) self.shootTimer = 0; // self.lives = 1; // For MVP, 1 hit = game over self.poweredUp = false; self.powerupTimer = 0; // Power-up effect self.setPowerup = function (duration) { self.poweredUp = true; self.powerupTimer = duration; ship.tint = 0x00ff99; }; self.clearPowerup = function () { self.poweredUp = false; self.powerupTimer = 0; ship.tint = 0xffffff; }; self.update = function () { if (self.shootTimer > 0) self.shootTimer--; if (self.poweredUp) { self.powerupTimer--; if (self.powerupTimer <= 0) { self.clearPowerup(); } } }; return self; }); // Powerup var Powerup = Container.expand(function () { var self = Container.call(this); var p = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 8; self.update = function () { self.y += self.speed; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000010 }); /**** * Game Code ****/ // --- LOGO SPLASH AND PRESS TO START --- // Add starfield background image var background = LK.getAsset('starfield', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, scaleX: 2048 / 1024, scaleY: 2732 / 1366 }); game.addChild(background); // Add logo (centered, large) var logo = new Text2('SPACE SHOOTER', { size: 220, fill: 0xFFFFFF, font: "Impact, 'Arial Black', Tahoma" }); logo.anchor.set(0.5, 0.5); logo.x = 2048 / 2; logo.y = 2732 / 2 - 200; game.addChild(logo); // Add "Press to Start" text var pressToStart = new Text2('Tap to Start', { size: 120, fill: 0x00ff99, font: "Impact, 'Arial Black', Tahoma" }); pressToStart.anchor.set(0.5, 0.5); pressToStart.x = 2048 / 2; pressToStart.y = 2732 / 2 + 200; game.addChild(pressToStart); // Hide game UI until started var scoreTxt, highscore, highscoreTxt, powerupCountdownTxt, livesTxt; var gameStarted = false; // Define main game arrays in global scope to avoid ReferenceError var playerBullets = []; var enemies = []; var enemyBullets = []; var powerups = []; // Define dragNode in global scope to avoid ReferenceError var dragNode = null; // Define spawn timers in global scope to avoid ReferenceError var spawnTimer = 0; var powerupSpawnTimer = 0; // Define enemy shooting variables in global scope to avoid ReferenceError var enemyShootingEnabled = false; var enemyShootInterval = 120; var lastEnemyShootInterval = 120; // Wait for first touch/click to start game.down = function (x, y, obj) { if (!gameStarted) { // Remove logo and start text logo.destroy(); pressToStart.destroy(); // Play background music LK.playMusic('galacticMusic'); // Score display scoreTxt = new Text2('0', { size: 120, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Highscore display highscore = storage.highscore || 0; highscoreTxt = new Text2("HI " + highscore, { size: 80, fill: 0xFFD700 }); highscoreTxt.anchor.set(1, 0); LK.gui.topRight.addChild(highscoreTxt); // Powerup countdown display (lower right) powerupCountdownTxt = new Text2('', { size: 80, fill: 0x00ff99 }); powerupCountdownTxt.anchor.set(1, 1); // bottom right LK.gui.bottomRight.addChild(powerupCountdownTxt); // Lives display (top left, but offset to avoid menu) livesTxt = new Text2('♥♥♥', { size: 100, fill: 0xff4444 }); livesTxt.anchor.set(0, 0); livesTxt.x = 110; // leave 100px for menu livesTxt.y = 0; LK.gui.top.addChild(livesTxt); // Game variables player; playerBullets = []; enemies = []; enemyBullets = []; powerups = []; dragNode = null; lastPlayerHit = false; spawnTimer = 0; powerupSpawnTimer = 0; enemyShootingEnabled = false; enemyShootInterval = 120; lastEnemyShootInterval = 120; // Re-enable move/drag handler game.move = handleMove; // Only start drag if touch is on player game.down = function (x, y, obj) { var local = player.toLocal(game.toGlobal({ x: x, y: y })); if (local.x >= -player.width / 2 && local.x <= player.width / 2 && local.y >= -player.height / 2 && local.y <= player.height / 2) { dragNode = player; handleMove(x, y, obj); } }; game.up = function (x, y, obj) { dragNode = null; }; gameStarted = true; } }; // --- END LOGO SPLASH --- // The rest of the game code will only run after gameStarted is true // Helper: Clamp value function clamp(val, min, max) { return Math.max(min, Math.min(max, val)); } // Initialize player player = new PlayerShip(); player.lives = 3; player.x = 2048 / 2; player.y = 2732 - 220; game.addChild(player); // Move handler (drag player ship) function handleMove(x, y, obj) { if (dragNode === player) { // Clamp player within screen bounds var halfW = player.width / 2; var halfH = player.height / 2; player.x = clamp(x, halfW, 2048 - halfW); player.y = clamp(y, 2048, 2732 - halfH); // Only allow movement in lower 700px } } game.move = handleMove; game.down = function (x, y, obj) { // Only start drag if touch is on player var local = player.toLocal(game.toGlobal({ x: x, y: y })); if (local.x >= -player.width / 2 && local.x <= player.width / 2 && local.y >= -player.height / 2 && local.y <= player.height / 2) { dragNode = player; handleMove(x, y, obj); } }; game.up = function (x, y, obj) { dragNode = null; }; // Fire player bullet (auto-fire, no mouse button needed) function firePlayerBullet() { if (player.shootTimer === 0) { var bullet = new PlayerBullet(); bullet.x = player.x; bullet.y = player.y - player.height / 2 - 10; playerBullets.push(bullet); game.addChild(bullet); LK.getSound('shoot').play(); player.shootTimer = player.poweredUp ? 6 : player.shootCooldown; // Power-up: triple shot if (player.poweredUp) { for (var i = -1; i <= 1; i += 2) { var b = new PlayerBullet(); b.x = player.x + i * 50; b.y = player.y - player.height / 2 - 10; b.rotation = i * 0.18; b.update = function (angle) { return function () { this.y += this.speed * Math.cos(angle); this.x += this.speed * Math.sin(angle); }; }(i * 0.18); playerBullets.push(b); game.addChild(b); } } } } // Spawn enemy function spawnEnemy() { var enemy = new EnemyShip(); enemy.x = 180 + Math.random() * (2048 - 360); enemy.y = -enemy.height / 2 - 10; // Set initial shootCooldown based on current global interval enemy.shootCooldown = enemyShootingEnabled ? enemyShootInterval + Math.floor(Math.random() * 30) : 120 + Math.floor(Math.random() * 60); enemy.shootTimer = Math.floor(Math.random() * enemy.shootCooldown); enemies.push(enemy); game.addChild(enemy); } // Spawn powerup function spawnPowerup() { var p = new Powerup(); p.x = 180 + Math.random() * (2048 - 360); p.y = -p.height / 2 - 10; powerups.push(p); game.addChild(p); } // Main update loop game.update = function () { // Player update player.update(); // Update lives display var livesStr = ''; for (var i = 0; i < player.lives; i++) livesStr += '♥'; if (livesTxt) livesTxt.setText(livesStr); // Update powerup countdown text if (player.poweredUp && player.powerupTimer > 0) { // Show seconds left, rounded up var seconds = Math.ceil(player.powerupTimer / 60); powerupCountdownTxt.setText(seconds + "s"); } else { if (powerupCountdownTxt) powerupCountdownTxt.setText(''); } // Player auto-fire if (LK.ticks % 2 === 0) { firePlayerBullet(); } // Update player bullets for (var i = playerBullets.length - 1; i >= 0; i--) { var b = playerBullets[i]; b.update(); // Remove if off screen if (b.y < -80) { b.destroy(); playerBullets.splice(i, 1); continue; } // Check collision with enemies for (var j = enemies.length - 1; j >= 0; j--) { var e = enemies[j]; if (b.intersects(e)) { e.hp--; if (e.hp <= 0) { // Explosion effect LK.effects.flashObject(e, 0xffffff, 200); // Add explosion sprite at enemy position var explosion = LK.getAsset('explosion', { anchorX: 0.5, anchorY: 0.5, x: e.x, y: e.y }); game.addChild(explosion); // Animate explosion fade out and destroy after 400ms tween(explosion, { alpha: 0 }, { duration: 400, onFinish: function onFinish() { explosion.destroy(); } }); LK.getSound('explosion').play(); LK.setScore(LK.getScore() + 10); scoreTxt.setText(LK.getScore()); // Highscore logic if (LK.getScore() > highscore) { highscore = LK.getScore(); storage.highscore = highscore; highscoreTxt.setText("HI " + highscore); } e.destroy(); enemies.splice(j, 1); } b.destroy(); playerBullets.splice(i, 1); break; } } } // Update enemies var playerWasHitThisFrame = false; // Track if player was hit this frame for (var i = enemies.length - 1; i >= 0; i--) { var e = enemies[i]; e.update(); // Remove if off screen if (e.y > 2732 + e.height) { e.destroy(); enemies.splice(i, 1); continue; } // Enemy shooting logic // Enable enemy shooting after player reaches 200 points if (!enemyShootingEnabled && LK.getScore() >= 200) { enemyShootingEnabled = true; } // Gradually increase fire rate after enemy shooting is enabled if (enemyShootingEnabled) { // Decrease interval every 10 seconds, down to a minimum var minInterval = 24; // fastest fire rate (lower = faster) var maxInterval = 120; // slowest fire rate (at start) // Use ticks since enabling shooting to ramp up fire rate if (typeof enemyShootingStartTick === "undefined") { enemyShootingStartTick = LK.ticks; } var elapsed = LK.ticks - enemyShootingStartTick; var interval = Math.max(minInterval, maxInterval - Math.floor(elapsed / 600) * 8); enemyShootInterval = interval; // If interval changed, update all enemies' shootCooldown if (enemyShootInterval !== lastEnemyShootInterval) { for (var j = 0; j < enemies.length; j++) { enemies[j].shootCooldown = enemyShootInterval + Math.floor(Math.random() * 30); } lastEnemyShootInterval = enemyShootInterval; } } // Enemy shooting if (enemyShootingEnabled && e.shootTimer === 0) { var eb = new EnemyBullet(); eb.x = e.x; eb.y = e.y + e.height / 2 + 10; enemyBullets.push(eb); game.addChild(eb); LK.getSound('enemyShoot').play(); e.shootTimer = e.shootCooldown; } // Check collision with player if (e.intersects(player)) { if (!e.lastHitPlayer) { if (!lastPlayerHit && !playerWasHitThisFrame) { LK.effects.flashScreen(0xff0000, 800); LK.getSound('explosion').play(); player.lives--; playerWasHitThisFrame = true; if (player.lives <= 0) { player.lives = 0; if (livesTxt) livesTxt.setText(''); LK.showGameOver(); } else { // Reset player position and give brief invulnerability player.x = 2048 / 2; player.y = 2732 - 220; } lastPlayerHit = true; } e.lastHitPlayer = true; } } else { e.lastHitPlayer = false; } } // Update enemy bullets for (var i = enemyBullets.length - 1; i >= 0; i--) { var eb = enemyBullets[i]; eb.update(); if (eb.y > 2732 + 60) { eb.destroy(); enemyBullets.splice(i, 1); continue; } // Check collision with player if (eb.intersects(player)) { if (!lastPlayerHit && !playerWasHitThisFrame) { LK.effects.flashScreen(0xff0000, 800); LK.getSound('explosion').play(); player.lives--; playerWasHitThisFrame = true; if (player.lives <= 0) { player.lives = 0; if (livesTxt) livesTxt.setText(''); LK.showGameOver(); } else { // Reset player position and give brief invulnerability player.x = 2048 / 2; player.y = 2732 - 220; } lastPlayerHit = true; } } } // Update powerups for (var i = powerups.length - 1; i >= 0; i--) { var p = powerups[i]; p.update(); if (p.y > 2732 + 60) { p.destroy(); powerups.splice(i, 1); continue; } // Check collision with player if (p.intersects(player)) { player.setPowerup(600); // 10 seconds at 60fps LK.getSound('powerup').play(); p.destroy(); powerups.splice(i, 1); } } // Enemy spawn logic spawnTimer--; if (spawnTimer <= 0) { spawnEnemy(); // After 600 points, spawn an extra enemy each spawn cycle if (LK.getScore() >= 600) { spawnEnemy(); } spawnTimer = 36 + Math.floor(Math.random() * 24); // spawn every 1s approx } // Powerup spawn logic powerupSpawnTimer--; if (powerupSpawnTimer <= 0) { if (Math.random() < 0.18) { spawnPowerup(); } powerupSpawnTimer = 360 + Math.floor(Math.random() * 240); // every 6-10s } // Reset lastPlayerHit if player is alive if (!player.destroyed) { lastPlayerHit = false; } }; // Reset game state on game over LK.on('gameover', function () { // Clean up all objects for (var i = 0; i < playerBullets.length; i++) playerBullets[i].destroy(); for (var i = 0; i < enemies.length; i++) enemies[i].destroy(); for (var i = 0; i < enemyBullets.length; i++) enemyBullets[i].destroy(); for (var i = 0; i < powerups.length; i++) powerups[i].destroy(); playerBullets = []; enemies = []; enemyBullets = []; powerups = []; lastPlayerHit = false; // Reset player lives if (player) player.lives = 3; // Update lives display var livesStr = ''; for (var i = 0; i < 3; i++) livesStr += '♥'; if (livesTxt) livesTxt.setText(livesStr); // Music will be handled by LK // Update highscore display in case storage was externally changed highscore = storage.highscore || 0; highscoreTxt.setText("HI " + highscore); }); // Reset game state on win (not used in MVP, but for future) LK.on('youwin', function () { for (var i = 0; i < playerBullets.length; i++) playerBullets[i].destroy(); for (var i = 0; i < enemies.length; i++) enemies[i].destroy(); for (var i = 0; i < enemyBullets.length; i++) enemyBullets[i].destroy(); for (var i = 0; i < powerups.length; i++) powerups[i].destroy(); playerBullets = []; enemies = []; enemyBullets = []; powerups = []; lastPlayerHit = false; // Reset player lives if (player) player.lives = 3; // Update lives display var livesStr = ''; for (var i = 0; i < 3; i++) livesStr += '♥'; if (livesTxt) livesTxt.setText(livesStr); // Update highscore display in case storage was externally changed highscore = storage.highscore || 0; highscoreTxt.setText("HI " + highscore); });
===================================================================
--- original.js
+++ change.js
@@ -153,8 +153,10 @@
var playerBullets = [];
var enemies = [];
var enemyBullets = [];
var powerups = [];
+// Define dragNode in global scope to avoid ReferenceError
+var dragNode = null;
// Define spawn timers in global scope to avoid ReferenceError
var spawnTimer = 0;
var powerupSpawnTimer = 0;
// Define enemy shooting variables in global scope to avoid ReferenceError
spaceship seen from above. In-Game asset. 2d. High contrast. No shadows
spaceship seen from up going down. In-Game asset. 2d. High contrast. No shadows
color blue
red laser beam. In-Game asset. 2d. High contrast. No shadows
color green
explosion. In-Game asset. 2d. High contrast. No shadows
starfield banner
make box yellow