User prompt
make animation enemy fall after hit
User prompt
add background asset
User prompt
player death after one hit
User prompt
erase level text
User prompt
endless game and delete boss
User prompt
player and enemy also boss get explode when hit ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
fix control player response
User prompt
take player possition first on the middle when game play
User prompt
fix smooth control
User prompt
get smooth control ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
fix level
User prompt
reduce lag
User prompt
reduce bullet speed player and enemy
User prompt
reduce speed of gameplay
User prompt
player multi direction shoot bullet
Code edit (1 edits merged)
Please save this source code
User prompt
Galactic Gunner: Auto-Blaster
Initial prompt
side scroller auto shooting game
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Boss var Boss = Container.expand(function () { var self = Container.call(this); var bossGfx = self.attachAsset('boss', { anchorX: 0.5, anchorY: 0.5 }); self.width = bossGfx.width; self.height = bossGfx.height; self.speed = 6; self.hp = 30; self.shootCooldown = 0; self.type = 'boss'; self.direction = 1; self.update = function () { self.x -= self.speed; // Move up and down self.y += self.direction * 7; if (self.y < 200) { self.direction = 1; } if (self.y > 2532) { self.direction = -1; } if (self.shootCooldown > 0) { self.shootCooldown--; } }; return self; }); // Enemy var Enemy = Container.expand(function () { var self = Container.call(this); var enemyGfx = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5 }); self.width = enemyGfx.width; self.height = enemyGfx.height; self.speed = 5 + Math.random() * 4; self.hp = 1; self.shootCooldown = 0; self.type = 'normal'; // or 'boss' self.update = function () { self.x -= self.speed; if (self.shootCooldown > 0) { self.shootCooldown--; } }; return self; }); // Enemy bullet var EnemyBullet = Container.expand(function () { var self = Container.call(this); var bulletGfx = self.attachAsset('enemyBullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 8; self.update = function () { self.x -= self.speed; }; return self; }); // Player bullet var PlayerBullet = Container.expand(function () { var self = Container.call(this); var bulletGfx = self.attachAsset('playerBullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 12; self.update = function () { // Default angle is 0 (right) if (typeof self.angle === "undefined") { self.angle = 0; } self.x += self.speed * Math.cos(self.angle); self.y += self.speed * Math.sin(self.angle); }; return self; }); // Power-up var Powerup = Container.expand(function () { var self = Container.call(this); var powerGfx = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 6; self.type = 'power'; // could be 'power', 'heal', etc. self.update = function () { self.x -= self.speed; }; return self; }); // Player spaceship var Ship = Container.expand(function () { var self = Container.call(this); var shipGfx = self.attachAsset('ship', { anchorX: 0.5, anchorY: 0.5 }); self.width = shipGfx.width; self.height = shipGfx.height; self.fireCooldown = 0; self.powerLevel = 1; // 1=single, 2=double, 3=triple shot self.invincible = false; self.invincibleTimer = 0; // Invincibility flash effect self.setInvincible = function (duration) { self.invincible = true; self.invincibleTimer = duration; tween(shipGfx, { alpha: 0.4 }, { duration: 100, easing: tween.linear, onFinish: function onFinish() { tween(shipGfx, { alpha: 1 }, { duration: 100, easing: tween.linear }); } }); }; // Called every tick self.update = function () { if (self.invincible) { self.invincibleTimer -= 1; if (self.invincibleTimer <= 0) { self.invincible = false; shipGfx.alpha = 1; } } // Track last drag direction for multi-directional shooting if (typeof self.lastShootAngle === "undefined") { self.lastShootAngle = 0; } if (typeof self.lastX === "undefined") { self.lastX = self.x; } if (typeof self.lastY === "undefined") { self.lastY = self.y; } if (self.x !== self.lastX || self.y !== self.lastY) { // Calculate angle of movement var dx = self.x - self.lastX; var dy = self.y - self.lastY; if (dx !== 0 || dy !== 0) { self.lastShootAngle = Math.atan2(dy, dx); } } self.lastX = self.x; self.lastY = self.y; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000010 }); /**** * Game Code ****/ // Play background music // Spaceship (player) // Player bullet // Enemy // Enemy bullet // Power-up // Boss // Sound effects // Music LK.playMusic('bgmusic'); // Game variables var ship; var playerBullets = []; var enemies = []; var enemyBullets = []; var powerups = []; var boss = null; var scoreTxt; var levelTxt; var dragNode = null; var lastShipX = 0, lastShipY = 0; var spawnTimer = 0; var powerupTimer = 0; var level = 1; var bossActive = false; var bossDefeated = false; var gameOver = false; // Bullet pools for reusing objects (reduces garbage collection) var playerBulletPool = []; var enemyBulletPool = []; // Helper function to get bullet from pool or create new one function getPlayerBulletFromPool() { if (playerBulletPool.length > 0) { var bullet = playerBulletPool.pop(); bullet.visible = true; return bullet; } return new PlayerBullet(); } function getEnemyBulletFromPool() { if (enemyBulletPool.length > 0) { var bullet = enemyBulletPool.pop(); bullet.visible = true; return bullet; } return new EnemyBullet(); } // Helper function to return bullet to pool function returnPlayerBulletToPool(bullet, index) { bullet.visible = false; playerBulletPool.push(bullet); playerBullets.splice(index, 1); } function returnEnemyBulletToPool(bullet, index) { bullet.visible = false; enemyBulletPool.push(bullet); enemyBullets.splice(index, 1); } // Score display scoreTxt = new Text2('0', { size: 120, fill: "#fff" }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Level display levelTxt = new Text2('Level 1', { size: 70, fill: "#aaf" }); levelTxt.anchor.set(0.5, 0); LK.gui.top.addChild(levelTxt); levelTxt.y = 120; // Create player ship ship = new Ship(); game.addChild(ship); ship.x = 300; ship.y = 2732 / 2; // Helper: clamp ship inside screen function clampShipPosition() { var halfW = ship.width / 2; var halfH = ship.height / 2; if (ship.x < 100 + halfW) { ship.x = 100 + halfW; } if (ship.x > 2048 - halfW) { ship.x = 2048 - halfW; } if (ship.y < halfH) { ship.y = halfH; } if (ship.y > 2732 - halfH) { ship.y = 2732 - halfH; } } // Handle dragging ship function handleMove(x, y, obj) { if (dragNode) { dragNode.x = x; dragNode.y = y; clampShipPosition(); } } game.move = handleMove; game.down = function (x, y, obj) { // Only allow drag if touch is on ship var local = ship.toLocal(game.toGlobal({ x: x, y: y })); if (local.x > -ship.width / 2 && local.x < ship.width / 2 && local.y > -ship.height / 2 && local.y < ship.height / 2) { dragNode = ship; handleMove(x, y, obj); } }; game.up = function (x, y, obj) { dragNode = null; }; // Spawn enemy function spawnEnemy() { var e = new Enemy(); e.x = 2048 + e.width / 2; e.y = 200 + Math.random() * (2732 - 400); e.hp = 1 + Math.floor(level / 2); e.speed = 5 + Math.random() * 4 + level * 0.6; e.shootCooldown = 90 + Math.floor(Math.random() * 80); enemies.push(e); game.addChild(e); } // Spawn powerup function spawnPowerup() { var p = new Powerup(); p.x = 2048 + 60; p.y = 200 + Math.random() * (2732 - 400); p.type = 'power'; powerups.push(p); game.addChild(p); } // Spawn boss function spawnBoss() { boss = new Boss(); boss.x = 2048 + boss.width / 2; boss.y = 2732 / 2; boss.hp = 30 + 10 * level; boss.shootCooldown = 40; bossActive = true; bossDefeated = false; game.addChild(boss); } // Main update loop game.update = function () { if (gameOver) { return; } // Ship update ship.update(); // Auto-fire if (ship.fireCooldown > 0) { ship.fireCooldown--; } if (ship.fireCooldown <= 0) { // Fire based on power level, but allow multi-directional shooting var bulletAngles = [ship.lastShootAngle || 0]; if (ship.powerLevel === 2) { bulletAngles = [(ship.lastShootAngle || 0) - Math.PI / 16, (ship.lastShootAngle || 0) + Math.PI / 16]; } if (ship.powerLevel >= 3) { bulletAngles = [(ship.lastShootAngle || 0) - Math.PI / 8, ship.lastShootAngle || 0, (ship.lastShootAngle || 0) + Math.PI / 8]; } for (var i = 0; i < bulletAngles.length; ++i) { var b = getPlayerBulletFromPool(); // Start at ship's nose b.x = ship.x + Math.cos(bulletAngles[i]) * (ship.width / 2 + 10); b.y = ship.y + Math.sin(bulletAngles[i]) * (ship.width / 2 + 10); b.angle = bulletAngles[i]; playerBullets.push(b); if (!b.parent) { game.addChild(b); } } LK.getSound('shoot').play(); ship.fireCooldown = 18; } // Update player bullets - optimized to reduce collision checking var bulletsToRemove = []; for (var i = playerBullets.length - 1; i >= 0; --i) { var b = playerBullets[i]; b.update(); // Remove if off screen if (b.x > 2048 + 50 || b.x < -50 || b.y > 2732 + 50 || b.y < -50) { returnPlayerBulletToPool(b, i); continue; } // Check if bullet already marked for removal if (bulletsToRemove.indexOf(i) !== -1) { continue; } // Hit enemy - only check enemies in proximity var bulletHitSomething = false; for (var j = enemies.length - 1; j >= 0; --j) { var e = enemies[j]; // Only check collision if enemy is close to bullet (rough proximity check) if (Math.abs(e.x - b.x) < 150 && Math.abs(e.y - b.y) < 150) { if (b.intersects(e)) { e.hp--; LK.getSound('explosion').play(); bulletHitSomething = true; if (e.hp <= 0) { LK.setScore(LK.getScore() + 10); scoreTxt.setText(LK.getScore()); e.destroy(); enemies.splice(j, 1); } break; } } } // If bullet hit an enemy, return the bullet to the pool and continue to next bullet if (bulletHitSomething) { returnPlayerBulletToPool(b, i); continue; } // Hit boss - only check if boss is active and bullet is close to boss if (bossActive && boss && Math.abs(boss.x - b.x) < 350 && Math.abs(boss.y - b.y) < 250) { if (b.intersects(boss)) { boss.hp--; LK.getSound('explosion').play(); returnPlayerBulletToPool(b, i); if (boss.hp <= 0 && !bossDefeated) { LK.setScore(LK.getScore() + 100); scoreTxt.setText(LK.getScore()); boss.destroy(); boss = null; bossActive = false; bossDefeated = true; // Next level level++; levelTxt.setText('Level ' + level); // Power up as reward ship.powerLevel = Math.min(ship.powerLevel + 1, 3); // Flash effect LK.effects.flashScreen(0x00ff00, 800); } } } } // Update enemies - optimized var enemiesNearPlayer = 0; for (var i = enemies.length - 1; i >= 0; --i) { var e = enemies[i]; e.update(); // Remove if off screen if (e.x < -e.width / 2) { e.destroy(); enemies.splice(i, 1); continue; } // Check if enemy is near player var isNearPlayer = Math.abs(e.x - ship.x) < 400; if (isNearPlayer) { enemiesNearPlayer++; } // Enemy shoots if (e.shootCooldown <= 0 && e.x < 2048 && e.x > 0) { // Limit shooting frequency based on how many enemies are near player if (enemiesNearPlayer < 3 || Math.random() < 0.3) { var eb = getEnemyBulletFromPool(); eb.x = e.x - e.width / 2 - 10; eb.y = e.y; enemyBullets.push(eb); if (!eb.parent) { game.addChild(eb); } LK.getSound('enemyShoot').play(); } // Increase cooldown when many enemies are present var cooldownBase = 80 + Math.floor(Math.random() * 60); e.shootCooldown = cooldownBase * (1 + (enemies.length > 10 ? 0.5 : 0)); } // Collide with ship - only check when close if (!ship.invincible && isNearPlayer && Math.abs(e.y - ship.y) < 150) { if (e.intersects(ship)) { // Ship hit ship.setInvincible(90); LK.effects.flashObject(ship, 0xff0000, 600); LK.effects.flashScreen(0xff0000, 400); LK.setScore(Math.max(0, LK.getScore() - 20)); scoreTxt.setText(LK.getScore()); } } } // Update enemy bullets - batch process with reduced collision checks var bulletsToCheck = []; // First update all bullets and mark ones to remove (off-screen) for (var i = enemyBullets.length - 1; i >= 0; --i) { var eb = enemyBullets[i]; eb.update(); if (eb.x < -50) { returnEnemyBulletToPool(eb, i); continue; } // Only check collision if ship is not invincible and bullet is near ship if (!ship.invincible && Math.abs(eb.x - ship.x) < 150 && Math.abs(eb.y - ship.y) < 150) { bulletsToCheck.push({ index: i, bullet: eb }); } } // Now only check collisions for bullets near the ship if (!ship.invincible) { for (var i = 0; i < bulletsToCheck.length; i++) { var bulletInfo = bulletsToCheck[i]; var eb = bulletInfo.bullet; if (eb.intersects(ship)) { ship.setInvincible(90); LK.effects.flashObject(ship, 0xff0000, 600); LK.effects.flashScreen(0xff0000, 400); LK.setScore(Math.max(0, LK.getScore() - 20)); scoreTxt.setText(LK.getScore()); eb.destroy(); enemyBullets.splice(bulletInfo.index, 1); // Game over if hit while invincible if (!ship.invincible) { gameOver = true; LK.showGameOver(); return; } break; // Exit loop after first hit } } } // Update powerups - only check collection when close for (var i = powerups.length - 1; i >= 0; --i) { var p = powerups[i]; p.update(); if (p.x < -50) { p.destroy(); powerups.splice(i, 1); continue; } // Collect - only check intersection when close to ship if (Math.abs(p.x - ship.x) < 120 && Math.abs(p.y - ship.y) < 120) { if (p.intersects(ship)) { LK.getSound('powerup').play(); ship.powerLevel = Math.min(ship.powerLevel + 1, 3); LK.setScore(LK.getScore() + 30); scoreTxt.setText(LK.getScore()); p.destroy(); powerups.splice(i, 1); } } } // Boss update - optimized if (bossActive && boss) { boss.update(); // Boss shoots - throttle shooting by distance to reduce bullet count if (boss.shootCooldown <= 0) { // Only shoot if boss is on screen if (boss.x < 2048) { // Limit bullet creation when far from player var distToPlayer = Math.abs(boss.x - ship.x); var bulletCount = distToPlayer < 800 ? 3 : 1; for (var i = 0; i < bulletCount; ++i) { var eb = getEnemyBulletFromPool(); eb.x = boss.x - boss.width / 2 - 10; eb.y = boss.y + (i - 1) * 60; enemyBullets.push(eb); if (!eb.parent) { game.addChild(eb); } } LK.getSound('enemyShoot').play(); } // Longer cooldown when far from player var cooldownMod = boss.x > 1500 ? 1.5 : 1; boss.shootCooldown = (60 + Math.floor(Math.random() * 45)) * cooldownMod; } // Collide with ship - only check when close if (!ship.invincible && Math.abs(boss.x - ship.x) < 300 && Math.abs(boss.y - ship.y) < 250) { if (boss.intersects(ship)) { ship.setInvincible(90); LK.effects.flashObject(ship, 0xff0000, 600); LK.effects.flashScreen(0xff0000, 400); LK.setScore(Math.max(0, LK.getScore() - 50)); scoreTxt.setText(LK.getScore()); // Game over if hit while invincible if (!ship.invincible) { gameOver = true; LK.showGameOver(); return; } } } } // Spawning logic if (!bossActive) { spawnTimer--; if (spawnTimer <= 0) { spawnEnemy(); spawnTimer = Math.max(45, 120 - level * 4); } // Powerup spawn powerupTimer--; if (powerupTimer <= 0) { spawnPowerup(); powerupTimer = 600 + Math.floor(Math.random() * 400); } // Boss appears every 10 enemies destroyed if (LK.getScore() > 0 && LK.getScore() % (100 * level) === 0 && !bossDefeated) { spawnBoss(); } } // Win condition: reach score 1000 if (LK.getScore() >= 1000) { LK.showYouWin(); gameOver = true; return; } }; // Reset game state on restart game.on('reset', function () { // Return bullets to pools instead of destroying for (var i = 0; i < playerBullets.length; ++i) { playerBullets[i].visible = false; playerBulletPool.push(playerBullets[i]); } for (var i = 0; i < enemyBullets.length; ++i) { enemyBullets[i].visible = false; enemyBulletPool.push(enemyBullets[i]); } // Destroy other objects for (var i = 0; i < enemies.length; ++i) { enemies[i].destroy(); } for (var i = 0; i < powerups.length; ++i) { powerups[i].destroy(); } if (boss) { boss.destroy(); } playerBullets = []; enemies = []; enemyBullets = []; powerups = []; boss = null; bossActive = false; bossDefeated = false; level = 1; ship.x = 300; ship.y = 2732 / 2; ship.powerLevel = 1; ship.invincible = false; ship.invincibleTimer = 0; LK.setScore(0); scoreTxt.setText('0'); levelTxt.setText('Level 1'); spawnTimer = 30; powerupTimer = 400; gameOver = false; });
===================================================================
--- original.js
+++ change.js
@@ -176,17 +176,17 @@
/****
* Game Code
****/
-// Music
-// Sound effects
-// Boss
-// Power-up
-// Enemy bullet
-// Enemy
-// Player bullet
-// Spaceship (player)
// Play background music
+// Spaceship (player)
+// Player bullet
+// Enemy
+// Enemy bullet
+// Power-up
+// Boss
+// Sound effects
+// Music
LK.playMusic('bgmusic');
// Game variables
var ship;
var playerBullets = [];
@@ -366,9 +366,9 @@
for (var i = playerBullets.length - 1; i >= 0; --i) {
var b = playerBullets[i];
b.update();
// Remove if off screen
- if (b.x > 2048 + 50) {
+ if (b.x > 2048 + 50 || b.x < -50 || b.y > 2732 + 50 || b.y < -50) {
returnPlayerBulletToPool(b, i);
continue;
}
// Check if bullet already marked for removal
@@ -383,9 +383,8 @@
if (Math.abs(e.x - b.x) < 150 && Math.abs(e.y - b.y) < 150) {
if (b.intersects(e)) {
e.hp--;
LK.getSound('explosion').play();
- returnPlayerBulletToPool(b, i);
bulletHitSomething = true;
if (e.hp <= 0) {
LK.setScore(LK.getScore() + 10);
scoreTxt.setText(LK.getScore());
@@ -395,19 +394,19 @@
break;
}
}
}
- // If bullet hit an enemy, continue to next bullet
+ // If bullet hit an enemy, return the bullet to the pool and continue to next bullet
if (bulletHitSomething) {
+ returnPlayerBulletToPool(b, i);
continue;
}
// Hit boss - only check if boss is active and bullet is close to boss
if (bossActive && boss && Math.abs(boss.x - b.x) < 350 && Math.abs(boss.y - b.y) < 250) {
if (b.intersects(boss)) {
boss.hp--;
LK.getSound('explosion').play();
- b.destroy();
- playerBullets.splice(i, 1);
+ returnPlayerBulletToPool(b, i);
if (boss.hp <= 0 && !bossDefeated) {
LK.setScore(LK.getScore() + 100);
scoreTxt.setText(LK.getScore());
boss.destroy();
@@ -466,14 +465,8 @@
LK.effects.flashObject(ship, 0xff0000, 600);
LK.effects.flashScreen(0xff0000, 400);
LK.setScore(Math.max(0, LK.getScore() - 20));
scoreTxt.setText(LK.getScore());
- // Game over if hit while invincible
- if (!ship.invincible) {
- gameOver = true;
- LK.showGameOver();
- return;
- }
}
}
}
// Update enemy bullets - batch process with reduced collision checks
pufferfish disney 2d image style. In-Game asset. 2d. High contrast. No shadows
clown fish disney 2d image style. In-Game asset. 2d. High contrast. No shadows
oval blue sea buble comic 2d image style. In-Game asset. 2d. High contrast. No shadows
green seaweet comic 2d image style. In-Game asset. 2d. High contrast. No shadows
veryy quite coral reef under sea disney 2d image style. In-Game asset. 2d. High contrast. No shadows