/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.damage = player ? player.damage : 20;
self.direction = {
x: 0,
y: 0
};
self.update = function () {
self.x += self.direction.x * self.speed;
self.y += self.direction.y * self.speed;
if (self.x < -50 || self.x > 2098 || self.y < -50 || self.y > 2782) {
self.shouldRemove = true;
}
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 100;
self.maxHealth = 100;
self.damage = 20;
self.fireRate = 30; // Lower = faster
self.speed = 4;
self.lastShot = 0;
self.takeDamage = function (amount) {
self.health -= amount;
if (self.health <= 0) {
self.health = 0;
LK.showGameOver();
} else {
LK.effects.flashObject(self, 0xff0000, 300);
LK.getSound('playerHit').play();
}
};
self.heal = function (amount) {
self.health = Math.min(self.maxHealth, self.health + amount);
};
return self;
});
var XPOrb = Container.expand(function () {
var self = Container.call(this);
var orbGraphics = self.attachAsset('xpOrb', {
anchorX: 0.5,
anchorY: 0.5
});
self.value = 10;
self.collectDistance = 30;
self.update = function () {
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < self.collectDistance) {
self.x += dx / distance * 6;
self.y += dy / distance * 6;
if (distance < 20) {
currentXP += self.value;
checkLevelUp();
self.shouldRemove = true;
}
}
};
return self;
});
var Zombie = Container.expand(function (type) {
var self = Container.call(this);
self.type = type || 'normal';
self.speed = 1;
self.health = 40;
self.damage = 25;
self.xpValue = 10;
var assetId = 'zombie';
if (self.type === 'fast') {
assetId = 'fastZombie';
self.speed = 2.5;
self.health = 25;
self.damage = 20;
self.xpValue = 15;
} else if (self.type === 'strong') {
assetId = 'strongZombie';
self.speed = 0.8;
self.health = 80;
self.damage = 40;
self.xpValue = 25;
}
var zombieGraphics = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
self.takeDamage = function (amount) {
self.health -= amount;
LK.effects.flashObject(self, 0xffffff, 200);
if (self.health <= 0) {
self.isDead = true;
LK.getSound('zombieHit').play();
}
};
self.update = function () {
if (self.isDead) return;
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 5) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
} else {
// Attack player
if (!self.lastAttack || LK.ticks - self.lastAttack > 60) {
player.takeDamage(self.damage);
self.lastAttack = LK.ticks;
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2C3E50
});
/****
* Game Code
****/
var player;
var zombies = [];
var bullets = [];
var xpOrbs = [];
var currentXP = 0;
var currentLevel = 1;
var xpToNextLevel = 100;
var waveNumber = 1;
var zombiesSpawned = 0;
var zombiesInWave = 10;
var spawnTimer = 0;
var spawnRate = 120; // frames between spawns
var isShowingUpgrade = false;
var upgrades = [];
// UI Elements
var healthBar, xpBar, levelText, waveText, scoreText;
function initializeUI() {
// Health bar background
var healthBg = LK.getAsset('healthBg', {
width: 400,
height: 20,
color: 0x800000,
shape: 'box'
});
healthBg.x = 100;
healthBg.y = 100;
LK.gui.topLeft.addChild(healthBg);
// Health bar
healthBar = LK.getAsset('healthBar', {
width: 400,
height: 20,
color: 0x00ff00,
shape: 'box'
});
healthBar.x = 100;
healthBar.y = 100;
LK.gui.topLeft.addChild(healthBar);
// XP bar background
var xpBg = LK.getAsset('xpBg', {
width: 400,
height: 15,
color: 0x404040,
shape: 'box'
});
xpBg.x = 100;
xpBg.y = 130;
LK.gui.topLeft.addChild(xpBg);
// XP bar
xpBar = LK.getAsset('xpBar', {
width: 400,
height: 15,
color: 0x00FFFF,
shape: 'box'
});
xpBar.x = 100;
xpBar.y = 130;
LK.gui.topLeft.addChild(xpBar);
// Level text
levelText = new Text2('Level: 1', {
size: 40,
fill: '#ffffff'
});
levelText.anchor.set(0, 0);
levelText.x = 100;
levelText.y = 50;
LK.gui.topLeft.addChild(levelText);
// Wave text
waveText = new Text2('Wave: 1', {
size: 30,
fill: '#ffffff'
});
waveText.anchor.set(0.5, 0);
waveText.x = 1024;
waveText.y = 50;
LK.gui.top.addChild(waveText);
// Score text
scoreText = new Text2('Score: 0', {
size: 30,
fill: '#ffffff'
});
scoreText.anchor.set(1, 0);
scoreText.x = 1948;
scoreText.y = 50;
LK.gui.topRight.addChild(scoreText);
}
function updateUI() {
if (healthBar) {
var healthPercent = player.health / player.maxHealth;
healthBar.width = 400 * healthPercent;
}
if (xpBar) {
var xpPercent = currentXP / xpToNextLevel;
xpBar.width = 400 * Math.min(xpPercent, 1);
}
if (levelText) {
levelText.setText('Level: ' + currentLevel);
}
if (waveText) {
waveText.setText('Wave: ' + waveNumber);
}
if (scoreText) {
scoreText.setText('Score: ' + LK.getScore());
}
}
function checkLevelUp() {
if (currentXP >= xpToNextLevel) {
currentXP -= xpToNextLevel;
currentLevel++;
xpToNextLevel = Math.floor(xpToNextLevel * 1.5);
LK.getSound('levelUp').play();
showUpgradeScreen();
}
}
function showUpgradeScreen() {
isShowingUpgrade = true;
// Create upgrade options
var availableUpgrades = [{
name: 'Damage +20%',
apply: function apply() {
player.damage = Math.floor(player.damage * 1.2);
}
}, {
name: 'Fire Rate +25%',
apply: function apply() {
player.fireRate = Math.max(5, Math.floor(player.fireRate * 0.75));
}
}, {
name: 'Max Health +50',
apply: function apply() {
player.maxHealth += 50;
player.heal(50);
}
}, {
name: 'Speed +20%',
apply: function apply() {
player.speed = player.speed * 1.2;
}
}, {
name: 'Health Regen',
apply: function apply() {
player.hasRegen = true;
}
}];
// Create upgrade UI (simplified - just pick first 3)
var upgradeOptions = [];
for (var i = 0; i < 3 && i < availableUpgrades.length; i++) {
upgradeOptions.push(availableUpgrades[i]);
}
// Create upgrade buttons
var upgradeContainer = new Container();
upgradeContainer.x = 1024;
upgradeContainer.y = 1366;
var bgPanel = LK.getAsset('upgradePanel', {
width: 800,
height: 600,
color: 0x1a1a1a,
shape: 'box'
});
upgradeContainer.addChild(bgPanel);
var titleText = new Text2('LEVEL UP! Choose an upgrade:', {
size: 50,
fill: '#00FFFF'
});
titleText.anchor.set(0.5, 0.5);
titleText.y = -200;
upgradeContainer.addChild(titleText);
for (var i = 0; i < upgradeOptions.length; i++) {
var option = upgradeOptions[i];
var button = LK.getAsset('upgradeButton' + i, {
width: 600,
height: 100,
color: 0x0066CC,
shape: 'box'
});
button.y = -50 + i * 120;
button.upgradeFunction = option.apply;
var buttonText = new Text2(option.name, {
size: 40,
fill: '#ffffff'
});
buttonText.anchor.set(0.5, 0.5);
button.addChild(buttonText);
button.down = function (x, y, obj) {
this.upgradeFunction();
game.removeChild(upgradeContainer);
isShowingUpgrade = false;
};
upgradeContainer.addChild(button);
}
game.addChild(upgradeContainer);
}
function spawnZombie() {
var type = 'normal';
var rand = Math.random();
if (waveNumber > 3 && rand < 0.3) type = 'fast';
if (waveNumber > 5 && rand < 0.2) type = 'strong';
var zombie = new Zombie(type);
// Spawn from edges
var edge = Math.floor(Math.random() * 4);
if (edge === 0) {
// top
zombie.x = Math.random() * 2048;
zombie.y = -50;
} else if (edge === 1) {
// right
zombie.x = 2098;
zombie.y = Math.random() * 2732;
} else if (edge === 2) {
// bottom
zombie.x = Math.random() * 2048;
zombie.y = 2782;
} else {
// left
zombie.x = -50;
zombie.y = Math.random() * 2732;
}
zombies.push(zombie);
game.addChild(zombie);
zombiesSpawned++;
}
function startNextWave() {
waveNumber++;
zombiesSpawned = 0;
zombiesInWave = Math.floor(10 + waveNumber * 2.5);
spawnRate = Math.max(30, 120 - waveNumber * 5);
}
// Initialize player
player = new Player();
player.x = 1024;
player.y = 1366;
game.addChild(player);
initializeUI();
var targetX = player.x;
var targetY = player.y;
game.move = function (x, y, obj) {
if (isShowingUpgrade) return;
targetX = x;
targetY = y;
};
game.down = function (x, y, obj) {
if (isShowingUpgrade) return;
targetX = x;
targetY = y;
};
game.update = function () {
if (isShowingUpgrade) return;
// Move player towards target
var dx = targetX - player.x;
var dy = targetY - player.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 5) {
player.x += dx / distance * player.speed;
player.y += dy / distance * player.speed;
}
// Keep player in bounds
player.x = Math.max(40, Math.min(2008, player.x));
player.y = Math.max(40, Math.min(2692, player.y));
// Player health regen
if (player.hasRegen && LK.ticks % 120 === 0) {
player.heal(5);
}
// Auto-shoot at nearest zombie
if (zombies.length > 0 && LK.ticks - player.lastShot >= player.fireRate) {
var nearestZombie = null;
var nearestDistance = Infinity;
for (var i = 0; i < zombies.length; i++) {
if (zombies[i].isDead) continue;
var zdx = zombies[i].x - player.x;
var zdy = zombies[i].y - player.y;
var zdist = Math.sqrt(zdx * zdx + zdy * zdy);
if (zdist < nearestDistance) {
nearestDistance = zdist;
nearestZombie = zombies[i];
}
}
if (nearestZombie && nearestDistance < 400) {
var bullet = new Bullet();
bullet.x = player.x;
bullet.y = player.y;
var bdx = nearestZombie.x - player.x;
var bdy = nearestZombie.y - player.y;
var bdist = Math.sqrt(bdx * bdx + bdy * bdy);
bullet.direction.x = bdx / bdist;
bullet.direction.y = bdy / bdist;
bullets.push(bullet);
game.addChild(bullet);
player.lastShot = LK.ticks;
LK.getSound('shoot').play();
}
}
// Update bullets
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
if (bullet.shouldRemove) {
bullet.destroy();
bullets.splice(i, 1);
continue;
}
// Check bullet-zombie collisions
for (var j = zombies.length - 1; j >= 0; j--) {
var zombie = zombies[j];
if (zombie.isDead) continue;
if (bullet.intersects(zombie)) {
zombie.takeDamage(bullet.damage);
bullet.shouldRemove = true;
if (zombie.isDead) {
LK.setScore(LK.getScore() + zombie.xpValue);
// Create XP orb
var xpOrb = new XPOrb();
xpOrb.x = zombie.x;
xpOrb.y = zombie.y;
xpOrb.value = zombie.xpValue;
xpOrbs.push(xpOrb);
game.addChild(xpOrb);
}
break;
}
}
}
// Update zombies
for (var i = zombies.length - 1; i >= 0; i--) {
var zombie = zombies[i];
if (zombie.isDead) {
zombie.destroy();
zombies.splice(i, 1);
}
}
// Update XP orbs
for (var i = xpOrbs.length - 1; i >= 0; i--) {
var orb = xpOrbs[i];
if (orb.shouldRemove) {
orb.destroy();
xpOrbs.splice(i, 1);
}
}
// Spawn zombies
spawnTimer++;
if (spawnTimer >= spawnRate && zombiesSpawned < zombiesInWave) {
spawnZombie();
spawnTimer = 0;
}
// Check if wave is complete
if (zombiesSpawned >= zombiesInWave && zombies.length === 0) {
startNextWave();
}
updateUI();
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.damage = player ? player.damage : 20;
self.direction = {
x: 0,
y: 0
};
self.update = function () {
self.x += self.direction.x * self.speed;
self.y += self.direction.y * self.speed;
if (self.x < -50 || self.x > 2098 || self.y < -50 || self.y > 2782) {
self.shouldRemove = true;
}
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 100;
self.maxHealth = 100;
self.damage = 20;
self.fireRate = 30; // Lower = faster
self.speed = 4;
self.lastShot = 0;
self.takeDamage = function (amount) {
self.health -= amount;
if (self.health <= 0) {
self.health = 0;
LK.showGameOver();
} else {
LK.effects.flashObject(self, 0xff0000, 300);
LK.getSound('playerHit').play();
}
};
self.heal = function (amount) {
self.health = Math.min(self.maxHealth, self.health + amount);
};
return self;
});
var XPOrb = Container.expand(function () {
var self = Container.call(this);
var orbGraphics = self.attachAsset('xpOrb', {
anchorX: 0.5,
anchorY: 0.5
});
self.value = 10;
self.collectDistance = 30;
self.update = function () {
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < self.collectDistance) {
self.x += dx / distance * 6;
self.y += dy / distance * 6;
if (distance < 20) {
currentXP += self.value;
checkLevelUp();
self.shouldRemove = true;
}
}
};
return self;
});
var Zombie = Container.expand(function (type) {
var self = Container.call(this);
self.type = type || 'normal';
self.speed = 1;
self.health = 40;
self.damage = 25;
self.xpValue = 10;
var assetId = 'zombie';
if (self.type === 'fast') {
assetId = 'fastZombie';
self.speed = 2.5;
self.health = 25;
self.damage = 20;
self.xpValue = 15;
} else if (self.type === 'strong') {
assetId = 'strongZombie';
self.speed = 0.8;
self.health = 80;
self.damage = 40;
self.xpValue = 25;
}
var zombieGraphics = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
self.takeDamage = function (amount) {
self.health -= amount;
LK.effects.flashObject(self, 0xffffff, 200);
if (self.health <= 0) {
self.isDead = true;
LK.getSound('zombieHit').play();
}
};
self.update = function () {
if (self.isDead) return;
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 5) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
} else {
// Attack player
if (!self.lastAttack || LK.ticks - self.lastAttack > 60) {
player.takeDamage(self.damage);
self.lastAttack = LK.ticks;
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2C3E50
});
/****
* Game Code
****/
var player;
var zombies = [];
var bullets = [];
var xpOrbs = [];
var currentXP = 0;
var currentLevel = 1;
var xpToNextLevel = 100;
var waveNumber = 1;
var zombiesSpawned = 0;
var zombiesInWave = 10;
var spawnTimer = 0;
var spawnRate = 120; // frames between spawns
var isShowingUpgrade = false;
var upgrades = [];
// UI Elements
var healthBar, xpBar, levelText, waveText, scoreText;
function initializeUI() {
// Health bar background
var healthBg = LK.getAsset('healthBg', {
width: 400,
height: 20,
color: 0x800000,
shape: 'box'
});
healthBg.x = 100;
healthBg.y = 100;
LK.gui.topLeft.addChild(healthBg);
// Health bar
healthBar = LK.getAsset('healthBar', {
width: 400,
height: 20,
color: 0x00ff00,
shape: 'box'
});
healthBar.x = 100;
healthBar.y = 100;
LK.gui.topLeft.addChild(healthBar);
// XP bar background
var xpBg = LK.getAsset('xpBg', {
width: 400,
height: 15,
color: 0x404040,
shape: 'box'
});
xpBg.x = 100;
xpBg.y = 130;
LK.gui.topLeft.addChild(xpBg);
// XP bar
xpBar = LK.getAsset('xpBar', {
width: 400,
height: 15,
color: 0x00FFFF,
shape: 'box'
});
xpBar.x = 100;
xpBar.y = 130;
LK.gui.topLeft.addChild(xpBar);
// Level text
levelText = new Text2('Level: 1', {
size: 40,
fill: '#ffffff'
});
levelText.anchor.set(0, 0);
levelText.x = 100;
levelText.y = 50;
LK.gui.topLeft.addChild(levelText);
// Wave text
waveText = new Text2('Wave: 1', {
size: 30,
fill: '#ffffff'
});
waveText.anchor.set(0.5, 0);
waveText.x = 1024;
waveText.y = 50;
LK.gui.top.addChild(waveText);
// Score text
scoreText = new Text2('Score: 0', {
size: 30,
fill: '#ffffff'
});
scoreText.anchor.set(1, 0);
scoreText.x = 1948;
scoreText.y = 50;
LK.gui.topRight.addChild(scoreText);
}
function updateUI() {
if (healthBar) {
var healthPercent = player.health / player.maxHealth;
healthBar.width = 400 * healthPercent;
}
if (xpBar) {
var xpPercent = currentXP / xpToNextLevel;
xpBar.width = 400 * Math.min(xpPercent, 1);
}
if (levelText) {
levelText.setText('Level: ' + currentLevel);
}
if (waveText) {
waveText.setText('Wave: ' + waveNumber);
}
if (scoreText) {
scoreText.setText('Score: ' + LK.getScore());
}
}
function checkLevelUp() {
if (currentXP >= xpToNextLevel) {
currentXP -= xpToNextLevel;
currentLevel++;
xpToNextLevel = Math.floor(xpToNextLevel * 1.5);
LK.getSound('levelUp').play();
showUpgradeScreen();
}
}
function showUpgradeScreen() {
isShowingUpgrade = true;
// Create upgrade options
var availableUpgrades = [{
name: 'Damage +20%',
apply: function apply() {
player.damage = Math.floor(player.damage * 1.2);
}
}, {
name: 'Fire Rate +25%',
apply: function apply() {
player.fireRate = Math.max(5, Math.floor(player.fireRate * 0.75));
}
}, {
name: 'Max Health +50',
apply: function apply() {
player.maxHealth += 50;
player.heal(50);
}
}, {
name: 'Speed +20%',
apply: function apply() {
player.speed = player.speed * 1.2;
}
}, {
name: 'Health Regen',
apply: function apply() {
player.hasRegen = true;
}
}];
// Create upgrade UI (simplified - just pick first 3)
var upgradeOptions = [];
for (var i = 0; i < 3 && i < availableUpgrades.length; i++) {
upgradeOptions.push(availableUpgrades[i]);
}
// Create upgrade buttons
var upgradeContainer = new Container();
upgradeContainer.x = 1024;
upgradeContainer.y = 1366;
var bgPanel = LK.getAsset('upgradePanel', {
width: 800,
height: 600,
color: 0x1a1a1a,
shape: 'box'
});
upgradeContainer.addChild(bgPanel);
var titleText = new Text2('LEVEL UP! Choose an upgrade:', {
size: 50,
fill: '#00FFFF'
});
titleText.anchor.set(0.5, 0.5);
titleText.y = -200;
upgradeContainer.addChild(titleText);
for (var i = 0; i < upgradeOptions.length; i++) {
var option = upgradeOptions[i];
var button = LK.getAsset('upgradeButton' + i, {
width: 600,
height: 100,
color: 0x0066CC,
shape: 'box'
});
button.y = -50 + i * 120;
button.upgradeFunction = option.apply;
var buttonText = new Text2(option.name, {
size: 40,
fill: '#ffffff'
});
buttonText.anchor.set(0.5, 0.5);
button.addChild(buttonText);
button.down = function (x, y, obj) {
this.upgradeFunction();
game.removeChild(upgradeContainer);
isShowingUpgrade = false;
};
upgradeContainer.addChild(button);
}
game.addChild(upgradeContainer);
}
function spawnZombie() {
var type = 'normal';
var rand = Math.random();
if (waveNumber > 3 && rand < 0.3) type = 'fast';
if (waveNumber > 5 && rand < 0.2) type = 'strong';
var zombie = new Zombie(type);
// Spawn from edges
var edge = Math.floor(Math.random() * 4);
if (edge === 0) {
// top
zombie.x = Math.random() * 2048;
zombie.y = -50;
} else if (edge === 1) {
// right
zombie.x = 2098;
zombie.y = Math.random() * 2732;
} else if (edge === 2) {
// bottom
zombie.x = Math.random() * 2048;
zombie.y = 2782;
} else {
// left
zombie.x = -50;
zombie.y = Math.random() * 2732;
}
zombies.push(zombie);
game.addChild(zombie);
zombiesSpawned++;
}
function startNextWave() {
waveNumber++;
zombiesSpawned = 0;
zombiesInWave = Math.floor(10 + waveNumber * 2.5);
spawnRate = Math.max(30, 120 - waveNumber * 5);
}
// Initialize player
player = new Player();
player.x = 1024;
player.y = 1366;
game.addChild(player);
initializeUI();
var targetX = player.x;
var targetY = player.y;
game.move = function (x, y, obj) {
if (isShowingUpgrade) return;
targetX = x;
targetY = y;
};
game.down = function (x, y, obj) {
if (isShowingUpgrade) return;
targetX = x;
targetY = y;
};
game.update = function () {
if (isShowingUpgrade) return;
// Move player towards target
var dx = targetX - player.x;
var dy = targetY - player.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 5) {
player.x += dx / distance * player.speed;
player.y += dy / distance * player.speed;
}
// Keep player in bounds
player.x = Math.max(40, Math.min(2008, player.x));
player.y = Math.max(40, Math.min(2692, player.y));
// Player health regen
if (player.hasRegen && LK.ticks % 120 === 0) {
player.heal(5);
}
// Auto-shoot at nearest zombie
if (zombies.length > 0 && LK.ticks - player.lastShot >= player.fireRate) {
var nearestZombie = null;
var nearestDistance = Infinity;
for (var i = 0; i < zombies.length; i++) {
if (zombies[i].isDead) continue;
var zdx = zombies[i].x - player.x;
var zdy = zombies[i].y - player.y;
var zdist = Math.sqrt(zdx * zdx + zdy * zdy);
if (zdist < nearestDistance) {
nearestDistance = zdist;
nearestZombie = zombies[i];
}
}
if (nearestZombie && nearestDistance < 400) {
var bullet = new Bullet();
bullet.x = player.x;
bullet.y = player.y;
var bdx = nearestZombie.x - player.x;
var bdy = nearestZombie.y - player.y;
var bdist = Math.sqrt(bdx * bdx + bdy * bdy);
bullet.direction.x = bdx / bdist;
bullet.direction.y = bdy / bdist;
bullets.push(bullet);
game.addChild(bullet);
player.lastShot = LK.ticks;
LK.getSound('shoot').play();
}
}
// Update bullets
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
if (bullet.shouldRemove) {
bullet.destroy();
bullets.splice(i, 1);
continue;
}
// Check bullet-zombie collisions
for (var j = zombies.length - 1; j >= 0; j--) {
var zombie = zombies[j];
if (zombie.isDead) continue;
if (bullet.intersects(zombie)) {
zombie.takeDamage(bullet.damage);
bullet.shouldRemove = true;
if (zombie.isDead) {
LK.setScore(LK.getScore() + zombie.xpValue);
// Create XP orb
var xpOrb = new XPOrb();
xpOrb.x = zombie.x;
xpOrb.y = zombie.y;
xpOrb.value = zombie.xpValue;
xpOrbs.push(xpOrb);
game.addChild(xpOrb);
}
break;
}
}
}
// Update zombies
for (var i = zombies.length - 1; i >= 0; i--) {
var zombie = zombies[i];
if (zombie.isDead) {
zombie.destroy();
zombies.splice(i, 1);
}
}
// Update XP orbs
for (var i = xpOrbs.length - 1; i >= 0; i--) {
var orb = xpOrbs[i];
if (orb.shouldRemove) {
orb.destroy();
xpOrbs.splice(i, 1);
}
}
// Spawn zombies
spawnTimer++;
if (spawnTimer >= spawnRate && zombiesSpawned < zombiesInWave) {
spawnZombie();
spawnTimer = 0;
}
// Check if wave is complete
if (zombiesSpawned >= zombiesInWave && zombies.length === 0) {
startNextWave();
}
updateUI();
};