/****
* 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;
}
}; /****
* 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;
}
};