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
});
self.health = 100;
self.maxHealth = 100;
self.ammo = 30;
self.maxAmmo = 100;
self.shootCooldown = 0;
self.invulnerabilityTime = 0;
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;
self.health = 1;
self.update = function () {
// Move 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
****/
// 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();
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 > 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);
// 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 = zombie.x;
powerUp.y = zombie.y;
powerUps.push(powerUp);
game.addChild(powerUp);
}
// Remove bullet and zombie
bullet.destroy();
bullets.splice(i, 1);
zombie.destroy();
zombies.splice(j, 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
}
}; ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,436 @@
-/****
+/****
+* 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
+ });
+ self.health = 100;
+ self.maxHealth = 100;
+ self.ammo = 30;
+ self.maxAmmo = 100;
+ self.shootCooldown = 0;
+ self.invulnerabilityTime = 0;
+ 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;
+ self.health = 1;
+ self.update = function () {
+ // Move 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: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x2F4F2F
+});
+
+/****
+* Game Code
+****/
+// 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();
+ 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 > 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);
+ // 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 = zombie.x;
+ powerUp.y = zombie.y;
+ powerUps.push(powerUp);
+ game.addChild(powerUp);
+ }
+ // Remove bullet and zombie
+ bullet.destroy();
+ bullets.splice(i, 1);
+ zombie.destroy();
+ zombies.splice(j, 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
+ }
+};
\ No newline at end of file