/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Bomb = Container.expand(function () {
var self = Container.call(this);
var bombGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0x444444,
scaleX: 2,
scaleY: 2
});
self.speed = 4;
self.damage = 2;
self.update = function () {
self.y += self.speed;
};
return self;
});
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -12;
self.damage = 1;
self.update = function () {
self.y += self.speed;
};
return self;
});
var Cloud = Container.expand(function () {
var self = Container.call(this);
var cloudType = ['cloud1', 'cloud2', 'cloud3'][Math.floor(Math.random() * 3)];
var cloudGraphics = self.attachAsset(cloudType, {
anchorX: 0.5,
anchorY: 0.5
});
cloudGraphics.alpha = 0.7;
self.speed = Math.random() * 2 + 1;
self.update = function () {
self.y += self.speed;
};
return self;
});
// Game variables
var Enemy1 = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy1', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 3;
self.health = 1;
self.scoreValue = 10;
self.enemyType = 1;
self.update = function () {
self.y += self.speed;
};
return self;
});
var Enemy2 = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy2', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 4;
self.health = 2;
self.scoreValue = 20;
self.enemyType = 2;
self.nextBombTime = 0;
self.bombInterval = Math.random() * 1500 + 3000; // Random between 3-4.5 seconds
self.update = function () {
self.y += self.speed;
// Zigzag movement
self.x += Math.sin(LK.ticks * 0.1) * 2;
// Drop bombs every 3-4.5 seconds
if (LK.ticks * 16.67 >= self.nextBombTime) {
// Convert ticks to milliseconds (60fps = 16.67ms per tick)
var bomb = new Bomb();
bomb.x = self.x;
bomb.y = self.y + 40;
bombs.push(bomb);
game.addChild(bomb);
// Set next bomb time (3-4.5 seconds from now)
self.bombInterval = Math.random() * 1500 + 3000;
self.nextBombTime = LK.ticks * 16.67 + self.bombInterval;
}
// Shoot bullets every 60 ticks
if (LK.ticks % 60 === 0) {
var enemyBullet = new EnemyBullet();
enemyBullet.x = self.x;
enemyBullet.y = self.y + 40;
enemyBullets.push(enemyBullet);
game.addChild(enemyBullet);
}
};
return self;
});
var Enemy3 = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy3', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 5;
self.health = 1;
self.scoreValue = 15;
self.enemyType = 3;
self.hasSpottedPlayer = false; // Track if this Enemy3 has already spotted the player
self.update = function () {
self.y += self.speed;
// Scout behavior - scan for player when in range
var distanceToPlayer = Math.abs(self.x - player.x);
var verticalDistance = Math.abs(self.y - player.y);
// If Enemy3 is close enough to "spot" the player (within scanning range)
if (distanceToPlayer < 300 && verticalDistance < 400 && !self.hasSpottedPlayer) {
self.hasSpottedPlayer = true;
// Show warning text
warningTxt.alpha = 1;
tween(warningTxt, {
alpha: 0
}, {
duration: 3000
}); // Fade out warning over 3 seconds
// Trigger Enemy2 spawn after warning
LK.setTimeout(function () {
var enemy2 = new Enemy2();
enemy2.x = Math.random() * 1900 + 100;
enemy2.y = -50;
enemy2.speed += Math.floor(currentWave / 3);
enemies.push(enemy2);
game.addChild(enemy2);
}, 1000); // Spawn Enemy2 1 second after warning appears
}
};
return self;
});
var Enemy4 = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy1', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0x800080
});
self.speed = 2;
self.health = 3;
self.scoreValue = 30;
self.enemyType = 4;
self.direction = 1; // 1 for right, -1 for left
self.verticalMoveTimer = 0;
self.update = function () {
// Horizontal movement back and forth
self.x += self.direction * 3;
// Change direction when reaching screen edges
if (self.x <= 100 || self.x >= 1948) {
self.direction *= -1;
self.y += 50; // Move down when changing direction
}
// Slow vertical movement
self.verticalMoveTimer++;
if (self.verticalMoveTimer > 30) {
self.y += self.speed;
self.verticalMoveTimer = 0;
}
// Shoot triple bullets every 90 ticks
if (LK.ticks % 90 === 0) {
// Center bullet
var centerBullet = new EnemyBullet();
centerBullet.x = self.x;
centerBullet.y = self.y + 40;
enemyBullets.push(centerBullet);
game.addChild(centerBullet);
// Left bullet
var leftBullet = new EnemyBullet();
leftBullet.x = self.x - 30;
leftBullet.y = self.y + 40;
enemyBullets.push(leftBullet);
game.addChild(leftBullet);
// Right bullet
var rightBullet = new EnemyBullet();
rightBullet.x = self.x + 30;
rightBullet.y = self.y + 40;
enemyBullets.push(rightBullet);
game.addChild(rightBullet);
}
};
return self;
});
var EnemyBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0xff0000
});
self.speed = 8;
self.damage = 1;
self.update = function () {
self.y += self.speed;
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.health = 3;
self.update = function () {
// Keep player in bounds - only allow movement along bottom edge
if (self.x < 40) self.x = 40;
if (self.x > 2008) self.x = 2008;
// Force player to stay at bottom of screen
self.y = 2400;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Game variables
var player;
var enemies = [];
var bullets = [];
var enemyBullets = [];
var bombs = [];
var clouds = [];
var score = 0;
var totalKills = 0;
var enemySpawnTimer = 0;
var cloudSpawnTimer = 0;
var currentWave = 1;
var enemiesSpawnedThisWave = 0;
var enemiesKilledThisWave = 0;
var enemiesPerWave = 5;
var waveInProgress = false;
var waveStartDelay = 0;
var maxEnemySpawnRate = 60;
// Initialize background clouds
for (var i = 0; i < 8; i++) {
var cloud = new Cloud();
cloud.x = Math.random() * 2048;
cloud.y = Math.random() * 2732;
clouds.push(cloud);
game.addChild(cloud);
}
// Create player
player = game.addChild(new Player());
player.x = 1024;
player.y = 2400;
// Score display
var scoreTxt = new Text2('Score: ' + score, {
size: 60,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0, 0);
LK.gui.topLeft.addChild(scoreTxt);
scoreTxt.x = 120;
scoreTxt.y = 20;
// Wave display
var waveTxt = new Text2('Wave: ' + currentWave, {
size: 60,
fill: 0xFFFF00
});
waveTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(waveTxt);
waveTxt.y = 20;
// Health display
var healthTxt = new Text2('Health: ' + player.health, {
size: 60,
fill: 0xFF0000
});
healthTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(healthTxt);
healthTxt.x = -20;
healthTxt.y = 20;
// Kills counter display
var killsTxt = new Text2('Kills: ' + totalKills, {
size: 60,
fill: 0x00FF00
});
killsTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(killsTxt);
killsTxt.x = -20;
killsTxt.y = 90;
// Warning text (initially hidden)
var warningTxt = new Text2('WARNING', {
size: 120,
fill: 0xFF0000
});
warningTxt.anchor.set(0.5, 0.5);
LK.gui.center.addChild(warningTxt);
warningTxt.alpha = 0; // Initially hidden
// Touch input handling for player movement
game.down = function (x, y, obj) {
// Move player to touch x position, keeping y at bottom
player.x = x;
};
game.move = function (x, y, obj) {
// Move player to touch x position while dragging
player.x = x;
};
// Main game loop
game.update = function () {
// Spawn new clouds
cloudSpawnTimer++;
if (cloudSpawnTimer > 120) {
var cloud = new Cloud();
cloud.x = Math.random() * 2048;
cloud.y = -100;
clouds.push(cloud);
game.addChild(cloud);
cloudSpawnTimer = 0;
}
// Update clouds
for (var i = clouds.length - 1; i >= 0; i--) {
var cloud = clouds[i];
if (cloud.y > 2800) {
cloud.destroy();
clouds.splice(i, 1);
}
}
// Continuous shooting every 10 ticks - bullets spawn from player position
if (LK.ticks % 10 === 0) {
var bullet = new Bullet();
bullet.x = player.x; // Spawn bullet at player's exact x position
bullet.y = player.y - 60; // Spawn bullet slightly above player
bullets.push(bullet);
game.addChild(bullet);
LK.getSound('shoot').play();
}
// Wave system - spawn enemies based on current wave
if (!waveInProgress && waveStartDelay <= 0) {
// Start new wave
waveInProgress = true;
enemiesSpawnedThisWave = 0;
enemiesKilledThisWave = 0;
enemiesPerWave = Math.min(5 + currentWave * 2, 20); // Increase enemies per wave, cap at 20
maxEnemySpawnRate = Math.max(30, 60 - currentWave * 3); // Faster spawning each wave, minimum 30 ticks
waveTxt.setText('Wave: ' + currentWave);
}
if (waveInProgress && enemiesSpawnedThisWave < enemiesPerWave) {
enemySpawnTimer++;
if (enemySpawnTimer > maxEnemySpawnRate) {
// Randomly choose enemy type
var enemyType = Math.floor(Math.random() * 3) + 1;
var enemy;
if (enemyType === 1) {
enemy = new Enemy1();
} else if (enemyType === 2) {
enemy = new Enemy2();
} else {
enemy = new Enemy3();
}
enemy.x = Math.random() * 1900 + 100;
enemy.y = -50;
// Make enemies faster in later waves
enemy.speed += Math.floor(currentWave / 3);
enemies.push(enemy);
game.addChild(enemy);
enemySpawnTimer = 0;
enemiesSpawnedThisWave++;
}
}
// Update bullets
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
// Remove bullets that are off screen
if (bullet.y < -50) {
bullet.destroy();
bullets.splice(i, 1);
continue;
}
// Check bullet-enemy collisions
for (var j = enemies.length - 1; j >= 0; j--) {
var enemy = enemies[j];
if (bullet.intersects(enemy)) {
// Damage enemy
enemy.health -= bullet.damage;
bullet.destroy();
bullets.splice(i, 1);
// Check if enemy is destroyed
if (enemy.health <= 0) {
LK.getSound('explosion').play();
// Create explosion visual at enemy position
var explosion = LK.getAsset('Bomm', {
anchorX: 0.5,
anchorY: 0.5
});
explosion.x = enemy.x;
explosion.y = enemy.y;
game.addChild(explosion);
// Animate explosion - scale up and fade out
tween(explosion, {
scaleX: 3,
scaleY: 3,
alpha: 0
}, {
duration: 800,
easing: tween.easeOut,
onFinish: function onFinish() {
explosion.destroy();
}
});
enemy.destroy();
enemies.splice(j, 1);
// Update score based on enemy type and wave
score += enemy.scoreValue * currentWave;
LK.setScore(score);
scoreTxt.setText('Score: ' + score);
// Update kills counter
totalKills++;
killsTxt.setText('Kills: ' + totalKills);
enemiesKilledThisWave++;
// Check if wave is complete
if (waveInProgress && enemiesKilledThisWave >= enemiesPerWave) {
waveInProgress = false;
currentWave++;
waveStartDelay = 120; // 2 second delay between waves
LK.effects.flashScreen(0x00ff00, 500); // Green flash for wave complete
}
} else {
// Enemy damaged but not destroyed - flash red
LK.effects.flashObject(enemy, 0xff0000, 200);
}
break;
}
}
}
// Update enemies
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
// Remove enemies that are off screen
if (enemy.y > 2800) {
enemy.destroy();
enemies.splice(i, 1);
continue;
}
// Check enemy-player collision
if (enemy.intersects(player)) {
player.health--;
healthTxt.setText('Health: ' + player.health);
if (player.health <= 0) {
LK.showGameOver();
} else {
LK.effects.flashObject(player, 0xff0000, 500);
}
enemy.destroy();
enemies.splice(i, 1);
}
}
// Update enemy bullets
for (var i = enemyBullets.length - 1; i >= 0; i--) {
var enemyBullet = enemyBullets[i];
// Remove bullets that are off screen
if (enemyBullet.y > 2800) {
enemyBullet.destroy();
enemyBullets.splice(i, 1);
continue;
}
// Check enemy bullet-player collision
if (enemyBullet.intersects(player)) {
player.health--;
healthTxt.setText('Health: ' + player.health);
enemyBullet.destroy();
enemyBullets.splice(i, 1);
if (player.health <= 0) {
LK.showGameOver();
} else {
LK.effects.flashObject(player, 0xff0000, 500);
}
}
}
// Update bombs
for (var i = bombs.length - 1; i >= 0; i--) {
var bomb = bombs[i];
// Remove bombs that are off screen
if (bomb.y > 2800) {
bomb.destroy();
bombs.splice(i, 1);
continue;
}
// Check bomb-player collision
if (bomb.intersects(player)) {
player.health -= bomb.damage;
healthTxt.setText('Health: ' + player.health);
bomb.destroy();
bombs.splice(i, 1);
if (player.health <= 0) {
LK.showGameOver();
} else {
LK.effects.flashObject(player, 0xff0000, 500);
}
}
}
// Handle wave start delay
if (waveStartDelay > 0) {
waveStartDelay--;
}
// Check if player failed to eliminate all enemies (game over condition)
// If enemies reach the bottom of the screen without being destroyed, it's game over
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
if (enemy.y > 2600) {
// Enemy reached near bottom of screen
LK.showGameOver();
break;
}
}
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Bomb = Container.expand(function () {
var self = Container.call(this);
var bombGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0x444444,
scaleX: 2,
scaleY: 2
});
self.speed = 4;
self.damage = 2;
self.update = function () {
self.y += self.speed;
};
return self;
});
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -12;
self.damage = 1;
self.update = function () {
self.y += self.speed;
};
return self;
});
var Cloud = Container.expand(function () {
var self = Container.call(this);
var cloudType = ['cloud1', 'cloud2', 'cloud3'][Math.floor(Math.random() * 3)];
var cloudGraphics = self.attachAsset(cloudType, {
anchorX: 0.5,
anchorY: 0.5
});
cloudGraphics.alpha = 0.7;
self.speed = Math.random() * 2 + 1;
self.update = function () {
self.y += self.speed;
};
return self;
});
// Game variables
var Enemy1 = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy1', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 3;
self.health = 1;
self.scoreValue = 10;
self.enemyType = 1;
self.update = function () {
self.y += self.speed;
};
return self;
});
var Enemy2 = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy2', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 4;
self.health = 2;
self.scoreValue = 20;
self.enemyType = 2;
self.nextBombTime = 0;
self.bombInterval = Math.random() * 1500 + 3000; // Random between 3-4.5 seconds
self.update = function () {
self.y += self.speed;
// Zigzag movement
self.x += Math.sin(LK.ticks * 0.1) * 2;
// Drop bombs every 3-4.5 seconds
if (LK.ticks * 16.67 >= self.nextBombTime) {
// Convert ticks to milliseconds (60fps = 16.67ms per tick)
var bomb = new Bomb();
bomb.x = self.x;
bomb.y = self.y + 40;
bombs.push(bomb);
game.addChild(bomb);
// Set next bomb time (3-4.5 seconds from now)
self.bombInterval = Math.random() * 1500 + 3000;
self.nextBombTime = LK.ticks * 16.67 + self.bombInterval;
}
// Shoot bullets every 60 ticks
if (LK.ticks % 60 === 0) {
var enemyBullet = new EnemyBullet();
enemyBullet.x = self.x;
enemyBullet.y = self.y + 40;
enemyBullets.push(enemyBullet);
game.addChild(enemyBullet);
}
};
return self;
});
var Enemy3 = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy3', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 5;
self.health = 1;
self.scoreValue = 15;
self.enemyType = 3;
self.hasSpottedPlayer = false; // Track if this Enemy3 has already spotted the player
self.update = function () {
self.y += self.speed;
// Scout behavior - scan for player when in range
var distanceToPlayer = Math.abs(self.x - player.x);
var verticalDistance = Math.abs(self.y - player.y);
// If Enemy3 is close enough to "spot" the player (within scanning range)
if (distanceToPlayer < 300 && verticalDistance < 400 && !self.hasSpottedPlayer) {
self.hasSpottedPlayer = true;
// Show warning text
warningTxt.alpha = 1;
tween(warningTxt, {
alpha: 0
}, {
duration: 3000
}); // Fade out warning over 3 seconds
// Trigger Enemy2 spawn after warning
LK.setTimeout(function () {
var enemy2 = new Enemy2();
enemy2.x = Math.random() * 1900 + 100;
enemy2.y = -50;
enemy2.speed += Math.floor(currentWave / 3);
enemies.push(enemy2);
game.addChild(enemy2);
}, 1000); // Spawn Enemy2 1 second after warning appears
}
};
return self;
});
var Enemy4 = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy1', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0x800080
});
self.speed = 2;
self.health = 3;
self.scoreValue = 30;
self.enemyType = 4;
self.direction = 1; // 1 for right, -1 for left
self.verticalMoveTimer = 0;
self.update = function () {
// Horizontal movement back and forth
self.x += self.direction * 3;
// Change direction when reaching screen edges
if (self.x <= 100 || self.x >= 1948) {
self.direction *= -1;
self.y += 50; // Move down when changing direction
}
// Slow vertical movement
self.verticalMoveTimer++;
if (self.verticalMoveTimer > 30) {
self.y += self.speed;
self.verticalMoveTimer = 0;
}
// Shoot triple bullets every 90 ticks
if (LK.ticks % 90 === 0) {
// Center bullet
var centerBullet = new EnemyBullet();
centerBullet.x = self.x;
centerBullet.y = self.y + 40;
enemyBullets.push(centerBullet);
game.addChild(centerBullet);
// Left bullet
var leftBullet = new EnemyBullet();
leftBullet.x = self.x - 30;
leftBullet.y = self.y + 40;
enemyBullets.push(leftBullet);
game.addChild(leftBullet);
// Right bullet
var rightBullet = new EnemyBullet();
rightBullet.x = self.x + 30;
rightBullet.y = self.y + 40;
enemyBullets.push(rightBullet);
game.addChild(rightBullet);
}
};
return self;
});
var EnemyBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0xff0000
});
self.speed = 8;
self.damage = 1;
self.update = function () {
self.y += self.speed;
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.health = 3;
self.update = function () {
// Keep player in bounds - only allow movement along bottom edge
if (self.x < 40) self.x = 40;
if (self.x > 2008) self.x = 2008;
// Force player to stay at bottom of screen
self.y = 2400;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Game variables
var player;
var enemies = [];
var bullets = [];
var enemyBullets = [];
var bombs = [];
var clouds = [];
var score = 0;
var totalKills = 0;
var enemySpawnTimer = 0;
var cloudSpawnTimer = 0;
var currentWave = 1;
var enemiesSpawnedThisWave = 0;
var enemiesKilledThisWave = 0;
var enemiesPerWave = 5;
var waveInProgress = false;
var waveStartDelay = 0;
var maxEnemySpawnRate = 60;
// Initialize background clouds
for (var i = 0; i < 8; i++) {
var cloud = new Cloud();
cloud.x = Math.random() * 2048;
cloud.y = Math.random() * 2732;
clouds.push(cloud);
game.addChild(cloud);
}
// Create player
player = game.addChild(new Player());
player.x = 1024;
player.y = 2400;
// Score display
var scoreTxt = new Text2('Score: ' + score, {
size: 60,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0, 0);
LK.gui.topLeft.addChild(scoreTxt);
scoreTxt.x = 120;
scoreTxt.y = 20;
// Wave display
var waveTxt = new Text2('Wave: ' + currentWave, {
size: 60,
fill: 0xFFFF00
});
waveTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(waveTxt);
waveTxt.y = 20;
// Health display
var healthTxt = new Text2('Health: ' + player.health, {
size: 60,
fill: 0xFF0000
});
healthTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(healthTxt);
healthTxt.x = -20;
healthTxt.y = 20;
// Kills counter display
var killsTxt = new Text2('Kills: ' + totalKills, {
size: 60,
fill: 0x00FF00
});
killsTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(killsTxt);
killsTxt.x = -20;
killsTxt.y = 90;
// Warning text (initially hidden)
var warningTxt = new Text2('WARNING', {
size: 120,
fill: 0xFF0000
});
warningTxt.anchor.set(0.5, 0.5);
LK.gui.center.addChild(warningTxt);
warningTxt.alpha = 0; // Initially hidden
// Touch input handling for player movement
game.down = function (x, y, obj) {
// Move player to touch x position, keeping y at bottom
player.x = x;
};
game.move = function (x, y, obj) {
// Move player to touch x position while dragging
player.x = x;
};
// Main game loop
game.update = function () {
// Spawn new clouds
cloudSpawnTimer++;
if (cloudSpawnTimer > 120) {
var cloud = new Cloud();
cloud.x = Math.random() * 2048;
cloud.y = -100;
clouds.push(cloud);
game.addChild(cloud);
cloudSpawnTimer = 0;
}
// Update clouds
for (var i = clouds.length - 1; i >= 0; i--) {
var cloud = clouds[i];
if (cloud.y > 2800) {
cloud.destroy();
clouds.splice(i, 1);
}
}
// Continuous shooting every 10 ticks - bullets spawn from player position
if (LK.ticks % 10 === 0) {
var bullet = new Bullet();
bullet.x = player.x; // Spawn bullet at player's exact x position
bullet.y = player.y - 60; // Spawn bullet slightly above player
bullets.push(bullet);
game.addChild(bullet);
LK.getSound('shoot').play();
}
// Wave system - spawn enemies based on current wave
if (!waveInProgress && waveStartDelay <= 0) {
// Start new wave
waveInProgress = true;
enemiesSpawnedThisWave = 0;
enemiesKilledThisWave = 0;
enemiesPerWave = Math.min(5 + currentWave * 2, 20); // Increase enemies per wave, cap at 20
maxEnemySpawnRate = Math.max(30, 60 - currentWave * 3); // Faster spawning each wave, minimum 30 ticks
waveTxt.setText('Wave: ' + currentWave);
}
if (waveInProgress && enemiesSpawnedThisWave < enemiesPerWave) {
enemySpawnTimer++;
if (enemySpawnTimer > maxEnemySpawnRate) {
// Randomly choose enemy type
var enemyType = Math.floor(Math.random() * 3) + 1;
var enemy;
if (enemyType === 1) {
enemy = new Enemy1();
} else if (enemyType === 2) {
enemy = new Enemy2();
} else {
enemy = new Enemy3();
}
enemy.x = Math.random() * 1900 + 100;
enemy.y = -50;
// Make enemies faster in later waves
enemy.speed += Math.floor(currentWave / 3);
enemies.push(enemy);
game.addChild(enemy);
enemySpawnTimer = 0;
enemiesSpawnedThisWave++;
}
}
// Update bullets
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
// Remove bullets that are off screen
if (bullet.y < -50) {
bullet.destroy();
bullets.splice(i, 1);
continue;
}
// Check bullet-enemy collisions
for (var j = enemies.length - 1; j >= 0; j--) {
var enemy = enemies[j];
if (bullet.intersects(enemy)) {
// Damage enemy
enemy.health -= bullet.damage;
bullet.destroy();
bullets.splice(i, 1);
// Check if enemy is destroyed
if (enemy.health <= 0) {
LK.getSound('explosion').play();
// Create explosion visual at enemy position
var explosion = LK.getAsset('Bomm', {
anchorX: 0.5,
anchorY: 0.5
});
explosion.x = enemy.x;
explosion.y = enemy.y;
game.addChild(explosion);
// Animate explosion - scale up and fade out
tween(explosion, {
scaleX: 3,
scaleY: 3,
alpha: 0
}, {
duration: 800,
easing: tween.easeOut,
onFinish: function onFinish() {
explosion.destroy();
}
});
enemy.destroy();
enemies.splice(j, 1);
// Update score based on enemy type and wave
score += enemy.scoreValue * currentWave;
LK.setScore(score);
scoreTxt.setText('Score: ' + score);
// Update kills counter
totalKills++;
killsTxt.setText('Kills: ' + totalKills);
enemiesKilledThisWave++;
// Check if wave is complete
if (waveInProgress && enemiesKilledThisWave >= enemiesPerWave) {
waveInProgress = false;
currentWave++;
waveStartDelay = 120; // 2 second delay between waves
LK.effects.flashScreen(0x00ff00, 500); // Green flash for wave complete
}
} else {
// Enemy damaged but not destroyed - flash red
LK.effects.flashObject(enemy, 0xff0000, 200);
}
break;
}
}
}
// Update enemies
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
// Remove enemies that are off screen
if (enemy.y > 2800) {
enemy.destroy();
enemies.splice(i, 1);
continue;
}
// Check enemy-player collision
if (enemy.intersects(player)) {
player.health--;
healthTxt.setText('Health: ' + player.health);
if (player.health <= 0) {
LK.showGameOver();
} else {
LK.effects.flashObject(player, 0xff0000, 500);
}
enemy.destroy();
enemies.splice(i, 1);
}
}
// Update enemy bullets
for (var i = enemyBullets.length - 1; i >= 0; i--) {
var enemyBullet = enemyBullets[i];
// Remove bullets that are off screen
if (enemyBullet.y > 2800) {
enemyBullet.destroy();
enemyBullets.splice(i, 1);
continue;
}
// Check enemy bullet-player collision
if (enemyBullet.intersects(player)) {
player.health--;
healthTxt.setText('Health: ' + player.health);
enemyBullet.destroy();
enemyBullets.splice(i, 1);
if (player.health <= 0) {
LK.showGameOver();
} else {
LK.effects.flashObject(player, 0xff0000, 500);
}
}
}
// Update bombs
for (var i = bombs.length - 1; i >= 0; i--) {
var bomb = bombs[i];
// Remove bombs that are off screen
if (bomb.y > 2800) {
bomb.destroy();
bombs.splice(i, 1);
continue;
}
// Check bomb-player collision
if (bomb.intersects(player)) {
player.health -= bomb.damage;
healthTxt.setText('Health: ' + player.health);
bomb.destroy();
bombs.splice(i, 1);
if (player.health <= 0) {
LK.showGameOver();
} else {
LK.effects.flashObject(player, 0xff0000, 500);
}
}
}
// Handle wave start delay
if (waveStartDelay > 0) {
waveStartDelay--;
}
// Check if player failed to eliminate all enemies (game over condition)
// If enemies reach the bottom of the screen without being destroyed, it's game over
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
if (enemy.y > 2600) {
// Enemy reached near bottom of screen
LK.showGameOver();
break;
}
}
};
Moln. In-Game asset. 2d. High contrast. No shadows
Moln. In-Game asset. 2d. High contrast. No shadows
Misil rikdad upp. In-Game asset. 2d. High contrast. No shadows
F-22 upp ifraĢn. In-Game asset. 2d. High contrast. No shadows
SR-71 uppifraĢn. In-Game asset. 2d. High contrast. No shadows
B-2 uppifraĢn. In-Game asset. 2d. High contrast. No shadows
Explosion. In-Game asset. 2d. High contrast. No shadows
A-10 uppifraĢn. In-Game asset. 2d. High contrast. No shadows