User prompt
musuh datang setiap 10 detik
User prompt
musuh datang setiap 7 detik
User prompt
buat kontrol kapal lebih halus dan tidak kilat ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please fix the bug: 'TypeError: Cannot read properties of null (reading 'x')' in or related to this line: 'if (Math.abs(dragNode.x - targetX) > 5) {' Line Number: 295 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
buat kapal dikontrol swipe dengan gerakan halus ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
fix music
User prompt
add background
User prompt
add background asset
User prompt
kurangi jumlah pesawat musuh menjadi 3
User prompt
delete bomb asset
User prompt
buat animasi tambahan kapal tenggelam saat game over ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
buat animasi ledakkan seperti 3 bola merah meledak saat player kena tembakkan untuk scene game over ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
buat animasi seperti 1 bola merah api ledakkan membesar saat musuh terkena tembakkan ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
tambah asset dengan nama enemyplane2 muncul dari sisi kanan ke kiri ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
perbaiki bahwa tidak ada enemyplane datang dari sisi kanan
User prompt
buat enemyplane musuh datang dari kiri ke kanan
User prompt
kurangi jumlah peluru player agar game tidak crash
User prompt
peluru musuh bisa hancur atau musnah saat kena tembak player ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
buat musuh mati terkena sekali tembak dengan animasi meledak ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
kurang jumlah musuh yang musuh yang muncul agar game tidak crash
User prompt
hilangkan musuh yang bergerak vertical kebawah
User prompt
musuh hanya bisa menembak 5 peluru
User prompt
musuh bisa datang dari kiri menuju kanan dan bisa datang dari kanan menuju kiri
User prompt
reduce enemy number
User prompt
Please fix the bug: 'TypeError: setTimeout is not a function' in or related to this line: 'setTimeout(function () {' Line Number: 228
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Battleship = Container.expand(function () {
var self = Container.call(this);
var shipGraphics = self.attachAsset('battleship', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 3;
self.fireTimer = 0;
self.fireRate = 30; // Fire every 0.5 second (reduced frequency)
self.update = function () {
self.fireTimer++;
// Only fire when timer reaches fire rate and limit total bullets
if (self.fireTimer >= self.fireRate && playerBullets.length < 8) {
self.fireTimer = 0;
var bullet = new PlayerBullet();
bullet.x = self.x;
bullet.y = self.y - 50;
playerBullets.push(bullet);
game.addChild(bullet);
LK.getSound('playerShoot').play();
}
};
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 = 6;
self.update = function () {
self.y += self.speed;
};
return self;
});
var EnemyPlane = Container.expand(function () {
var self = Container.call(this);
var planeGraphics = self.attachAsset('enemyPlane', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2;
self.speedX = 0;
self.speedY = 2;
self.health = 1;
self.fireTimer = 0;
self.fireRate = 120; // Fire every 2 seconds
self.bulletCount = 0; // Track number of bullets fired
self.maxBullets = 5; // Maximum bullets this enemy can fire
self.update = function () {
self.x += self.speedX;
self.y += self.speedY;
self.fireTimer++;
// Fire bullets occasionally
if (self.fireTimer >= self.fireRate && Math.random() < 0.3 && self.bulletCount < self.maxBullets) {
self.fireTimer = 0;
self.bulletCount++; // Increment bullet count
var bullet = new EnemyBullet();
bullet.x = self.x;
bullet.y = self.y + 30;
enemyBullets.push(bullet);
game.addChild(bullet);
}
};
return self;
});
var EnemyPlane2 = Container.expand(function () {
var self = Container.call(this);
var planeGraphics = self.attachAsset('enemyplane2', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2;
self.speedX = 0;
self.speedY = 2;
self.health = 1;
self.fireTimer = 0;
self.fireRate = 120; // Fire every 2 seconds
self.bulletCount = 0; // Track number of bullets fired
self.maxBullets = 5; // Maximum bullets this enemy can fire
self.update = function () {
self.x += self.speedX;
self.y += self.speedY;
self.fireTimer++;
// Fire bullets occasionally
if (self.fireTimer >= self.fireRate && Math.random() < 0.3 && self.bulletCount < self.maxBullets) {
self.fireTimer = 0;
self.bulletCount++; // Increment bullet count
var bullet = new EnemyBullet();
bullet.x = self.x;
bullet.y = self.y + 30;
enemyBullets.push(bullet);
game.addChild(bullet);
}
};
return self;
});
var Explosion = Container.expand(function () {
var self = Container.call(this);
var explosionGraphics = self.attachAsset('explosion', {
anchorX: 0.5,
anchorY: 0.5
});
self.alpha = 0.8;
self.scaleX = 0.1;
self.scaleY = 0.1;
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 = -8;
self.update = function () {
self.y += self.speed;
};
return self;
});
var PlayerExplosion = Container.expand(function () {
var self = Container.call(this);
// Create 3 explosion balls
var ball1 = self.attachAsset('explosion', {
anchorX: 0.5,
anchorY: 0.5
});
var ball2 = self.attachAsset('explosion', {
anchorX: 0.5,
anchorY: 0.5
});
var ball3 = self.attachAsset('explosion', {
anchorX: 0.5,
anchorY: 0.5
});
// Position balls in triangle formation
ball1.x = 0;
ball1.y = -30;
ball2.x = -25;
ball2.y = 20;
ball3.x = 25;
ball3.y = 20;
// Initialize all balls small and transparent
ball1.scaleX = ball1.scaleY = 0.1;
ball2.scaleX = ball2.scaleY = 0.1;
ball3.scaleX = ball3.scaleY = 0.1;
ball1.alpha = ball2.alpha = ball3.alpha = 0.9;
self.explode = function () {
// Animate ball 1
tween(ball1, {
scaleX: 4,
scaleY: 4,
alpha: 0
}, {
duration: 800,
easing: tween.easeOut
});
// Animate ball 2 with slight delay
LK.setTimeout(function () {
tween(ball2, {
scaleX: 3.5,
scaleY: 3.5,
alpha: 0
}, {
duration: 700,
easing: tween.easeOut
});
}, 150);
// Animate ball 3 with more delay
LK.setTimeout(function () {
tween(ball3, {
scaleX: 4.5,
scaleY: 4.5,
alpha: 0
}, {
duration: 900,
easing: tween.easeOut,
onFinish: function onFinish() {
self.destroy();
}
});
}, 300);
};
return self;
});
var SinkingShip = Container.expand(function () {
var self = Container.call(this);
var shipGraphics = self.attachAsset('battleship', {
anchorX: 0.5,
anchorY: 0.5
});
self.sink = function () {
// Animate ship sinking down and rotating
tween(self, {
y: self.y + 200,
rotation: 0.3,
alpha: 0
}, {
duration: 2000,
easing: tween.easeIn,
onFinish: function onFinish() {
self.destroy();
}
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x001122
});
/****
* Game Code
****/
// Add background
var background = game.addChild(LK.getAsset('background', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
}));
// Game variables
var battleship;
var playerBullets = [];
var enemyPlanes = [];
var enemyPlanes2 = [];
var enemyBullets = [];
var waveTimer = 0;
var waveSize = 1;
var enemySpawnRate = 600; // 10 seconds (10 * 60 FPS = 600 ticks)
var dragNode = null;
var targetX = 2048 / 2; // Target position for smooth movement
var isMoving = false; // Track if ship is currently moving
// UI Elements
var scoreTxt = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var healthTxt = new Text2('Health: 3', {
size: 50,
fill: 0xFF0000
});
healthTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(healthTxt);
// Create battleship
battleship = game.addChild(new Battleship());
battleship.x = 2048 / 2;
battleship.y = 2732 - 150;
// Touch/Mouse controls
function handleMove(x, y, obj) {
if (dragNode) {
// Set target position instead of immediate movement
targetX = Math.max(60, Math.min(2048 - 60, x));
// Start smooth movement if not already moving
if (!isMoving) {
isMoving = true;
tween(dragNode, {
x: targetX
}, {
duration: 400,
easing: tween.easeInOut,
onFinish: function onFinish() {
isMoving = false;
// If target changed during movement, start new tween
if (dragNode && Math.abs(dragNode.x - targetX) > 5) {
isMoving = true;
tween(dragNode, {
x: targetX
}, {
duration: 300,
easing: tween.easeInOut,
onFinish: function onFinish() {
isMoving = false;
}
});
}
}
});
} else {
// If already moving, stop current tween and start new one
tween.stop(dragNode, {
x: true
});
isMoving = true;
tween(dragNode, {
x: targetX
}, {
duration: 300,
easing: tween.easeInOut,
onFinish: function onFinish() {
isMoving = false;
}
});
}
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
dragNode = battleship;
handleMove(x, y, obj);
};
game.up = function (x, y, obj) {
dragNode = null;
};
// Spawn enemy waves
function spawnEnemyWave() {
// Spawn exactly 3 enemy planes total
for (var i = 0; i < 3; i++) {
if (i < 2) {
// Spawn 2 regular enemies from left
var enemy = new EnemyPlane();
enemy.x = -50;
enemy.y = 200 + Math.random() * 800;
enemy.speedX = 2 + Math.random() * 2; // Always positive (left to right)
enemy.speedY = 0.5 + Math.random() * 1;
enemyPlanes.push(enemy);
game.addChild(enemy);
} else {
// Spawn 1 enemyplane2 from right
var enemy2 = new EnemyPlane2();
enemy2.x = 2098; // Start from right side
enemy2.y = 200 + Math.random() * 800;
enemy2.speedX = -(2 + Math.random() * 2); // Always negative (right to left)
enemy2.speedY = 0.5 + Math.random() * 1;
enemyPlanes2.push(enemy2);
game.addChild(enemy2);
}
}
}
// Play background music
LK.playMusic('12epicwar');
// Main game update loop
game.update = function () {
waveTimer++;
// Spawn enemy waves
if (waveTimer >= enemySpawnRate) {
waveTimer = 0;
spawnEnemyWave();
// Increase difficulty over time
if (enemySpawnRate > 300) {
// Minimum 5 seconds instead of 3 seconds
enemySpawnRate -= 2;
}
if (waveSize < 2) {
waveSize += 0.1;
}
}
// Update and check player bullets
for (var i = playerBullets.length - 1; i >= 0; i--) {
var bullet = playerBullets[i];
if (bullet.lastY === undefined) bullet.lastY = bullet.y;
// Remove bullets that go off screen
if (bullet.lastY >= -10 && bullet.y < -10) {
bullet.destroy();
playerBullets.splice(i, 1);
continue;
}
// Check collision with enemy planes
var hitTarget = false;
for (var j = enemyPlanes.length - 1; j >= 0; j--) {
var enemy = enemyPlanes[j];
if (bullet.intersects(enemy)) {
// Enemy hit - dies in one shot with explosion animation
LK.setScore(LK.getScore() + 100);
scoreTxt.setText('Score: ' + LK.getScore());
LK.getSound('enemyHit').play();
// Create red fire explosion
var explosion = new Explosion();
explosion.x = enemy.x;
explosion.y = enemy.y;
game.addChild(explosion);
// Animate explosion growing and fading
tween(explosion, {
scaleX: 3,
scaleY: 3,
alpha: 0
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
explosion.destroy();
}
});
// Destroy enemy immediately
enemy.destroy();
enemyPlanes.splice(j, 1);
bullet.destroy();
playerBullets.splice(i, 1);
hitTarget = true;
break;
}
}
// Check collision with enemy planes2
if (!hitTarget) {
for (var j = enemyPlanes2.length - 1; j >= 0; j--) {
var enemy2 = enemyPlanes2[j];
if (bullet.intersects(enemy2)) {
// Enemy hit - dies in one shot with explosion animation
LK.setScore(LK.getScore() + 100);
scoreTxt.setText('Score: ' + LK.getScore());
LK.getSound('enemyHit').play();
// Create red fire explosion
var explosion = new Explosion();
explosion.x = enemy2.x;
explosion.y = enemy2.y;
game.addChild(explosion);
// Animate explosion growing and fading
tween(explosion, {
scaleX: 3,
scaleY: 3,
alpha: 0
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
explosion.destroy();
}
});
// Destroy enemy immediately
enemy2.destroy();
enemyPlanes2.splice(j, 1);
bullet.destroy();
playerBullets.splice(i, 1);
hitTarget = true;
break;
}
}
}
// Check collision with enemy bullets
if (!hitTarget) {
for (var k = enemyBullets.length - 1; k >= 0; k--) {
var enemyBullet = enemyBullets[k];
if (bullet.intersects(enemyBullet)) {
// Create explosion animation for both bullets
tween(bullet, {
scaleX: 2,
scaleY: 2,
alpha: 0
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
bullet.destroy();
}
});
tween(enemyBullet, {
scaleX: 2,
scaleY: 2,
alpha: 0
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
enemyBullet.destroy();
}
});
// Flash effect for bullet collision
LK.effects.flashObject(bullet, 0xffff00, 200);
LK.effects.flashObject(enemyBullet, 0xff4500, 200);
playerBullets.splice(i, 1);
enemyBullets.splice(k, 1);
hitTarget = true;
break;
}
}
}
if (!hitTarget) {
bullet.lastY = bullet.y;
}
}
// Update and check enemy planes
for (var i = enemyPlanes.length - 1; i >= 0; i--) {
var enemy = enemyPlanes[i];
if (enemy.lastY === undefined) enemy.lastY = enemy.y;
if (enemy.lastX === undefined) enemy.lastX = enemy.x;
// Remove enemies that go off screen (bottom)
if (enemy.lastY <= 2782 && enemy.y > 2782) {
enemy.destroy();
enemyPlanes.splice(i, 1);
continue;
}
// Remove enemies that go off screen (left side)
if (enemy.lastX >= -100 && enemy.x < -100) {
enemy.destroy();
enemyPlanes.splice(i, 1);
continue;
}
enemy.lastY = enemy.y;
enemy.lastX = enemy.x;
}
// Update and check enemy planes2
for (var i = enemyPlanes2.length - 1; i >= 0; i--) {
var enemy2 = enemyPlanes2[i];
if (enemy2.lastY === undefined) enemy2.lastY = enemy2.y;
if (enemy2.lastX === undefined) enemy2.lastX = enemy2.x;
// Remove enemies that go off screen (bottom)
if (enemy2.lastY <= 2782 && enemy2.y > 2782) {
enemy2.destroy();
enemyPlanes2.splice(i, 1);
continue;
}
// Remove enemies that go off screen (right side)
if (enemy2.lastX <= 2148 && enemy2.x > 2148) {
enemy2.destroy();
enemyPlanes2.splice(i, 1);
continue;
}
enemy2.lastY = enemy2.y;
enemy2.lastX = enemy2.x;
}
// Update and check enemy bullets
for (var i = enemyBullets.length - 1; i >= 0; i--) {
var bullet = enemyBullets[i];
if (bullet.lastY === undefined) bullet.lastY = bullet.y;
// Remove bullets that go off screen
if (bullet.lastY <= 2782 && bullet.y > 2782) {
bullet.destroy();
enemyBullets.splice(i, 1);
continue;
}
// Check collision with battleship
if (bullet.intersects(battleship)) {
battleship.health--;
healthTxt.setText('Health: ' + battleship.health);
LK.effects.flashObject(battleship, 0xff0000, 500);
LK.getSound('playerHit').play();
bullet.destroy();
enemyBullets.splice(i, 1);
if (battleship.health <= 0) {
// Create 3-ball explosion animation
var playerExplosion = new PlayerExplosion();
playerExplosion.x = battleship.x;
playerExplosion.y = battleship.y;
game.addChild(playerExplosion);
playerExplosion.explode();
// Create sinking ship animation
var sinkingShip = new SinkingShip();
sinkingShip.x = battleship.x;
sinkingShip.y = battleship.y;
game.addChild(sinkingShip);
// Hide original battleship
battleship.alpha = 0;
// Start sinking animation after explosion starts
LK.setTimeout(function () {
sinkingShip.sink();
}, 600);
// Show game over after all animations complete
LK.setTimeout(function () {
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
}, 3200);
return;
}
continue;
}
bullet.lastY = bullet.y;
}
}; ===================================================================
--- original.js
+++ change.js
@@ -239,9 +239,9 @@
var enemyPlanes2 = [];
var enemyBullets = [];
var waveTimer = 0;
var waveSize = 1;
-var enemySpawnRate = 420; // 7 seconds (7 * 60 FPS = 420 ticks)
+var enemySpawnRate = 600; // 10 seconds (10 * 60 FPS = 600 ticks)
var dragNode = null;
var targetX = 2048 / 2; // Target position for smooth movement
var isMoving = false; // Track if ship is currently moving
// UI Elements
@@ -351,10 +351,10 @@
if (waveTimer >= enemySpawnRate) {
waveTimer = 0;
spawnEnemyWave();
// Increase difficulty over time
- if (enemySpawnRate > 180) {
- // Minimum 3 seconds instead of 1 second
+ if (enemySpawnRate > 300) {
+ // Minimum 5 seconds instead of 3 seconds
enemySpawnRate -= 2;
}
if (waveSize < 2) {
waveSize += 0.1;