User prompt
Please fix the bug: 'TypeError: zombie.die is not a function' in or related to this line: 'zombie.die();' Line Number: 623
User prompt
Please fix the bug: 'ReferenceError: updateUI is not defined' in or related to this line: 'updateUI();' Line Number: 631
User prompt
Please fix the bug: 'ReferenceError: SHOOT_THRESHOLD is not defined' in or related to this line: 'if (rightJoystick.distance > SHOOT_THRESHOLD) {' Line Number: 605
User prompt
Please fix the bug: 'ReferenceError: PLAYER_SPEED is not defined' in or related to this line: 'player.x += moveInput.x * PLAYER_SPEED;' Line Number: 595
User prompt
Please fix the bug: 'ZOMBIE_BASE_SPEED is not defined' in or related to this line: 'var ZOMBIE_TYPES = [{' Line Number: 543
Code edit (1 edits merged)
Please save this source code
User prompt
No matter where you shoot, the swarm of bullets goes in the Y direction.
User prompt
Zombies become invisible and reduce player health. Fix this bug.
User prompt
Apply disintegration effect when zombies are hit ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Zombies disintegrate in red when shot ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Zombies should double their speed and try to dodge bullets.
User prompt
Wherever we drag the right joystick, the gun will point there and fire, and put a sprite on the gun.
Code edit (1 edits merged)
Please save this source code
User prompt
Zombie Siege: Survivor's Last Stand
Initial prompt
Game Idea: Create a 2D top-down zombie shooter mobile game. Player: A single human survivor with a gun. Controls: There are two on-screen joysticks: Left joystick: Controls player movement (X,Y axis). Right joystick: Controls aiming direction. When pushed, the character’s gun aims toward the joystick direction and fires automatically if pushed far enough. Perspective: Top-down (bird’s-eye view). Enemies: Zombies continuously spawn at random positions outside the screen and move towards the player. Gameplay: Zombies deal damage on contact. Player can shoot and kill zombies. Killed zombies can drop items like ammo or health packs (optional). Player’s score increases for each zombie killed. Visuals: Simple sprites for player, zombies, bullets, blood splatter effect when zombies get shot. Background: Urban or post-apocalyptic style. Audio: Background music with a horror or action vibe. Gunshot and zombie sounds. Upgrades: (Optional) Unlock stronger weapons as the player survives longer. Platform: Mobile devices (Android/iOS).
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.velocityX = 0;
self.velocityY = 0;
self.lifeTime = 0;
self.maxLifeTime = 180; // 3 seconds at 60fps
self.update = function () {
self.x += self.velocityX;
self.y += self.velocityY;
self.lifeTime++;
// Remove if off screen or too old
if (self.x < -50 || self.x > 2098 || self.y < -50 || self.y > 2782 || self.lifeTime > self.maxLifeTime) {
self.destroy();
for (var i = bullets.length - 1; i >= 0; i--) {
if (bullets[i] === self) {
bullets.splice(i, 1);
break;
}
}
}
};
return self;
});
var Joystick = Container.expand(function () {
var self = Container.call(this);
var base = self.attachAsset('joystickBase', {
anchorX: 0.5,
anchorY: 0.5
});
var knob = self.attachAsset('joystickKnob', {
anchorX: 0.5,
anchorY: 0.5
});
self.isActive = false;
self.startX = 0;
self.startY = 0;
self.deltaX = 0;
self.deltaY = 0;
self.distance = 0;
self.angle = 0;
self.maxDistance = 50;
self.activate = function (x, y) {
self.isActive = true;
self.startX = x;
self.startY = y;
self.x = x;
self.y = y;
self.visible = true;
};
self.updatePosition = function (x, y) {
if (self.isActive) {
self.deltaX = x - self.startX;
self.deltaY = y - self.startY;
self.distance = Math.sqrt(self.deltaX * self.deltaX + self.deltaY * self.deltaY);
self.angle = Math.atan2(self.deltaY, self.deltaX);
if (self.distance > self.maxDistance) {
self.deltaX = Math.cos(self.angle) * self.maxDistance;
self.deltaY = Math.sin(self.angle) * self.maxDistance;
self.distance = self.maxDistance;
}
knob.x = self.deltaX;
knob.y = self.deltaY;
}
};
self.deactivate = function () {
self.isActive = false;
self.visible = false;
self.deltaX = 0;
self.deltaY = 0;
self.distance = 0;
knob.x = 0;
knob.y = 0;
};
self.getNormalizedInput = function () {
if (self.distance === 0) {
return {
x: 0,
y: 0
};
}
return {
x: self.deltaX / self.maxDistance,
y: self.deltaY / self.maxDistance
};
};
self.visible = false;
base.alpha = 0.5;
knob.alpha = 0.7;
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
var gunGraphics = self.attachAsset('gun', {
anchorX: 0,
anchorY: 0.5,
x: 0,
y: 0
});
self.health = 100;
self.maxHealth = 100;
self.ammo = 30;
self.maxAmmo = 100;
self.shootCooldown = 0;
self.invulnerabilityTime = 0;
self.gunRotation = 0;
self.updateGunRotation = function (angle) {
self.gunRotation = angle;
gunGraphics.rotation = angle;
};
self.takeDamage = function (damage) {
if (self.invulnerabilityTime <= 0) {
self.health -= damage;
self.invulnerabilityTime = 60; // 1 second at 60fps
LK.getSound('playerHit').play();
LK.effects.flashObject(self, 0xFF0000, 500);
if (self.health <= 0) {
LK.showGameOver();
}
}
};
self.update = function () {
if (self.shootCooldown > 0) {
self.shootCooldown--;
}
if (self.invulnerabilityTime > 0) {
self.invulnerabilityTime--;
}
};
return self;
});
var PowerUp = Container.expand(function (type) {
var self = Container.call(this);
self.type = type;
var powerUpGraphics = self.attachAsset(type === 'health' ? 'healthPack' : 'ammoPack', {
anchorX: 0.5,
anchorY: 0.5
});
self.lifeTime = 0;
self.maxLifeTime = 600; // 10 seconds at 60fps
self.update = function () {
self.lifeTime++;
// Pulse effect
var pulse = 1 + Math.sin(self.lifeTime * 0.1) * 0.1;
powerUpGraphics.scaleX = pulse;
powerUpGraphics.scaleY = pulse;
// Check collision with player
if (self.intersects(player)) {
if (self.type === 'health') {
player.health = Math.min(player.maxHealth, player.health + 25);
} else {
player.ammo = Math.min(player.maxAmmo, player.ammo + 15);
}
LK.getSound('pickup').play();
self.destroy();
for (var i = powerUps.length - 1; i >= 0; i--) {
if (powerUps[i] === self) {
powerUps.splice(i, 1);
break;
}
}
}
// Remove if too old
if (self.lifeTime > self.maxLifeTime) {
self.destroy();
for (var i = powerUps.length - 1; i >= 0; i--) {
if (powerUps[i] === self) {
powerUps.splice(i, 1);
break;
}
}
}
};
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 = (1 + Math.random() * 0.5) * 2; // Double the speed
self.health = 1;
self.dodgeCooldown = 0;
self.dodgeVelocityX = 0;
self.dodgeVelocityY = 0;
self.die = function () {
// Store zombie position for power-up drop
var zombieX = self.x;
var zombieY = self.y;
// Red disintegration effect
tween(self, {
tint: 0xFF0000,
alpha: 0,
scaleX: 0.3,
scaleY: 0.3
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
self.destroy();
}
});
// Chance to drop power-up
if (Math.random() < 0.15) {
// 15% chance
var powerUpType = Math.random() < 0.6 ? 'health' : 'ammo';
var powerUp = new PowerUp(powerUpType);
powerUp.x = zombieX;
powerUp.y = zombieY;
powerUps.push(powerUp);
game.addChild(powerUp);
}
};
self.update = function () {
// Reduce dodge cooldown
if (self.dodgeCooldown > 0) {
self.dodgeCooldown--;
}
// Check for nearby bullets to dodge
var shouldDodge = false;
var dodgeX = 0;
var dodgeY = 0;
if (self.dodgeCooldown <= 0) {
for (var i = 0; i < bullets.length; i++) {
var bullet = bullets[i];
var bulletDx = bullet.x - self.x;
var bulletDy = bullet.y - self.y;
var bulletDistance = Math.sqrt(bulletDx * bulletDx + bulletDy * bulletDy);
// Check if bullet is close and heading towards zombie
if (bulletDistance < 120) {
var bulletDirection = Math.atan2(bullet.velocityY, bullet.velocityX);
var zombieDirection = Math.atan2(bulletDy, bulletDx);
var angleDiff = Math.abs(bulletDirection - zombieDirection);
// If bullet is roughly heading towards zombie
if (angleDiff < 1.5 || angleDiff > Math.PI * 2 - 1.5) {
shouldDodge = true;
// Dodge perpendicular to bullet direction
dodgeX = -bullet.velocityY;
dodgeY = bullet.velocityX;
var dodgeLength = Math.sqrt(dodgeX * dodgeX + dodgeY * dodgeY);
if (dodgeLength > 0) {
dodgeX = dodgeX / dodgeLength * self.speed * 1.5;
dodgeY = dodgeY / dodgeLength * self.speed * 1.5;
}
break;
}
}
}
}
if (shouldDodge) {
self.dodgeVelocityX = dodgeX;
self.dodgeVelocityY = dodgeY;
self.dodgeCooldown = 30; // 0.5 second dodge cooldown
}
// Apply dodge movement if active
if (self.dodgeCooldown > 20) {
self.x += self.dodgeVelocityX;
self.y += self.dodgeVelocityY;
} else {
// Normal movement towards player
var dx = player.x - self.x;
var dy = player.y - 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;
}
}
// Check collision with player
if (self.intersects(player)) {
player.takeDamage(10);
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2F4F2F
});
/****
* Game Code
****/
// Utility function to remove items from arrays
function removeFromArray(array, item) {
for (var i = array.length - 1; i >= 0; i--) {
if (array[i] === item) {
array.splice(i, 1);
break;
}
}
}
// Game variables
var player;
var zombies = [];
var bullets = [];
var powerUps = [];
var leftJoystick;
var rightJoystick;
var activeTouch = null;
var secondTouch = null;
var zombieSpawnTimer = 0;
var zombieSpawnRate = 120; // Start spawning every 2 seconds
var minSpawnRate = 30; // Minimum spawn rate (0.5 seconds)
var difficultyTimer = 0;
var score = 0;
// UI elements
var healthBar = LK.getAsset('healthPack', {
anchorX: 0,
anchorY: 0,
scaleX: 10,
scaleY: 1,
x: 100,
y: 50
});
var ammoText = new Text2('Ammo: 30', {
size: 40,
fill: 0xFFFFFF
});
ammoText.anchor.set(0, 0);
var scoreText = new Text2('Score: 0', {
size: 50,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
// Add UI to GUI
LK.gui.topLeft.addChild(healthBar);
LK.gui.topLeft.addChild(ammoText);
ammoText.x = 100;
ammoText.y = 100;
LK.gui.top.addChild(scoreText);
// Initialize player
player = game.addChild(new Player());
player.x = 1024;
player.y = 1366;
// Initialize joysticks
leftJoystick = game.addChild(new Joystick());
rightJoystick = game.addChild(new Joystick());
// Input handling
game.down = function (x, y, obj) {
if (x < 1024) {
// Left side - movement joystick
if (!leftJoystick.isActive) {
leftJoystick.activate(x, y);
activeTouch = {
x: x,
y: y,
side: 'left'
};
}
} else {
// Right side - shooting joystick
if (!rightJoystick.isActive) {
rightJoystick.activate(x, y);
if (!activeTouch) {
activeTouch = {
x: x,
y: y,
side: 'right'
};
} else {
secondTouch = {
x: x,
y: y,
side: 'right'
};
}
}
}
};
game.move = function (x, y, obj) {
if (activeTouch && activeTouch.side === 'left') {
leftJoystick.updatePosition(x, y);
} else if (activeTouch && activeTouch.side === 'right') {
rightJoystick.updatePosition(x, y);
}
if (secondTouch && secondTouch.side === 'right') {
rightJoystick.updatePosition(x, y);
} else if (secondTouch && secondTouch.side === 'left') {
leftJoystick.updatePosition(x, y);
}
};
game.up = function (x, y, obj) {
if (activeTouch && (activeTouch.side === 'left' && x < 1024 || activeTouch.side === 'right' && x >= 1024)) {
if (activeTouch.side === 'left') {
leftJoystick.deactivate();
} else {
rightJoystick.deactivate();
}
activeTouch = secondTouch;
secondTouch = null;
} else if (secondTouch && (secondTouch.side === 'left' && x < 1024 || secondTouch.side === 'right' && x >= 1024)) {
if (secondTouch.side === 'left') {
leftJoystick.deactivate();
} else {
rightJoystick.deactivate();
}
secondTouch = null;
}
};
function spawnZombie() {
var zombie = new Zombie();
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 = 2098;
zombie.y = Math.random() * 2732;
break;
case 2:
// Bottom
zombie.x = Math.random() * 2048;
zombie.y = 2782;
break;
case 3:
// Left
zombie.x = -50;
zombie.y = Math.random() * 2732;
break;
}
zombies.push(zombie);
game.addChild(zombie);
}
function fireBullet() {
if (player.ammo > 0 && player.shootCooldown <= 0) {
var bullet = new Bullet();
bullet.x = player.x;
bullet.y = player.y;
var input = rightJoystick.getNormalizedInput();
// Only fire if there's actual joystick input
if (input.x !== 0 || input.y !== 0) {
bullet.velocityX = input.x * bullet.speed;
bullet.velocityY = input.y * bullet.speed;
bullets.push(bullet);
game.addChild(bullet);
player.ammo--;
player.shootCooldown = 15; // Quarter second cooldown
LK.getSound('shoot').play();
}
}
}
;
game.update = function () {
// Handle movement
var moveInput = leftJoystick.getNormalizedInput();
player.x += moveInput.x * 4;
player.y += moveInput.y * 4;
// Keep player in bounds
player.x = Math.max(40, Math.min(2008, player.x));
player.y = Math.max(40, Math.min(2692, player.y));
// Handle shooting
var shootInput = rightJoystick.getNormalizedInput();
if (rightJoystick.distance > 0) {
// Update gun rotation to point towards joystick direction
var gunAngle = Math.atan2(shootInput.y, shootInput.x);
player.updateGunRotation(gunAngle);
}
if (rightJoystick.distance > 30) {
// Only shoot if joystick is pushed far enough
fireBullet();
}
// Spawn zombies
zombieSpawnTimer++;
if (zombieSpawnTimer >= zombieSpawnRate) {
spawnZombie();
zombieSpawnTimer = 0;
}
// Increase difficulty over time
difficultyTimer++;
if (difficultyTimer >= 600) {
// Every 10 seconds
if (zombieSpawnRate > minSpawnRate) {
zombieSpawnRate -= 5;
}
difficultyTimer = 0;
}
// Check bullet-zombie collisions
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
for (var j = zombies.length - 1; j >= 0; j--) {
var zombie = zombies[j];
if (bullet.intersects(zombie)) {
// Zombie hit
LK.getSound('zombieHit').play();
score += 10;
LK.setScore(score);
scoreText.setText('Score: ' + score);
// Store zombie position for power-up drop
var zombieX = zombie.x;
var zombieY = zombie.y;
// Remove zombie from array and game immediately
zombies.splice(j, 1);
// Red disintegration effect
tween(zombie, {
tint: 0xFF0000,
alpha: 0,
scaleX: 0.3,
scaleY: 0.3
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
zombie.destroy();
}
});
// Chance to drop power-up
if (Math.random() < 0.15) {
// 15% chance
var powerUpType = Math.random() < 0.6 ? 'health' : 'ammo';
var powerUp = new PowerUp(powerUpType);
powerUp.x = zombieX;
powerUp.y = zombieY;
powerUps.push(powerUp);
game.addChild(powerUp);
}
// Remove bullet
bullet.destroy();
bullets.splice(i, 1);
break;
}
}
}
// Update UI
healthBar.scaleX = player.health / player.maxHealth * 10;
ammoText.setText('Ammo: ' + player.ammo);
// Change health bar color based on health
if (player.health < 25) {
healthBar.tint = 0xFF0000; // Red
} else if (player.health < 50) {
healthBar.tint = 0xFFFF00; // Yellow
} else {
healthBar.tint = 0x00FF00; // Green
}
};
/***********************
* EK ÖZELLİKLER
***********************/
// Player movement speed
var PLAYER_SPEED = 4;
// Shooting threshold for joystick sensitivity
var SHOOT_THRESHOLD = 30;
// Zombi temel hızı
var ZOMBIE_BASE_SPEED = 2;
// Zombi türleri
var ZOMBIE_TYPES = [{
type: 'normal',
speed: ZOMBIE_BASE_SPEED,
health: 1
}, {
type: 'runner',
speed: ZOMBIE_BASE_SPEED * 1.8,
health: 0.5
}, {
type: 'tank',
speed: ZOMBIE_BASE_SPEED * 0.6,
health: 3
}];
// Level up skorları
var LEVEL_THRESHOLDS = [0, 200, 500, 1000];
var currentLevel = 1;
/***********************
* LEVEL SYSTEM
***********************/
function checkLevelUp() {
if (score >= LEVEL_THRESHOLDS[currentLevel]) {
currentLevel++;
zombieSpawnRate = Math.max(ZOMBIE_SPAWN_MIN, zombieSpawnRate - 10);
showLevelUp(currentLevel);
}
}
function showLevelUp(level) {
var levelText = new Text2("LEVEL ".concat(level), {
size: 100,
fill: 0xFFD700
});
levelText.anchor.set(0.5);
levelText.x = 1024;
levelText.y = 1366;
LK.gui.center.addChild(levelText);
tween(levelText, {
alpha: 0
}, {
duration: 2000,
easing: tween.easeIn,
onFinish: function onFinish() {
return levelText.destroy();
}
});
}
/***********************
* GAME LOOP PATCH
***********************/
game.update = function () {
var moveInput = leftJoystick.getNormalizedInput();
player.x += moveInput.x * PLAYER_SPEED;
player.y += moveInput.y * PLAYER_SPEED;
player.x = Math.max(40, Math.min(2008, player.x));
player.y = Math.max(40, Math.min(2692, player.y));
var shootInput = rightJoystick.getNormalizedInput();
if (rightJoystick.distance > 0) {
player.updateGunRotation(Math.atan2(shootInput.y, shootInput.x));
}
if (rightJoystick.distance > SHOOT_THRESHOLD) fireBullet();
zombieSpawnTimer++;
if (zombieSpawnTimer >= zombieSpawnRate) {
spawnZombie();
zombieSpawnTimer = 0;
}
for (var _i = 0, _arr = [].concat(bullets); _i < _arr.length; _i++) {
var bullet = _arr[_i];
for (var _i2 = 0, _arr2 = [].concat(zombies); _i2 < _arr2.length; _i2++) {
var zombie = _arr2[_i2];
if (bullet.intersects(zombie)) {
LK.getSound('zombieHit').play();
score += 10;
checkLevelUp(); // HER ZOMBİDE LEVEL KONTROL
zombie.die();
bullet.destroy();
removeFromArray(bullets, bullet);
removeFromArray(zombies, zombie);
break;
}
}
}
updateUI();
};
function updateUI() {
// Update health bar
healthBar.scaleX = player.health / player.maxHealth * 10;
ammoText.setText('Ammo: ' + player.ammo);
scoreText.setText('Score: ' + score);
// Change health bar color based on health
if (player.health < 25) {
healthBar.tint = 0xFF0000; // Red
} else if (player.health < 50) {
healthBar.tint = 0xFFFF00; // Yellow
} else {
healthBar.tint = 0x00FF00; // Green
}
} /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.velocityX = 0;
self.velocityY = 0;
self.lifeTime = 0;
self.maxLifeTime = 180; // 3 seconds at 60fps
self.update = function () {
self.x += self.velocityX;
self.y += self.velocityY;
self.lifeTime++;
// Remove if off screen or too old
if (self.x < -50 || self.x > 2098 || self.y < -50 || self.y > 2782 || self.lifeTime > self.maxLifeTime) {
self.destroy();
for (var i = bullets.length - 1; i >= 0; i--) {
if (bullets[i] === self) {
bullets.splice(i, 1);
break;
}
}
}
};
return self;
});
var Joystick = Container.expand(function () {
var self = Container.call(this);
var base = self.attachAsset('joystickBase', {
anchorX: 0.5,
anchorY: 0.5
});
var knob = self.attachAsset('joystickKnob', {
anchorX: 0.5,
anchorY: 0.5
});
self.isActive = false;
self.startX = 0;
self.startY = 0;
self.deltaX = 0;
self.deltaY = 0;
self.distance = 0;
self.angle = 0;
self.maxDistance = 50;
self.activate = function (x, y) {
self.isActive = true;
self.startX = x;
self.startY = y;
self.x = x;
self.y = y;
self.visible = true;
};
self.updatePosition = function (x, y) {
if (self.isActive) {
self.deltaX = x - self.startX;
self.deltaY = y - self.startY;
self.distance = Math.sqrt(self.deltaX * self.deltaX + self.deltaY * self.deltaY);
self.angle = Math.atan2(self.deltaY, self.deltaX);
if (self.distance > self.maxDistance) {
self.deltaX = Math.cos(self.angle) * self.maxDistance;
self.deltaY = Math.sin(self.angle) * self.maxDistance;
self.distance = self.maxDistance;
}
knob.x = self.deltaX;
knob.y = self.deltaY;
}
};
self.deactivate = function () {
self.isActive = false;
self.visible = false;
self.deltaX = 0;
self.deltaY = 0;
self.distance = 0;
knob.x = 0;
knob.y = 0;
};
self.getNormalizedInput = function () {
if (self.distance === 0) {
return {
x: 0,
y: 0
};
}
return {
x: self.deltaX / self.maxDistance,
y: self.deltaY / self.maxDistance
};
};
self.visible = false;
base.alpha = 0.5;
knob.alpha = 0.7;
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
var gunGraphics = self.attachAsset('gun', {
anchorX: 0,
anchorY: 0.5,
x: 0,
y: 0
});
self.health = 100;
self.maxHealth = 100;
self.ammo = 30;
self.maxAmmo = 100;
self.shootCooldown = 0;
self.invulnerabilityTime = 0;
self.gunRotation = 0;
self.updateGunRotation = function (angle) {
self.gunRotation = angle;
gunGraphics.rotation = angle;
};
self.takeDamage = function (damage) {
if (self.invulnerabilityTime <= 0) {
self.health -= damage;
self.invulnerabilityTime = 60; // 1 second at 60fps
LK.getSound('playerHit').play();
LK.effects.flashObject(self, 0xFF0000, 500);
if (self.health <= 0) {
LK.showGameOver();
}
}
};
self.update = function () {
if (self.shootCooldown > 0) {
self.shootCooldown--;
}
if (self.invulnerabilityTime > 0) {
self.invulnerabilityTime--;
}
};
return self;
});
var PowerUp = Container.expand(function (type) {
var self = Container.call(this);
self.type = type;
var powerUpGraphics = self.attachAsset(type === 'health' ? 'healthPack' : 'ammoPack', {
anchorX: 0.5,
anchorY: 0.5
});
self.lifeTime = 0;
self.maxLifeTime = 600; // 10 seconds at 60fps
self.update = function () {
self.lifeTime++;
// Pulse effect
var pulse = 1 + Math.sin(self.lifeTime * 0.1) * 0.1;
powerUpGraphics.scaleX = pulse;
powerUpGraphics.scaleY = pulse;
// Check collision with player
if (self.intersects(player)) {
if (self.type === 'health') {
player.health = Math.min(player.maxHealth, player.health + 25);
} else {
player.ammo = Math.min(player.maxAmmo, player.ammo + 15);
}
LK.getSound('pickup').play();
self.destroy();
for (var i = powerUps.length - 1; i >= 0; i--) {
if (powerUps[i] === self) {
powerUps.splice(i, 1);
break;
}
}
}
// Remove if too old
if (self.lifeTime > self.maxLifeTime) {
self.destroy();
for (var i = powerUps.length - 1; i >= 0; i--) {
if (powerUps[i] === self) {
powerUps.splice(i, 1);
break;
}
}
}
};
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 = (1 + Math.random() * 0.5) * 2; // Double the speed
self.health = 1;
self.dodgeCooldown = 0;
self.dodgeVelocityX = 0;
self.dodgeVelocityY = 0;
self.die = function () {
// Store zombie position for power-up drop
var zombieX = self.x;
var zombieY = self.y;
// Red disintegration effect
tween(self, {
tint: 0xFF0000,
alpha: 0,
scaleX: 0.3,
scaleY: 0.3
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
self.destroy();
}
});
// Chance to drop power-up
if (Math.random() < 0.15) {
// 15% chance
var powerUpType = Math.random() < 0.6 ? 'health' : 'ammo';
var powerUp = new PowerUp(powerUpType);
powerUp.x = zombieX;
powerUp.y = zombieY;
powerUps.push(powerUp);
game.addChild(powerUp);
}
};
self.update = function () {
// Reduce dodge cooldown
if (self.dodgeCooldown > 0) {
self.dodgeCooldown--;
}
// Check for nearby bullets to dodge
var shouldDodge = false;
var dodgeX = 0;
var dodgeY = 0;
if (self.dodgeCooldown <= 0) {
for (var i = 0; i < bullets.length; i++) {
var bullet = bullets[i];
var bulletDx = bullet.x - self.x;
var bulletDy = bullet.y - self.y;
var bulletDistance = Math.sqrt(bulletDx * bulletDx + bulletDy * bulletDy);
// Check if bullet is close and heading towards zombie
if (bulletDistance < 120) {
var bulletDirection = Math.atan2(bullet.velocityY, bullet.velocityX);
var zombieDirection = Math.atan2(bulletDy, bulletDx);
var angleDiff = Math.abs(bulletDirection - zombieDirection);
// If bullet is roughly heading towards zombie
if (angleDiff < 1.5 || angleDiff > Math.PI * 2 - 1.5) {
shouldDodge = true;
// Dodge perpendicular to bullet direction
dodgeX = -bullet.velocityY;
dodgeY = bullet.velocityX;
var dodgeLength = Math.sqrt(dodgeX * dodgeX + dodgeY * dodgeY);
if (dodgeLength > 0) {
dodgeX = dodgeX / dodgeLength * self.speed * 1.5;
dodgeY = dodgeY / dodgeLength * self.speed * 1.5;
}
break;
}
}
}
}
if (shouldDodge) {
self.dodgeVelocityX = dodgeX;
self.dodgeVelocityY = dodgeY;
self.dodgeCooldown = 30; // 0.5 second dodge cooldown
}
// Apply dodge movement if active
if (self.dodgeCooldown > 20) {
self.x += self.dodgeVelocityX;
self.y += self.dodgeVelocityY;
} else {
// Normal movement towards player
var dx = player.x - self.x;
var dy = player.y - 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;
}
}
// Check collision with player
if (self.intersects(player)) {
player.takeDamage(10);
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2F4F2F
});
/****
* Game Code
****/
// Utility function to remove items from arrays
function removeFromArray(array, item) {
for (var i = array.length - 1; i >= 0; i--) {
if (array[i] === item) {
array.splice(i, 1);
break;
}
}
}
// Game variables
var player;
var zombies = [];
var bullets = [];
var powerUps = [];
var leftJoystick;
var rightJoystick;
var activeTouch = null;
var secondTouch = null;
var zombieSpawnTimer = 0;
var zombieSpawnRate = 120; // Start spawning every 2 seconds
var minSpawnRate = 30; // Minimum spawn rate (0.5 seconds)
var difficultyTimer = 0;
var score = 0;
// UI elements
var healthBar = LK.getAsset('healthPack', {
anchorX: 0,
anchorY: 0,
scaleX: 10,
scaleY: 1,
x: 100,
y: 50
});
var ammoText = new Text2('Ammo: 30', {
size: 40,
fill: 0xFFFFFF
});
ammoText.anchor.set(0, 0);
var scoreText = new Text2('Score: 0', {
size: 50,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
// Add UI to GUI
LK.gui.topLeft.addChild(healthBar);
LK.gui.topLeft.addChild(ammoText);
ammoText.x = 100;
ammoText.y = 100;
LK.gui.top.addChild(scoreText);
// Initialize player
player = game.addChild(new Player());
player.x = 1024;
player.y = 1366;
// Initialize joysticks
leftJoystick = game.addChild(new Joystick());
rightJoystick = game.addChild(new Joystick());
// Input handling
game.down = function (x, y, obj) {
if (x < 1024) {
// Left side - movement joystick
if (!leftJoystick.isActive) {
leftJoystick.activate(x, y);
activeTouch = {
x: x,
y: y,
side: 'left'
};
}
} else {
// Right side - shooting joystick
if (!rightJoystick.isActive) {
rightJoystick.activate(x, y);
if (!activeTouch) {
activeTouch = {
x: x,
y: y,
side: 'right'
};
} else {
secondTouch = {
x: x,
y: y,
side: 'right'
};
}
}
}
};
game.move = function (x, y, obj) {
if (activeTouch && activeTouch.side === 'left') {
leftJoystick.updatePosition(x, y);
} else if (activeTouch && activeTouch.side === 'right') {
rightJoystick.updatePosition(x, y);
}
if (secondTouch && secondTouch.side === 'right') {
rightJoystick.updatePosition(x, y);
} else if (secondTouch && secondTouch.side === 'left') {
leftJoystick.updatePosition(x, y);
}
};
game.up = function (x, y, obj) {
if (activeTouch && (activeTouch.side === 'left' && x < 1024 || activeTouch.side === 'right' && x >= 1024)) {
if (activeTouch.side === 'left') {
leftJoystick.deactivate();
} else {
rightJoystick.deactivate();
}
activeTouch = secondTouch;
secondTouch = null;
} else if (secondTouch && (secondTouch.side === 'left' && x < 1024 || secondTouch.side === 'right' && x >= 1024)) {
if (secondTouch.side === 'left') {
leftJoystick.deactivate();
} else {
rightJoystick.deactivate();
}
secondTouch = null;
}
};
function spawnZombie() {
var zombie = new Zombie();
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 = 2098;
zombie.y = Math.random() * 2732;
break;
case 2:
// Bottom
zombie.x = Math.random() * 2048;
zombie.y = 2782;
break;
case 3:
// Left
zombie.x = -50;
zombie.y = Math.random() * 2732;
break;
}
zombies.push(zombie);
game.addChild(zombie);
}
function fireBullet() {
if (player.ammo > 0 && player.shootCooldown <= 0) {
var bullet = new Bullet();
bullet.x = player.x;
bullet.y = player.y;
var input = rightJoystick.getNormalizedInput();
// Only fire if there's actual joystick input
if (input.x !== 0 || input.y !== 0) {
bullet.velocityX = input.x * bullet.speed;
bullet.velocityY = input.y * bullet.speed;
bullets.push(bullet);
game.addChild(bullet);
player.ammo--;
player.shootCooldown = 15; // Quarter second cooldown
LK.getSound('shoot').play();
}
}
}
;
game.update = function () {
// Handle movement
var moveInput = leftJoystick.getNormalizedInput();
player.x += moveInput.x * 4;
player.y += moveInput.y * 4;
// Keep player in bounds
player.x = Math.max(40, Math.min(2008, player.x));
player.y = Math.max(40, Math.min(2692, player.y));
// Handle shooting
var shootInput = rightJoystick.getNormalizedInput();
if (rightJoystick.distance > 0) {
// Update gun rotation to point towards joystick direction
var gunAngle = Math.atan2(shootInput.y, shootInput.x);
player.updateGunRotation(gunAngle);
}
if (rightJoystick.distance > 30) {
// Only shoot if joystick is pushed far enough
fireBullet();
}
// Spawn zombies
zombieSpawnTimer++;
if (zombieSpawnTimer >= zombieSpawnRate) {
spawnZombie();
zombieSpawnTimer = 0;
}
// Increase difficulty over time
difficultyTimer++;
if (difficultyTimer >= 600) {
// Every 10 seconds
if (zombieSpawnRate > minSpawnRate) {
zombieSpawnRate -= 5;
}
difficultyTimer = 0;
}
// Check bullet-zombie collisions
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
for (var j = zombies.length - 1; j >= 0; j--) {
var zombie = zombies[j];
if (bullet.intersects(zombie)) {
// Zombie hit
LK.getSound('zombieHit').play();
score += 10;
LK.setScore(score);
scoreText.setText('Score: ' + score);
// Store zombie position for power-up drop
var zombieX = zombie.x;
var zombieY = zombie.y;
// Remove zombie from array and game immediately
zombies.splice(j, 1);
// Red disintegration effect
tween(zombie, {
tint: 0xFF0000,
alpha: 0,
scaleX: 0.3,
scaleY: 0.3
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
zombie.destroy();
}
});
// Chance to drop power-up
if (Math.random() < 0.15) {
// 15% chance
var powerUpType = Math.random() < 0.6 ? 'health' : 'ammo';
var powerUp = new PowerUp(powerUpType);
powerUp.x = zombieX;
powerUp.y = zombieY;
powerUps.push(powerUp);
game.addChild(powerUp);
}
// Remove bullet
bullet.destroy();
bullets.splice(i, 1);
break;
}
}
}
// Update UI
healthBar.scaleX = player.health / player.maxHealth * 10;
ammoText.setText('Ammo: ' + player.ammo);
// Change health bar color based on health
if (player.health < 25) {
healthBar.tint = 0xFF0000; // Red
} else if (player.health < 50) {
healthBar.tint = 0xFFFF00; // Yellow
} else {
healthBar.tint = 0x00FF00; // Green
}
};
/***********************
* EK ÖZELLİKLER
***********************/
// Player movement speed
var PLAYER_SPEED = 4;
// Shooting threshold for joystick sensitivity
var SHOOT_THRESHOLD = 30;
// Zombi temel hızı
var ZOMBIE_BASE_SPEED = 2;
// Zombi türleri
var ZOMBIE_TYPES = [{
type: 'normal',
speed: ZOMBIE_BASE_SPEED,
health: 1
}, {
type: 'runner',
speed: ZOMBIE_BASE_SPEED * 1.8,
health: 0.5
}, {
type: 'tank',
speed: ZOMBIE_BASE_SPEED * 0.6,
health: 3
}];
// Level up skorları
var LEVEL_THRESHOLDS = [0, 200, 500, 1000];
var currentLevel = 1;
/***********************
* LEVEL SYSTEM
***********************/
function checkLevelUp() {
if (score >= LEVEL_THRESHOLDS[currentLevel]) {
currentLevel++;
zombieSpawnRate = Math.max(ZOMBIE_SPAWN_MIN, zombieSpawnRate - 10);
showLevelUp(currentLevel);
}
}
function showLevelUp(level) {
var levelText = new Text2("LEVEL ".concat(level), {
size: 100,
fill: 0xFFD700
});
levelText.anchor.set(0.5);
levelText.x = 1024;
levelText.y = 1366;
LK.gui.center.addChild(levelText);
tween(levelText, {
alpha: 0
}, {
duration: 2000,
easing: tween.easeIn,
onFinish: function onFinish() {
return levelText.destroy();
}
});
}
/***********************
* GAME LOOP PATCH
***********************/
game.update = function () {
var moveInput = leftJoystick.getNormalizedInput();
player.x += moveInput.x * PLAYER_SPEED;
player.y += moveInput.y * PLAYER_SPEED;
player.x = Math.max(40, Math.min(2008, player.x));
player.y = Math.max(40, Math.min(2692, player.y));
var shootInput = rightJoystick.getNormalizedInput();
if (rightJoystick.distance > 0) {
player.updateGunRotation(Math.atan2(shootInput.y, shootInput.x));
}
if (rightJoystick.distance > SHOOT_THRESHOLD) fireBullet();
zombieSpawnTimer++;
if (zombieSpawnTimer >= zombieSpawnRate) {
spawnZombie();
zombieSpawnTimer = 0;
}
for (var _i = 0, _arr = [].concat(bullets); _i < _arr.length; _i++) {
var bullet = _arr[_i];
for (var _i2 = 0, _arr2 = [].concat(zombies); _i2 < _arr2.length; _i2++) {
var zombie = _arr2[_i2];
if (bullet.intersects(zombie)) {
LK.getSound('zombieHit').play();
score += 10;
checkLevelUp(); // HER ZOMBİDE LEVEL KONTROL
zombie.die();
bullet.destroy();
removeFromArray(bullets, bullet);
removeFromArray(zombies, zombie);
break;
}
}
}
updateUI();
};
function updateUI() {
// Update health bar
healthBar.scaleX = player.health / player.maxHealth * 10;
ammoText.setText('Ammo: ' + player.ammo);
scoreText.setText('Score: ' + score);
// Change health bar color based on health
if (player.health < 25) {
healthBar.tint = 0xFF0000; // Red
} else if (player.health < 50) {
healthBar.tint = 0xFFFF00; // Yellow
} else {
healthBar.tint = 0x00FF00; // Green
}
}