User prompt
If the Player moves i should Not shoot constaly
User prompt
The Player should face to the Last Touch and walk towards IT
User prompt
Mach einen anderen Weg zu bewegen
User prompt
Add a shoot button in the down right Corner
User prompt
Make IT so that you dont shoot when you move only If you Press the shoot button
User prompt
Mach alles ein bisschen groฬรer
User prompt
Make a shoot button
Code edit (1 edits merged)
Please save this source code
User prompt
Zombie Apocalypse: Survival Shooter
Initial prompt
Make a Zombie Shooter
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { highScore: 0, totalKills: 0 }); /**** * Classes ****/ var Bullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 20; self.dirX = 0; self.dirY = 0; self.damage = 10; self.update = function () { self.x += self.dirX * self.speed; self.y += self.dirY * self.speed; }; return self; }); var Powerup = Container.expand(function (type) { var self = Container.call(this); self.type = type || 'health'; var assetId; switch (self.type) { case 'health': assetId = 'healthPack'; break; case 'ammo': assetId = 'ammoPack'; break; case 'rapidFire': assetId = 'rapidFirePowerup'; break; case 'damageBoost': assetId = 'damageBoostPowerup'; break; } var powerupGraphics = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); self.lifespan = 300; // 5 seconds at 60fps self.update = function () { self.lifespan--; // Make powerup blink when about to expire if (self.lifespan < 60) { self.visible = LK.ticks % 10 < 5; } }; return self; }); var Survivor = Container.expand(function () { var self = Container.call(this); var survivorGraphics = self.attachAsset('survivor', { anchorX: 0.5, anchorY: 0.5 }); self.health = 100; self.maxHealth = 100; self.ammo = 30; self.maxAmmo = 30; self.speed = 10; self.fireRate = 10; // Ticks between shots self.fireCooldown = 0; self.damageMultiplier = 1; self.rapidFireTimer = 0; self.damageBoostTimer = 0; self.move = function (direction) { if (direction.x) { self.x += direction.x * self.speed; } if (direction.y) { self.y += direction.y * self.speed; } // Keep player within game bounds if (self.x < 50) { self.x = 50; } if (self.x > 2048 - 50) { self.x = 2048 - 50; } if (self.y < 50) { self.y = 50; } if (self.y > 2732 - 50) { self.y = 2732 - 50; } }; self.shoot = function (targetX, targetY) { if (self.ammo <= 0 || self.fireCooldown > 0) { return null; } self.ammo--; self.fireCooldown = self.rapidFireTimer > 0 ? Math.floor(self.fireRate / 2) : self.fireRate; var bullet = new Bullet(); bullet.x = self.x; bullet.y = self.y; // Calculate direction vector var dirX = targetX - self.x; var dirY = targetY - self.y; // Normalize direction var length = Math.sqrt(dirX * dirX + dirY * dirY); bullet.dirX = dirX / length; bullet.dirY = dirY / length; // Set damage based on player's current damage multiplier bullet.damage = 10 * self.damageMultiplier; LK.getSound('shoot').play(); return bullet; }; self.takeDamage = function (amount) { self.health -= amount; LK.getSound('playerHit').play(); // Flash player red when taking damage LK.effects.flashObject(self, 0xff0000, 300); if (self.health <= 0) { self.health = 0; return true; // Player is dead } return false; }; self.collectPowerup = function (type) { LK.getSound('powerup').play(); switch (type) { case 'health': self.health = Math.min(self.health + 25, self.maxHealth); break; case 'ammo': self.ammo = Math.min(self.ammo + 15, self.maxAmmo); break; case 'rapidFire': self.rapidFireTimer = 300; // 5 seconds at 60fps LK.effects.flashObject(self, 0x9b59b6, 300); break; case 'damageBoost': self.damageMultiplier = 2; self.damageBoostTimer = 300; // 5 seconds at 60fps LK.effects.flashObject(self, 0xe67e22, 300); break; } }; self.update = function () { if (self.fireCooldown > 0) { self.fireCooldown--; } if (self.rapidFireTimer > 0) { self.rapidFireTimer--; if (self.rapidFireTimer === 0) { // End rapid fire effect } } if (self.damageBoostTimer > 0) { self.damageBoostTimer--; if (self.damageBoostTimer === 0) { self.damageMultiplier = 1; } } }; return self; }); var Zombie = Container.expand(function () { var self = Container.call(this); var zombieGraphics = self.attachAsset('zombie', { anchorX: 0.5, anchorY: 0.5 }); self.health = 30; self.speed = 3; self.damage = 10; self.attackCooldown = 0; self.attackRate = 30; // Ticks between attacks self.update = function () { if (self.attackCooldown > 0) { self.attackCooldown--; } // Movement is handled in the game update function }; self.takeDamage = function (amount) { self.health -= amount; LK.getSound('zombieHit').play(); // Flash zombie green when taking damage LK.effects.flashObject(self, 0xff0000, 200); if (self.health <= 0) { return true; // Zombie is dead } return false; }; self.canAttack = function () { return self.attackCooldown === 0; }; self.attack = function () { self.attackCooldown = self.attackRate; return self.damage; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1a1a1a }); /**** * Game Code ****/ // Game state variables var player; var zombies = []; var bullets = []; var powerups = []; var direction = { x: 0, y: 0 }; var targetX = 0; var targetY = 0; var isShooting = false; var wave = 1; var zombiesKilled = 0; var waveZombies = 5; // Starting zombies per wave var score = 0; var gameOver = false; var powerupSpawnChance = 0.01; // 1% chance per tick to spawn a powerup // UI elements var scoreText; var waveText; var healthBar; var ammoText; var gameOverText; // Initialize game function initGame() { // Create player player = new Survivor(); player.x = 2048 / 2; player.y = 2732 / 2; game.addChild(player); // Initialize UI elements createUI(); // Start first wave startWave(wave); // Start background music LK.playMusic('gameMusic'); } function createUI() { // Score text scoreText = new Text2('Score: 0', { size: 90, fill: 0xFFFFFF }); scoreText.anchor.set(0, 0); scoreText.x = 50; scoreText.y = 50; LK.gui.addChild(scoreText); // Wave text waveText = new Text2('Wave: 1', { size: 90, fill: 0xFFFFFF }); waveText.anchor.set(1, 0); waveText.x = 2048 - 50; waveText.y = 50; LK.gui.addChild(waveText); // Health bar healthBar = new Container(); var healthBarBg = LK.getAsset('bullet', { anchorX: 0, anchorY: 0, width: 600, height: 45, tint: 0x333333 }); var healthBarFill = LK.getAsset('bullet', { anchorX: 0, anchorY: 0, width: 600, height: 45, tint: 0xe74c3c }); healthBar.addChild(healthBarBg); healthBar.addChild(healthBarFill); healthBar.fillBar = healthBarFill; healthBar.x = 50; healthBar.y = 120; LK.gui.addChild(healthBar); // Ammo text ammoText = new Text2('Ammo: 30/30', { size: 60, fill: 0xFFFFFF }); ammoText.anchor.set(0, 0); ammoText.x = 50; ammoText.y = 160; LK.gui.addChild(ammoText); // Shoot button var shootButton = new Container(); var shootButtonBg = LK.getAsset('bullet', { anchorX: 0.5, anchorY: 0.5, width: 200, height: 200, tint: 0x3498db }); shootButton.addChild(shootButtonBg); shootButton.x = 2048 - 100; shootButton.y = 2732 - 100; shootButton.interactive = true; shootButton.on('down', function () { isShooting = true; }); shootButton.on('up', function () { isShooting = false; }); LK.gui.addChild(shootButton); } function startWave(waveNumber) { wave = waveNumber; waveZombies = 5 + (wave - 1) * 3; waveText.setText('Wave: ' + wave); // Spawn initial zombies for (var i = 0; i < Math.min(waveZombies, 10); i++) { spawnZombie(); } } function spawnZombie() { var zombie = new Zombie(); // Determine spawn location (outside the screen) var side = Math.floor(Math.random() * 4); // 0: top, 1: right, 2: bottom, 3: left switch (side) { case 0: // Top zombie.x = Math.random() * 2048; zombie.y = -100; break; case 1: // Right zombie.x = 2048 + 100; zombie.y = Math.random() * 2732; break; case 2: // Bottom zombie.x = Math.random() * 2048; zombie.y = 2732 + 100; break; case 3: // Left zombie.x = -100; zombie.y = Math.random() * 2732; break; } // Adjust zombie difficulty based on wave zombie.health = 30 + (wave - 1) * 10; zombie.speed = 3 + (wave - 1) * 0.2; if (wave > 5) { zombie.damage = 10 + (wave - 5) * 2; } game.addChild(zombie); zombies.push(zombie); } function spawnPowerup() { // Determine random position on screen var x = 100 + Math.random() * (2048 - 200); var y = 100 + Math.random() * (2732 - 200); // Determine powerup type var types = ['health', 'ammo', 'rapidFire', 'damageBoost']; var type = types[Math.floor(Math.random() * types.length)]; var powerup = new Powerup(type); powerup.x = x; powerup.y = y; game.addChild(powerup); powerups.push(powerup); } function updateUI() { // Update score scoreText.setText('Score: ' + score); // Update health bar var healthPercent = player.health / player.maxHealth; healthBar.fillBar.width = 400 * healthPercent; // Update ammo text ammoText.setText('Ammo: ' + player.ammo + '/' + player.maxAmmo); } // Mouse/Touch input handlers game.down = function (x, y, obj) { targetX = x; targetY = y; isShooting = true; }; game.move = function (x, y, obj) { targetX = x; targetY = y; }; game.up = function (x, y, obj) { isShooting = false; }; // Main game update loop game.update = function () { if (gameOver) { return; } // Update player player.update(); // Handle player movement based on touch position // Move player toward touch point var dx = targetX - player.x; var dy = targetY - player.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { // Normalize direction direction.x = dx / distance; direction.y = dy / distance; // Rotate player to face the target player.rotation = Math.atan2(dy, dx); // Move player towards the target player.move(direction); } // Try to shoot only if the shoot button is pressed if (isShooting && player.fireCooldown === 0 && player.ammo > 0) { var bullet = player.shoot(targetX, targetY); if (bullet) { game.addChild(bullet); bullets.push(bullet); } } // Update zombies for (var i = zombies.length - 1; i >= 0; i--) { var zombie = zombies[i]; zombie.update(); // Move zombie towards player var dx = player.x - zombie.x; var dy = player.y - zombie.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { zombie.x += dx / distance * zombie.speed; zombie.y += dy / distance * zombie.speed; } // Check for collision with player if (zombie.intersects(player)) { if (zombie.canAttack()) { var damage = zombie.attack(); var playerDead = player.takeDamage(damage); if (playerDead) { handleGameOver(); return; } } } } // Update bullets for (var i = bullets.length - 1; i >= 0; i--) { var bullet = bullets[i]; bullet.update(); // Check if bullet is off screen if (bullet.x < -50 || bullet.x > 2048 + 50 || bullet.y < -50 || bullet.y > 2732 + 50) { game.removeChild(bullet); bullets.splice(i, 1); continue; } // Check for collisions with zombies var hitZombie = false; for (var j = zombies.length - 1; j >= 0; j--) { var zombie = zombies[j]; if (bullet.intersects(zombie)) { hitZombie = true; var zombieDead = zombie.takeDamage(bullet.damage); if (zombieDead) { game.removeChild(zombie); zombies.splice(j, 1); zombiesKilled++; score += 100 * wave; // Spawn more zombies if needed for the current wave if (zombies.length + zombiesKilled < waveZombies) { spawnZombie(); } // Check if wave is complete if (zombiesKilled >= waveZombies && zombies.length === 0) { zombiesKilled = 0; wave++; startWave(wave); // Give player ammo bonus between waves player.ammo = Math.min(player.ammo + 15, player.maxAmmo); // Give player health bonus between waves player.health = Math.min(player.health + 20, player.maxHealth); } } break; } } if (hitZombie) { game.removeChild(bullet); bullets.splice(i, 1); } } // Update powerups for (var i = powerups.length - 1; i >= 0; i--) { var powerup = powerups[i]; powerup.update(); // Check if powerup expired if (powerup.lifespan <= 0) { game.removeChild(powerup); powerups.splice(i, 1); continue; } // Check for collision with player if (powerup.intersects(player)) { player.collectPowerup(powerup.type); game.removeChild(powerup); powerups.splice(i, 1); } } // Random chance to spawn powerup if (Math.random() < powerupSpawnChance && powerups.length < 3) { spawnPowerup(); } // Update UI updateUI(); }; function handleGameOver() { gameOver = true; // Save high score if (score > storage.highScore) { storage.highScore = score; } // Update total kills storage.totalKills += zombiesKilled; // Show game over screen LK.showGameOver(); } // Initialize the game initGame();
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
highScore: 0,
totalKills: 0
});
/****
* Classes
****/
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 20;
self.dirX = 0;
self.dirY = 0;
self.damage = 10;
self.update = function () {
self.x += self.dirX * self.speed;
self.y += self.dirY * self.speed;
};
return self;
});
var Powerup = Container.expand(function (type) {
var self = Container.call(this);
self.type = type || 'health';
var assetId;
switch (self.type) {
case 'health':
assetId = 'healthPack';
break;
case 'ammo':
assetId = 'ammoPack';
break;
case 'rapidFire':
assetId = 'rapidFirePowerup';
break;
case 'damageBoost':
assetId = 'damageBoostPowerup';
break;
}
var powerupGraphics = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
self.lifespan = 300; // 5 seconds at 60fps
self.update = function () {
self.lifespan--;
// Make powerup blink when about to expire
if (self.lifespan < 60) {
self.visible = LK.ticks % 10 < 5;
}
};
return self;
});
var Survivor = Container.expand(function () {
var self = Container.call(this);
var survivorGraphics = self.attachAsset('survivor', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 100;
self.maxHealth = 100;
self.ammo = 30;
self.maxAmmo = 30;
self.speed = 10;
self.fireRate = 10; // Ticks between shots
self.fireCooldown = 0;
self.damageMultiplier = 1;
self.rapidFireTimer = 0;
self.damageBoostTimer = 0;
self.move = function (direction) {
if (direction.x) {
self.x += direction.x * self.speed;
}
if (direction.y) {
self.y += direction.y * self.speed;
}
// Keep player within game bounds
if (self.x < 50) {
self.x = 50;
}
if (self.x > 2048 - 50) {
self.x = 2048 - 50;
}
if (self.y < 50) {
self.y = 50;
}
if (self.y > 2732 - 50) {
self.y = 2732 - 50;
}
};
self.shoot = function (targetX, targetY) {
if (self.ammo <= 0 || self.fireCooldown > 0) {
return null;
}
self.ammo--;
self.fireCooldown = self.rapidFireTimer > 0 ? Math.floor(self.fireRate / 2) : self.fireRate;
var bullet = new Bullet();
bullet.x = self.x;
bullet.y = self.y;
// Calculate direction vector
var dirX = targetX - self.x;
var dirY = targetY - self.y;
// Normalize direction
var length = Math.sqrt(dirX * dirX + dirY * dirY);
bullet.dirX = dirX / length;
bullet.dirY = dirY / length;
// Set damage based on player's current damage multiplier
bullet.damage = 10 * self.damageMultiplier;
LK.getSound('shoot').play();
return bullet;
};
self.takeDamage = function (amount) {
self.health -= amount;
LK.getSound('playerHit').play();
// Flash player red when taking damage
LK.effects.flashObject(self, 0xff0000, 300);
if (self.health <= 0) {
self.health = 0;
return true; // Player is dead
}
return false;
};
self.collectPowerup = function (type) {
LK.getSound('powerup').play();
switch (type) {
case 'health':
self.health = Math.min(self.health + 25, self.maxHealth);
break;
case 'ammo':
self.ammo = Math.min(self.ammo + 15, self.maxAmmo);
break;
case 'rapidFire':
self.rapidFireTimer = 300; // 5 seconds at 60fps
LK.effects.flashObject(self, 0x9b59b6, 300);
break;
case 'damageBoost':
self.damageMultiplier = 2;
self.damageBoostTimer = 300; // 5 seconds at 60fps
LK.effects.flashObject(self, 0xe67e22, 300);
break;
}
};
self.update = function () {
if (self.fireCooldown > 0) {
self.fireCooldown--;
}
if (self.rapidFireTimer > 0) {
self.rapidFireTimer--;
if (self.rapidFireTimer === 0) {
// End rapid fire effect
}
}
if (self.damageBoostTimer > 0) {
self.damageBoostTimer--;
if (self.damageBoostTimer === 0) {
self.damageMultiplier = 1;
}
}
};
return self;
});
var Zombie = Container.expand(function () {
var self = Container.call(this);
var zombieGraphics = self.attachAsset('zombie', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 30;
self.speed = 3;
self.damage = 10;
self.attackCooldown = 0;
self.attackRate = 30; // Ticks between attacks
self.update = function () {
if (self.attackCooldown > 0) {
self.attackCooldown--;
}
// Movement is handled in the game update function
};
self.takeDamage = function (amount) {
self.health -= amount;
LK.getSound('zombieHit').play();
// Flash zombie green when taking damage
LK.effects.flashObject(self, 0xff0000, 200);
if (self.health <= 0) {
return true; // Zombie is dead
}
return false;
};
self.canAttack = function () {
return self.attackCooldown === 0;
};
self.attack = function () {
self.attackCooldown = self.attackRate;
return self.damage;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a1a
});
/****
* Game Code
****/
// Game state variables
var player;
var zombies = [];
var bullets = [];
var powerups = [];
var direction = {
x: 0,
y: 0
};
var targetX = 0;
var targetY = 0;
var isShooting = false;
var wave = 1;
var zombiesKilled = 0;
var waveZombies = 5; // Starting zombies per wave
var score = 0;
var gameOver = false;
var powerupSpawnChance = 0.01; // 1% chance per tick to spawn a powerup
// UI elements
var scoreText;
var waveText;
var healthBar;
var ammoText;
var gameOverText;
// Initialize game
function initGame() {
// Create player
player = new Survivor();
player.x = 2048 / 2;
player.y = 2732 / 2;
game.addChild(player);
// Initialize UI elements
createUI();
// Start first wave
startWave(wave);
// Start background music
LK.playMusic('gameMusic');
}
function createUI() {
// Score text
scoreText = new Text2('Score: 0', {
size: 90,
fill: 0xFFFFFF
});
scoreText.anchor.set(0, 0);
scoreText.x = 50;
scoreText.y = 50;
LK.gui.addChild(scoreText);
// Wave text
waveText = new Text2('Wave: 1', {
size: 90,
fill: 0xFFFFFF
});
waveText.anchor.set(1, 0);
waveText.x = 2048 - 50;
waveText.y = 50;
LK.gui.addChild(waveText);
// Health bar
healthBar = new Container();
var healthBarBg = LK.getAsset('bullet', {
anchorX: 0,
anchorY: 0,
width: 600,
height: 45,
tint: 0x333333
});
var healthBarFill = LK.getAsset('bullet', {
anchorX: 0,
anchorY: 0,
width: 600,
height: 45,
tint: 0xe74c3c
});
healthBar.addChild(healthBarBg);
healthBar.addChild(healthBarFill);
healthBar.fillBar = healthBarFill;
healthBar.x = 50;
healthBar.y = 120;
LK.gui.addChild(healthBar);
// Ammo text
ammoText = new Text2('Ammo: 30/30', {
size: 60,
fill: 0xFFFFFF
});
ammoText.anchor.set(0, 0);
ammoText.x = 50;
ammoText.y = 160;
LK.gui.addChild(ammoText);
// Shoot button
var shootButton = new Container();
var shootButtonBg = LK.getAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5,
width: 200,
height: 200,
tint: 0x3498db
});
shootButton.addChild(shootButtonBg);
shootButton.x = 2048 - 100;
shootButton.y = 2732 - 100;
shootButton.interactive = true;
shootButton.on('down', function () {
isShooting = true;
});
shootButton.on('up', function () {
isShooting = false;
});
LK.gui.addChild(shootButton);
}
function startWave(waveNumber) {
wave = waveNumber;
waveZombies = 5 + (wave - 1) * 3;
waveText.setText('Wave: ' + wave);
// Spawn initial zombies
for (var i = 0; i < Math.min(waveZombies, 10); i++) {
spawnZombie();
}
}
function spawnZombie() {
var zombie = new Zombie();
// Determine spawn location (outside the screen)
var side = Math.floor(Math.random() * 4); // 0: top, 1: right, 2: bottom, 3: left
switch (side) {
case 0:
// Top
zombie.x = Math.random() * 2048;
zombie.y = -100;
break;
case 1:
// Right
zombie.x = 2048 + 100;
zombie.y = Math.random() * 2732;
break;
case 2:
// Bottom
zombie.x = Math.random() * 2048;
zombie.y = 2732 + 100;
break;
case 3:
// Left
zombie.x = -100;
zombie.y = Math.random() * 2732;
break;
}
// Adjust zombie difficulty based on wave
zombie.health = 30 + (wave - 1) * 10;
zombie.speed = 3 + (wave - 1) * 0.2;
if (wave > 5) {
zombie.damage = 10 + (wave - 5) * 2;
}
game.addChild(zombie);
zombies.push(zombie);
}
function spawnPowerup() {
// Determine random position on screen
var x = 100 + Math.random() * (2048 - 200);
var y = 100 + Math.random() * (2732 - 200);
// Determine powerup type
var types = ['health', 'ammo', 'rapidFire', 'damageBoost'];
var type = types[Math.floor(Math.random() * types.length)];
var powerup = new Powerup(type);
powerup.x = x;
powerup.y = y;
game.addChild(powerup);
powerups.push(powerup);
}
function updateUI() {
// Update score
scoreText.setText('Score: ' + score);
// Update health bar
var healthPercent = player.health / player.maxHealth;
healthBar.fillBar.width = 400 * healthPercent;
// Update ammo text
ammoText.setText('Ammo: ' + player.ammo + '/' + player.maxAmmo);
}
// Mouse/Touch input handlers
game.down = function (x, y, obj) {
targetX = x;
targetY = y;
isShooting = true;
};
game.move = function (x, y, obj) {
targetX = x;
targetY = y;
};
game.up = function (x, y, obj) {
isShooting = false;
};
// Main game update loop
game.update = function () {
if (gameOver) {
return;
}
// Update player
player.update();
// Handle player movement based on touch position
// Move player toward touch point
var dx = targetX - player.x;
var dy = targetY - player.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
// Normalize direction
direction.x = dx / distance;
direction.y = dy / distance;
// Rotate player to face the target
player.rotation = Math.atan2(dy, dx);
// Move player towards the target
player.move(direction);
}
// Try to shoot only if the shoot button is pressed
if (isShooting && player.fireCooldown === 0 && player.ammo > 0) {
var bullet = player.shoot(targetX, targetY);
if (bullet) {
game.addChild(bullet);
bullets.push(bullet);
}
}
// Update zombies
for (var i = zombies.length - 1; i >= 0; i--) {
var zombie = zombies[i];
zombie.update();
// Move zombie towards player
var dx = player.x - zombie.x;
var dy = player.y - zombie.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
zombie.x += dx / distance * zombie.speed;
zombie.y += dy / distance * zombie.speed;
}
// Check for collision with player
if (zombie.intersects(player)) {
if (zombie.canAttack()) {
var damage = zombie.attack();
var playerDead = player.takeDamage(damage);
if (playerDead) {
handleGameOver();
return;
}
}
}
}
// Update bullets
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
bullet.update();
// Check if bullet is off screen
if (bullet.x < -50 || bullet.x > 2048 + 50 || bullet.y < -50 || bullet.y > 2732 + 50) {
game.removeChild(bullet);
bullets.splice(i, 1);
continue;
}
// Check for collisions with zombies
var hitZombie = false;
for (var j = zombies.length - 1; j >= 0; j--) {
var zombie = zombies[j];
if (bullet.intersects(zombie)) {
hitZombie = true;
var zombieDead = zombie.takeDamage(bullet.damage);
if (zombieDead) {
game.removeChild(zombie);
zombies.splice(j, 1);
zombiesKilled++;
score += 100 * wave;
// Spawn more zombies if needed for the current wave
if (zombies.length + zombiesKilled < waveZombies) {
spawnZombie();
}
// Check if wave is complete
if (zombiesKilled >= waveZombies && zombies.length === 0) {
zombiesKilled = 0;
wave++;
startWave(wave);
// Give player ammo bonus between waves
player.ammo = Math.min(player.ammo + 15, player.maxAmmo);
// Give player health bonus between waves
player.health = Math.min(player.health + 20, player.maxHealth);
}
}
break;
}
}
if (hitZombie) {
game.removeChild(bullet);
bullets.splice(i, 1);
}
}
// Update powerups
for (var i = powerups.length - 1; i >= 0; i--) {
var powerup = powerups[i];
powerup.update();
// Check if powerup expired
if (powerup.lifespan <= 0) {
game.removeChild(powerup);
powerups.splice(i, 1);
continue;
}
// Check for collision with player
if (powerup.intersects(player)) {
player.collectPowerup(powerup.type);
game.removeChild(powerup);
powerups.splice(i, 1);
}
}
// Random chance to spawn powerup
if (Math.random() < powerupSpawnChance && powerups.length < 3) {
spawnPowerup();
}
// Update UI
updateUI();
};
function handleGameOver() {
gameOver = true;
// Save high score
if (score > storage.highScore) {
storage.highScore = score;
}
// Update total kills
storage.totalKills += zombiesKilled;
// Show game over screen
LK.showGameOver();
}
// Initialize the game
initGame();