/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { highScore: 0, highWave: 1 }); /**** * Classes ****/ var Bullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 15; self.damage = 20; self.direction = { x: 0, y: -1 }; // Default direction: up self.update = function () { self.x += self.direction.x * self.speed; self.y += self.direction.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 = 10; self.health = 100; self.maxHealth = 100; self.fireRate = 20; // Frames between shots self.fireCounter = 0; self.invincible = false; self.invincibleTimer = 0; self.weaponPowerLevel = 1; self.weaponPowerTimer = 0; self.takeDamage = function (amount) { if (self.invincible) { return; } self.health -= amount; // Create blood effect var blood = LK.getAsset('blood', { anchorX: 0.5, anchorY: 0.5, x: self.x, y: self.y }); game.addChild(blood); LK.effects.flashObject(blood, 0xff0000, 500); // Make blood fade out over 2 seconds tween(blood, { alpha: 0 }, { duration: 2000 }); if (self.health <= 0) { self.health = 0; gameOver(); } // Flash player on hit LK.effects.flashObject(self, 0xff0000, 500); // Make player invincible for a short time self.invincible = true; self.invincibleTimer = 60; // 1 second at 60fps // Play hit sound LK.getSound('playerHit').play(); // Update health bar updateHealthBar(); }; self.collectPowerup = function (type) { LK.getSound('powerupCollect').play(); if (type === 'health') { self.health = Math.min(self.health + 20, self.maxHealth); updateHealthBar(); } else if (type === 'weapon') { self.weaponPowerLevel = 2; self.weaponPowerTimer = 300; // 5 seconds at 60fps } }; self.update = function () { // Handle invincibility if (self.invincible) { self.invincibleTimer--; // Flicker effect self.alpha = self.invincibleTimer % 10 < 5 ? 0.5 : 1; if (self.invincibleTimer <= 0) { self.invincible = false; self.alpha = 1; } } // Handle weapon power timer if (self.weaponPowerLevel > 1) { self.weaponPowerTimer--; if (self.weaponPowerTimer <= 0) { self.weaponPowerLevel = 1; } } // Update fire counter if (self.fireCounter > 0) { self.fireCounter--; } }; return self; }); var Powerup = Container.expand(function () { var self = Container.call(this); var powerupGraphics = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5 }); self.type = 'health'; // Can be: health, weapon self.lifetime = 300; // 5 seconds at 60fps self.init = function (type) { self.type = type || (Math.random() < 0.7 ? 'health' : 'weapon'); if (self.type === 'health') { powerupGraphics.tint = 0x2ecc71; // Green } else if (self.type === 'weapon') { powerupGraphics.tint = 0xf39c12; // Orange } }; self.update = function () { // Subtle floating animation self.y += Math.sin(LK.ticks * 0.1) * 0.5; // Fade out when about to disappear if (self.lifetime < 60) { self.alpha = self.lifetime / 60; } self.lifetime--; }; return self; }); var Zombie = Container.expand(function () { var self = Container.call(this); var zombieGraphics = self.attachAsset('zombie', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 2; self.health = 40; self.damage = 10; self.hitTimer = 0; self.type = 'normal'; // Can be: normal, fast, tank self.init = function (type) { self.type = type || 'normal'; // Set zombie properties based on type if (self.type === 'fast') { self.speed = 3.5; self.health = 25; zombieGraphics.tint = 0xe74c3c; // Red tint } else if (self.type === 'tank') { self.speed = 1.2; self.health = 80; self.damage = 20; zombieGraphics.tint = 0x8e44ad; // Purple tint zombieGraphics.scale.set(1.4, 1.4); } }; self.takeDamage = function (damage) { self.health -= damage; // Create blood effect var blood = LK.getAsset('blood', { anchorX: 0.5, anchorY: 0.5, x: self.x, y: self.y }); game.addChild(blood); LK.effects.flashObject(blood, 0xff0000, 200); // Make blood fade out over 2 seconds tween(blood, { alpha: 0 }, { duration: 2000 }); // Flash zombie on hit LK.effects.flashObject(self, 0xff0000, 200); // Play hit sound LK.getSound('zombieHit').play(); if (self.health <= 0) { // Add to score var scoreValue = self.type === 'normal' ? 10 : self.type === 'fast' ? 15 : 25; LK.setScore(LK.getScore() + scoreValue); updateScoreDisplay(); // Chance to spawn a powerup if (Math.random() < 0.2) { spawnPowerup(self.x, self.y); } return true; // Zombie is dead } return false; // Zombie still alive }; self.update = function () { // Move towards player if (player) { var dx = player.x - self.x; var dy = player.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { self.x += dx / dist * self.speed; self.y += dy / dist * self.speed; } // Attack player on collision if (self.hitTimer <= 0 && self.intersects(player)) { player.takeDamage(self.damage); self.hitTimer = 30; // Half second cooldown } if (self.hitTimer > 0) { self.hitTimer--; } } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ //{0.1} var cityBackground = LK.getAsset('cityBackground', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 }); game.addChild(cityBackground); // Game variables var player; var bullets = []; var zombies = []; var powerups = []; var waveNumber = 1; var zombiesInWave = 5; var waveTimer = 0; var spawnDelay = 60; // 1 second between zombie spawns var spawnCounter = 0; var zombiesSpawned = 0; var waveCooldown = false; var gameStarted = false; var healthBar; var healthBarBg; var scoreText; var waveText; // Setup game function setupGame() { // Create high score text var highScoreText = new Text2('High Score: ' + storage.highScore, { size: 80, fill: 0xFFFFFF }); highScoreText.anchor.set(0, 0); LK.gui.topLeft.addChild(highScoreText); player = new Player(); player.x = 2048 / 2; player.y = 2732 - 300; game.addChild(player); // Create health bar background healthBarBg = LK.getAsset('healthBarBg', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 - 100 }); LK.gui.bottom.addChild(healthBarBg); // Create health bar healthBar = LK.getAsset('healthBar', { anchorX: 0, anchorY: 0.5, x: 2048 / 2 - 200, y: 2732 - 100 }); LK.gui.bottom.addChild(healthBar); // Create score text scoreText = new Text2('Score: 0', { size: 80, fill: 0xFFFFFF }); scoreText.anchor.set(1, 0); LK.gui.topRight.addChild(scoreText); // Create wave text waveText = new Text2('Wave: 1', { size: 80, fill: 0xFF0000 }); waveText.anchor.set(0.5, 1); LK.gui.bottom.addChild(waveText); // Create high wave text var highWaveText = new Text2('High Wave: ' + storage.highWave, { size: 80, fill: 0xFF0000 }); highWaveText.anchor.set(0.5, 1); LK.gui.bottom.addChild(highWaveText); // Set high wave text position after waveText is initialized highWaveText.y = waveText.y - highWaveText.height; // Reset game state LK.setScore(0); updateScoreDisplay(); bullets = []; zombies = []; powerups = []; waveNumber = 1; zombiesInWave = 5; waveTimer = 180; // 3 second delay before first wave spawnCounter = 0; zombiesSpawned = 0; waveCooldown = false; gameStarted = true; // Play background music LK.playMusic('gameMusic', { fade: { start: 0, end: 0.5, duration: 1000 } }); } // Update score display function updateScoreDisplay() { scoreText.setText('Score: ' + LK.getScore()); } // Update wave display function updateWaveDisplay() { waveText.setText('Wave: ' + waveNumber); } // Update health bar function updateHealthBar() { if (player) { var healthPercentage = player.health / player.maxHealth; healthBar.scale.x = healthPercentage; } } // Spawn a zombie function spawnZombie() { var zombie = new Zombie(); // Determine zombie type based on wave and randomness var zombieType = 'normal'; var rand = Math.random(); if (waveNumber >= 3) { if (rand < 0.2) { zombieType = 'fast'; } else if (waveNumber >= 5 && rand < 0.3) { zombieType = 'tank'; } } zombie.init(zombieType); // Position zombie at a random edge of the screen var side = Math.floor(Math.random() * 4); switch (side) { case 0: // Top zombie.x = Math.random() * 2048; zombie.y = -50; break; case 1: // Right zombie.x = 2048 + 50; zombie.y = Math.random() * 2732; break; case 2: // Bottom zombie.x = Math.random() * 2048; zombie.y = 2732 + 50; break; case 3: // Left zombie.x = -50; zombie.y = Math.random() * 2732; break; } zombies.push(zombie); game.addChild(zombie); zombiesSpawned++; } // Spawn a powerup at the given position function spawnPowerup(x, y) { var powerup = new Powerup(); powerup.x = x; powerup.y = y; powerup.init(); powerups.push(powerup); game.addChild(powerup); } // Fire a bullet function fireBullet() { if (!player || player.fireCounter > 0) { return; } LK.getSound('shoot').play(); // Handle different weapon power levels if (player.weaponPowerLevel === 1) { // Single bullet var bullet = new Bullet(); bullet.x = player.x; bullet.y = player.y - 50; bullets.push(bullet); game.addChild(bullet); } else if (player.weaponPowerLevel === 2) { // Triple shot for (var i = -1; i <= 1; i++) { var bullet = new Bullet(); bullet.x = player.x; bullet.y = player.y - 50; var angle = i * Math.PI / 8; bullet.direction = { x: Math.sin(angle), y: -Math.cos(angle) }; bullets.push(bullet); game.addChild(bullet); } } player.fireCounter = player.fireRate; } // Game over function function gameOver() { LK.effects.flashScreen(0xff0000, 1000); LK.stopMusic(); if (LK.getScore() > storage.highScore) { storage.highScore = LK.getScore(); } LK.showGameOver(); } // Drag functionality var isDragging = false; // Mouse/touch down game.down = function (x, y, obj) { if (!gameStarted) { setupGame(); return; } isDragging = true; fireBullet(); }; // Mouse/touch up game.up = function (x, y, obj) { isDragging = false; }; // Mouse/touch move game.move = function (x, y, obj) { if (isDragging && player) { player.x = x; player.y = y; // Keep player within boundaries player.x = Math.max(60, Math.min(player.x, 2048 - 60)); player.y = Math.max(60, Math.min(player.y, 2732 - 60)); } }; // Main update function game.update = function () { if (!gameStarted) { return; } // Wave management if (waveTimer > 0) { waveTimer--; if (waveTimer === 0 && waveCooldown) { // Start next wave waveNumber++; updateWaveDisplay(); zombiesInWave = 5 + waveNumber * 2; zombiesSpawned = 0; waveCooldown = false; } } // Spawn zombies if (!waveCooldown && zombiesSpawned < zombiesInWave) { spawnCounter++; if (spawnCounter >= spawnDelay) { spawnCounter = 0; spawnZombie(); } } // Check if wave is complete if (!waveCooldown && zombiesSpawned >= zombiesInWave && zombies.length === 0) { waveCooldown = true; waveTimer = 180; // 3 second break between waves } // 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) { bullet.destroy(); 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; // Damage zombie if (zombie.takeDamage(bullet.damage)) { zombie.destroy(); zombies.splice(j, 1); } break; } } // Remove bullet if it hit a zombie if (hitZombie) { bullet.destroy(); bullets.splice(i, 1); } } // Update zombies for (var i = 0; i < zombies.length; i++) { zombies[i].update(); } // Update powerups for (var i = powerups.length - 1; i >= 0; i--) { var powerup = powerups[i]; powerup.update(); // Check if powerup is collected if (player && powerup.intersects(player)) { player.collectPowerup(powerup.type); powerup.destroy(); powerups.splice(i, 1); continue; } // Remove powerup if lifetime is over if (powerup.lifetime <= 0) { powerup.destroy(); powerups.splice(i, 1); } } // Update player if (player) { player.update(); // Auto-fire if dragging if (isDragging && player.fireCounter <= 0) { fireBullet(); } } }; // Initial setup - display start screen var startText = new Text2('Tap to Start', { size: 120, fill: 0xFFFFFF }); startText.anchor.set(0.5, 0.5); LK.gui.center.addChild(startText); var instructionText = new Text2('Drag to move, tap to shoot', { size: 60, fill: 0xFFFFFF }); instructionText.anchor.set(0.5, 0.5); instructionText.y = 100; LK.gui.center.addChild(instructionText); // Reset when tapped LK.setInterval(function () { if (!gameStarted) { return; } startText.visible = false; instructionText.visible = false; }, 100);
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
highScore: 0,
highWave: 1
});
/****
* Classes
****/
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 15;
self.damage = 20;
self.direction = {
x: 0,
y: -1
}; // Default direction: up
self.update = function () {
self.x += self.direction.x * self.speed;
self.y += self.direction.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 = 10;
self.health = 100;
self.maxHealth = 100;
self.fireRate = 20; // Frames between shots
self.fireCounter = 0;
self.invincible = false;
self.invincibleTimer = 0;
self.weaponPowerLevel = 1;
self.weaponPowerTimer = 0;
self.takeDamage = function (amount) {
if (self.invincible) {
return;
}
self.health -= amount;
// Create blood effect
var blood = LK.getAsset('blood', {
anchorX: 0.5,
anchorY: 0.5,
x: self.x,
y: self.y
});
game.addChild(blood);
LK.effects.flashObject(blood, 0xff0000, 500);
// Make blood fade out over 2 seconds
tween(blood, {
alpha: 0
}, {
duration: 2000
});
if (self.health <= 0) {
self.health = 0;
gameOver();
}
// Flash player on hit
LK.effects.flashObject(self, 0xff0000, 500);
// Make player invincible for a short time
self.invincible = true;
self.invincibleTimer = 60; // 1 second at 60fps
// Play hit sound
LK.getSound('playerHit').play();
// Update health bar
updateHealthBar();
};
self.collectPowerup = function (type) {
LK.getSound('powerupCollect').play();
if (type === 'health') {
self.health = Math.min(self.health + 20, self.maxHealth);
updateHealthBar();
} else if (type === 'weapon') {
self.weaponPowerLevel = 2;
self.weaponPowerTimer = 300; // 5 seconds at 60fps
}
};
self.update = function () {
// Handle invincibility
if (self.invincible) {
self.invincibleTimer--;
// Flicker effect
self.alpha = self.invincibleTimer % 10 < 5 ? 0.5 : 1;
if (self.invincibleTimer <= 0) {
self.invincible = false;
self.alpha = 1;
}
}
// Handle weapon power timer
if (self.weaponPowerLevel > 1) {
self.weaponPowerTimer--;
if (self.weaponPowerTimer <= 0) {
self.weaponPowerLevel = 1;
}
}
// Update fire counter
if (self.fireCounter > 0) {
self.fireCounter--;
}
};
return self;
});
var Powerup = Container.expand(function () {
var self = Container.call(this);
var powerupGraphics = self.attachAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5
});
self.type = 'health'; // Can be: health, weapon
self.lifetime = 300; // 5 seconds at 60fps
self.init = function (type) {
self.type = type || (Math.random() < 0.7 ? 'health' : 'weapon');
if (self.type === 'health') {
powerupGraphics.tint = 0x2ecc71; // Green
} else if (self.type === 'weapon') {
powerupGraphics.tint = 0xf39c12; // Orange
}
};
self.update = function () {
// Subtle floating animation
self.y += Math.sin(LK.ticks * 0.1) * 0.5;
// Fade out when about to disappear
if (self.lifetime < 60) {
self.alpha = self.lifetime / 60;
}
self.lifetime--;
};
return self;
});
var Zombie = Container.expand(function () {
var self = Container.call(this);
var zombieGraphics = self.attachAsset('zombie', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2;
self.health = 40;
self.damage = 10;
self.hitTimer = 0;
self.type = 'normal'; // Can be: normal, fast, tank
self.init = function (type) {
self.type = type || 'normal';
// Set zombie properties based on type
if (self.type === 'fast') {
self.speed = 3.5;
self.health = 25;
zombieGraphics.tint = 0xe74c3c; // Red tint
} else if (self.type === 'tank') {
self.speed = 1.2;
self.health = 80;
self.damage = 20;
zombieGraphics.tint = 0x8e44ad; // Purple tint
zombieGraphics.scale.set(1.4, 1.4);
}
};
self.takeDamage = function (damage) {
self.health -= damage;
// Create blood effect
var blood = LK.getAsset('blood', {
anchorX: 0.5,
anchorY: 0.5,
x: self.x,
y: self.y
});
game.addChild(blood);
LK.effects.flashObject(blood, 0xff0000, 200);
// Make blood fade out over 2 seconds
tween(blood, {
alpha: 0
}, {
duration: 2000
});
// Flash zombie on hit
LK.effects.flashObject(self, 0xff0000, 200);
// Play hit sound
LK.getSound('zombieHit').play();
if (self.health <= 0) {
// Add to score
var scoreValue = self.type === 'normal' ? 10 : self.type === 'fast' ? 15 : 25;
LK.setScore(LK.getScore() + scoreValue);
updateScoreDisplay();
// Chance to spawn a powerup
if (Math.random() < 0.2) {
spawnPowerup(self.x, self.y);
}
return true; // Zombie is dead
}
return false; // Zombie still alive
};
self.update = function () {
// Move towards player
if (player) {
var dx = player.x - self.x;
var dy = player.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 0) {
self.x += dx / dist * self.speed;
self.y += dy / dist * self.speed;
}
// Attack player on collision
if (self.hitTimer <= 0 && self.intersects(player)) {
player.takeDamage(self.damage);
self.hitTimer = 30; // Half second cooldown
}
if (self.hitTimer > 0) {
self.hitTimer--;
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
//{0.1}
var cityBackground = LK.getAsset('cityBackground', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2
});
game.addChild(cityBackground);
// Game variables
var player;
var bullets = [];
var zombies = [];
var powerups = [];
var waveNumber = 1;
var zombiesInWave = 5;
var waveTimer = 0;
var spawnDelay = 60; // 1 second between zombie spawns
var spawnCounter = 0;
var zombiesSpawned = 0;
var waveCooldown = false;
var gameStarted = false;
var healthBar;
var healthBarBg;
var scoreText;
var waveText;
// Setup game
function setupGame() {
// Create high score text
var highScoreText = new Text2('High Score: ' + storage.highScore, {
size: 80,
fill: 0xFFFFFF
});
highScoreText.anchor.set(0, 0);
LK.gui.topLeft.addChild(highScoreText);
player = new Player();
player.x = 2048 / 2;
player.y = 2732 - 300;
game.addChild(player);
// Create health bar background
healthBarBg = LK.getAsset('healthBarBg', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 - 100
});
LK.gui.bottom.addChild(healthBarBg);
// Create health bar
healthBar = LK.getAsset('healthBar', {
anchorX: 0,
anchorY: 0.5,
x: 2048 / 2 - 200,
y: 2732 - 100
});
LK.gui.bottom.addChild(healthBar);
// Create score text
scoreText = new Text2('Score: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreText.anchor.set(1, 0);
LK.gui.topRight.addChild(scoreText);
// Create wave text
waveText = new Text2('Wave: 1', {
size: 80,
fill: 0xFF0000
});
waveText.anchor.set(0.5, 1);
LK.gui.bottom.addChild(waveText);
// Create high wave text
var highWaveText = new Text2('High Wave: ' + storage.highWave, {
size: 80,
fill: 0xFF0000
});
highWaveText.anchor.set(0.5, 1);
LK.gui.bottom.addChild(highWaveText);
// Set high wave text position after waveText is initialized
highWaveText.y = waveText.y - highWaveText.height;
// Reset game state
LK.setScore(0);
updateScoreDisplay();
bullets = [];
zombies = [];
powerups = [];
waveNumber = 1;
zombiesInWave = 5;
waveTimer = 180; // 3 second delay before first wave
spawnCounter = 0;
zombiesSpawned = 0;
waveCooldown = false;
gameStarted = true;
// Play background music
LK.playMusic('gameMusic', {
fade: {
start: 0,
end: 0.5,
duration: 1000
}
});
}
// Update score display
function updateScoreDisplay() {
scoreText.setText('Score: ' + LK.getScore());
}
// Update wave display
function updateWaveDisplay() {
waveText.setText('Wave: ' + waveNumber);
}
// Update health bar
function updateHealthBar() {
if (player) {
var healthPercentage = player.health / player.maxHealth;
healthBar.scale.x = healthPercentage;
}
}
// Spawn a zombie
function spawnZombie() {
var zombie = new Zombie();
// Determine zombie type based on wave and randomness
var zombieType = 'normal';
var rand = Math.random();
if (waveNumber >= 3) {
if (rand < 0.2) {
zombieType = 'fast';
} else if (waveNumber >= 5 && rand < 0.3) {
zombieType = 'tank';
}
}
zombie.init(zombieType);
// Position zombie at a random edge of the screen
var side = Math.floor(Math.random() * 4);
switch (side) {
case 0:
// Top
zombie.x = Math.random() * 2048;
zombie.y = -50;
break;
case 1:
// Right
zombie.x = 2048 + 50;
zombie.y = Math.random() * 2732;
break;
case 2:
// Bottom
zombie.x = Math.random() * 2048;
zombie.y = 2732 + 50;
break;
case 3:
// Left
zombie.x = -50;
zombie.y = Math.random() * 2732;
break;
}
zombies.push(zombie);
game.addChild(zombie);
zombiesSpawned++;
}
// Spawn a powerup at the given position
function spawnPowerup(x, y) {
var powerup = new Powerup();
powerup.x = x;
powerup.y = y;
powerup.init();
powerups.push(powerup);
game.addChild(powerup);
}
// Fire a bullet
function fireBullet() {
if (!player || player.fireCounter > 0) {
return;
}
LK.getSound('shoot').play();
// Handle different weapon power levels
if (player.weaponPowerLevel === 1) {
// Single bullet
var bullet = new Bullet();
bullet.x = player.x;
bullet.y = player.y - 50;
bullets.push(bullet);
game.addChild(bullet);
} else if (player.weaponPowerLevel === 2) {
// Triple shot
for (var i = -1; i <= 1; i++) {
var bullet = new Bullet();
bullet.x = player.x;
bullet.y = player.y - 50;
var angle = i * Math.PI / 8;
bullet.direction = {
x: Math.sin(angle),
y: -Math.cos(angle)
};
bullets.push(bullet);
game.addChild(bullet);
}
}
player.fireCounter = player.fireRate;
}
// Game over function
function gameOver() {
LK.effects.flashScreen(0xff0000, 1000);
LK.stopMusic();
if (LK.getScore() > storage.highScore) {
storage.highScore = LK.getScore();
}
LK.showGameOver();
}
// Drag functionality
var isDragging = false;
// Mouse/touch down
game.down = function (x, y, obj) {
if (!gameStarted) {
setupGame();
return;
}
isDragging = true;
fireBullet();
};
// Mouse/touch up
game.up = function (x, y, obj) {
isDragging = false;
};
// Mouse/touch move
game.move = function (x, y, obj) {
if (isDragging && player) {
player.x = x;
player.y = y;
// Keep player within boundaries
player.x = Math.max(60, Math.min(player.x, 2048 - 60));
player.y = Math.max(60, Math.min(player.y, 2732 - 60));
}
};
// Main update function
game.update = function () {
if (!gameStarted) {
return;
}
// Wave management
if (waveTimer > 0) {
waveTimer--;
if (waveTimer === 0 && waveCooldown) {
// Start next wave
waveNumber++;
updateWaveDisplay();
zombiesInWave = 5 + waveNumber * 2;
zombiesSpawned = 0;
waveCooldown = false;
}
}
// Spawn zombies
if (!waveCooldown && zombiesSpawned < zombiesInWave) {
spawnCounter++;
if (spawnCounter >= spawnDelay) {
spawnCounter = 0;
spawnZombie();
}
}
// Check if wave is complete
if (!waveCooldown && zombiesSpawned >= zombiesInWave && zombies.length === 0) {
waveCooldown = true;
waveTimer = 180; // 3 second break between waves
}
// 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) {
bullet.destroy();
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;
// Damage zombie
if (zombie.takeDamage(bullet.damage)) {
zombie.destroy();
zombies.splice(j, 1);
}
break;
}
}
// Remove bullet if it hit a zombie
if (hitZombie) {
bullet.destroy();
bullets.splice(i, 1);
}
}
// Update zombies
for (var i = 0; i < zombies.length; i++) {
zombies[i].update();
}
// Update powerups
for (var i = powerups.length - 1; i >= 0; i--) {
var powerup = powerups[i];
powerup.update();
// Check if powerup is collected
if (player && powerup.intersects(player)) {
player.collectPowerup(powerup.type);
powerup.destroy();
powerups.splice(i, 1);
continue;
}
// Remove powerup if lifetime is over
if (powerup.lifetime <= 0) {
powerup.destroy();
powerups.splice(i, 1);
}
}
// Update player
if (player) {
player.update();
// Auto-fire if dragging
if (isDragging && player.fireCounter <= 0) {
fireBullet();
}
}
};
// Initial setup - display start screen
var startText = new Text2('Tap to Start', {
size: 120,
fill: 0xFFFFFF
});
startText.anchor.set(0.5, 0.5);
LK.gui.center.addChild(startText);
var instructionText = new Text2('Drag to move, tap to shoot', {
size: 60,
fill: 0xFFFFFF
});
instructionText.anchor.set(0.5, 0.5);
instructionText.y = 100;
LK.gui.center.addChild(instructionText);
// Reset when tapped
LK.setInterval(function () {
if (!gameStarted) {
return;
}
startText.visible = false;
instructionText.visible = false;
}, 100);
Make an 8-bit zombie. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Make an 8 bit boy with a gun. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Make a city background. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Make it a 8 bit red splatter. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Make it a yellow bullet . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat