/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Bullet = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('ammo', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 12;
self.targetX = 0;
self.targetY = 0;
self.directionX = 0;
self.directionY = 0;
self.setTarget = function (targetX, targetY) {
var dx = targetX - self.x;
var dy = targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
self.directionX = dx / distance;
self.directionY = dy / distance;
}
};
self.update = function () {
self.x += self.directionX * self.speed;
self.y += self.directionY * self.speed;
};
return self;
});
var Debris = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('debris', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var Supply = Container.expand(function (type) {
var self = Container.call(this);
self.type = type;
var assetName = type;
var graphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
self.value = type === 'medicine' ? 25 : type === 'food' ? 15 : 3;
return self;
});
var Survivor = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('survivor', {
anchorX: 0.5,
anchorY: 0.5
});
// Add weapon visual
var weapon = self.attachAsset('ammo', {
anchorX: 0.5,
anchorY: 0.5,
x: 20,
y: -10,
scaleX: 1.5,
scaleY: 1.5
});
self.health = 100;
self.ammoCount = 5;
self.maxSpeed = 6;
self.currentSpeed = 0;
self.isMoving = false;
self.detectionRadius = 180;
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health < 0) self.health = 0;
LK.effects.flashObject(self, 0xff0000, 500);
LK.getSound('damage').play();
};
self.heal = function (amount) {
self.health += amount;
if (self.health > 100) self.health = 100;
LK.effects.flashObject(self, 0x00ff00, 300);
};
self.addAmmo = function (amount) {
self.ammoCount += amount;
};
self.shoot = function () {
if (self.ammoCount > 0) {
self.ammoCount--;
LK.getSound('shoot').play();
return true;
}
return false;
};
return self;
});
var Zombie = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('zombie', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 1.5;
self.detectionRadius = 150;
self.isAlerted = false;
self.targetX = self.x;
self.targetY = self.y;
self.patrolDistance = 225;
self.originalX = 0;
self.originalY = 0;
self.patrolDirection = 1;
self.alert = function () {
if (!self.isAlerted) {
self.isAlerted = true;
self.speed = 3.75;
tween(graphics, {
tint: 0xff4444
}, {
duration: 300
});
}
};
self.update = function () {
if (self.isAlerted) {
// Chase player
var dx = survivor.x - self.x;
var dy = survivor.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 5) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
} else {
// Patrol behavior
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 10) {
// Reached patrol point, set new target
self.targetX = self.originalX + (Math.random() - 0.5) * self.patrolDistance;
self.targetY = self.originalY + (Math.random() - 0.5) * self.patrolDistance;
// Keep within bounds
self.targetX = Math.max(100, Math.min(1948, self.targetX));
self.targetY = Math.max(300, Math.min(2432, self.targetY));
} else {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2d3748
});
/****
* Game Code
****/
// Game variables
var survivor;
var zombies = [];
var supplies = [];
var debris = [];
var bullets = [];
var obstacles = [];
var dragNode = null;
var gameTime = 0;
var lastHealthDecrease = 0;
var lastSupplySpawn = 0;
var lastZombieSpawn = 0;
var difficultyLevel = 1;
// UI Elements
var healthText = new Text2('Health: 100', {
size: 60,
fill: '#ff0000'
});
healthText.anchor.set(0, 0);
LK.gui.topLeft.addChild(healthText);
healthText.x = 120;
healthText.y = 20;
var ammoText = new Text2('Ammo: 5', {
size: 60,
fill: '#ffff00'
});
ammoText.anchor.set(0, 0);
LK.gui.topLeft.addChild(ammoText);
ammoText.x = 120;
ammoText.y = 105;
var scoreText = new Text2('Score: 0', {
size: 75,
fill: '#ffffff'
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
// Add dark overlay effect to background
var darkOverlay = LK.getAsset('box', {
width: 2048,
height: 2732,
color: 0x000000,
alpha: 0.3,
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
});
game.addChild(darkOverlay);
// Initialize survivor
survivor = game.addChild(new Survivor());
survivor.x = 1024;
survivor.y = 2000;
// Spawn initial debris
for (var i = 0; i < 4; i++) {
var debrisItem = game.addChild(new Debris());
debrisItem.x = 200 + Math.random() * 1648;
debrisItem.y = 400 + Math.random() * 1800;
debris.push(debrisItem);
}
// Spawn initial zombies
for (var i = 0; i < 3; i++) {
var zombie = game.addChild(new Zombie());
zombie.x = 300 + Math.random() * 1448;
zombie.y = 300 + Math.random() * 1500;
zombie.originalX = zombie.x;
zombie.originalY = zombie.y;
zombie.targetX = zombie.x;
zombie.targetY = zombie.y;
zombies.push(zombie);
}
// Spawn initial obstacles
for (var i = 0; i < 3; i++) {
var obstacle = game.addChild(new Obstacle());
obstacle.x = 300 + Math.random() * 1448;
obstacle.y = 500 + Math.random() * 1500;
obstacles.push(obstacle);
}
// Spawn initial supplies
for (var i = 0; i < 5; i++) {
spawnSupply();
}
function spawnSupply() {
var types = ['medicine', 'food', 'ammo'];
var type = types[Math.floor(Math.random() * types.length)];
var supply = game.addChild(new Supply(type));
// Spawn away from debris and zombies
var validPosition = false;
var attempts = 0;
while (!validPosition && attempts < 10) {
supply.x = 100 + Math.random() * 1848;
supply.y = 300 + Math.random() * 2132;
validPosition = true;
// Check distance from debris
for (var j = 0; j < debris.length; j++) {
var dist = Math.sqrt(Math.pow(supply.x - debris[j].x, 2) + Math.pow(supply.y - debris[j].y, 2));
if (dist < 120) {
validPosition = false;
break;
}
}
attempts++;
}
supplies.push(supply);
}
function spawnZombie() {
var zombie = game.addChild(new Zombie());
// Spawn at edges of screen
var side = Math.floor(Math.random() * 4);
if (side === 0) {
// top
zombie.x = Math.random() * 2048;
zombie.y = 200;
} else if (side === 1) {
// right
zombie.x = 1900;
zombie.y = Math.random() * 2732;
} else if (side === 2) {
// bottom
zombie.x = Math.random() * 2048;
zombie.y = 2500;
} else {
// left
zombie.x = 150;
zombie.y = Math.random() * 2732;
}
zombie.originalX = zombie.x;
zombie.originalY = zombie.y;
zombie.targetX = zombie.x;
zombie.targetY = zombie.y;
zombies.push(zombie);
}
function updateUI() {
healthText.setText('Health: ' + Math.floor(survivor.health));
ammoText.setText('Ammo: ' + survivor.ammoCount);
scoreText.setText('Score: ' + LK.getScore());
}
// Event handlers
game.down = function (x, y, obj) {
dragNode = survivor;
// Initialize position tracking
survivor.lastX = survivor.x;
survivor.lastY = survivor.y;
survivor.isMoving = true;
// Shoot bullet towards clicked position
if (survivor.shoot()) {
var bullet = game.addChild(new Bullet());
bullet.x = survivor.x;
bullet.y = survivor.y;
bullet.setTarget(x, y);
bullets.push(bullet);
}
};
game.up = function (x, y, obj) {
dragNode = null;
survivor.isMoving = false;
};
game.move = function (x, y, obj) {
if (dragNode) {
// Store previous position before moving
survivor.lastX = survivor.x;
survivor.lastY = survivor.y;
// Calculate desired position
var targetX = Math.max(50, Math.min(1998, x));
var targetY = Math.max(300, Math.min(2682, y));
// Calculate direction and distance
var dx = targetX - survivor.x;
var dy = targetY - survivor.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Apply speed limit
if (distance > 0) {
var moveDistance = Math.min(distance, survivor.maxSpeed);
survivor.x += dx / distance * moveDistance;
survivor.y += dy / distance * moveDistance;
}
survivor.isMoving = true;
}
};
game.update = function () {
gameTime += 16; // Approximately 16ms per frame at 60fps
// Health decreases over time
if (gameTime - lastHealthDecrease > 3000) {
// Every 3 seconds
survivor.health -= 2;
lastHealthDecrease = gameTime;
}
// Check game over
if (survivor.health <= 0) {
LK.showGameOver();
return;
}
// Spawn supplies
if (gameTime - lastSupplySpawn > 8000) {
// Every 8 seconds
spawnSupply();
lastSupplySpawn = gameTime;
}
// Spawn zombies (increasing difficulty)
difficultyLevel = Math.floor(gameTime / 30000) + 1; // Increase difficulty every 30 seconds
var zombieSpawnRate = Math.max(5000 - difficultyLevel * 500, 2000); // Faster spawning over time
if (gameTime - lastZombieSpawn > zombieSpawnRate) {
spawnZombie();
lastZombieSpawn = gameTime;
}
// Check zombie detection
for (var i = 0; i < zombies.length; i++) {
var zombie = zombies[i];
var dist = Math.sqrt(Math.pow(survivor.x - zombie.x, 2) + Math.pow(survivor.y - zombie.y, 2));
if (dist < zombie.detectionRadius) {
if (survivor.isMoving) {
// Fast movement alerts zombies
zombie.alert();
} else if (dist < 90) {
// Very close detection even when stationary
zombie.alert();
}
}
// Check collision with survivor
if (survivor.intersects(zombie)) {
survivor.takeDamage(10);
}
}
// Check supply collection
for (var i = supplies.length - 1; i >= 0; i--) {
var supply = supplies[i];
if (survivor.intersects(supply)) {
LK.getSound('collect').play();
if (supply.type === 'medicine') {
survivor.heal(supply.value);
LK.setScore(LK.getScore() + 20);
} else if (supply.type === 'food') {
survivor.heal(supply.value);
LK.setScore(LK.getScore() + 15);
} else if (supply.type === 'ammo') {
survivor.addAmmo(supply.value);
LK.setScore(LK.getScore() + 10);
}
supply.destroy();
supplies.splice(i, 1);
}
}
// Update bullets
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
// Remove bullets that go off screen
if (bullet.x < -50 || bullet.x > 2098 || bullet.y < -50 || bullet.y > 2782) {
bullet.destroy();
bullets.splice(i, 1);
continue;
}
// Check bullet collision with obstacles
var hitObstacle = false;
for (var j = 0; j < obstacles.length; j++) {
if (bullet.intersects(obstacles[j])) {
hitObstacle = true;
break;
}
}
if (hitObstacle) {
bullet.destroy();
bullets.splice(i, 1);
continue;
}
// Check bullet collision with zombies
var hitZombie = false;
for (var j = 0; j < zombies.length; j++) {
var zombie = zombies[j];
if (bullet.intersects(zombie)) {
// Remove zombie
zombie.destroy();
zombies.splice(j, 1);
LK.setScore(LK.getScore() + 50);
hitZombie = true;
break;
}
}
if (hitZombie) {
bullet.destroy();
bullets.splice(i, 1);
continue;
}
}
// Check survivor collision with obstacles for movement blocking
for (var i = 0; i < obstacles.length; i++) {
if (survivor.intersects(obstacles[i])) {
// Store previous position to prevent passing through obstacles
if (survivor.lastX === undefined) survivor.lastX = survivor.x;
if (survivor.lastY === undefined) survivor.lastY = survivor.y;
// Revert to last valid position
survivor.x = survivor.lastX;
survivor.y = survivor.lastY;
break;
}
}
// Add score for survival time
if (LK.ticks % 60 === 0) {
// Every second
LK.setScore(LK.getScore() + 1);
}
updateUI();
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Bullet = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('ammo', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 12;
self.targetX = 0;
self.targetY = 0;
self.directionX = 0;
self.directionY = 0;
self.setTarget = function (targetX, targetY) {
var dx = targetX - self.x;
var dy = targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
self.directionX = dx / distance;
self.directionY = dy / distance;
}
};
self.update = function () {
self.x += self.directionX * self.speed;
self.y += self.directionY * self.speed;
};
return self;
});
var Debris = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('debris', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var Supply = Container.expand(function (type) {
var self = Container.call(this);
self.type = type;
var assetName = type;
var graphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
self.value = type === 'medicine' ? 25 : type === 'food' ? 15 : 3;
return self;
});
var Survivor = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('survivor', {
anchorX: 0.5,
anchorY: 0.5
});
// Add weapon visual
var weapon = self.attachAsset('ammo', {
anchorX: 0.5,
anchorY: 0.5,
x: 20,
y: -10,
scaleX: 1.5,
scaleY: 1.5
});
self.health = 100;
self.ammoCount = 5;
self.maxSpeed = 6;
self.currentSpeed = 0;
self.isMoving = false;
self.detectionRadius = 180;
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health < 0) self.health = 0;
LK.effects.flashObject(self, 0xff0000, 500);
LK.getSound('damage').play();
};
self.heal = function (amount) {
self.health += amount;
if (self.health > 100) self.health = 100;
LK.effects.flashObject(self, 0x00ff00, 300);
};
self.addAmmo = function (amount) {
self.ammoCount += amount;
};
self.shoot = function () {
if (self.ammoCount > 0) {
self.ammoCount--;
LK.getSound('shoot').play();
return true;
}
return false;
};
return self;
});
var Zombie = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('zombie', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 1.5;
self.detectionRadius = 150;
self.isAlerted = false;
self.targetX = self.x;
self.targetY = self.y;
self.patrolDistance = 225;
self.originalX = 0;
self.originalY = 0;
self.patrolDirection = 1;
self.alert = function () {
if (!self.isAlerted) {
self.isAlerted = true;
self.speed = 3.75;
tween(graphics, {
tint: 0xff4444
}, {
duration: 300
});
}
};
self.update = function () {
if (self.isAlerted) {
// Chase player
var dx = survivor.x - self.x;
var dy = survivor.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 5) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
} else {
// Patrol behavior
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 10) {
// Reached patrol point, set new target
self.targetX = self.originalX + (Math.random() - 0.5) * self.patrolDistance;
self.targetY = self.originalY + (Math.random() - 0.5) * self.patrolDistance;
// Keep within bounds
self.targetX = Math.max(100, Math.min(1948, self.targetX));
self.targetY = Math.max(300, Math.min(2432, self.targetY));
} else {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2d3748
});
/****
* Game Code
****/
// Game variables
var survivor;
var zombies = [];
var supplies = [];
var debris = [];
var bullets = [];
var obstacles = [];
var dragNode = null;
var gameTime = 0;
var lastHealthDecrease = 0;
var lastSupplySpawn = 0;
var lastZombieSpawn = 0;
var difficultyLevel = 1;
// UI Elements
var healthText = new Text2('Health: 100', {
size: 60,
fill: '#ff0000'
});
healthText.anchor.set(0, 0);
LK.gui.topLeft.addChild(healthText);
healthText.x = 120;
healthText.y = 20;
var ammoText = new Text2('Ammo: 5', {
size: 60,
fill: '#ffff00'
});
ammoText.anchor.set(0, 0);
LK.gui.topLeft.addChild(ammoText);
ammoText.x = 120;
ammoText.y = 105;
var scoreText = new Text2('Score: 0', {
size: 75,
fill: '#ffffff'
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
// Add dark overlay effect to background
var darkOverlay = LK.getAsset('box', {
width: 2048,
height: 2732,
color: 0x000000,
alpha: 0.3,
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
});
game.addChild(darkOverlay);
// Initialize survivor
survivor = game.addChild(new Survivor());
survivor.x = 1024;
survivor.y = 2000;
// Spawn initial debris
for (var i = 0; i < 4; i++) {
var debrisItem = game.addChild(new Debris());
debrisItem.x = 200 + Math.random() * 1648;
debrisItem.y = 400 + Math.random() * 1800;
debris.push(debrisItem);
}
// Spawn initial zombies
for (var i = 0; i < 3; i++) {
var zombie = game.addChild(new Zombie());
zombie.x = 300 + Math.random() * 1448;
zombie.y = 300 + Math.random() * 1500;
zombie.originalX = zombie.x;
zombie.originalY = zombie.y;
zombie.targetX = zombie.x;
zombie.targetY = zombie.y;
zombies.push(zombie);
}
// Spawn initial obstacles
for (var i = 0; i < 3; i++) {
var obstacle = game.addChild(new Obstacle());
obstacle.x = 300 + Math.random() * 1448;
obstacle.y = 500 + Math.random() * 1500;
obstacles.push(obstacle);
}
// Spawn initial supplies
for (var i = 0; i < 5; i++) {
spawnSupply();
}
function spawnSupply() {
var types = ['medicine', 'food', 'ammo'];
var type = types[Math.floor(Math.random() * types.length)];
var supply = game.addChild(new Supply(type));
// Spawn away from debris and zombies
var validPosition = false;
var attempts = 0;
while (!validPosition && attempts < 10) {
supply.x = 100 + Math.random() * 1848;
supply.y = 300 + Math.random() * 2132;
validPosition = true;
// Check distance from debris
for (var j = 0; j < debris.length; j++) {
var dist = Math.sqrt(Math.pow(supply.x - debris[j].x, 2) + Math.pow(supply.y - debris[j].y, 2));
if (dist < 120) {
validPosition = false;
break;
}
}
attempts++;
}
supplies.push(supply);
}
function spawnZombie() {
var zombie = game.addChild(new Zombie());
// Spawn at edges of screen
var side = Math.floor(Math.random() * 4);
if (side === 0) {
// top
zombie.x = Math.random() * 2048;
zombie.y = 200;
} else if (side === 1) {
// right
zombie.x = 1900;
zombie.y = Math.random() * 2732;
} else if (side === 2) {
// bottom
zombie.x = Math.random() * 2048;
zombie.y = 2500;
} else {
// left
zombie.x = 150;
zombie.y = Math.random() * 2732;
}
zombie.originalX = zombie.x;
zombie.originalY = zombie.y;
zombie.targetX = zombie.x;
zombie.targetY = zombie.y;
zombies.push(zombie);
}
function updateUI() {
healthText.setText('Health: ' + Math.floor(survivor.health));
ammoText.setText('Ammo: ' + survivor.ammoCount);
scoreText.setText('Score: ' + LK.getScore());
}
// Event handlers
game.down = function (x, y, obj) {
dragNode = survivor;
// Initialize position tracking
survivor.lastX = survivor.x;
survivor.lastY = survivor.y;
survivor.isMoving = true;
// Shoot bullet towards clicked position
if (survivor.shoot()) {
var bullet = game.addChild(new Bullet());
bullet.x = survivor.x;
bullet.y = survivor.y;
bullet.setTarget(x, y);
bullets.push(bullet);
}
};
game.up = function (x, y, obj) {
dragNode = null;
survivor.isMoving = false;
};
game.move = function (x, y, obj) {
if (dragNode) {
// Store previous position before moving
survivor.lastX = survivor.x;
survivor.lastY = survivor.y;
// Calculate desired position
var targetX = Math.max(50, Math.min(1998, x));
var targetY = Math.max(300, Math.min(2682, y));
// Calculate direction and distance
var dx = targetX - survivor.x;
var dy = targetY - survivor.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Apply speed limit
if (distance > 0) {
var moveDistance = Math.min(distance, survivor.maxSpeed);
survivor.x += dx / distance * moveDistance;
survivor.y += dy / distance * moveDistance;
}
survivor.isMoving = true;
}
};
game.update = function () {
gameTime += 16; // Approximately 16ms per frame at 60fps
// Health decreases over time
if (gameTime - lastHealthDecrease > 3000) {
// Every 3 seconds
survivor.health -= 2;
lastHealthDecrease = gameTime;
}
// Check game over
if (survivor.health <= 0) {
LK.showGameOver();
return;
}
// Spawn supplies
if (gameTime - lastSupplySpawn > 8000) {
// Every 8 seconds
spawnSupply();
lastSupplySpawn = gameTime;
}
// Spawn zombies (increasing difficulty)
difficultyLevel = Math.floor(gameTime / 30000) + 1; // Increase difficulty every 30 seconds
var zombieSpawnRate = Math.max(5000 - difficultyLevel * 500, 2000); // Faster spawning over time
if (gameTime - lastZombieSpawn > zombieSpawnRate) {
spawnZombie();
lastZombieSpawn = gameTime;
}
// Check zombie detection
for (var i = 0; i < zombies.length; i++) {
var zombie = zombies[i];
var dist = Math.sqrt(Math.pow(survivor.x - zombie.x, 2) + Math.pow(survivor.y - zombie.y, 2));
if (dist < zombie.detectionRadius) {
if (survivor.isMoving) {
// Fast movement alerts zombies
zombie.alert();
} else if (dist < 90) {
// Very close detection even when stationary
zombie.alert();
}
}
// Check collision with survivor
if (survivor.intersects(zombie)) {
survivor.takeDamage(10);
}
}
// Check supply collection
for (var i = supplies.length - 1; i >= 0; i--) {
var supply = supplies[i];
if (survivor.intersects(supply)) {
LK.getSound('collect').play();
if (supply.type === 'medicine') {
survivor.heal(supply.value);
LK.setScore(LK.getScore() + 20);
} else if (supply.type === 'food') {
survivor.heal(supply.value);
LK.setScore(LK.getScore() + 15);
} else if (supply.type === 'ammo') {
survivor.addAmmo(supply.value);
LK.setScore(LK.getScore() + 10);
}
supply.destroy();
supplies.splice(i, 1);
}
}
// Update bullets
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
// Remove bullets that go off screen
if (bullet.x < -50 || bullet.x > 2098 || bullet.y < -50 || bullet.y > 2782) {
bullet.destroy();
bullets.splice(i, 1);
continue;
}
// Check bullet collision with obstacles
var hitObstacle = false;
for (var j = 0; j < obstacles.length; j++) {
if (bullet.intersects(obstacles[j])) {
hitObstacle = true;
break;
}
}
if (hitObstacle) {
bullet.destroy();
bullets.splice(i, 1);
continue;
}
// Check bullet collision with zombies
var hitZombie = false;
for (var j = 0; j < zombies.length; j++) {
var zombie = zombies[j];
if (bullet.intersects(zombie)) {
// Remove zombie
zombie.destroy();
zombies.splice(j, 1);
LK.setScore(LK.getScore() + 50);
hitZombie = true;
break;
}
}
if (hitZombie) {
bullet.destroy();
bullets.splice(i, 1);
continue;
}
}
// Check survivor collision with obstacles for movement blocking
for (var i = 0; i < obstacles.length; i++) {
if (survivor.intersects(obstacles[i])) {
// Store previous position to prevent passing through obstacles
if (survivor.lastX === undefined) survivor.lastX = survivor.x;
if (survivor.lastY === undefined) survivor.lastY = survivor.y;
// Revert to last valid position
survivor.x = survivor.lastX;
survivor.y = survivor.lastY;
break;
}
}
// Add score for survival time
if (LK.ticks % 60 === 0) {
// Every second
LK.setScore(LK.getScore() + 1);
}
updateUI();
};
Kutu. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Mermi . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Ekmek . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
İlaç . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Zombi. In-Game asset. 2d. High contrast. No shadows
Kurtulan. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat