User prompt
add combos and make the trail bigger, make the time limit 150 sec. and make it at the bottom make it say tap the cubes to get points, ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
add a trail behind the player when they moce, and addd the enemys back ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
remove the menu and make the volume slider at the bottom left, witht he slider going up. so start the game instantly after 2 sec ↪💡 Consider importing and using the following plugins: @upit/tween.v1, @upit/storage.v1
User prompt
i still cant click them! and where it says health, make it say, tap or swipe into the cubes for points
User prompt
make the buttons bigger and clickable eith the mouse
User prompt
Please fix the bug: 'storage.get is not a function' in or related to this line: 'var musicVolume = storage.get('musicVolume', 1.0);' Line Number: 332 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
make the play and settings button accutally be able to play and to go to settings, so i can click them, in settings there should be music volume ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
make the buttons work, and make background music, and so the cube i move has a deley so if i click somewhere it goes there smoothly ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'toGlobal')' in or related to this line: 'var localPos = self.toLocal(obj.parent.toGlobal(obj.position));' Line Number: 82
User prompt
can you add sounds effects and particles, and a menu when you ttart the game with play and setting for enemy stuff, make the enemys try to run away tho ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
make it so i have to drag and like run into them to kill them
Code edit (1 edits merged)
Please save this source code
User prompt
Zombie Siege Defense
Initial prompt
make a zombie wave shooter, take minimum 1.5 min
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var FastZombie = Container.expand(function () {
var self = Container.call(this);
var zombieGraphics = self.attachAsset('fastZombie', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 1;
self.maxHealth = 1;
self.speed = 3;
self.points = 15;
self.lastX = 0;
self.lastY = 0;
self.update = function () {
if (player) {
self.lastX = self.x;
self.lastY = self.y;
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
// Run away from player instead of towards
self.x -= dx / distance * self.speed * zombieSpeedMultiplier;
self.y -= dy / distance * self.speed * zombieSpeedMultiplier;
}
}
};
return self;
});
var Menu = Container.expand(function () {
var self = Container.call(this);
var playButton = self.attachAsset('menuButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: -100
});
var playText = new Text2('PLAY', {
size: 60,
fill: 0xFFFFFF
});
playText.anchor.set(0.5, 0.5);
playText.y = -100;
self.addChild(playText);
var settingsButton = self.attachAsset('settingButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 50
});
var settingsText = new Text2('SETTINGS', {
size: 40,
fill: 0xFFFFFF
});
settingsText.anchor.set(0.5, 0.5);
settingsText.y = 50;
self.addChild(settingsText);
self.down = function (x, y, obj) {
var localPos = self.toLocal(obj.parent.toGlobal(obj.position));
if (localPos.y > -150 && localPos.y < -50) {
LK.getSound('menuClick').play();
startGame();
} else if (localPos.y > 10 && localPos.y < 90) {
LK.getSound('menuClick').play();
showSettings();
}
};
return self;
});
var Particle = Container.expand(function () {
var self = Container.call(this);
var particleGraphics = self.attachAsset('particle', {
anchorX: 0.5,
anchorY: 0.5
});
self.vx = 0;
self.vy = 0;
self.life = 60;
self.maxLife = 60;
self.update = function () {
self.x += self.vx;
self.y += self.vy;
self.life--;
self.alpha = self.life / self.maxLife;
if (self.life <= 0) {
self.destroy();
}
};
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.lastCollidedZombies = [];
return self;
});
var SettingsMenu = Container.expand(function () {
var self = Container.call(this);
var titleText = new Text2('SETTINGS', {
size: 80,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.y = -300;
self.addChild(titleText);
var zombieSpeedText = new Text2('Zombie Speed: ' + zombieSpeedMultiplier, {
size: 50,
fill: 0xFFFFFF
});
zombieSpeedText.anchor.set(0.5, 0.5);
zombieSpeedText.y = -150;
self.addChild(zombieSpeedText);
var speedUpButton = self.attachAsset('settingButton', {
anchorX: 0.5,
anchorY: 0.5,
x: -200,
y: -100
});
var speedUpText = new Text2('+', {
size: 60,
fill: 0xFFFFFF
});
speedUpText.anchor.set(0.5, 0.5);
speedUpText.x = -200;
speedUpText.y = -100;
self.addChild(speedUpText);
var speedDownButton = self.attachAsset('settingButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 200,
y: -100
});
var speedDownText = new Text2('-', {
size: 60,
fill: 0xFFFFFF
});
speedDownText.anchor.set(0.5, 0.5);
speedDownText.x = 200;
speedDownText.y = -100;
self.addChild(speedDownText);
var backButton = self.attachAsset('menuButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 200
});
var backText = new Text2('BACK', {
size: 60,
fill: 0xFFFFFF
});
backText.anchor.set(0.5, 0.5);
backText.y = 200;
self.addChild(backText);
self.down = function (x, y, obj) {
var localPos = self.toLocal(obj.parent.toGlobal(obj.position));
if (localPos.x > -350 && localPos.x < -50 && localPos.y > -140 && localPos.y < -60) {
// Speed up
zombieSpeedMultiplier = Math.min(3, zombieSpeedMultiplier + 0.2);
zombieSpeedText.setText('Zombie Speed: ' + zombieSpeedMultiplier.toFixed(1));
LK.getSound('menuClick').play();
} else if (localPos.x > 50 && localPos.x < 350 && localPos.y > -140 && localPos.y < -60) {
// Speed down
zombieSpeedMultiplier = Math.max(0.2, zombieSpeedMultiplier - 0.2);
zombieSpeedText.setText('Zombie Speed: ' + zombieSpeedMultiplier.toFixed(1));
LK.getSound('menuClick').play();
} else if (localPos.y > 150 && localPos.y < 250) {
// Back
LK.getSound('menuClick').play();
showMenu();
}
};
return self;
});
var TankZombie = Container.expand(function () {
var self = Container.call(this);
var zombieGraphics = self.attachAsset('tankZombie', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 3;
self.maxHealth = 3;
self.speed = 1;
self.points = 25;
self.lastX = 0;
self.lastY = 0;
self.update = function () {
if (player) {
self.lastX = self.x;
self.lastY = self.y;
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
// Run away from player instead of towards
self.x -= dx / distance * self.speed * zombieSpeedMultiplier;
self.y -= dy / distance * self.speed * zombieSpeedMultiplier;
}
}
};
return self;
});
var Zombie = Container.expand(function () {
var self = Container.call(this);
var zombieGraphics = self.attachAsset('zombie', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 1;
self.maxHealth = 1;
self.speed = 1.5;
self.points = 10;
self.lastX = 0;
self.lastY = 0;
self.update = function () {
if (player) {
self.lastX = self.x;
self.lastY = self.y;
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
// Run away from player instead of towards
self.x -= dx / distance * self.speed;
self.y -= dy / distance * self.speed;
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2F4F2F
});
/****
* Game Code
****/
// Game state variables
var gameState = 'menu'; // 'menu', 'settings', 'playing'
var menu;
var settingsMenu;
var particles = [];
var zombieSpeedMultiplier = 1.0;
// Game variables
var player;
var zombies = [];
var currentWave = 1;
var zombiesSpawned = 0;
var zombiesKilled = 0;
var gameTime = 0;
var waveTime = 0;
var spawnTimer = 0;
var dragNode = null;
var killStreak = 0;
var killStreakTimer = 0;
// Wave configuration
var waveConfigs = [{
zombieCount: 8,
spawnDelay: 90,
zombieTypes: ['zombie']
}, {
zombieCount: 12,
spawnDelay: 75,
zombieTypes: ['zombie', 'fastZombie']
}, {
zombieCount: 16,
spawnDelay: 60,
zombieTypes: ['zombie', 'fastZombie']
}, {
zombieCount: 20,
spawnDelay: 50,
zombieTypes: ['zombie', 'fastZombie', 'tankZombie']
}, {
zombieCount: 25,
spawnDelay: 45,
zombieTypes: ['zombie', 'fastZombie', 'tankZombie']
}, {
zombieCount: 30,
spawnDelay: 40,
zombieTypes: ['zombie', 'fastZombie', 'tankZombie']
}, {
zombieCount: 35,
spawnDelay: 35,
zombieTypes: ['zombie', 'fastZombie', 'tankZombie']
}, {
zombieCount: 40,
spawnDelay: 30,
zombieTypes: ['zombie', 'fastZombie', 'tankZombie']
}];
// UI Elements
var scoreText = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(0, 0);
scoreText.x = 120;
scoreText.y = 20;
LK.gui.topLeft.addChild(scoreText);
var waveText = new Text2('Wave: 1', {
size: 60,
fill: 0xFFFFFF
});
waveText.anchor.set(0.5, 0);
LK.gui.top.addChild(waveText);
var timerText = new Text2('Time: 90', {
size: 60,
fill: 0xFFFFFF
});
timerText.anchor.set(1, 0);
timerText.x = -20;
timerText.y = 20;
LK.gui.topRight.addChild(timerText);
var healthText = new Text2('Health: 100', {
size: 50,
fill: 0xFFFFFF
});
healthText.anchor.set(0.5, 1);
healthText.y = -20;
LK.gui.bottom.addChild(healthText);
// Menu system functions
function showMenu() {
gameState = 'menu';
if (settingsMenu) {
settingsMenu.destroy();
settingsMenu = null;
}
if (!menu) {
menu = game.addChild(new Menu());
menu.x = 1024;
menu.y = 1366;
}
}
function showSettings() {
gameState = 'settings';
if (menu) {
menu.destroy();
menu = null;
}
if (!settingsMenu) {
settingsMenu = game.addChild(new SettingsMenu());
settingsMenu.x = 1024;
settingsMenu.y = 1366;
}
}
function startGame() {
gameState = 'playing';
if (menu) {
menu.destroy();
menu = null;
}
if (settingsMenu) {
settingsMenu.destroy();
settingsMenu = null;
}
// Initialize player
if (!player) {
player = game.addChild(new Player());
player.x = 1024;
player.y = 1366;
}
}
function createParticles(x, y, count, color) {
for (var i = 0; i < count; i++) {
var particle = new Particle();
particle.x = x;
particle.y = y;
particle.vx = (Math.random() - 0.5) * 10;
particle.vy = (Math.random() - 0.5) * 10;
if (color) {
tween(particle, {
tint: color
}, {
duration: 0
});
}
particles.push(particle);
game.addChild(particle);
}
}
// Start with menu
showMenu();
// Spawn zombie function
function spawnZombie() {
var config = waveConfigs[Math.min(currentWave - 1, waveConfigs.length - 1)];
var zombieTypes = config.zombieTypes;
var randomType = zombieTypes[Math.floor(Math.random() * zombieTypes.length)];
var zombie;
if (randomType === 'fastZombie') {
zombie = new FastZombie();
} else if (randomType === 'tankZombie') {
zombie = new TankZombie();
} else {
zombie = new Zombie();
}
// Apply speed multiplier
zombie.speed *= zombieSpeedMultiplier;
// Spawn from random edge
var edge = Math.floor(Math.random() * 4);
if (edge === 0) {
// Top
zombie.x = Math.random() * 2048;
zombie.y = -30;
} else if (edge === 1) {
// Right
zombie.x = 2078;
zombie.y = Math.random() * 2732;
} else if (edge === 2) {
// Bottom
zombie.x = Math.random() * 2048;
zombie.y = 2762;
} else {
// Left
zombie.x = -30;
zombie.y = Math.random() * 2732;
}
zombie.lastX = zombie.x;
zombie.lastY = zombie.y;
// Create spawn particles
createParticles(zombie.x, zombie.y, 6, 0x8b4513);
zombies.push(zombie);
game.addChild(zombie);
zombiesSpawned++;
}
// Update UI function
function updateUI() {
scoreText.setText('Score: ' + LK.getScore());
waveText.setText('Wave: ' + currentWave);
timerText.setText('Time: ' + Math.max(0, Math.ceil((90 * 60 - gameTime) / 60)));
healthText.setText('Health: ' + player.health);
}
// Handle move events
function handleMove(x, y, obj) {
if (dragNode) {
// Keep player within bounds
dragNode.x = Math.max(40, Math.min(2008, x));
dragNode.y = Math.max(40, Math.min(2692, y));
}
}
// Game event handlers
game.move = handleMove;
game.down = function (x, y, obj) {
dragNode = player;
handleMove(x, y, obj);
};
game.up = function (x, y, obj) {
dragNode = null;
};
// Main game update loop
game.update = function () {
// Update particles
for (var p = particles.length - 1; p >= 0; p--) {
var particle = particles[p];
if (particle.life <= 0) {
particles.splice(p, 1);
}
}
// Only run game logic when playing
if (gameState !== 'playing' || !player) {
return;
}
gameTime++;
waveTime++;
// Update kill streak timer
if (killStreakTimer > 0) {
killStreakTimer--;
if (killStreakTimer <= 0) {
killStreak = 0;
}
}
// Wave management
var config = waveConfigs[Math.min(currentWave - 1, waveConfigs.length - 1)];
// Spawn zombies
if (zombiesSpawned < config.zombieCount) {
spawnTimer++;
if (spawnTimer >= config.spawnDelay) {
spawnZombie();
spawnTimer = 0;
}
}
// Check wave completion
if (zombiesSpawned >= config.zombieCount && zombies.length === 0) {
currentWave++;
zombiesSpawned = 0;
waveTime = 0;
// Bonus points for wave completion
LK.setScore(LK.getScore() + currentWave * 50);
LK.getSound('waveStart').play();
// Restore some health
player.health = Math.min(player.maxHealth, player.health + 20);
// Create celebration particles
createParticles(player.x, player.y, 15, 0x00ff00);
}
// Update zombies and check player collision for combat
for (var k = zombies.length - 1; k >= 0; k--) {
var zombie = zombies[k];
// Initialize collision tracking if not exists
if (zombie.lastCollidingWithPlayer === undefined) {
zombie.lastCollidingWithPlayer = false;
}
// Check current collision state
var currentlyColliding = zombie.intersects(player);
// If collision just started (transition from false to true)
if (!zombie.lastCollidingWithPlayer && currentlyColliding) {
// Player kills zombie by running into it
zombie.health--;
// Flash zombie when hit
LK.effects.flashObject(zombie, 0xff0000, 200);
LK.getSound('playerAttack').play();
// Create hit particles
createParticles(zombie.x, zombie.y, 8, 0xff0000);
if (zombie.health <= 0) {
// Add score with kill streak multiplier
var points = zombie.points * (1 + killStreak * 0.1);
LK.setScore(LK.getScore() + Math.floor(points));
killStreak++;
killStreakTimer = 180; // 3 seconds
// Create death particles
createParticles(zombie.x, zombie.y, 12, 0xffff00);
LK.getSound('zombieDeath').play();
zombie.destroy();
zombies.splice(k, 1);
zombiesKilled++;
} else {
// If zombie survives, player takes damage
player.health -= 5;
LK.effects.flashScreen(0xff0000, 300);
LK.getSound('playerHurt').play();
if (player.health <= 0) {
LK.showGameOver();
return;
}
}
}
// Update collision tracking
zombie.lastCollidingWithPlayer = currentlyColliding;
}
// Check win condition (90 seconds = 5400 frames at 60fps)
if (gameTime >= 5400) {
LK.showYouWin();
return;
}
// Update UI
updateUI();
}; ===================================================================
--- original.js
+++ change.js
@@ -25,15 +25,77 @@
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;
+ // Run away from player instead of towards
+ self.x -= dx / distance * self.speed * zombieSpeedMultiplier;
+ self.y -= dy / distance * self.speed * zombieSpeedMultiplier;
}
}
};
return self;
});
+var Menu = Container.expand(function () {
+ var self = Container.call(this);
+ var playButton = self.attachAsset('menuButton', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 0,
+ y: -100
+ });
+ var playText = new Text2('PLAY', {
+ size: 60,
+ fill: 0xFFFFFF
+ });
+ playText.anchor.set(0.5, 0.5);
+ playText.y = -100;
+ self.addChild(playText);
+ var settingsButton = self.attachAsset('settingButton', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 0,
+ y: 50
+ });
+ var settingsText = new Text2('SETTINGS', {
+ size: 40,
+ fill: 0xFFFFFF
+ });
+ settingsText.anchor.set(0.5, 0.5);
+ settingsText.y = 50;
+ self.addChild(settingsText);
+ self.down = function (x, y, obj) {
+ var localPos = self.toLocal(obj.parent.toGlobal(obj.position));
+ if (localPos.y > -150 && localPos.y < -50) {
+ LK.getSound('menuClick').play();
+ startGame();
+ } else if (localPos.y > 10 && localPos.y < 90) {
+ LK.getSound('menuClick').play();
+ showSettings();
+ }
+ };
+ return self;
+});
+var Particle = Container.expand(function () {
+ var self = Container.call(this);
+ var particleGraphics = self.attachAsset('particle', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.vx = 0;
+ self.vy = 0;
+ self.life = 60;
+ self.maxLife = 60;
+ self.update = function () {
+ self.x += self.vx;
+ self.y += self.vy;
+ self.life--;
+ self.alpha = self.life / self.maxLife;
+ if (self.life <= 0) {
+ self.destroy();
+ }
+ };
+ return self;
+});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
@@ -43,8 +105,85 @@
self.maxHealth = 100;
self.lastCollidedZombies = [];
return self;
});
+var SettingsMenu = Container.expand(function () {
+ var self = Container.call(this);
+ var titleText = new Text2('SETTINGS', {
+ size: 80,
+ fill: 0xFFFFFF
+ });
+ titleText.anchor.set(0.5, 0.5);
+ titleText.y = -300;
+ self.addChild(titleText);
+ var zombieSpeedText = new Text2('Zombie Speed: ' + zombieSpeedMultiplier, {
+ size: 50,
+ fill: 0xFFFFFF
+ });
+ zombieSpeedText.anchor.set(0.5, 0.5);
+ zombieSpeedText.y = -150;
+ self.addChild(zombieSpeedText);
+ var speedUpButton = self.attachAsset('settingButton', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: -200,
+ y: -100
+ });
+ var speedUpText = new Text2('+', {
+ size: 60,
+ fill: 0xFFFFFF
+ });
+ speedUpText.anchor.set(0.5, 0.5);
+ speedUpText.x = -200;
+ speedUpText.y = -100;
+ self.addChild(speedUpText);
+ var speedDownButton = self.attachAsset('settingButton', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 200,
+ y: -100
+ });
+ var speedDownText = new Text2('-', {
+ size: 60,
+ fill: 0xFFFFFF
+ });
+ speedDownText.anchor.set(0.5, 0.5);
+ speedDownText.x = 200;
+ speedDownText.y = -100;
+ self.addChild(speedDownText);
+ var backButton = self.attachAsset('menuButton', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 0,
+ y: 200
+ });
+ var backText = new Text2('BACK', {
+ size: 60,
+ fill: 0xFFFFFF
+ });
+ backText.anchor.set(0.5, 0.5);
+ backText.y = 200;
+ self.addChild(backText);
+ self.down = function (x, y, obj) {
+ var localPos = self.toLocal(obj.parent.toGlobal(obj.position));
+ if (localPos.x > -350 && localPos.x < -50 && localPos.y > -140 && localPos.y < -60) {
+ // Speed up
+ zombieSpeedMultiplier = Math.min(3, zombieSpeedMultiplier + 0.2);
+ zombieSpeedText.setText('Zombie Speed: ' + zombieSpeedMultiplier.toFixed(1));
+ LK.getSound('menuClick').play();
+ } else if (localPos.x > 50 && localPos.x < 350 && localPos.y > -140 && localPos.y < -60) {
+ // Speed down
+ zombieSpeedMultiplier = Math.max(0.2, zombieSpeedMultiplier - 0.2);
+ zombieSpeedText.setText('Zombie Speed: ' + zombieSpeedMultiplier.toFixed(1));
+ LK.getSound('menuClick').play();
+ } else if (localPos.y > 150 && localPos.y < 250) {
+ // Back
+ LK.getSound('menuClick').play();
+ showMenu();
+ }
+ };
+ return self;
+});
var TankZombie = Container.expand(function () {
var self = Container.call(this);
var zombieGraphics = self.attachAsset('tankZombie', {
anchorX: 0.5,
@@ -63,10 +202,11 @@
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;
+ // Run away from player instead of towards
+ self.x -= dx / distance * self.speed * zombieSpeedMultiplier;
+ self.y -= dy / distance * self.speed * zombieSpeedMultiplier;
}
}
};
return self;
@@ -90,10 +230,11 @@
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;
+ // Run away from player instead of towards
+ self.x -= dx / distance * self.speed;
+ self.y -= dy / distance * self.speed;
}
}
};
return self;
@@ -108,8 +249,14 @@
/****
* Game Code
****/
+// Game state variables
+var gameState = 'menu'; // 'menu', 'settings', 'playing'
+var menu;
+var settingsMenu;
+var particles = [];
+var zombieSpeedMultiplier = 1.0;
// Game variables
var player;
var zombies = [];
var currentWave = 1;
@@ -184,12 +331,70 @@
});
healthText.anchor.set(0.5, 1);
healthText.y = -20;
LK.gui.bottom.addChild(healthText);
-// Initialize player
-player = game.addChild(new Player());
-player.x = 1024;
-player.y = 1366;
+// Menu system functions
+function showMenu() {
+ gameState = 'menu';
+ if (settingsMenu) {
+ settingsMenu.destroy();
+ settingsMenu = null;
+ }
+ if (!menu) {
+ menu = game.addChild(new Menu());
+ menu.x = 1024;
+ menu.y = 1366;
+ }
+}
+function showSettings() {
+ gameState = 'settings';
+ if (menu) {
+ menu.destroy();
+ menu = null;
+ }
+ if (!settingsMenu) {
+ settingsMenu = game.addChild(new SettingsMenu());
+ settingsMenu.x = 1024;
+ settingsMenu.y = 1366;
+ }
+}
+function startGame() {
+ gameState = 'playing';
+ if (menu) {
+ menu.destroy();
+ menu = null;
+ }
+ if (settingsMenu) {
+ settingsMenu.destroy();
+ settingsMenu = null;
+ }
+ // Initialize player
+ if (!player) {
+ player = game.addChild(new Player());
+ player.x = 1024;
+ player.y = 1366;
+ }
+}
+function createParticles(x, y, count, color) {
+ for (var i = 0; i < count; i++) {
+ var particle = new Particle();
+ particle.x = x;
+ particle.y = y;
+ particle.vx = (Math.random() - 0.5) * 10;
+ particle.vy = (Math.random() - 0.5) * 10;
+ if (color) {
+ tween(particle, {
+ tint: color
+ }, {
+ duration: 0
+ });
+ }
+ particles.push(particle);
+ game.addChild(particle);
+ }
+}
+// Start with menu
+showMenu();
// Spawn zombie function
function spawnZombie() {
var config = waveConfigs[Math.min(currentWave - 1, waveConfigs.length - 1)];
var zombieTypes = config.zombieTypes;
@@ -201,8 +406,10 @@
zombie = new TankZombie();
} else {
zombie = new Zombie();
}
+ // Apply speed multiplier
+ zombie.speed *= zombieSpeedMultiplier;
// Spawn from random edge
var edge = Math.floor(Math.random() * 4);
if (edge === 0) {
// Top
@@ -222,8 +429,10 @@
zombie.y = Math.random() * 2732;
}
zombie.lastX = zombie.x;
zombie.lastY = zombie.y;
+ // Create spawn particles
+ createParticles(zombie.x, zombie.y, 6, 0x8b4513);
zombies.push(zombie);
game.addChild(zombie);
zombiesSpawned++;
}
@@ -252,8 +461,19 @@
dragNode = null;
};
// Main game update loop
game.update = function () {
+ // Update particles
+ for (var p = particles.length - 1; p >= 0; p--) {
+ var particle = particles[p];
+ if (particle.life <= 0) {
+ particles.splice(p, 1);
+ }
+ }
+ // Only run game logic when playing
+ if (gameState !== 'playing' || !player) {
+ return;
+ }
gameTime++;
waveTime++;
// Update kill streak timer
if (killStreakTimer > 0) {
@@ -281,8 +501,10 @@
LK.setScore(LK.getScore() + currentWave * 50);
LK.getSound('waveStart').play();
// Restore some health
player.health = Math.min(player.maxHealth, player.health + 20);
+ // Create celebration particles
+ createParticles(player.x, player.y, 15, 0x00ff00);
}
// Update zombies and check player collision for combat
for (var k = zombies.length - 1; k >= 0; k--) {
var zombie = zombies[k];
@@ -297,22 +519,28 @@
// Player kills zombie by running into it
zombie.health--;
// Flash zombie when hit
LK.effects.flashObject(zombie, 0xff0000, 200);
- LK.getSound('zombieHit').play();
+ LK.getSound('playerAttack').play();
+ // Create hit particles
+ createParticles(zombie.x, zombie.y, 8, 0xff0000);
if (zombie.health <= 0) {
// Add score with kill streak multiplier
var points = zombie.points * (1 + killStreak * 0.1);
LK.setScore(LK.getScore() + Math.floor(points));
killStreak++;
killStreakTimer = 180; // 3 seconds
+ // Create death particles
+ createParticles(zombie.x, zombie.y, 12, 0xffff00);
+ LK.getSound('zombieDeath').play();
zombie.destroy();
zombies.splice(k, 1);
zombiesKilled++;
} else {
// If zombie survives, player takes damage
player.health -= 5;
LK.effects.flashScreen(0xff0000, 300);
+ LK.getSound('playerHurt').play();
if (player.health <= 0) {
LK.showGameOver();
return;
}