User prompt
When the player reaches 70 points, a shield will appear on her for 3 seconds and she will not take damage.
User prompt
Player must look in the direction he is shooting
User prompt
After the 2nd background, when you reach 100 points, 3 more backgrounds will appear and in the same way, the enemies in the new background will be replaced by other enemies.
User prompt
When you switch to the new background, the enemies will disappear
User prompt
reset the scoreboard and leveler when it goes to the new background
User prompt
When you win the game, the game does not end and continues in another background
User prompt
add seconds and minutes signs
User prompt
enemies should come less in 2 levels, level 3 should start at 70 score and enemies should increase
User prompt
enemies should come less in 2 levels, level 3 should start at 70 score and enemies should increase
User prompt
HealthPickup ShieldPickup add
User prompt
extra health and shield coming from the surroundings, when you take health, your health increases by 1, when you take a shield, you do not take damage for 5 seconds
User prompt
Die in 3 damage
User prompt
glows red when taking damage from enemies and kills enemies in 3 hits
User prompt
100 score game over
User prompt
The second stage will come after 30 scores.
User prompt
In the second stage, the enemies will come faster and more, and our fire rate will increase.
User prompt
enemies move slower
User prompt
shoot where you click
Code edit (1 edits merged)
Please save this source code
User prompt
Bullet Clash: Enemy Onslaught
User prompt
add enemy variety
Initial prompt
Make me a 3D war game set in space
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Enemy base class var Enemy = Container.expand(function () { var self = Container.call(this); self.type = 'base'; self.speed = 4; self.update = function () {}; return self; }); // Enemy: Spinner (orbits the central target) var EnemySpinner = Enemy.expand(function () { var self = Enemy.call(this); var asset = self.attachAsset('enemySpinner', { anchorX: 0.5, anchorY: 0.5 }); self.type = 'spinner'; self.radius = 400 + Math.random() * 200; self.angle = Math.random() * Math.PI * 2; self.speed = 0.012 + Math.random() * 0.005; self.update = function () { self.angle += self.speed; self.x = centralTarget.x + Math.cos(self.angle) * self.radius; self.y = centralTarget.y + Math.sin(self.angle) * self.radius; }; return self; }); // Enemy: Seeker (moves toward player) var EnemySeeker = Enemy.expand(function () { var self = Enemy.call(this); var asset = self.attachAsset('enemySeeker', { anchorX: 0.5, anchorY: 0.5 }); self.type = 'seeker'; self.speed = 3; self.update = function () { // Move toward player if (!player) return; var dx = player.x - self.x; var dy = player.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { self.x += dx / dist * self.speed; self.y += dy / dist * self.speed; } }; return self; }); // Enemy: Dasher (dashes horizontally or vertically) var EnemyDasher = Enemy.expand(function () { var self = Enemy.call(this); var asset = self.attachAsset('enemyDasher', { anchorX: 0.5, anchorY: 0.5 }); self.type = 'dasher'; self.axis = Math.random() < 0.5 ? 'x' : 'y'; self.speed = 9 + Math.random() * 3; self.direction = Math.random() < 0.5 ? 1 : -1; self.update = function () { if (self.axis === 'x') { self.x += self.speed * self.direction; } else { self.y += self.speed * self.direction; } }; return self; }); // Player class var Player = Container.expand(function () { var self = Container.call(this); var asset = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); self.radius = 700; self.angle = -Math.PI / 2; self.x = 0; self.y = 0; self.updatePosition = function () { self.x = centralTarget.x + Math.cos(self.angle) * self.radius; self.y = centralTarget.y + Math.sin(self.angle) * self.radius; }; self.updatePosition(); return self; }); // Player bullet var PlayerBullet = Container.expand(function () { var self = Container.call(this); var bulletAsset = self.attachAsset('playerBullet', { anchorX: 0.5, anchorY: 0.5 }); // vx, vy will be set on creation self.vx = 0; self.vy = -32; self.update = function () { self.x += self.vx; self.y += self.vy; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x181c20 }); /**** * Game Code ****/ // Music // Sound for hit target // Sound for enemy destroyed // Sound for shooting // Enemy type 3: Dasher // Enemy type 2: Spinner // Enemy type 1: Seeker // Central target // Player bullet // Player character // Central target var centralTarget = LK.getAsset('centralTarget', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 }); game.addChild(centralTarget); // Player var player = new Player(); player.updatePosition(); game.addChild(player); // Bullets and enemies arrays var playerBullets = []; var enemies = []; // Score var scoreTxt = new Text2('0', { size: 120, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Difficulty and spawn control var spawnTimer = 0; var spawnInterval = 90; // frames var enemyTypes = ['seeker']; var difficultyTimer = 0; // Stage control var stage = 1; var fireTimer = 0; var fireInterval = 18; // frames between shots, default for stage 1 // Drag control var dragging = false; var dragStartAngle = 0; var dragStartX = 0; var dragStartY = 0; // Helper: get angle from center to (x, y) function getAngleToCenter(x, y) { var dx = x - centralTarget.x; var dy = y - centralTarget.y; return Math.atan2(dy, dx); } // Move handler: drag around the central target function handleMove(x, y, obj) { if (!dragging) return; var angle = getAngleToCenter(x, y); player.angle = angle; player.updatePosition(); } game.move = handleMove; game.down = function (x, y, obj) { // Only start drag if not on top left 100x100 if (x < 100 && y < 100) return; dragging = true; handleMove(x, y, obj); }; game.up = function (x, y, obj) { dragging = false; }; // Shoot on tap anywhere (except top left) game.down = function (x, y, obj) { if (x < 100 && y < 100) return; // Fire bullet toward tap/click var bullet = new PlayerBullet(); bullet.x = player.x; bullet.y = player.y; bullet.lastY = bullet.y; bullet.lastIntersecting = false; // Calculate direction from player to tap/click var dx = x - player.x; var dy = y - player.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { var speed = 32; bullet.vx = dx / dist * speed; bullet.vy = dy / dist * speed; } else { bullet.vx = 0; bullet.vy = -32; } playerBullets.push(bullet); game.addChild(bullet); LK.getSound('shoot').play(); // Also allow drag dragging = true; handleMove(x, y, obj); }; game.up = function (x, y, obj) { dragging = false; }; // Enemy spawn logic function spawnEnemy() { var type = enemyTypes[Math.floor(Math.random() * enemyTypes.length)]; var enemy; if (type === 'seeker') { enemy = new EnemySeeker(); // Spawn at random edge var edge = Math.floor(Math.random() * 4); if (edge === 0) { // top enemy.x = Math.random() * 2048; enemy.y = -100; } else if (edge === 1) { // right enemy.x = 2048 + 100; enemy.y = Math.random() * 2732; } else if (edge === 2) { // bottom enemy.x = Math.random() * 2048; enemy.y = 2732 + 100; } else { // left enemy.x = -100; enemy.y = Math.random() * 2732; } } else if (type === 'spinner') { enemy = new EnemySpinner(); // Place at random angle enemy.angle = Math.random() * Math.PI * 2; enemy.radius = 400 + Math.random() * 400; enemy.x = centralTarget.x + Math.cos(enemy.angle) * enemy.radius; enemy.y = centralTarget.y + Math.sin(enemy.angle) * enemy.radius; } else if (type === 'dasher') { enemy = new EnemyDasher(); // Start at random edge if (enemy.axis === 'x') { enemy.x = enemy.direction > 0 ? -100 : 2048 + 100; enemy.y = Math.random() * 2732; } else { enemy.x = Math.random() * 2048; enemy.y = enemy.direction > 0 ? -100 : 2732 + 100; } } if (enemy) { enemy.lastIntersectingPlayer = false; enemy.lastIntersectingTarget = false; enemies.push(enemy); game.addChild(enemy); } } // Main update loop game.update = function () { // Difficulty scaling difficultyTimer++; if (difficultyTimer % 600 === 0 && enemyTypes.length < 3) { if (enemyTypes.length === 1) { enemyTypes.push('spinner'); } else if (enemyTypes.length === 2) { enemyTypes.push('dasher'); } if (spawnInterval > 40) spawnInterval -= 10; } // Stage progression: switch to stage 2 at score 15 if (stage === 1 && LK.getScore() >= 15) { stage = 2; spawnInterval = 30; // much faster enemy spawn fireInterval = 7; // much faster fire rate } // Spawn enemies spawnTimer++; if (spawnTimer >= spawnInterval) { // In stage 2, spawn 2 enemies per interval if (stage === 2) { spawnEnemy(); spawnEnemy(); } else { spawnEnemy(); } spawnTimer = 0; } // Automatic fire logic (increased fire rate in stage 2) fireTimer++; if (fireTimer >= fireInterval && dragging) { // Fire bullet toward current player angle (in direction player is facing) var bullet = new PlayerBullet(); bullet.x = player.x; bullet.y = player.y; bullet.lastY = bullet.y; bullet.lastIntersecting = false; // Fire toward central target var dx = centralTarget.x - player.x; var dy = centralTarget.y - player.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { var speed = 32; bullet.vx = dx / dist * speed; bullet.vy = dy / dist * speed; } else { bullet.vx = 0; bullet.vy = -32; } playerBullets.push(bullet); game.addChild(bullet); LK.getSound('shoot').play(); fireTimer = 0; } // Update player bullets for (var i = playerBullets.length - 1; i >= 0; i--) { var bullet = playerBullets[i]; bullet.update(); // Remove if off screen if (bullet.y < -60 || bullet.y > 2732 + 60 || bullet.x < -60 || bullet.x > 2048 + 60) { bullet.destroy(); playerBullets.splice(i, 1); continue; } // Check hit on central target var hitTarget = bullet.intersects(centralTarget); if (!bullet.lastIntersecting && hitTarget) { LK.setScore(LK.getScore() + 1); scoreTxt.setText(LK.getScore()); LK.getSound('targetHit').play(); bullet.destroy(); playerBullets.splice(i, 1); // Win condition if (LK.getScore() >= 30) { LK.showYouWin(); return; } continue; } bullet.lastIntersecting = hitTarget; // Check hit on enemies for (var j = enemies.length - 1; j >= 0; j--) { var enemy = enemies[j]; if (bullet.intersects(enemy)) { LK.getSound('enemyDown').play(); bullet.destroy(); playerBullets.splice(i, 1); enemy.destroy(); enemies.splice(j, 1); break; } } } // Update enemies for (var i = enemies.length - 1; i >= 0; i--) { var enemy = enemies[i]; enemy.update(); // Remove if off screen (for dashers) if (enemy.x < -200 || enemy.x > 2048 + 200 || enemy.y < -200 || enemy.y > 2732 + 200) { enemy.destroy(); enemies.splice(i, 1); continue; } // Check collision with player var hitPlayer = enemy.intersects(player); if (!enemy.lastIntersectingPlayer && hitPlayer) { LK.effects.flashScreen(0xff0000, 800); LK.showGameOver(); return; } enemy.lastIntersectingPlayer = hitPlayer; // Check collision with central target (optional: could penalize or just remove) var hitTarget = enemy.intersects(centralTarget); if (!enemy.lastIntersectingTarget && hitTarget) { // Remove enemy enemy.destroy(); enemies.splice(i, 1); continue; } enemy.lastIntersectingTarget = hitTarget; } }; // Play background music LK.playMusic('bgmusic', { fade: { start: 0, end: 1, duration: 1200 } });
===================================================================
--- original.js
+++ change.js
@@ -155,8 +155,12 @@
var spawnTimer = 0;
var spawnInterval = 90; // frames
var enemyTypes = ['seeker'];
var difficultyTimer = 0;
+// Stage control
+var stage = 1;
+var fireTimer = 0;
+var fireInterval = 18; // frames between shots, default for stage 1
// Drag control
var dragging = false;
var dragStartAngle = 0;
var dragStartX = 0;
@@ -276,14 +280,52 @@
enemyTypes.push('dasher');
}
if (spawnInterval > 40) spawnInterval -= 10;
}
+ // Stage progression: switch to stage 2 at score 15
+ if (stage === 1 && LK.getScore() >= 15) {
+ stage = 2;
+ spawnInterval = 30; // much faster enemy spawn
+ fireInterval = 7; // much faster fire rate
+ }
// Spawn enemies
spawnTimer++;
if (spawnTimer >= spawnInterval) {
- spawnEnemy();
+ // In stage 2, spawn 2 enemies per interval
+ if (stage === 2) {
+ spawnEnemy();
+ spawnEnemy();
+ } else {
+ spawnEnemy();
+ }
spawnTimer = 0;
}
+ // Automatic fire logic (increased fire rate in stage 2)
+ fireTimer++;
+ if (fireTimer >= fireInterval && dragging) {
+ // Fire bullet toward current player angle (in direction player is facing)
+ var bullet = new PlayerBullet();
+ bullet.x = player.x;
+ bullet.y = player.y;
+ bullet.lastY = bullet.y;
+ bullet.lastIntersecting = false;
+ // Fire toward central target
+ var dx = centralTarget.x - player.x;
+ var dy = centralTarget.y - player.y;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ if (dist > 0) {
+ var speed = 32;
+ bullet.vx = dx / dist * speed;
+ bullet.vy = dy / dist * speed;
+ } else {
+ bullet.vx = 0;
+ bullet.vy = -32;
+ }
+ playerBullets.push(bullet);
+ game.addChild(bullet);
+ LK.getSound('shoot').play();
+ fireTimer = 0;
+ }
// Update player bullets
for (var i = playerBullets.length - 1; i >= 0; i--) {
var bullet = playerBullets[i];
bullet.update();