User prompt
When the player drops a special bomb, it will directly find and destroy the nearest plane.
User prompt
Let the player drop special powerful bombs when he hits 5 fighter jets.
User prompt
when the game starts, the enemy planes will come vertically.
User prompt
when the game starts, the number of enemy planes will increase consecutively.
User prompt
enemy planes speed up every 30 seconds.
User prompt
put a time bar above the game screen.
User prompt
enemy planes speed up every minute.
User prompt
put an explosion effect when planes are destroyed ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
the player's airplane has a life bar and three hits ends the game.
Code edit (1 edits merged)
Please save this source code
User prompt
Sky Dogfight
Initial prompt
make a game where airplanes fight each other.
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var EnemyBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('enemyBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
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
});
planeGraphics.rotation = Math.PI;
self.speed = 2;
self.lastShot = 0;
self.shotInterval = 120; // 2 seconds at 60fps
self.health = 1;
self.update = function () {
// Move down vertically
self.y += self.speed;
// Shooting logic
self.lastShot++;
if (self.lastShot >= self.shotInterval) {
self.shoot();
self.lastShot = 0;
}
};
self.shoot = function () {
if (self.parent) {
var bullet = new EnemyBullet();
bullet.x = self.x;
bullet.y = self.y + 40;
bullet.lastY = bullet.y;
enemyBullets.push(bullet);
game.addChild(bullet);
LK.getSound('enemyShoot').play();
}
};
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 = -12;
self.update = function () {
self.y += self.speed;
};
return self;
});
var PlayerPlane = Container.expand(function () {
var self = Container.call(this);
var planeGraphics = self.attachAsset('playerPlane', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 3;
self.lastShot = 0;
self.shotCooldown = 10; // shots per second limit
self.shoot = function () {
if (self.lastShot <= 0) {
var bullet = new PlayerBullet();
bullet.x = self.x;
bullet.y = self.y - 50;
bullet.lastY = bullet.y;
playerBullets.push(bullet);
game.addChild(bullet);
LK.getSound('shoot').play();
self.lastShot = self.shotCooldown;
}
};
self.dropBomb = function () {
if (specialBombsAvailable > 0) {
// Find nearest enemy plane
var nearestEnemy = null;
var nearestDistance = Infinity;
for (var i = 0; i < enemyPlanes.length; i++) {
var enemy = enemyPlanes[i];
var dx = self.x - enemy.x;
var dy = self.y - enemy.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < nearestDistance) {
nearestDistance = distance;
nearestEnemy = enemy;
}
}
// If we found an enemy, destroy it directly
if (nearestEnemy) {
// Award score for bomb kill
LK.setScore(LK.getScore() + 20);
scoreTxt.setText('Score: ' + LK.getScore());
// Track fighter jets hit
fighterJetsHit++;
if (fighterJetsHit >= 5) {
// Award special bomb every 5 hits
specialBombsAvailable++;
bombTxt.setText('Bombs: ' + specialBombsAvailable);
fighterJetsHit = 0; // Reset counter
}
// Destroy enemy with explosion
LK.effects.flashObject(nearestEnemy, 0xff0000, 300);
LK.getSound('explosion').play();
createExplosion(nearestEnemy);
// Remove from enemy planes array
for (var j = enemyPlanes.length - 1; j >= 0; j--) {
if (enemyPlanes[j] === nearestEnemy) {
enemyPlanes.splice(j, 1);
break;
}
}
// Create flash effect to show bomb was used
LK.effects.flashScreen(0xFFFF00, 300);
}
specialBombsAvailable--;
bombTxt.setText('Bombs: ' + specialBombsAvailable);
LK.getSound('shoot').play();
}
};
self.update = function () {
if (self.lastShot > 0) {
self.lastShot--;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Game variables
var playerPlane;
var enemyPlanes = [];
var playerBullets = [];
var enemyBullets = [];
var specialBombs = [];
var enemySpawnTimer = 0;
var enemySpawnInterval = 180; // 3 seconds at 60fps
var difficultyTimer = 0;
var speedIncreaseTimer = 0;
var baseEnemySpeed = 2;
var dragNode = null;
var enemySpawnCount = 1; // Number of enemy planes to spawn at once
var enemyIncreaseTimer = 0;
var fighterJetsHit = 0; // Track number of fighter jets hit
var specialBombsAvailable = 0; // Track available special bombs
var lastTapTime = 0; // For double-tap detection
// Explosion effect function
function createExplosion(target) {
// Create explosion animation using tween
tween(target, {
scaleX: 2,
scaleY: 2,
alpha: 0,
rotation: target.rotation + Math.PI
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
target.destroy();
}
});
}
// Create score display
var scoreTxt = new Text2('Score: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Create life bar display
var lifeTxt = new Text2('Lives: 3', {
size: 80,
fill: 0xFF0000
});
lifeTxt.anchor.set(0.5, 0);
lifeTxt.x = 0;
lifeTxt.y = 100;
LK.gui.top.addChild(lifeTxt);
// Create time bar display
var timeTxt = new Text2('Time: 0:00', {
size: 80,
fill: 0xFFFF00
});
timeTxt.anchor.set(0.5, 0);
timeTxt.x = 0;
timeTxt.y = 200;
LK.gui.top.addChild(timeTxt);
// Create special bomb display
var bombTxt = new Text2('Bombs: 0', {
size: 80,
fill: 0x00FF00
});
bombTxt.anchor.set(0.5, 0);
bombTxt.x = 0;
bombTxt.y = 300;
LK.gui.top.addChild(bombTxt);
// Create player plane
playerPlane = game.addChild(new PlayerPlane());
playerPlane.x = 1024;
playerPlane.y = 2400;
// Game event handlers
function handleMove(x, y, obj) {
if (dragNode) {
// Keep player plane within screen bounds
dragNode.x = Math.max(60, Math.min(1988, x));
dragNode.y = Math.max(40, Math.min(2692, y));
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
// Start dragging player plane
dragNode = playerPlane;
handleMove(x, y, obj);
// Check for double-tap to drop bomb
var currentTime = LK.ticks;
if (currentTime - lastTapTime < 30) {
// 30 ticks = 0.5 seconds
// Double-tap detected - drop bomb
playerPlane.dropBomb();
} else {
// Single tap - shoot bullet
playerPlane.shoot();
}
lastTapTime = currentTime;
};
game.up = function (x, y, obj) {
dragNode = null;
};
// Main game update loop
game.update = function () {
// Update timers
enemySpawnTimer++;
difficultyTimer++;
speedIncreaseTimer++;
// Update time display
var gameTimeSeconds = Math.floor(LK.ticks / 60);
var minutes = Math.floor(gameTimeSeconds / 60);
var seconds = gameTimeSeconds % 60;
var timeString = minutes + ':' + (seconds < 10 ? '0' : '') + seconds;
timeTxt.setText('Time: ' + timeString);
// Increase difficulty over time
if (difficultyTimer % 1800 == 0) {
// Every 30 seconds
enemySpawnInterval = Math.max(60, enemySpawnInterval - 20);
}
// Increase enemy plane speed every 30 seconds
if (speedIncreaseTimer % 1800 == 0) {
// Every 30 seconds (1800 ticks at 60fps)
baseEnemySpeed += 0.5;
// Update speed for all existing enemy planes
for (var k = 0; k < enemyPlanes.length; k++) {
enemyPlanes[k].speed = baseEnemySpeed;
}
}
// Increase enemy spawn count every 45 seconds
enemyIncreaseTimer++;
if (enemyIncreaseTimer % 2700 == 0) {
// Every 45 seconds (2700 ticks at 60fps)
enemySpawnCount++;
}
// Spawn enemy planes
if (enemySpawnTimer >= enemySpawnInterval) {
// Spawn multiple enemy planes based on enemySpawnCount
for (var spawnIndex = 0; spawnIndex < enemySpawnCount; spawnIndex++) {
var enemy = new EnemyPlane();
enemy.x = Math.random() * 1800 + 124;
enemy.y = -100 - spawnIndex * 150; // Offset vertically to avoid overlap
enemy.speed = baseEnemySpeed;
enemy.lastY = enemy.y;
enemy.lastIntersecting = false;
enemyPlanes.push(enemy);
game.addChild(enemy);
}
enemySpawnTimer = 0;
}
// Update 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 >= -50 && bullet.y < -50) {
bullet.destroy();
playerBullets.splice(i, 1);
continue;
}
// Check collision with enemy planes
var hitEnemy = false;
for (var j = enemyPlanes.length - 1; j >= 0; j--) {
var enemy = enemyPlanes[j];
if (bullet.intersects(enemy)) {
// Hit enemy
LK.setScore(LK.getScore() + 10);
scoreTxt.setText('Score: ' + LK.getScore());
// Track fighter jets hit
fighterJetsHit++;
if (fighterJetsHit >= 5) {
// Award special bomb every 5 hits
specialBombsAvailable++;
bombTxt.setText('Bombs: ' + specialBombsAvailable);
fighterJetsHit = 0; // Reset counter
}
// Destroy enemy with explosion
LK.effects.flashObject(enemy, 0xff0000, 300);
LK.getSound('explosion').play();
createExplosion(enemy);
enemyPlanes.splice(j, 1);
// Destroy bullet
bullet.destroy();
playerBullets.splice(i, 1);
hitEnemy = true;
break;
}
}
if (!hitEnemy) {
bullet.lastY = bullet.y;
}
}
// Update 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 player
if (bullet.intersects(playerPlane)) {
// Player hit - reduce life
playerPlane.health--;
lifeTxt.setText('Lives: ' + playerPlane.health);
// Flash player plane red
LK.effects.flashObject(playerPlane, 0xff0000, 500);
LK.getSound('explosion').play();
// Remove the bullet that hit the player
bullet.destroy();
enemyBullets.splice(i, 1);
// Check if player is dead
if (playerPlane.health <= 0) {
createExplosion(playerPlane);
LK.effects.flashScreen(0xff0000, 1000);
LK.setTimeout(function () {
LK.showGameOver();
}, 300);
return;
}
continue;
}
bullet.lastY = bullet.y;
}
// Update enemy planes
for (var i = enemyPlanes.length - 1; i >= 0; i--) {
var enemy = enemyPlanes[i];
if (enemy.lastY === undefined) enemy.lastY = enemy.y;
// Remove enemies that go off screen
if (enemy.lastY <= 2782 && enemy.y > 2782) {
enemy.destroy();
enemyPlanes.splice(i, 1);
continue;
}
// Check collision with player
if (enemy.intersects(playerPlane)) {
// Player hit by enemy plane - reduce life
playerPlane.health--;
lifeTxt.setText('Lives: ' + playerPlane.health);
// Flash player plane red
LK.effects.flashObject(playerPlane, 0xff0000, 500);
LK.getSound('explosion').play();
// Remove the enemy that hit the player
createExplosion(enemy);
enemyPlanes.splice(i, 1);
// Check if player is dead
if (playerPlane.health <= 0) {
createExplosion(playerPlane);
LK.effects.flashScreen(0xff0000, 1000);
LK.setTimeout(function () {
LK.showGameOver();
}, 300);
return;
}
continue;
}
enemy.lastY = enemy.y;
}
// Victory condition - survive for high score
if (LK.getScore() >= 500) {
LK.showYouWin();
}
};
// Start background music
LK.playMusic('bgmusic'); ===================================================================
--- original.js
+++ change.js
@@ -86,14 +86,48 @@
}
};
self.dropBomb = function () {
if (specialBombsAvailable > 0) {
- var bomb = new SpecialBomb();
- bomb.x = self.x;
- bomb.y = self.y - 50;
- bomb.lastY = bomb.y;
- specialBombs.push(bomb);
- game.addChild(bomb);
+ // Find nearest enemy plane
+ var nearestEnemy = null;
+ var nearestDistance = Infinity;
+ for (var i = 0; i < enemyPlanes.length; i++) {
+ var enemy = enemyPlanes[i];
+ var dx = self.x - enemy.x;
+ var dy = self.y - enemy.y;
+ var distance = Math.sqrt(dx * dx + dy * dy);
+ if (distance < nearestDistance) {
+ nearestDistance = distance;
+ nearestEnemy = enemy;
+ }
+ }
+ // If we found an enemy, destroy it directly
+ if (nearestEnemy) {
+ // Award score for bomb kill
+ LK.setScore(LK.getScore() + 20);
+ scoreTxt.setText('Score: ' + LK.getScore());
+ // Track fighter jets hit
+ fighterJetsHit++;
+ if (fighterJetsHit >= 5) {
+ // Award special bomb every 5 hits
+ specialBombsAvailable++;
+ bombTxt.setText('Bombs: ' + specialBombsAvailable);
+ fighterJetsHit = 0; // Reset counter
+ }
+ // Destroy enemy with explosion
+ LK.effects.flashObject(nearestEnemy, 0xff0000, 300);
+ LK.getSound('explosion').play();
+ createExplosion(nearestEnemy);
+ // Remove from enemy planes array
+ for (var j = enemyPlanes.length - 1; j >= 0; j--) {
+ if (enemyPlanes[j] === nearestEnemy) {
+ enemyPlanes.splice(j, 1);
+ break;
+ }
+ }
+ // Create flash effect to show bomb was used
+ LK.effects.flashScreen(0xFFFF00, 300);
+ }
specialBombsAvailable--;
bombTxt.setText('Bombs: ' + specialBombsAvailable);
LK.getSound('shoot').play();
}
@@ -104,24 +138,8 @@
}
};
return self;
});
-var SpecialBomb = Container.expand(function () {
- var self = Container.call(this);
- var bombGraphics = self.attachAsset('playerBullet', {
- anchorX: 0.5,
- anchorY: 0.5
- });
- bombGraphics.tint = 0xFF0000; // Red tint for special bomb
- bombGraphics.scaleX = 2;
- bombGraphics.scaleY = 2;
- self.speed = -8;
- self.explosionRadius = 200;
- self.update = function () {
- self.y += self.speed;
- };
- return self;
-});
/****
* Initialize Game
****/
@@ -353,54 +371,8 @@
continue;
}
bullet.lastY = bullet.y;
}
- // Update special bombs
- for (var i = specialBombs.length - 1; i >= 0; i--) {
- var bomb = specialBombs[i];
- if (bomb.lastY === undefined) bomb.lastY = bomb.y;
- // Remove bombs that go off screen
- if (bomb.lastY >= -50 && bomb.y < -50) {
- bomb.destroy();
- specialBombs.splice(i, 1);
- continue;
- }
- // Check collision with enemy planes (area damage)
- var bombHit = false;
- for (var j = enemyPlanes.length - 1; j >= 0; j--) {
- var enemy = enemyPlanes[j];
- var dx = bomb.x - enemy.x;
- var dy = bomb.y - enemy.y;
- var distance = Math.sqrt(dx * dx + dy * dy);
- if (distance < bomb.explosionRadius) {
- // Hit enemy with area damage
- LK.setScore(LK.getScore() + 20); // Higher score for bomb kills
- scoreTxt.setText('Score: ' + LK.getScore());
- // Track fighter jets hit
- fighterJetsHit++;
- if (fighterJetsHit >= 5) {
- // Award special bomb every 5 hits
- specialBombsAvailable++;
- bombTxt.setText('Bombs: ' + specialBombsAvailable);
- fighterJetsHit = 0; // Reset counter
- }
- // Destroy enemy with explosion
- LK.effects.flashObject(enemy, 0xff0000, 300);
- LK.getSound('explosion').play();
- createExplosion(enemy);
- enemyPlanes.splice(j, 1);
- bombHit = true;
- }
- }
- if (bombHit) {
- // Create larger explosion effect for bomb
- LK.effects.flashScreen(0xFFFF00, 300);
- bomb.destroy();
- specialBombs.splice(i, 1);
- } else {
- bomb.lastY = bomb.y;
- }
- }
// Update enemy planes
for (var i = enemyPlanes.length - 1; i >= 0; i--) {
var enemy = enemyPlanes[i];
if (enemy.lastY === undefined) enemy.lastY = enemy.y;