/****
* Classes
****/
// Bullet class: fired by player, moves right, destroys zombies
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletAsset = self.attachAsset('zombie', {
anchorX: 0.5,
anchorY: 0.5
});
bulletAsset.width = 60;
bulletAsset.height = 60;
bulletAsset.tint = 0xffe066; // yellow
self.speed = 32;
self.lastX = self.x;
self.update = function () {
self.lastX = self.x;
self.x += self.speed;
};
return self;
});
// Extra Strong Zombie class: moves left, requires 3 hits to die
var ExtraStrongZombie = Container.expand(function () {
var self = Container.call(this);
var zombieAsset = self.attachAsset('zombie', {
anchorX: 0.5,
anchorY: 0.5
});
zombieAsset.width = 160;
zombieAsset.height = 160;
zombieAsset.tint = 0x9c27b0; // purple for extra strong zombie
self.speed = 2.5 + Math.random() * 2;
self.health = 3; // requires 3 hits
self.lastX = self.x;
self.lastY = self.y;
self.update = function () {
self.lastX = self.x;
self.lastY = self.y;
self.x -= self.speed;
};
return self;
});
// Player class: the hero that can move and shoot
var Player = Container.expand(function () {
var self = Container.call(this);
// Attach player asset, centered
var playerAsset = self.attachAsset('character', {
anchorX: 0.5,
anchorY: 0.5
});
self.x = 400;
self.y = 1366;
self.speed = 18;
self.lastY = self.y;
self.lastX = self.x;
// Move up/down/left/right
self.moveTo = function (x, y) {
self.x = x;
self.y = y;
};
// Update method (not much needed for player)
self.update = function () {
self.lastY = self.y;
self.lastX = self.x;
};
return self;
});
// Strong Zombie class: moves left, requires 2 hits to die
var StrongZombie = Container.expand(function () {
var self = Container.call(this);
var zombieAsset = self.attachAsset('zombie', {
anchorX: 0.5,
anchorY: 0.5
});
zombieAsset.width = 140;
zombieAsset.height = 140;
zombieAsset.tint = 0xff5722; // orange-red for strong zombie
self.speed = 2 + Math.random() * 2;
self.health = 2; // requires 2 hits
self.lastX = self.x;
self.lastY = self.y;
self.update = function () {
self.lastX = self.x;
self.lastY = self.y;
self.x -= self.speed;
};
return self;
});
// Zombie class: moves left, dies on bullet hit
var Zombie = Container.expand(function () {
var self = Container.call(this);
var zombieAsset = self.attachAsset('zombie', {
anchorX: 0.5,
anchorY: 0.5
});
zombieAsset.width = 120;
zombieAsset.height = 120;
zombieAsset.tint = 0x4caf50; // green
self.speed = 4 + Math.random() * 3;
self.lastX = self.x;
self.lastY = self.y;
self.update = function () {
self.lastX = self.x;
self.lastY = self.y;
self.x -= self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Game constants
var zombieSpawnInterval = 60; // frames between zombies
var bulletCooldown = 30; // frames for 0.5 second delay after 2 shots
var playerMoveRadius = 1000; // how far player can move from left
var difficultySelected = true; // track if difficulty has been selected
var selectedDifficulty = 'normal'; // default difficulty
var speedMultiplier = 1.0; // speed multiplier based on difficulty
// Game state
var player;
var zombies = [];
var bullets = [];
var score = 0;
var gameStarted = false;
var lastZombieTick = 0;
var lastBulletTick = 0;
var shotsInBurst = 0; // track shots in current burst
var burstCooldownActive = false; // track if in cooldown period
var lastShotTime = 0; // track timing between shots
var zombiesEscaped = 0;
var enemiesSpawned = 0;
var currentAmmo = 10; // current ammo available
var reloadActive = false; // track if in reload period
var lastReloadTick = 0; // track when reload started
var reloadDuration = 120; // 2 seconds at 60fps
var totalShotsFired = 0; // track total shots fired
var infiniteHealthActive = false; // track if infinite health cheat is active
// Add score text to GUI
var scoreText = new Text2('0', {
size: 150,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
// Add ammo text to GUI
var ammoText = new Text2('Ammo: 10', {
size: 100,
fill: 0xffe066
});
ammoText.anchor.set(1, 0);
LK.gui.topRight.addChild(ammoText);
// Add cheat status text to GUI
var cheatText = new Text2('', {
size: 80,
fill: 0x00ff00
});
cheatText.anchor.set(0.5, 0);
cheatText.y = 200;
LK.gui.top.addChild(cheatText);
// Start screen overlay with tap-to-start
var startScreen = new Container();
var startBg = LK.getAsset('zombie', {
anchorX: 0.5,
anchorY: 0.5
});
startBg.width = 900;
startBg.height = 900;
startBg.tint = 0x222244;
startScreen.addChild(startBg);
startBg.x = 0;
startBg.y = 0;
var startText = new Text2('Dodge the green zombies!', {
size: 120,
fill: 0xffffff
});
startText.anchor.set(0.5, 0.5);
startText.x = 0;
startText.y = -100;
startScreen.addChild(startText);
var howToText = new Text2('Tap anywhere to start!', {
size: 80,
fill: 0xffe066
});
howToText.anchor.set(0.5, 0.5);
howToText.x = 0;
howToText.y = 100;
startScreen.addChild(howToText);
// Center overlay
startScreen.x = 2048 / 2;
startScreen.y = 2732 / 2;
// Add to game
game.addChild(startScreen);
startScreen.visible = false;
// Start the game
function startGame() {
// Reset state
for (var i = 0; i < zombies.length; i++) {
zombies[i].destroy();
}
zombies = [];
for (var i = 0; i < bullets.length; i++) {
bullets[i].destroy();
}
bullets = [];
score = 0;
scoreText.setText(score);
zombiesEscaped = 0;
enemiesSpawned = 0;
gameStarted = true;
lastZombieTick = LK.ticks;
lastBulletTick = 0;
shotsInBurst = 0;
burstCooldownActive = false;
lastShotTime = 0;
currentAmmo = 10;
reloadActive = false;
lastReloadTick = 0;
totalShotsFired = 0;
infiniteHealthActive = false;
ammoText.setText('Ammo: ' + currentAmmo);
cheatText.setText('');
// Hide start screen
if (typeof startScreen !== "undefined") {
startScreen.visible = false;
}
// Create player
if (player) player.destroy();
player = new Player();
player.x = 400;
player.y = 1366;
game.addChild(player);
}
// Handle tap: move player to tap and shoot
game.down = function (x, y, obj) {
if (!gameStarted) {
// Start game on any tap
startGame();
return;
}
// Move player only vertically (x stays the same, y is clamped)
var py = Math.max(120, Math.min(y, 2732 - 120));
player.moveTo(player.x, py);
// Shoot bullet if not reloading and has ammo
if (!reloadActive && currentAmmo > 0) {
var bullet = new Bullet();
bullet.x = player.x + 80;
bullet.y = player.y;
bullets.push(bullet);
game.addChild(bullet);
currentAmmo--;
totalShotsFired++;
ammoText.setText('Ammo: ' + currentAmmo);
// Start reload if out of ammo
if (currentAmmo <= 0) {
reloadActive = true;
lastReloadTick = LK.ticks;
ammoText.setText('Reloading...');
}
}
};
// Main update loop
game.update = function () {
if (!gameStarted) return;
// Update player
if (player) player.update();
// Handle reload
if (reloadActive && LK.ticks - lastReloadTick > reloadDuration) {
reloadActive = false;
currentAmmo = 10;
ammoText.setText('Ammo: ' + currentAmmo);
// Check if player shot all 10 ammo without hitting anything (cheat activation)
var bulletsMissed = 0;
for (var b = 0; b < bullets.length; b++) {
if (bullets[b].x > 2048) bulletsMissed++;
}
if (totalShotsFired >= 10 && bulletsMissed >= 10 && !infiniteHealthActive) {
infiniteHealthActive = true;
cheatText.setText('INFINITE HEALTH ACTIVATED!');
LK.effects.flashScreen(0x00ff00, 1000);
}
}
// Clear all zombies and spawn special reload zombie at start of reload
if (reloadActive && LK.ticks - lastReloadTick === 1) {
// Clear all existing zombies
for (var k = zombies.length - 1; k >= 0; k--) {
zombies[k].destroy();
zombies.splice(k, 1);
}
// Spawn one special reload zombie that requires 2 hits and moves very slowly
var reloadZombie = new StrongZombie();
reloadZombie.speed = 1 * speedMultiplier; // very slow with difficulty modifier
reloadZombie.health = 2; // requires 2 shots
reloadZombie.x = 2048 + 80;
reloadZombie.y = 200 + Math.random() * (2732 - 400);
zombies.push(reloadZombie);
game.addChild(reloadZombie);
}
// Spawn zombies (but not during reload when special zombie is active)
if (!reloadActive && LK.ticks - lastZombieTick > zombieSpawnInterval) {
var zombie;
enemiesSpawned++;
// Spawn different zombies based on mode and score
if (selectedDifficulty === 'endless') {
// In endless mode, spawn random types with random speeds
var randomType = Math.random();
if (randomType < 0.3) {
zombie = new Zombie();
} else if (randomType < 0.6) {
zombie = new StrongZombie();
} else {
zombie = new ExtraStrongZombie();
}
// Random speed multiplier for endless mode (0.5x to 3x)
var randomSpeedMultiplier = 0.5 + Math.random() * 2.5;
zombie.speed = zombie.speed * randomSpeedMultiplier;
} else if (score >= 50) {
zombie = new ExtraStrongZombie();
zombie.speed = zombie.speed * speedMultiplier;
} else if (enemiesSpawned > 30) {
zombie = new StrongZombie();
zombie.speed = zombie.speed * speedMultiplier;
} else {
zombie = new Zombie();
zombie.speed = zombie.speed * speedMultiplier;
}
zombie.x = 2048 + 80;
zombie.y = 200 + Math.random() * (2732 - 400);
zombies.push(zombie);
game.addChild(zombie);
lastZombieTick = LK.ticks;
}
// Track escaped zombies
for (var i = zombies.length - 1; i >= 0; i--) {
var zombie = zombies[i];
zombie.update();
// Remove if off screen
if (zombie.x < -120) {
LK.effects.flashScreen(0xff0000, 800); // Flash screen red when zombie escapes
zombie.destroy();
zombies.splice(i, 1);
zombiesEscaped++;
// Game over if 10 zombies escape
if (zombiesEscaped >= 10) {
LK.showGameOver();
gameStarted = false;
return;
}
continue;
}
// Check collision with player
if (player.intersects(zombie)) {
if (!infiniteHealthActive) {
LK.effects.flashScreen(0xff0000, 800);
LK.showGameOver();
gameStarted = false;
return;
} else {
// With infinite health, just flash green and destroy the zombie
LK.effects.flashScreen(0x00ff00, 300);
zombie.destroy();
zombies.splice(i, 1);
score += 1;
scoreText.setText(score);
continue;
}
}
}
// Update bullets
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
bullet.update();
// Remove if off screen
if (bullet.x > 2048 + 120) {
bullet.destroy();
bullets.splice(i, 1);
continue;
}
// Check collision with zombies
for (var j = zombies.length - 1; j >= 0; j--) {
var zombie = zombies[j];
if (bullet.intersects(zombie)) {
// Remove bullet
bullet.destroy();
bullets.splice(i, 1);
// Handle zombie health
if (zombie.health && zombie.health > 1) {
// Strong zombie takes damage
zombie.health--;
// Flash zombie to show damage
LK.effects.flashObject(zombie, 0xffffff, 200);
} else {
// Kill zombie (normal or strong zombie with 1 health left)
zombie.destroy();
zombies.splice(j, 1);
// Score
score += 1;
scoreText.setText(score);
// Mode progression logic
if (selectedDifficulty === 'normal' && score >= 50) {
selectedDifficulty = 'hard';
speedMultiplier = 2.0;
LK.effects.flashScreen(0xffff00, 1000);
var modeText = new Text2('HARD MODE UNLOCKED!', {
size: 120,
fill: 0xffff00
});
modeText.anchor.set(0.5, 0.5);
modeText.x = 2048 / 2;
modeText.y = 2732 / 2;
game.addChild(modeText);
LK.setTimeout(function () {
modeText.destroy();
}, 3000);
} else if (selectedDifficulty === 'hard' && score >= 60) {
selectedDifficulty = 'endless';
speedMultiplier = 1.5;
LK.effects.flashScreen(0x00ff00, 1500);
var medalText = new Text2('🏆 MEDAL EARNED! ENDLESS MODE!', {
size: 120,
fill: 0x00ff00
});
medalText.anchor.set(0.5, 0.5);
medalText.x = 2048 / 2;
medalText.y = 2732 / 2;
game.addChild(medalText);
LK.setTimeout(function () {
medalText.destroy();
}, 4000);
} else if (selectedDifficulty === 'hard' && score >= 50) {
selectedDifficulty = 'endless';
speedMultiplier = 1.5;
LK.effects.flashScreen(0x0080ff, 1000);
var endlessText = new Text2('ENDLESS MODE UNLOCKED!', {
size: 120,
fill: 0x0080ff
});
endlessText.anchor.set(0.5, 0.5);
endlessText.x = 2048 / 2;
endlessText.y = 2732 / 2;
game.addChild(endlessText);
LK.setTimeout(function () {
endlessText.destroy();
}, 3000);
}
}
break;
}
}
}
};
// Start in idle state
gameStarted = false;
scoreText.setText('0');
// Show start screen initially
if (typeof startScreen !== "undefined") {
startScreen.visible = true;
} /****
* Classes
****/
// Bullet class: fired by player, moves right, destroys zombies
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletAsset = self.attachAsset('zombie', {
anchorX: 0.5,
anchorY: 0.5
});
bulletAsset.width = 60;
bulletAsset.height = 60;
bulletAsset.tint = 0xffe066; // yellow
self.speed = 32;
self.lastX = self.x;
self.update = function () {
self.lastX = self.x;
self.x += self.speed;
};
return self;
});
// Extra Strong Zombie class: moves left, requires 3 hits to die
var ExtraStrongZombie = Container.expand(function () {
var self = Container.call(this);
var zombieAsset = self.attachAsset('zombie', {
anchorX: 0.5,
anchorY: 0.5
});
zombieAsset.width = 160;
zombieAsset.height = 160;
zombieAsset.tint = 0x9c27b0; // purple for extra strong zombie
self.speed = 2.5 + Math.random() * 2;
self.health = 3; // requires 3 hits
self.lastX = self.x;
self.lastY = self.y;
self.update = function () {
self.lastX = self.x;
self.lastY = self.y;
self.x -= self.speed;
};
return self;
});
// Player class: the hero that can move and shoot
var Player = Container.expand(function () {
var self = Container.call(this);
// Attach player asset, centered
var playerAsset = self.attachAsset('character', {
anchorX: 0.5,
anchorY: 0.5
});
self.x = 400;
self.y = 1366;
self.speed = 18;
self.lastY = self.y;
self.lastX = self.x;
// Move up/down/left/right
self.moveTo = function (x, y) {
self.x = x;
self.y = y;
};
// Update method (not much needed for player)
self.update = function () {
self.lastY = self.y;
self.lastX = self.x;
};
return self;
});
// Strong Zombie class: moves left, requires 2 hits to die
var StrongZombie = Container.expand(function () {
var self = Container.call(this);
var zombieAsset = self.attachAsset('zombie', {
anchorX: 0.5,
anchorY: 0.5
});
zombieAsset.width = 140;
zombieAsset.height = 140;
zombieAsset.tint = 0xff5722; // orange-red for strong zombie
self.speed = 2 + Math.random() * 2;
self.health = 2; // requires 2 hits
self.lastX = self.x;
self.lastY = self.y;
self.update = function () {
self.lastX = self.x;
self.lastY = self.y;
self.x -= self.speed;
};
return self;
});
// Zombie class: moves left, dies on bullet hit
var Zombie = Container.expand(function () {
var self = Container.call(this);
var zombieAsset = self.attachAsset('zombie', {
anchorX: 0.5,
anchorY: 0.5
});
zombieAsset.width = 120;
zombieAsset.height = 120;
zombieAsset.tint = 0x4caf50; // green
self.speed = 4 + Math.random() * 3;
self.lastX = self.x;
self.lastY = self.y;
self.update = function () {
self.lastX = self.x;
self.lastY = self.y;
self.x -= self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Game constants
var zombieSpawnInterval = 60; // frames between zombies
var bulletCooldown = 30; // frames for 0.5 second delay after 2 shots
var playerMoveRadius = 1000; // how far player can move from left
var difficultySelected = true; // track if difficulty has been selected
var selectedDifficulty = 'normal'; // default difficulty
var speedMultiplier = 1.0; // speed multiplier based on difficulty
// Game state
var player;
var zombies = [];
var bullets = [];
var score = 0;
var gameStarted = false;
var lastZombieTick = 0;
var lastBulletTick = 0;
var shotsInBurst = 0; // track shots in current burst
var burstCooldownActive = false; // track if in cooldown period
var lastShotTime = 0; // track timing between shots
var zombiesEscaped = 0;
var enemiesSpawned = 0;
var currentAmmo = 10; // current ammo available
var reloadActive = false; // track if in reload period
var lastReloadTick = 0; // track when reload started
var reloadDuration = 120; // 2 seconds at 60fps
var totalShotsFired = 0; // track total shots fired
var infiniteHealthActive = false; // track if infinite health cheat is active
// Add score text to GUI
var scoreText = new Text2('0', {
size: 150,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
// Add ammo text to GUI
var ammoText = new Text2('Ammo: 10', {
size: 100,
fill: 0xffe066
});
ammoText.anchor.set(1, 0);
LK.gui.topRight.addChild(ammoText);
// Add cheat status text to GUI
var cheatText = new Text2('', {
size: 80,
fill: 0x00ff00
});
cheatText.anchor.set(0.5, 0);
cheatText.y = 200;
LK.gui.top.addChild(cheatText);
// Start screen overlay with tap-to-start
var startScreen = new Container();
var startBg = LK.getAsset('zombie', {
anchorX: 0.5,
anchorY: 0.5
});
startBg.width = 900;
startBg.height = 900;
startBg.tint = 0x222244;
startScreen.addChild(startBg);
startBg.x = 0;
startBg.y = 0;
var startText = new Text2('Dodge the green zombies!', {
size: 120,
fill: 0xffffff
});
startText.anchor.set(0.5, 0.5);
startText.x = 0;
startText.y = -100;
startScreen.addChild(startText);
var howToText = new Text2('Tap anywhere to start!', {
size: 80,
fill: 0xffe066
});
howToText.anchor.set(0.5, 0.5);
howToText.x = 0;
howToText.y = 100;
startScreen.addChild(howToText);
// Center overlay
startScreen.x = 2048 / 2;
startScreen.y = 2732 / 2;
// Add to game
game.addChild(startScreen);
startScreen.visible = false;
// Start the game
function startGame() {
// Reset state
for (var i = 0; i < zombies.length; i++) {
zombies[i].destroy();
}
zombies = [];
for (var i = 0; i < bullets.length; i++) {
bullets[i].destroy();
}
bullets = [];
score = 0;
scoreText.setText(score);
zombiesEscaped = 0;
enemiesSpawned = 0;
gameStarted = true;
lastZombieTick = LK.ticks;
lastBulletTick = 0;
shotsInBurst = 0;
burstCooldownActive = false;
lastShotTime = 0;
currentAmmo = 10;
reloadActive = false;
lastReloadTick = 0;
totalShotsFired = 0;
infiniteHealthActive = false;
ammoText.setText('Ammo: ' + currentAmmo);
cheatText.setText('');
// Hide start screen
if (typeof startScreen !== "undefined") {
startScreen.visible = false;
}
// Create player
if (player) player.destroy();
player = new Player();
player.x = 400;
player.y = 1366;
game.addChild(player);
}
// Handle tap: move player to tap and shoot
game.down = function (x, y, obj) {
if (!gameStarted) {
// Start game on any tap
startGame();
return;
}
// Move player only vertically (x stays the same, y is clamped)
var py = Math.max(120, Math.min(y, 2732 - 120));
player.moveTo(player.x, py);
// Shoot bullet if not reloading and has ammo
if (!reloadActive && currentAmmo > 0) {
var bullet = new Bullet();
bullet.x = player.x + 80;
bullet.y = player.y;
bullets.push(bullet);
game.addChild(bullet);
currentAmmo--;
totalShotsFired++;
ammoText.setText('Ammo: ' + currentAmmo);
// Start reload if out of ammo
if (currentAmmo <= 0) {
reloadActive = true;
lastReloadTick = LK.ticks;
ammoText.setText('Reloading...');
}
}
};
// Main update loop
game.update = function () {
if (!gameStarted) return;
// Update player
if (player) player.update();
// Handle reload
if (reloadActive && LK.ticks - lastReloadTick > reloadDuration) {
reloadActive = false;
currentAmmo = 10;
ammoText.setText('Ammo: ' + currentAmmo);
// Check if player shot all 10 ammo without hitting anything (cheat activation)
var bulletsMissed = 0;
for (var b = 0; b < bullets.length; b++) {
if (bullets[b].x > 2048) bulletsMissed++;
}
if (totalShotsFired >= 10 && bulletsMissed >= 10 && !infiniteHealthActive) {
infiniteHealthActive = true;
cheatText.setText('INFINITE HEALTH ACTIVATED!');
LK.effects.flashScreen(0x00ff00, 1000);
}
}
// Clear all zombies and spawn special reload zombie at start of reload
if (reloadActive && LK.ticks - lastReloadTick === 1) {
// Clear all existing zombies
for (var k = zombies.length - 1; k >= 0; k--) {
zombies[k].destroy();
zombies.splice(k, 1);
}
// Spawn one special reload zombie that requires 2 hits and moves very slowly
var reloadZombie = new StrongZombie();
reloadZombie.speed = 1 * speedMultiplier; // very slow with difficulty modifier
reloadZombie.health = 2; // requires 2 shots
reloadZombie.x = 2048 + 80;
reloadZombie.y = 200 + Math.random() * (2732 - 400);
zombies.push(reloadZombie);
game.addChild(reloadZombie);
}
// Spawn zombies (but not during reload when special zombie is active)
if (!reloadActive && LK.ticks - lastZombieTick > zombieSpawnInterval) {
var zombie;
enemiesSpawned++;
// Spawn different zombies based on mode and score
if (selectedDifficulty === 'endless') {
// In endless mode, spawn random types with random speeds
var randomType = Math.random();
if (randomType < 0.3) {
zombie = new Zombie();
} else if (randomType < 0.6) {
zombie = new StrongZombie();
} else {
zombie = new ExtraStrongZombie();
}
// Random speed multiplier for endless mode (0.5x to 3x)
var randomSpeedMultiplier = 0.5 + Math.random() * 2.5;
zombie.speed = zombie.speed * randomSpeedMultiplier;
} else if (score >= 50) {
zombie = new ExtraStrongZombie();
zombie.speed = zombie.speed * speedMultiplier;
} else if (enemiesSpawned > 30) {
zombie = new StrongZombie();
zombie.speed = zombie.speed * speedMultiplier;
} else {
zombie = new Zombie();
zombie.speed = zombie.speed * speedMultiplier;
}
zombie.x = 2048 + 80;
zombie.y = 200 + Math.random() * (2732 - 400);
zombies.push(zombie);
game.addChild(zombie);
lastZombieTick = LK.ticks;
}
// Track escaped zombies
for (var i = zombies.length - 1; i >= 0; i--) {
var zombie = zombies[i];
zombie.update();
// Remove if off screen
if (zombie.x < -120) {
LK.effects.flashScreen(0xff0000, 800); // Flash screen red when zombie escapes
zombie.destroy();
zombies.splice(i, 1);
zombiesEscaped++;
// Game over if 10 zombies escape
if (zombiesEscaped >= 10) {
LK.showGameOver();
gameStarted = false;
return;
}
continue;
}
// Check collision with player
if (player.intersects(zombie)) {
if (!infiniteHealthActive) {
LK.effects.flashScreen(0xff0000, 800);
LK.showGameOver();
gameStarted = false;
return;
} else {
// With infinite health, just flash green and destroy the zombie
LK.effects.flashScreen(0x00ff00, 300);
zombie.destroy();
zombies.splice(i, 1);
score += 1;
scoreText.setText(score);
continue;
}
}
}
// Update bullets
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
bullet.update();
// Remove if off screen
if (bullet.x > 2048 + 120) {
bullet.destroy();
bullets.splice(i, 1);
continue;
}
// Check collision with zombies
for (var j = zombies.length - 1; j >= 0; j--) {
var zombie = zombies[j];
if (bullet.intersects(zombie)) {
// Remove bullet
bullet.destroy();
bullets.splice(i, 1);
// Handle zombie health
if (zombie.health && zombie.health > 1) {
// Strong zombie takes damage
zombie.health--;
// Flash zombie to show damage
LK.effects.flashObject(zombie, 0xffffff, 200);
} else {
// Kill zombie (normal or strong zombie with 1 health left)
zombie.destroy();
zombies.splice(j, 1);
// Score
score += 1;
scoreText.setText(score);
// Mode progression logic
if (selectedDifficulty === 'normal' && score >= 50) {
selectedDifficulty = 'hard';
speedMultiplier = 2.0;
LK.effects.flashScreen(0xffff00, 1000);
var modeText = new Text2('HARD MODE UNLOCKED!', {
size: 120,
fill: 0xffff00
});
modeText.anchor.set(0.5, 0.5);
modeText.x = 2048 / 2;
modeText.y = 2732 / 2;
game.addChild(modeText);
LK.setTimeout(function () {
modeText.destroy();
}, 3000);
} else if (selectedDifficulty === 'hard' && score >= 60) {
selectedDifficulty = 'endless';
speedMultiplier = 1.5;
LK.effects.flashScreen(0x00ff00, 1500);
var medalText = new Text2('🏆 MEDAL EARNED! ENDLESS MODE!', {
size: 120,
fill: 0x00ff00
});
medalText.anchor.set(0.5, 0.5);
medalText.x = 2048 / 2;
medalText.y = 2732 / 2;
game.addChild(medalText);
LK.setTimeout(function () {
medalText.destroy();
}, 4000);
} else if (selectedDifficulty === 'hard' && score >= 50) {
selectedDifficulty = 'endless';
speedMultiplier = 1.5;
LK.effects.flashScreen(0x0080ff, 1000);
var endlessText = new Text2('ENDLESS MODE UNLOCKED!', {
size: 120,
fill: 0x0080ff
});
endlessText.anchor.set(0.5, 0.5);
endlessText.x = 2048 / 2;
endlessText.y = 2732 / 2;
game.addChild(endlessText);
LK.setTimeout(function () {
endlessText.destroy();
}, 3000);
}
}
break;
}
}
}
};
// Start in idle state
gameStarted = false;
scoreText.setText('0');
// Show start screen initially
if (typeof startScreen !== "undefined") {
startScreen.visible = true;
}