User prompt
Please fix the bug: 'Uncaught TypeError: Cannot set properties of null (setting 'x')' in or related to this line: 'player.x = px;' Line Number: 348
User prompt
Add a starting screen ( with the title and a play button )
User prompt
Make the boss to take 6 hits to defeat it
User prompt
Make the boss to shoot the rockets less frequently, and less spread themed rather faster bullets in single direction and ricochet.
User prompt
Make the enemy ships to stay in one place too ( randomly ) also decrease the frequency of the rockets from enemies to spawn
User prompt
make the enemy space ship to take 3 hits to defeat it ( instead of 1 ), also at 0 point spawn in 2 enemies, 1 point add an enemy ship with the previous ones, continue the same until point 6, cap the number of ships to be 6
User prompt
For each point gained upto 5, add one more enemy ship in the screen
User prompt
Revert the logic, make random ships to spawn
User prompt
Fix after defeating the first 2 enemy ships, no ship is spawning in
User prompt
If there is no enemy ship spawn in +1 ship
User prompt
Start by spawning in 2 enemy ship and for each rocket defeated spawn in +1 enemy ship
User prompt
Get the hearts little bit to the left
User prompt
Slow down the enemy speed and bullet speed. And the bullet should only go vertically down ( don't target the player )
Code edit (1 edits merged)
Please save this source code
User prompt
Space Shooter: Alien Onslaught
Initial prompt
Hi Ava, Now I want to create a game based on space shooter. Game Mechanic: -> We control a space ship beginning from the bottom of the screen, which shoots out rockets. -> Enemies are alien space ship that follows from above the screen. -> Enemies shoot rockets at us too, and we have to dodge it. -> Certain enemies are different ( very rare to spawn ) which can give power ups. Gameplay: -> Make the ship to follow the clicked mouse, ( the ship should be constantly shooting the rockets ) -> The ship has 3 lives, when hit by enemy rockets, we loose health -> power ups from aliens: Fast shooting guns, extra life ( grants extra life ), destroy all ball ( grab to destroy everything ), shield ( to protect from enemy attacks for a brief time ) Gameplay mech: -> Clearing enemies grants points, enemies should go to random locations on top, should not come down, they shoot randomly. each alien ship defeated grants 1 point, when reaching 20 points, a single boss spaceship appears, when defeated we win ( the boss shoot rockets frequently, and in different directions that richochet the screens )
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Bomb (for screen clear effect) var Bomb = Container.expand(function () { var self = Container.call(this); var bomb = self.attachAsset('bomb', { anchorX: 0.5, anchorY: 0.5, alpha: 0.7 }); return self; }); // Boss var Boss = Container.expand(function () { var self = Container.call(this); var boss = self.attachAsset('boss', { anchorX: 0.5, anchorY: 0.5 }); self.hp = 30; self.targetX = 1024; self.moveSpeed = 18; self.shootCooldown = 30; self.update = function () { // Move horizontally only var dx = self.targetX - self.x; if (Math.abs(dx) > self.moveSpeed) { self.x += dx > 0 ? self.moveSpeed : -self.moveSpeed; } else { self.x = self.targetX; // Pick new target self.targetX = 300 + Math.random() * (2048 - 600); } // Shooting self.shootCooldown--; if (self.shootCooldown <= 0) { self.shootCooldown = 18; spawnBossRockets(self); } }; return self; }); // Boss Rocket var BossRocket = Container.expand(function () { var self = Container.call(this); var rocket = self.attachAsset('bossRocket', { anchorX: 0.5, anchorY: 0.5 }); self.dx = 0; self.dy = 28; self.ricochet = true; self.update = function () { self.x += self.dx; self.y += self.dy; // Ricochet off walls if (self.ricochet) { if (self.x < 0 && self.dx < 0) self.dx *= -1; if (self.x > 2048 && self.dx > 0) self.dx *= -1; } }; return self; }); // Enemy Rocket var EnemyRocket = Container.expand(function () { var self = Container.call(this); var rocket = self.attachAsset('enemyRocket', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 10; // slowed down enemy rocket speed self.dx = 0; // always vertical, no horizontal movement self.dy = self.speed; self.ricochet = false; self.update = function () { self.x += self.dx; self.y += self.dy; // Ricochet off walls if enabled if (self.ricochet) { if (self.x < 0 && self.dx < 0) self.dx *= -1; if (self.x > 2048 && self.dx > 0) self.dx *= -1; } }; 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.targetX = 0; self.targetY = 0; self.moveSpeed = 5 + Math.random() * 3; // slowed down enemy movement self.shootCooldown = 60 + Math.floor(Math.random() * 60); self.isRare = false; // rare enemies drop powerups self.update = function () { // Move toward target var dx = self.targetX - self.x; var dy = self.targetY - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > self.moveSpeed) { self.x += dx / dist * self.moveSpeed; self.y += dy / dist * self.moveSpeed; } else { self.x = self.targetX; self.y = self.targetY; // Pick new target self.targetX = 200 + Math.random() * (2048 - 400); self.targetY = 200 + Math.random() * 800; } // Shooting self.shootCooldown--; if (self.shootCooldown <= 0) { self.shootCooldown = 60 + Math.floor(Math.random() * 60); spawnEnemyRocket(self); } }; return self; }); // Player Rocket var PlayerRocket = Container.expand(function () { var self = Container.call(this); var rocket = self.attachAsset('playerRocket', { 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.lives = 3; self.shielded = false; self.fastShoot = false; self.shootTimer = 0; self.shieldNode = null; self.update = function () { // nothing here, movement is handled by drag }; self.setShield = function (active) { if (active && !self.shielded) { self.shielded = true; self.shieldNode = new Shield(); self.shieldNode.x = 0; self.shieldNode.y = 0; self.addChild(self.shieldNode); } else if (!active && self.shielded) { if (self.shieldNode) { self.shieldNode.destroy(); self.shieldNode = null; } self.shielded = false; } }; return self; }); // PowerUp var PowerUp = Container.expand(function () { var self = Container.call(this); var powerup = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5 }); self.type = 'fast'; // 'fast', 'life', 'shield', 'bomb' self.speed = 12; self.update = function () { self.y += self.speed; }; return self; }); // Shield var Shield = Container.expand(function () { var self = Container.call(this); var shield = self.attachAsset('shield', { anchorX: 0.5, anchorY: 0.5, alpha: 0.4 }); return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // Music // Sounds // Bomb: white ellipse // Boss rocket: magenta box // Boss: purple box // Shield: cyan ellipse // Power-up: green ellipse // Enemy rocket: orange box // Enemy ship: red ellipse // Player rocket: yellow box // Player ship: blue box // Play music LK.playMusic('spacebg'); // Score, lives, state var score = 0; var lives = 3; var player = null; var playerShieldTimeout = 0; var playerFastShootTimeout = 0; var playerBombActive = false; var playerInvulnTimeout = 0; var boss = null; var bossActive = false; var bossDefeated = false; var bossHpTxt = null; // Arrays for game objects var playerRockets = []; var enemyRockets = []; var bossRockets = []; var enemies = []; var powerups = []; var bombs = []; // GUI var scoreTxt = new Text2('0', { size: 120, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); var livesTxt = new Text2('♥♥♥', { size: 90, fill: 0xFF6666 }); livesTxt.anchor.set(1, 0); livesTxt.x = -60; LK.gui.topRight.addChild(livesTxt); // Helper: update GUI function updateScore() { scoreTxt.setText(score); } function updateLives() { var s = ''; for (var i = 0; i < lives; ++i) s += '♥'; livesTxt.setText(s); } function showBossHp(hp) { if (!bossHpTxt) { bossHpTxt = new Text2('Boss: ' + hp, { size: 90, fill: 0xFFCCFF }); bossHpTxt.anchor.set(0.5, 0); LK.gui.bottom.addChild(bossHpTxt); } else { bossHpTxt.setText('Boss: ' + hp); } } function hideBossHp() { if (bossHpTxt) { bossHpTxt.destroy(); bossHpTxt = null; } } // Spawn player player = new PlayerShip(); player.x = 1024; player.y = 2732 - 180; game.addChild(player); // Dragging var dragNode = null; game.down = function (x, y, obj) { // Only allow drag if touch is on player if (player && Math.abs(x - player.x) < 120 && Math.abs(y - player.y) < 80) { dragNode = player; } }; game.up = function (x, y, obj) { dragNode = null; }; function handleMove(x, y, obj) { if (dragNode === player) { // Clamp to screen var px = Math.max(80, Math.min(2048 - 80, x)); var py = Math.max(2732 - 300, Math.min(2732 - 80, y)); player.x = px; player.y = py; } } game.move = handleMove; // Spawn enemy function spawnEnemy() { var e = new EnemyShip(); e.x = 200 + Math.random() * (2048 - 400); e.y = 100 + Math.random() * 200; e.targetX = 200 + Math.random() * (2048 - 400); e.targetY = 200 + Math.random() * 800; // 1 in 7 is rare if (Math.random() < 0.14) { e.isRare = true; // Tint rare enemies e.children[0].tint = 0x00ff99; } enemies.push(e); game.addChild(e); } // Spawn powerup function spawnPowerUp(x, y) { var p = new PowerUp(); p.x = x; p.y = y; // Random type var r = Math.random(); if (r < 0.25) p.type = 'fast';else if (r < 0.5) p.type = 'life';else if (r < 0.75) p.type = 'shield';else p.type = 'bomb'; // Color by type if (p.type === 'fast') p.children[0].tint = 0x44ff44; if (p.type === 'life') p.children[0].tint = 0xff66cc; if (p.type === 'shield') p.children[0].tint = 0x00ffff; if (p.type === 'bomb') p.children[0].tint = 0xffffff; powerups.push(p); game.addChild(p); } // Spawn player rocket function spawnPlayerRocket() { var r = new PlayerRocket(); r.x = player.x; r.y = player.y - 80; playerRockets.push(r); game.addChild(r); LK.getSound('shoot').play(); } // Spawn enemy rocket function spawnEnemyRocket(enemy) { var r = new EnemyRocket(); r.x = enemy.x; r.y = enemy.y + 60; // Only shoot vertically down, no targeting r.dx = 0; r.dy = r.speed; r.ricochet = false; enemyRockets.push(r); game.addChild(r); LK.getSound('enemyShoot').play(); } // Spawn boss function spawnBoss() { boss = new Boss(); boss.x = 1024; boss.y = 400; boss.hp = 30; bossActive = true; game.addChild(boss); showBossHp(boss.hp); } // Spawn boss rockets (multi-directional) function spawnBossRockets(bossObj) { var angles = [0, -0.3, 0.3, -0.6, 0.6]; for (var i = 0; i < angles.length; ++i) { var r = new BossRocket(); r.x = bossObj.x; r.y = bossObj.y + 100; var angle = Math.PI / 2 + angles[i]; r.dx = Math.cos(angle) * 18; r.dy = Math.sin(angle) * 28; r.ricochet = true; bossRockets.push(r); game.addChild(r); } LK.getSound('bossShoot').play(); } // Bomb effect: clear all enemy/boss rockets and damage all enemies function activateBomb() { if (playerBombActive) return; playerBombActive = true; var bomb = new Bomb(); bomb.x = player.x; bomb.y = player.y - 100; bombs.push(bomb); game.addChild(bomb); LK.getSound('bomb').play(); // Flash LK.effects.flashScreen(0xffffff, 400); // Destroy all enemy/boss rockets for (var i = enemyRockets.length - 1; i >= 0; --i) { enemyRockets[i].destroy(); enemyRockets.splice(i, 1); } for (var i = bossRockets.length - 1; i >= 0; --i) { bossRockets[i].destroy(); bossRockets.splice(i, 1); } // Damage all enemies for (var i = enemies.length - 1; i >= 0; --i) { enemies[i].destroy(); enemies.splice(i, 1); score += 1; updateScore(); } // Damage boss if present if (bossActive && boss) { boss.hp -= 5; if (boss.hp < 0) boss.hp = 0; showBossHp(boss.hp); LK.effects.flashObject(boss, 0xffffff, 400); } // Remove bomb after effect LK.setTimeout(function () { if (bomb) bomb.destroy(); playerBombActive = false; }, 600); } // Main update game.update = function () { // Player shooting if (player) { player.shootTimer--; var shootInterval = player.fastShoot ? 7 : 18; if (player.shootTimer <= 0) { player.shootTimer = shootInterval; spawnPlayerRocket(); } } // Player powerup timers if (playerFastShootTimeout > 0) { playerFastShootTimeout--; if (playerFastShootTimeout === 0) { player.fastShoot = false; } } if (playerShieldTimeout > 0) { playerShieldTimeout--; if (playerShieldTimeout === 0) { player.setShield(false); } } if (playerInvulnTimeout > 0) { playerInvulnTimeout--; } // Update player rockets for (var i = playerRockets.length - 1; i >= 0; --i) { var r = playerRockets[i]; r.update(); // Off screen if (r.y < -80) { r.destroy(); playerRockets.splice(i, 1); continue; } // Hit enemy for (var j = enemies.length - 1; j >= 0; --j) { var e = enemies[j]; if (r.intersects(e)) { LK.getSound('explosion').play(); r.destroy(); playerRockets.splice(i, 1); // Powerup drop if (e.isRare) { spawnPowerUp(e.x, e.y); } e.destroy(); enemies.splice(j, 1); score += 1; updateScore(); break; } } // Hit boss if (bossActive && boss && r.intersects(boss)) { LK.getSound('hit').play(); r.destroy(); playerRockets.splice(i, 1); boss.hp -= 1; showBossHp(boss.hp); LK.effects.flashObject(boss, 0xff33cc, 200); if (boss.hp <= 0) { // Boss defeated bossDefeated = true; boss.destroy(); boss = null; bossActive = false; hideBossHp(); LK.effects.flashScreen(0x00ffcc, 1200); LK.setScore(score); LK.showYouWin(); return; } } } // Update enemy rockets for (var i = enemyRockets.length - 1; i >= 0; --i) { var r = enemyRockets[i]; r.update(); // Off screen if (r.y > 2732 + 80 || r.x < -80 || r.x > 2048 + 80) { r.destroy(); enemyRockets.splice(i, 1); continue; } // Hit player if (player && r.intersects(player)) { r.destroy(); enemyRockets.splice(i, 1); if (player.shielded) { LK.getSound('shield').play(); player.setShield(false); } else if (playerInvulnTimeout === 0) { lives -= 1; updateLives(); LK.getSound('hit').play(); LK.effects.flashObject(player, 0xff0000, 600); playerInvulnTimeout = 60; if (lives <= 0) { LK.effects.flashScreen(0xff0000, 1200); LK.setScore(score); LK.showGameOver(); return; } } } } // Update boss rockets for (var i = bossRockets.length - 1; i >= 0; --i) { var r = bossRockets[i]; r.update(); // Off screen if (r.y > 2732 + 80 || r.x < -80 || r.x > 2048 + 80) { r.destroy(); bossRockets.splice(i, 1); continue; } // Hit player if (player && r.intersects(player)) { r.destroy(); bossRockets.splice(i, 1); if (player.shielded) { LK.getSound('shield').play(); player.setShield(false); } else if (playerInvulnTimeout === 0) { lives -= 1; updateLives(); LK.getSound('hit').play(); LK.effects.flashObject(player, 0xff0000, 600); playerInvulnTimeout = 60; if (lives <= 0) { LK.effects.flashScreen(0xff0000, 1200); LK.setScore(score); LK.showGameOver(); return; } } } } // Update enemies for (var i = enemies.length - 1; i >= 0; --i) { var e = enemies[i]; e.update(); // Off screen (shouldn't happen) if (e.y > 2732 + 100) { e.destroy(); enemies.splice(i, 1); continue; } // Collide with player if (player && e.intersects(player)) { LK.getSound('hit').play(); e.destroy(); enemies.splice(i, 1); if (player.shielded) { player.setShield(false); } else if (playerInvulnTimeout === 0) { lives -= 1; updateLives(); LK.effects.flashObject(player, 0xff0000, 600); playerInvulnTimeout = 60; if (lives <= 0) { LK.effects.flashScreen(0xff0000, 1200); LK.setScore(score); LK.showGameOver(); return; } } } } // Update powerups for (var i = powerups.length - 1; i >= 0; --i) { var p = powerups[i]; p.update(); // Off screen if (p.y > 2732 + 80) { p.destroy(); powerups.splice(i, 1); continue; } // Collect if (player && p.intersects(player)) { LK.getSound('powerup').play(); if (p.type === 'fast') { player.fastShoot = true; playerFastShootTimeout = 360; } else if (p.type === 'life') { lives += 1; updateLives(); LK.getSound('lifeup').play(); } else if (p.type === 'shield') { player.setShield(true); playerShieldTimeout = 360; LK.getSound('shield').play(); } else if (p.type === 'bomb') { activateBomb(); } p.destroy(); powerups.splice(i, 1); } } // Update bombs for (var i = bombs.length - 1; i >= 0; --i) { // Bombs are visual only, auto destroy after effect } // Boss if (bossActive && boss) { boss.update(); } // Spawn enemies: 1 per point up to 5, always keep at least score (max 5) enemies on screen if (!bossActive) { var desiredEnemies = Math.min(score, 5); if (desiredEnemies < 1) desiredEnemies = 1; var toSpawn = desiredEnemies - enemies.length; for (var i = 0; i < toSpawn; ++i) { spawnEnemy(); } } // Boss appears at 20 points if (!bossActive && !bossDefeated && score >= 20) { // Remove all enemies for (var i = enemies.length - 1; i >= 0; --i) { enemies[i].destroy(); enemies.splice(i, 1); } spawnBoss(); } }; // Set initial GUI updateScore(); updateLives();
===================================================================
--- original.js
+++ change.js
@@ -635,12 +635,13 @@
// Boss
if (bossActive && boss) {
boss.update();
}
- // Spawn enemies randomly if not bossActive
- if (!bossActive && enemies.length < 2) {
- // Always keep at least 2 enemies on screen
- var toSpawn = 2 - enemies.length;
+ // Spawn enemies: 1 per point up to 5, always keep at least score (max 5) enemies on screen
+ if (!bossActive) {
+ var desiredEnemies = Math.min(score, 5);
+ if (desiredEnemies < 1) desiredEnemies = 1;
+ var toSpawn = desiredEnemies - enemies.length;
for (var i = 0; i < toSpawn; ++i) {
spawnEnemy();
}
}
A bomb. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Boss ship top down. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Enemy ship. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Spaceship for players. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
make it greyish
Kinda a spike ball very red. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Diamond, . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat