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