/****
* Classes
****/
var Gun = Container.expand(function () {
var self = Container.call(this);
var gunGraphics = self.attachAsset('gun', {
anchorX: 0.5,
anchorY: 0.5
});
var muzzleFlash = self.attachAsset('muzzleFlash', {
anchorX: 0.5,
anchorY: 0.5,
x: 30,
y: 0
});
muzzleFlash.visible = false;
self.fire = function () {
// Show muzzle flash
muzzleFlash.visible = true;
LK.getSound('gunShot').play();
// Hide muzzle flash after brief moment
LK.setTimeout(function () {
muzzleFlash.visible = false;
}, 100);
};
return self;
});
var Hero = Container.expand(function () {
var self = Container.call(this);
var heroGraphics = self.attachAsset('hero', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 1;
self.gun = self.addChild(new Gun());
self.gun.x = 30;
self.gun.y = -10;
// Target position for hero to follow cursor
self.targetX = self.x;
self.targetY = self.y;
self.speed = 5;
self.aimAt = function (targetX, targetY) {
var dx = targetX - self.x;
var dy = targetY - self.y;
var angle = Math.atan2(dy, dx);
self.gun.rotation = angle;
// Update gun position based on rotation to simulate holding it
var gunOffsetX = Math.cos(angle) * 25;
var gunOffsetY = Math.sin(angle) * 25;
self.gun.x = gunOffsetX;
self.gun.y = gunOffsetY;
};
self.shoot = function () {
self.gun.fire();
};
self.update = function () {
// Move toward target cursor position
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 5) {
// Use faster speed if right button is held down (25% faster)
var currentSpeed = isRightButtonDown ? self.speed * 1.25 : self.speed;
// Only move if not very close to target
self.x += dx / distance * currentSpeed;
self.y += dy / distance * currentSpeed;
// Keep hero within screen bounds
self.x = Math.max(40, Math.min(2048 - 40, self.x));
self.y = Math.max(40, Math.min(2732 - 40, self.y));
}
};
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.targetX = 0;
self.targetY = 0;
self.update = function () {
// Move toward target (hero position)
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
};
return self;
});
/****
* Initialize Game
****/
// Game variables
var game = new LK.Game({
backgroundColor: 0x8B4513
});
/****
* Game Code
****/
// Game variables
var hero;
var zombies = [];
var dragNode = null;
var spawnTimer = 0;
var spawnInterval = 120; // Start spawning every 2 seconds
var gameTime = 0;
var lastHeroX = 0;
var lastHeroY = 0;
var isRightButtonDown = false;
var playerHealth = 100;
var maxHealth = 100;
// Create score display
var scoreTxt = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Create health bar at bottom right
var healthTxt = new Text2('Health: 100/100', {
size: 50,
fill: 0x00FF00
});
healthTxt.anchor.set(1, 1);
LK.gui.bottomRight.addChild(healthTxt);
// Create and position hero at center
hero = game.addChild(new Hero());
hero.x = 2048 / 2;
hero.y = 2732 / 2;
hero.targetX = hero.x;
hero.targetY = hero.y;
lastHeroX = hero.x;
lastHeroY = hero.y;
// Start energetic background music
LK.playMusic('enerjik');
// Add event listeners for right mouse button
LK.on('contextmenu', function (event) {
isRightButtonDown = true;
});
LK.on('contextmenuup', function (event) {
isRightButtonDown = false;
});
// Spawn zombie at random edge
function spawnZombie() {
var zombie = new Zombie();
var edge = Math.floor(Math.random() * 4); // 0=top, 1=right, 2=bottom, 3=left
switch (edge) {
case 0:
// Top
zombie.x = Math.random() * 2048;
zombie.y = -30;
break;
case 1:
// Right
zombie.x = 2048 + 30;
zombie.y = Math.random() * 2732;
break;
case 2:
// Bottom
zombie.x = Math.random() * 2048;
zombie.y = 2732 + 30;
break;
case 3:
// Left
zombie.x = -30;
zombie.y = Math.random() * 2732;
break;
}
zombie.targetX = hero.x;
zombie.targetY = hero.y;
zombie.speed = 1.5 + gameTime / 1800 + LK.getScore() / 500; // Increase speed over time and score
zombie.lastIntersecting = false;
zombies.push(zombie);
game.addChild(zombie);
}
// Handle dragging
game.down = function (x, y, obj) {
// Aim gun at tap location
hero.aimAt(x, y);
// Check if tapping on zombie to destroy it
for (var i = zombies.length - 1; i >= 0; i--) {
var zombie = zombies[i];
var distance = Math.sqrt((x - zombie.x) * (x - zombie.x) + (y - zombie.y) * (y - zombie.y));
if (distance < 150) {
// Shoot and destroy zombie
hero.shoot();
LK.setScore(LK.getScore() + 10);
scoreTxt.setText('Score: ' + LK.getScore());
LK.getSound('zombieHit').play();
LK.effects.flashObject(zombie, 0xffff00, 200);
zombie.destroy();
zombies.splice(i, 1);
break;
}
}
};
game.move = function (x, y, obj) {
// Store cursor position for hero to follow
hero.targetX = x;
hero.targetY = y;
// Always aim gun at current cursor/touch position
hero.aimAt(x, y);
};
game.up = function (x, y, obj) {
// No longer needed for dragging
};
// Main game loop
game.update = function () {
gameTime++;
spawnTimer++;
// Update hero target for zombies
if (hero.x !== lastHeroX || hero.y !== lastHeroY) {
for (var i = 0; i < zombies.length; i++) {
zombies[i].targetX = hero.x;
zombies[i].targetY = hero.y;
}
lastHeroX = hero.x;
lastHeroY = hero.y;
}
// Spawn zombies with increasing frequency based on score
var scoreBonus = Math.floor(LK.getScore() / 50); // Every 50 points reduces spawn interval
var currentSpawnInterval = Math.max(20, spawnInterval - Math.floor(gameTime / 600) - scoreBonus * 10);
if (spawnTimer >= currentSpawnInterval) {
spawnZombie();
spawnTimer = 0;
}
// Update zombies and check collisions
for (var i = zombies.length - 1; i >= 0; i--) {
var zombie = zombies[i];
// Check collision with hero
var currentIntersecting = zombie.intersects(hero);
if (!zombie.lastIntersecting && currentIntersecting) {
// Zombie hit - reduce health by 25
playerHealth -= 25;
LK.getSound('gameOverSound').play();
LK.effects.flashScreen(0xff0000, 500);
// Update health bar color based on health level
var healthColor = 0x00FF00; // Green
if (playerHealth <= 50) healthColor = 0xFFFF00; // Yellow
if (playerHealth <= 25) healthColor = 0xFF0000; // Red
healthTxt.setText('Health: ' + playerHealth + '/' + maxHealth);
healthTxt.fill = healthColor;
// Check if health reaches 0
if (playerHealth <= 0) {
LK.showGameOver();
return;
}
// Remove the zombie that hit the player
zombie.destroy();
zombies.splice(i, 1);
continue;
}
zombie.lastIntersecting = currentIntersecting;
// Remove zombies that are too far off screen
if (zombie.x < -100 || zombie.x > 2148 || zombie.y < -100 || zombie.y > 2832) {
zombie.destroy();
zombies.splice(i, 1);
}
}
}; /****
* Classes
****/
var Gun = Container.expand(function () {
var self = Container.call(this);
var gunGraphics = self.attachAsset('gun', {
anchorX: 0.5,
anchorY: 0.5
});
var muzzleFlash = self.attachAsset('muzzleFlash', {
anchorX: 0.5,
anchorY: 0.5,
x: 30,
y: 0
});
muzzleFlash.visible = false;
self.fire = function () {
// Show muzzle flash
muzzleFlash.visible = true;
LK.getSound('gunShot').play();
// Hide muzzle flash after brief moment
LK.setTimeout(function () {
muzzleFlash.visible = false;
}, 100);
};
return self;
});
var Hero = Container.expand(function () {
var self = Container.call(this);
var heroGraphics = self.attachAsset('hero', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 1;
self.gun = self.addChild(new Gun());
self.gun.x = 30;
self.gun.y = -10;
// Target position for hero to follow cursor
self.targetX = self.x;
self.targetY = self.y;
self.speed = 5;
self.aimAt = function (targetX, targetY) {
var dx = targetX - self.x;
var dy = targetY - self.y;
var angle = Math.atan2(dy, dx);
self.gun.rotation = angle;
// Update gun position based on rotation to simulate holding it
var gunOffsetX = Math.cos(angle) * 25;
var gunOffsetY = Math.sin(angle) * 25;
self.gun.x = gunOffsetX;
self.gun.y = gunOffsetY;
};
self.shoot = function () {
self.gun.fire();
};
self.update = function () {
// Move toward target cursor position
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 5) {
// Use faster speed if right button is held down (25% faster)
var currentSpeed = isRightButtonDown ? self.speed * 1.25 : self.speed;
// Only move if not very close to target
self.x += dx / distance * currentSpeed;
self.y += dy / distance * currentSpeed;
// Keep hero within screen bounds
self.x = Math.max(40, Math.min(2048 - 40, self.x));
self.y = Math.max(40, Math.min(2732 - 40, self.y));
}
};
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.targetX = 0;
self.targetY = 0;
self.update = function () {
// Move toward target (hero position)
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
};
return self;
});
/****
* Initialize Game
****/
// Game variables
var game = new LK.Game({
backgroundColor: 0x8B4513
});
/****
* Game Code
****/
// Game variables
var hero;
var zombies = [];
var dragNode = null;
var spawnTimer = 0;
var spawnInterval = 120; // Start spawning every 2 seconds
var gameTime = 0;
var lastHeroX = 0;
var lastHeroY = 0;
var isRightButtonDown = false;
var playerHealth = 100;
var maxHealth = 100;
// Create score display
var scoreTxt = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Create health bar at bottom right
var healthTxt = new Text2('Health: 100/100', {
size: 50,
fill: 0x00FF00
});
healthTxt.anchor.set(1, 1);
LK.gui.bottomRight.addChild(healthTxt);
// Create and position hero at center
hero = game.addChild(new Hero());
hero.x = 2048 / 2;
hero.y = 2732 / 2;
hero.targetX = hero.x;
hero.targetY = hero.y;
lastHeroX = hero.x;
lastHeroY = hero.y;
// Start energetic background music
LK.playMusic('enerjik');
// Add event listeners for right mouse button
LK.on('contextmenu', function (event) {
isRightButtonDown = true;
});
LK.on('contextmenuup', function (event) {
isRightButtonDown = false;
});
// Spawn zombie at random edge
function spawnZombie() {
var zombie = new Zombie();
var edge = Math.floor(Math.random() * 4); // 0=top, 1=right, 2=bottom, 3=left
switch (edge) {
case 0:
// Top
zombie.x = Math.random() * 2048;
zombie.y = -30;
break;
case 1:
// Right
zombie.x = 2048 + 30;
zombie.y = Math.random() * 2732;
break;
case 2:
// Bottom
zombie.x = Math.random() * 2048;
zombie.y = 2732 + 30;
break;
case 3:
// Left
zombie.x = -30;
zombie.y = Math.random() * 2732;
break;
}
zombie.targetX = hero.x;
zombie.targetY = hero.y;
zombie.speed = 1.5 + gameTime / 1800 + LK.getScore() / 500; // Increase speed over time and score
zombie.lastIntersecting = false;
zombies.push(zombie);
game.addChild(zombie);
}
// Handle dragging
game.down = function (x, y, obj) {
// Aim gun at tap location
hero.aimAt(x, y);
// Check if tapping on zombie to destroy it
for (var i = zombies.length - 1; i >= 0; i--) {
var zombie = zombies[i];
var distance = Math.sqrt((x - zombie.x) * (x - zombie.x) + (y - zombie.y) * (y - zombie.y));
if (distance < 150) {
// Shoot and destroy zombie
hero.shoot();
LK.setScore(LK.getScore() + 10);
scoreTxt.setText('Score: ' + LK.getScore());
LK.getSound('zombieHit').play();
LK.effects.flashObject(zombie, 0xffff00, 200);
zombie.destroy();
zombies.splice(i, 1);
break;
}
}
};
game.move = function (x, y, obj) {
// Store cursor position for hero to follow
hero.targetX = x;
hero.targetY = y;
// Always aim gun at current cursor/touch position
hero.aimAt(x, y);
};
game.up = function (x, y, obj) {
// No longer needed for dragging
};
// Main game loop
game.update = function () {
gameTime++;
spawnTimer++;
// Update hero target for zombies
if (hero.x !== lastHeroX || hero.y !== lastHeroY) {
for (var i = 0; i < zombies.length; i++) {
zombies[i].targetX = hero.x;
zombies[i].targetY = hero.y;
}
lastHeroX = hero.x;
lastHeroY = hero.y;
}
// Spawn zombies with increasing frequency based on score
var scoreBonus = Math.floor(LK.getScore() / 50); // Every 50 points reduces spawn interval
var currentSpawnInterval = Math.max(20, spawnInterval - Math.floor(gameTime / 600) - scoreBonus * 10);
if (spawnTimer >= currentSpawnInterval) {
spawnZombie();
spawnTimer = 0;
}
// Update zombies and check collisions
for (var i = zombies.length - 1; i >= 0; i--) {
var zombie = zombies[i];
// Check collision with hero
var currentIntersecting = zombie.intersects(hero);
if (!zombie.lastIntersecting && currentIntersecting) {
// Zombie hit - reduce health by 25
playerHealth -= 25;
LK.getSound('gameOverSound').play();
LK.effects.flashScreen(0xff0000, 500);
// Update health bar color based on health level
var healthColor = 0x00FF00; // Green
if (playerHealth <= 50) healthColor = 0xFFFF00; // Yellow
if (playerHealth <= 25) healthColor = 0xFF0000; // Red
healthTxt.setText('Health: ' + playerHealth + '/' + maxHealth);
healthTxt.fill = healthColor;
// Check if health reaches 0
if (playerHealth <= 0) {
LK.showGameOver();
return;
}
// Remove the zombie that hit the player
zombie.destroy();
zombies.splice(i, 1);
continue;
}
zombie.lastIntersecting = currentIntersecting;
// Remove zombies that are too far off screen
if (zombie.x < -100 || zombie.x > 2148 || zombie.y < -100 || zombie.y > 2832) {
zombie.destroy();
zombies.splice(i, 1);
}
}
};
gun. In-Game asset. 2d. High contrast. No shadows
a muzzle flash. In-Game asset. 2d. High contrast. No shadows
a horror zombie. In-Game asset. 2d. High contrast. No shadows
A man who survives but does not have a gun in his hand, his hand holds a gun but does not have a gun. In-Game asset. 2d. High contrast. No shadows