/**** * Classes ****/ // City class: represents a city to defend var City = Container.expand(function () { var self = Container.call(this); var cityAsset = self.attachAsset('city', { anchorX: 0.5, anchorY: 1.0 }); self.width = cityAsset.width; self.height = cityAsset.height; self.destroyed = false; self.destroyCity = function () { self.destroyed = true; self.visible = false; }; return self; }); // --- Game Variables --- // CounterMissile class: player's missile var CounterMissile = Container.expand(function () { var self = Container.call(this); var missileAsset = self.attachAsset('counterMissile', { anchorX: 0.5, anchorY: 1.0 }); self.speed = 24; self.targetX = 0; self.targetY = 0; self.lastX = self.x; self.lastY = self.y; self.setTarget = function (x, y) { self.targetX = x; self.targetY = y; var dx = self.targetX - self.x; var dy = self.targetY - self.y; var dist = Math.sqrt(dx * dx + dy * dy); self.vx = dx / dist * self.speed; self.vy = dy / dist * self.speed; // Rotate missile to face direction of travel if (dist > 0) { // The missile asset points up (anchorY: 1.0), so angle is atan2(dx, -dy) // But for standard missile, use atan2(dx, -dy) or atan2(-dy, dx) depending on asset orientation // Here, asset points up, so rotation = Math.atan2(dx, -dy) // But in PIXI, rotation 0 is to the right, so to point up, use Math.atan2(dx, -dy) // Actually, to point the missile in the direction of travel, use Math.atan2(dx, -dy) // But in practice, for a missile pointing up, rotation = Math.atan2(dx, -dy) // Let's use Math.atan2(dx, -dy) self.rotation = Math.atan2(dx, -dy); } }; self.update = function () { self.x += self.vx; self.y += self.vy; // Continuously update rotation to face direction of travel if (self.vx !== 0 || self.vy !== 0) { self.rotation = Math.atan2(self.vx, -self.vy); } }; return self; }); // EnemyMissile class: descending enemy missile var EnemyMissile = Container.expand(function () { var self = Container.call(this); var missileAsset = self.attachAsset('enemyMissile', { anchorX: 0.5, anchorY: 0.0 }); self.speed = 6; // Default, will be overridden on spawn self.targetX = 200 + Math.random() * (2048 - 400); self.targetY = 2200 + Math.random() * 400; self.lastY = self.y; self.update = function () { // Move towards target var dx = self.targetX - self.x; var dy = self.targetY - 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; }); // Explosion class: visual effect for missile hit var Explosion = Container.expand(function () { var self = Container.call(this); // Use a simple ellipse shape for explosion var explosionAsset = self.attachAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, scaleX: 1, scaleY: 1, alpha: 0.7 }); self.life = 18; // frames (0.3s at 60fps) self.age = 0; self.update = function () { self.age++; // Animate: grow and fade out explosionAsset.scaleX = explosionAsset.scaleY = 1 + self.age * 0.15; explosionAsset.alpha = Math.max(0, 0.7 * (1 - self.age / self.life)); if (self.age >= self.life) { self.destroy(); } }; return self; }); // MuzzleFlash class: bigger and longer-lived flash at the muzzle when firing var MuzzleFlash = Container.expand(function () { var self = Container.call(this); // Use the new muzzleFlash asset, centered var flashAsset = self.attachAsset('muzzleFlash', { anchorX: 0.5, anchorY: 1.0, scaleX: 1.2, scaleY: 0.6, alpha: 0.85 }); self.life = 28; // frames (~0.47s at 60fps), even longer self.age = 0; self.update = function () { self.age++; // Animate: fade out only (no scale animation) flashAsset.scaleX = 1.2; flashAsset.scaleY = 0.6; flashAsset.alpha = Math.max(0, 0.85 * (1 - self.age / self.life)); if (self.age >= self.life) { self.destroy(); } }; return self; }); // Player class: controls the anti-missile battery var Player = Container.expand(function () { var self = Container.call(this); var playerAsset = self.attachAsset('playerBattery', { anchorX: 0.5, anchorY: 0.5 }); self.width = playerAsset.width; self.height = playerAsset.height; self.update = function () {}; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // --- Game Variables --- var player; var cities = []; var enemyMissiles = []; var counterMissiles = []; var scoreText; var spawnTimer; var gameOver = false; // Cooldown for counter missile firing var canFire = true; var fireCooldownTimer = null; // --- Add background image --- var background = LK.getAsset('background', { anchorX: 0, anchorY: 0, x: 0, y: 0, width: 2048, height: 2732 }); game.addChildAt(background, 0); // --- Setup Game Elements --- function setupGame() { // Add player battery at bottom center player = new Player(); player.x = 2048 / 2; player.y = 2350; game.addChild(player); // Add cities to defend var cityCount = 5; var spacing = 2048 / (cityCount + 1); for (var i = 0; i < cityCount; i++) { var city = new City(); city.x = spacing * (i + 1); city.y = 2650; game.addChild(city); cities.push(city); } ; // --- Update explosions --- if (typeof explosions === "undefined") { explosions = []; } // Find all explosions in game.children and update them, remove if destroyed for (var i = game.children.length - 1; i >= 0; i--) { var obj = game.children[i]; if (obj && obj.update && obj.constructor && obj.constructor.name === "Explosion") { obj.update(); if (obj.destroyed) { game.removeChild(obj); } } } // Score text scoreText = new Text2('0', { size: 120, fill: "#fff" }); scoreText.anchor.set(0.5, 0); LK.gui.top.addChild(scoreText); // Start enemy missile spawn timer spawnTimer = LK.setInterval(spawnEnemyMissile, 60 * 8); } // --- Calculate enemy missile speed based on score --- function getEnemyMissileSpeed() { // Base speed is 6, increases up to +10 as score increases, capped at 16 var base = 6; var max = 16; var score = LK.getScore(); var speed = base + Math.min(10, Math.floor(score / 500)); // Increase speed by 75% if only one base is left if (typeof cities !== "undefined") { var aliveCities = 0; for (var i = 0; i < cities.length; i++) { if (!cities[i].destroyed) aliveCities++; } if (aliveCities === 1) { speed = speed * 1.75; } } return Math.min(speed, max * 1.75); } // --- Enemy Missile Spawner --- function spawnEnemyMissile() { if (gameOver) return; var missile = new EnemyMissile(); missile.x = 200 + Math.random() * (2048 - 400); missile.y = -80; missile.speed = getEnemyMissileSpeed(); // Target a random city that is not destroyed var aliveCities = cities.filter(function (c) { return !c.destroyed; }); if (aliveCities.length === 0) return; var targetCity = aliveCities[Math.floor(Math.random() * aliveCities.length)]; missile.targetX = targetCity.x; missile.targetY = targetCity.y - 40; // Set missile initial rotation to face the target var dx = missile.targetX - missile.x; var dy = missile.targetY - missile.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { missile.vx = dx / dist * missile.speed; missile.vy = dy / dist * missile.speed; missile.rotation = Math.atan2(missile.vx, -missile.vy); } enemyMissiles.push(missile); game.addChild(missile); } // --- Game Touch: Launch CounterMissile or Start Drag --- game.down = function (x, y, obj) { if (gameOver) return; // If touch/click is on the player battery, start dragging // Use bounding box for touch area var px = player.x, py = player.y; var halfW = player.width / 2, halfH = player.height / 2; if (x >= px - halfW && x <= px + halfW && y >= py - halfH && y <= py + halfH) { // Start dragging playerDragging = true; player.dragTargetX = x; return; } if (!canFire) return; // Only allow firing from above the player if (y < player.y - 100) { var missile = new CounterMissile(); missile.x = player.x; missile.y = player.y - 60; missile.setTarget(x, y); counterMissiles.push(missile); game.addChild(missile); // --- Muzzle flash effect at missile launch position and direction --- var muzzleFlash = new MuzzleFlash(); // Place muzzle flash at the missile's initial position muzzleFlash.x = missile.x; muzzleFlash.y = missile.y; // Align muzzle flash rotation to match the missile's rotation muzzleFlash.rotation = missile.rotation; game.addChild(muzzleFlash); // Start cooldown canFire = false; if (fireCooldownTimer !== null) { LK.clearTimeout(fireCooldownTimer); } fireCooldownTimer = LK.setTimeout(function () { canFire = true; fireCooldownTimer = null; }, 300); } }; // --- Game Move: Drag Counter Battery if dragging --- game.move = function (x, y, obj) { if (gameOver) return; if (typeof playerDragging !== "undefined" && playerDragging) { player.dragTargetX = x; } }; // --- Game Up: End Drag --- game.up = function (x, y, obj) { if (typeof playerDragging !== "undefined" && playerDragging) { playerDragging = false; } }; // --- Game Update Loop --- game.update = function () { if (gameOver) return; // --- Moveable Counter Battery (Player) --- if (typeof playerDragging !== "undefined" && playerDragging) { // Clamp player.x to within game bounds (leave some margin for battery width) var minX = player.width / 2; var maxX = 2048 - player.width / 2; if (player.dragTargetX < minX) player.x = minX;else if (player.dragTargetX > maxX) player.x = maxX;else player.x = player.dragTargetX; } // --- Update and remove muzzle flashes --- for (var i = game.children.length - 1; i >= 0; i--) { var obj = game.children[i]; if (obj && obj.update && obj.constructor && obj.constructor.name === "MuzzleFlash") { obj.update(); if (obj.destroyed) { game.removeChild(obj); } } } // Update enemy missiles for (var i = enemyMissiles.length - 1; i >= 0; i--) { var em = enemyMissiles[i]; em.update(); // Check if hit a city for (var j = 0; j < cities.length; j++) { var city = cities[j]; if (!city.destroyed && em.intersects(city)) { // Spawn explosion at city location var explosion = new Explosion(); explosion.x = city.x; explosion.y = city.y - city.height / 2; game.addChild(explosion); city.destroyCity(); // Deduct score based on how many cities have been destroyed var destroyedCount = 0; for (var d = 0; d < cities.length; d++) { if (cities[d].destroyed) destroyedCount++; } var penalty = 0; if (destroyedCount === 1) penalty = 500;else if (destroyedCount === 2) penalty = 750;else if (destroyedCount === 3) penalty = 1000;else if (destroyedCount === 4) penalty = 1250; // Do not lose any points if the last base is destroyed (destroyedCount === 5) if (penalty > 0) { LK.setScore(Math.max(0, LK.getScore() - penalty)); scoreText.setText(LK.getScore()); } em.destroy(); enemyMissiles.splice(i, 1); // Check for game over if (cities.filter(function (c) { return !c.destroyed; }).length === 0) { gameOver = true; LK.showGameOver(); } break; } } // Remove if off screen or landed on empty space or destroyed base if (em.y > 2732) { // Check if landed on a destroyed base var landedOnDestroyedBase = false; for (var j = 0; j < cities.length; j++) { var city = cities[j]; if (city.destroyed && em.intersects(city)) { landedOnDestroyedBase = true; break; } } // Spawn explosion at missile's last position if it didn't hit a city or landed on destroyed base var explosion = new Explosion(); explosion.x = em.x; explosion.y = em.y; game.addChild(explosion); em.destroy(); enemyMissiles.splice(i, 1); } } // Update counter missiles for (var i = counterMissiles.length - 1; i >= 0; i--) { var cm = counterMissiles[i]; cm.update(); // Remove if off screen if (cm.x < 0 || cm.x > 2048 || cm.y < 0 || cm.y > 2732) { cm.destroy(); counterMissiles.splice(i, 1); continue; } // Check for collision with enemy missiles for (var j = enemyMissiles.length - 1; j >= 0; j--) { var em = enemyMissiles[j]; if (cm.intersects(em)) { // Spawn explosion at collision point var explosion = new Explosion(); explosion.x = em.x; explosion.y = em.y; game.addChild(explosion); // Destroy both cm.destroy(); em.destroy(); counterMissiles.splice(i, 1); enemyMissiles.splice(j, 1); // Score LK.setScore(LK.getScore() + 100); scoreText.setText(LK.getScore()); break; } } } }; // --- Start Game --- setupGame();
/****
* Classes
****/
// City class: represents a city to defend
var City = Container.expand(function () {
var self = Container.call(this);
var cityAsset = self.attachAsset('city', {
anchorX: 0.5,
anchorY: 1.0
});
self.width = cityAsset.width;
self.height = cityAsset.height;
self.destroyed = false;
self.destroyCity = function () {
self.destroyed = true;
self.visible = false;
};
return self;
});
// --- Game Variables ---
// CounterMissile class: player's missile
var CounterMissile = Container.expand(function () {
var self = Container.call(this);
var missileAsset = self.attachAsset('counterMissile', {
anchorX: 0.5,
anchorY: 1.0
});
self.speed = 24;
self.targetX = 0;
self.targetY = 0;
self.lastX = self.x;
self.lastY = self.y;
self.setTarget = function (x, y) {
self.targetX = x;
self.targetY = y;
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
self.vx = dx / dist * self.speed;
self.vy = dy / dist * self.speed;
// Rotate missile to face direction of travel
if (dist > 0) {
// The missile asset points up (anchorY: 1.0), so angle is atan2(dx, -dy)
// But for standard missile, use atan2(dx, -dy) or atan2(-dy, dx) depending on asset orientation
// Here, asset points up, so rotation = Math.atan2(dx, -dy)
// But in PIXI, rotation 0 is to the right, so to point up, use Math.atan2(dx, -dy)
// Actually, to point the missile in the direction of travel, use Math.atan2(dx, -dy)
// But in practice, for a missile pointing up, rotation = Math.atan2(dx, -dy)
// Let's use Math.atan2(dx, -dy)
self.rotation = Math.atan2(dx, -dy);
}
};
self.update = function () {
self.x += self.vx;
self.y += self.vy;
// Continuously update rotation to face direction of travel
if (self.vx !== 0 || self.vy !== 0) {
self.rotation = Math.atan2(self.vx, -self.vy);
}
};
return self;
});
// EnemyMissile class: descending enemy missile
var EnemyMissile = Container.expand(function () {
var self = Container.call(this);
var missileAsset = self.attachAsset('enemyMissile', {
anchorX: 0.5,
anchorY: 0.0
});
self.speed = 6; // Default, will be overridden on spawn
self.targetX = 200 + Math.random() * (2048 - 400);
self.targetY = 2200 + Math.random() * 400;
self.lastY = self.y;
self.update = function () {
// Move towards target
var dx = self.targetX - self.x;
var dy = self.targetY - 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;
});
// Explosion class: visual effect for missile hit
var Explosion = Container.expand(function () {
var self = Container.call(this);
// Use a simple ellipse shape for explosion
var explosionAsset = self.attachAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1,
scaleY: 1,
alpha: 0.7
});
self.life = 18; // frames (0.3s at 60fps)
self.age = 0;
self.update = function () {
self.age++;
// Animate: grow and fade out
explosionAsset.scaleX = explosionAsset.scaleY = 1 + self.age * 0.15;
explosionAsset.alpha = Math.max(0, 0.7 * (1 - self.age / self.life));
if (self.age >= self.life) {
self.destroy();
}
};
return self;
});
// MuzzleFlash class: bigger and longer-lived flash at the muzzle when firing
var MuzzleFlash = Container.expand(function () {
var self = Container.call(this);
// Use the new muzzleFlash asset, centered
var flashAsset = self.attachAsset('muzzleFlash', {
anchorX: 0.5,
anchorY: 1.0,
scaleX: 1.2,
scaleY: 0.6,
alpha: 0.85
});
self.life = 28; // frames (~0.47s at 60fps), even longer
self.age = 0;
self.update = function () {
self.age++;
// Animate: fade out only (no scale animation)
flashAsset.scaleX = 1.2;
flashAsset.scaleY = 0.6;
flashAsset.alpha = Math.max(0, 0.85 * (1 - self.age / self.life));
if (self.age >= self.life) {
self.destroy();
}
};
return self;
});
// Player class: controls the anti-missile battery
var Player = Container.expand(function () {
var self = Container.call(this);
var playerAsset = self.attachAsset('playerBattery', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = playerAsset.width;
self.height = playerAsset.height;
self.update = function () {};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// --- Game Variables ---
var player;
var cities = [];
var enemyMissiles = [];
var counterMissiles = [];
var scoreText;
var spawnTimer;
var gameOver = false;
// Cooldown for counter missile firing
var canFire = true;
var fireCooldownTimer = null;
// --- Add background image ---
var background = LK.getAsset('background', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0,
width: 2048,
height: 2732
});
game.addChildAt(background, 0);
// --- Setup Game Elements ---
function setupGame() {
// Add player battery at bottom center
player = new Player();
player.x = 2048 / 2;
player.y = 2350;
game.addChild(player);
// Add cities to defend
var cityCount = 5;
var spacing = 2048 / (cityCount + 1);
for (var i = 0; i < cityCount; i++) {
var city = new City();
city.x = spacing * (i + 1);
city.y = 2650;
game.addChild(city);
cities.push(city);
}
;
// --- Update explosions ---
if (typeof explosions === "undefined") {
explosions = [];
}
// Find all explosions in game.children and update them, remove if destroyed
for (var i = game.children.length - 1; i >= 0; i--) {
var obj = game.children[i];
if (obj && obj.update && obj.constructor && obj.constructor.name === "Explosion") {
obj.update();
if (obj.destroyed) {
game.removeChild(obj);
}
}
}
// Score text
scoreText = new Text2('0', {
size: 120,
fill: "#fff"
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
// Start enemy missile spawn timer
spawnTimer = LK.setInterval(spawnEnemyMissile, 60 * 8);
}
// --- Calculate enemy missile speed based on score ---
function getEnemyMissileSpeed() {
// Base speed is 6, increases up to +10 as score increases, capped at 16
var base = 6;
var max = 16;
var score = LK.getScore();
var speed = base + Math.min(10, Math.floor(score / 500));
// Increase speed by 75% if only one base is left
if (typeof cities !== "undefined") {
var aliveCities = 0;
for (var i = 0; i < cities.length; i++) {
if (!cities[i].destroyed) aliveCities++;
}
if (aliveCities === 1) {
speed = speed * 1.75;
}
}
return Math.min(speed, max * 1.75);
}
// --- Enemy Missile Spawner ---
function spawnEnemyMissile() {
if (gameOver) return;
var missile = new EnemyMissile();
missile.x = 200 + Math.random() * (2048 - 400);
missile.y = -80;
missile.speed = getEnemyMissileSpeed();
// Target a random city that is not destroyed
var aliveCities = cities.filter(function (c) {
return !c.destroyed;
});
if (aliveCities.length === 0) return;
var targetCity = aliveCities[Math.floor(Math.random() * aliveCities.length)];
missile.targetX = targetCity.x;
missile.targetY = targetCity.y - 40;
// Set missile initial rotation to face the target
var dx = missile.targetX - missile.x;
var dy = missile.targetY - missile.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 0) {
missile.vx = dx / dist * missile.speed;
missile.vy = dy / dist * missile.speed;
missile.rotation = Math.atan2(missile.vx, -missile.vy);
}
enemyMissiles.push(missile);
game.addChild(missile);
}
// --- Game Touch: Launch CounterMissile or Start Drag ---
game.down = function (x, y, obj) {
if (gameOver) return;
// If touch/click is on the player battery, start dragging
// Use bounding box for touch area
var px = player.x,
py = player.y;
var halfW = player.width / 2,
halfH = player.height / 2;
if (x >= px - halfW && x <= px + halfW && y >= py - halfH && y <= py + halfH) {
// Start dragging
playerDragging = true;
player.dragTargetX = x;
return;
}
if (!canFire) return;
// Only allow firing from above the player
if (y < player.y - 100) {
var missile = new CounterMissile();
missile.x = player.x;
missile.y = player.y - 60;
missile.setTarget(x, y);
counterMissiles.push(missile);
game.addChild(missile);
// --- Muzzle flash effect at missile launch position and direction ---
var muzzleFlash = new MuzzleFlash();
// Place muzzle flash at the missile's initial position
muzzleFlash.x = missile.x;
muzzleFlash.y = missile.y;
// Align muzzle flash rotation to match the missile's rotation
muzzleFlash.rotation = missile.rotation;
game.addChild(muzzleFlash);
// Start cooldown
canFire = false;
if (fireCooldownTimer !== null) {
LK.clearTimeout(fireCooldownTimer);
}
fireCooldownTimer = LK.setTimeout(function () {
canFire = true;
fireCooldownTimer = null;
}, 300);
}
};
// --- Game Move: Drag Counter Battery if dragging ---
game.move = function (x, y, obj) {
if (gameOver) return;
if (typeof playerDragging !== "undefined" && playerDragging) {
player.dragTargetX = x;
}
};
// --- Game Up: End Drag ---
game.up = function (x, y, obj) {
if (typeof playerDragging !== "undefined" && playerDragging) {
playerDragging = false;
}
};
// --- Game Update Loop ---
game.update = function () {
if (gameOver) return;
// --- Moveable Counter Battery (Player) ---
if (typeof playerDragging !== "undefined" && playerDragging) {
// Clamp player.x to within game bounds (leave some margin for battery width)
var minX = player.width / 2;
var maxX = 2048 - player.width / 2;
if (player.dragTargetX < minX) player.x = minX;else if (player.dragTargetX > maxX) player.x = maxX;else player.x = player.dragTargetX;
}
// --- Update and remove muzzle flashes ---
for (var i = game.children.length - 1; i >= 0; i--) {
var obj = game.children[i];
if (obj && obj.update && obj.constructor && obj.constructor.name === "MuzzleFlash") {
obj.update();
if (obj.destroyed) {
game.removeChild(obj);
}
}
}
// Update enemy missiles
for (var i = enemyMissiles.length - 1; i >= 0; i--) {
var em = enemyMissiles[i];
em.update();
// Check if hit a city
for (var j = 0; j < cities.length; j++) {
var city = cities[j];
if (!city.destroyed && em.intersects(city)) {
// Spawn explosion at city location
var explosion = new Explosion();
explosion.x = city.x;
explosion.y = city.y - city.height / 2;
game.addChild(explosion);
city.destroyCity();
// Deduct score based on how many cities have been destroyed
var destroyedCount = 0;
for (var d = 0; d < cities.length; d++) {
if (cities[d].destroyed) destroyedCount++;
}
var penalty = 0;
if (destroyedCount === 1) penalty = 500;else if (destroyedCount === 2) penalty = 750;else if (destroyedCount === 3) penalty = 1000;else if (destroyedCount === 4) penalty = 1250;
// Do not lose any points if the last base is destroyed (destroyedCount === 5)
if (penalty > 0) {
LK.setScore(Math.max(0, LK.getScore() - penalty));
scoreText.setText(LK.getScore());
}
em.destroy();
enemyMissiles.splice(i, 1);
// Check for game over
if (cities.filter(function (c) {
return !c.destroyed;
}).length === 0) {
gameOver = true;
LK.showGameOver();
}
break;
}
}
// Remove if off screen or landed on empty space or destroyed base
if (em.y > 2732) {
// Check if landed on a destroyed base
var landedOnDestroyedBase = false;
for (var j = 0; j < cities.length; j++) {
var city = cities[j];
if (city.destroyed && em.intersects(city)) {
landedOnDestroyedBase = true;
break;
}
}
// Spawn explosion at missile's last position if it didn't hit a city or landed on destroyed base
var explosion = new Explosion();
explosion.x = em.x;
explosion.y = em.y;
game.addChild(explosion);
em.destroy();
enemyMissiles.splice(i, 1);
}
}
// Update counter missiles
for (var i = counterMissiles.length - 1; i >= 0; i--) {
var cm = counterMissiles[i];
cm.update();
// Remove if off screen
if (cm.x < 0 || cm.x > 2048 || cm.y < 0 || cm.y > 2732) {
cm.destroy();
counterMissiles.splice(i, 1);
continue;
}
// Check for collision with enemy missiles
for (var j = enemyMissiles.length - 1; j >= 0; j--) {
var em = enemyMissiles[j];
if (cm.intersects(em)) {
// Spawn explosion at collision point
var explosion = new Explosion();
explosion.x = em.x;
explosion.y = em.y;
game.addChild(explosion);
// Destroy both
cm.destroy();
em.destroy();
counterMissiles.splice(i, 1);
enemyMissiles.splice(j, 1);
// Score
LK.setScore(LK.getScore() + 100);
scoreText.setText(LK.getScore());
break;
}
}
}
};
// --- Start Game ---
setupGame();
a 2d pixel art missile. In-Game asset. 2d. High contrast. No shadows
2d pixel art explosion. In-Game asset. 2d. High contrast. No shadows
2d pixel art military base. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
make the gray concrete shorter. make the clouds smaller, more realistic and less frequent.
a 2d pixel art anti-air battery. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat