/****
* 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