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"); var storage = LK.import("@upit/storage.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) { // Chase player 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); self.interactive = true; var playButton = self.attachAsset('menuButton', { anchorX: 0.5, anchorY: 0.5, x: 0, y: -100, scaleX: 1.5, scaleY: 1.5 }); 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, scaleX: 1.8, scaleY: 1.8 }); 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) { // Use the x,y parameters directly instead of obj.parent.toGlobal var localPos = self.toLocal({ x: x, y: y }); if (localPos.y > -175 && localPos.y < -25) { LK.getSound('menuClick').play(); startGame(); } else if (localPos.y > -22 && localPos.y < 122) { 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); self.interactive = true; var titleText = new Text2('SETTINGS', { size: 80, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0.5); titleText.y = -300; self.addChild(titleText); var musicVolumeText = new Text2('Music Volume: ' + Math.round(musicVolume * 100) + '%', { size: 50, fill: 0xFFFFFF }); musicVolumeText.anchor.set(0.5, 0.5); musicVolumeText.y = -200; self.addChild(musicVolumeText); var volumeUpButton = self.attachAsset('settingButton', { anchorX: 0.5, anchorY: 0.5, x: -200, y: -150, scaleX: 1.4, scaleY: 1.4 }); var volumeUpText = new Text2('+', { size: 60, fill: 0xFFFFFF }); volumeUpText.anchor.set(0.5, 0.5); volumeUpText.x = -200; volumeUpText.y = -150; self.addChild(volumeUpText); var volumeDownButton = self.attachAsset('settingButton', { anchorX: 0.5, anchorY: 0.5, x: 200, y: -150, scaleX: 1.4, scaleY: 1.4 }); var volumeDownText = new Text2('-', { size: 60, fill: 0xFFFFFF }); volumeDownText.anchor.set(0.5, 0.5); volumeDownText.x = 200; volumeDownText.y = -150; self.addChild(volumeDownText); var zombieSpeedText = new Text2('Zombie Speed: ' + zombieSpeedMultiplier, { size: 50, fill: 0xFFFFFF }); zombieSpeedText.anchor.set(0.5, 0.5); zombieSpeedText.y = -50; self.addChild(zombieSpeedText); var speedUpButton = self.attachAsset('settingButton', { anchorX: 0.5, anchorY: 0.5, x: -200, y: 0, scaleX: 1.4, scaleY: 1.4 }); var speedUpText = new Text2('+', { size: 60, fill: 0xFFFFFF }); speedUpText.anchor.set(0.5, 0.5); speedUpText.x = -200; speedUpText.y = 0; self.addChild(speedUpText); var speedDownButton = self.attachAsset('settingButton', { anchorX: 0.5, anchorY: 0.5, x: 200, y: 0, scaleX: 1.4, scaleY: 1.4 }); var speedDownText = new Text2('-', { size: 60, fill: 0xFFFFFF }); speedDownText.anchor.set(0.5, 0.5); speedDownText.x = 200; speedDownText.y = 0; self.addChild(speedDownText); var backButton = self.attachAsset('menuButton', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 200, scaleX: 1.5, scaleY: 1.5 }); 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) { // Use the x,y parameters directly instead of obj.parent.toGlobal var localPos = self.toLocal({ x: x, y: y }); if (localPos.x > -410 && localPos.x < 10 && localPos.y > -206 && localPos.y < -94) { // Volume up musicVolume = Math.min(1, musicVolume + 0.1); musicVolumeText.setText('Music Volume: ' + Math.round(musicVolume * 100) + '%'); storage.musicVolume = musicVolume; LK.getSound('menuClick').play(); } else if (localPos.x > -10 && localPos.x < 410 && localPos.y > -206 && localPos.y < -94) { // Volume down musicVolume = Math.max(0, musicVolume - 0.1); musicVolumeText.setText('Music Volume: ' + Math.round(musicVolume * 100) + '%'); storage.musicVolume = musicVolume; LK.getSound('menuClick').play(); } else if (localPos.x > -410 && localPos.x < 10 && localPos.y > -56 && localPos.y < 56) { // Speed up zombieSpeedMultiplier = Math.min(3, zombieSpeedMultiplier + 0.2); zombieSpeedText.setText('Zombie Speed: ' + zombieSpeedMultiplier.toFixed(1)); LK.getSound('menuClick').play(); } else if (localPos.x > -10 && localPos.x < 410 && localPos.y > -56 && localPos.y < 56) { // 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 > 125 && localPos.y < 275) { // 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) { // Chase player self.x += dx / distance * self.speed * zombieSpeedMultiplier; self.y += dy / distance * self.speed * zombieSpeedMultiplier; } } }; return self; }); var TrailParticle = Container.expand(function () { var self = Container.call(this); var trailGraphics = self.attachAsset('particle', { anchorX: 0.5, anchorY: 0.5 }); self.life = 30; self.maxLife = 30; self.update = function () { self.life--; self.alpha = self.life / self.maxLife; self.scaleX = self.alpha * trailSize; self.scaleY = self.alpha * trailSize; if (self.life <= 0) { self.destroy(); } }; 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) { // Chase player self.x += dx / distance * self.speed * zombieSpeedMultiplier; self.y += dy / distance * self.speed * zombieSpeedMultiplier; } } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2F4F2F }); /**** * Game Code ****/ // Game state variables var gameState = 'playing'; // Always playing now var particles = []; var zombieSpeedMultiplier = 1.0; var musicVolume = storage.musicVolume || 1.0; // Game variables var player; var zombies = []; var trailParticles = []; var playerLastX = 0; var playerLastY = 0; var trailTimer = 0; 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; var combo = 0; var comboTimer = 0; var maxCombo = 0; var trailSize = 1.5; // Make trail bigger // 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 instructionText = new Text2('Tap the cubes to get points', { size: 50, fill: 0xFFFFFF }); instructionText.anchor.set(0.5, 1); instructionText.y = -20; LK.gui.bottom.addChild(instructionText); var comboText = new Text2('Combo: 0', { size: 60, fill: 0xFFD700 }); comboText.anchor.set(1, 0); comboText.x = -20; comboText.y = 100; LK.gui.topRight.addChild(comboText); // Initialize game function function initializeGame() { // Initialize player if (!player) { player = game.addChild(new Player()); player.x = 1024; player.y = 1366; playerLastX = player.x; playerLastY = player.y; } // Start background music LK.playMusic('backgroundMusic', { loop: true, volume: musicVolume }); } 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); } } // Create volume slider at bottom left var volumeSliderBg = LK.getAsset('settingButton', { anchorX: 0, anchorY: 1, x: 20, y: 0, scaleX: 0.5, scaleY: 2 }); LK.gui.bottomLeft.addChild(volumeSliderBg); var volumeSliderHandle = LK.getAsset('player', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.6, scaleY: 0.6 }); volumeSliderBg.addChild(volumeSliderHandle); var volumeText = new Text2(Math.round(musicVolume * 100) + '%', { size: 30, fill: 0xFFFFFF }); volumeText.anchor.set(0.5, 0.5); volumeText.x = 75; volumeText.y = 0; volumeSliderBg.addChild(volumeText); // Position handle based on volume (0 = bottom, 1 = top) volumeSliderHandle.x = 75; volumeSliderHandle.y = -20 - musicVolume * 120; // Make slider interactive volumeSliderBg.interactive = true; volumeSliderBg.down = function (x, y, obj) { var localPos = volumeSliderBg.toLocal({ x: x, y: y }); // Calculate volume based on Y position (inverted since 0,0 is top-left) var newVolume = Math.max(0, Math.min(1, (-localPos.y + 20) / 120)); musicVolume = newVolume; storage.musicVolume = musicVolume; // Update handle position tween(volumeSliderHandle, { y: -20 - musicVolume * 120 }, { duration: 200 }); volumeText.setText(Math.round(musicVolume * 100) + '%'); LK.getSound('menuClick').play(); }; // Start game after 2 seconds LK.setTimeout(function () { initializeGame(); }, 2000); // 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((150 * 60 - gameTime) / 60))); comboText.setText('Combo: ' + combo + (maxCombo > 0 ? ' (Best: ' + maxCombo + ')' : '')); } // Handle move events function handleMove(x, y, obj) { if (dragNode) { // Keep target position within bounds var targetX = Math.max(40, Math.min(2008, x)); var targetY = Math.max(40, Math.min(2692, y)); // Stop any existing movement tween tween.stop(dragNode, { x: true, y: true }); // Smoothly move to target position tween(dragNode, { x: targetX, y: targetY }, { duration: 300, easing: tween.easeOut }); } } // Game event handlers game.move = handleMove; game.down = function (x, y, obj) { if (player) { 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); } } // Update trail particles for (var t = trailParticles.length - 1; t >= 0; t--) { var trailParticle = trailParticles[t]; if (trailParticle.life <= 0) { trailParticles.splice(t, 1); } } // Create player trail when moving if (player) { var playerMoved = Math.abs(player.x - playerLastX) > 5 || Math.abs(player.y - playerLastY) > 5; if (playerMoved) { trailTimer++; if (trailTimer >= 3) { // Create trail every 3 frames when moving var trail = new TrailParticle(); trail.x = playerLastX; trail.y = playerLastY; tween(trail, { tint: 0x4caf50 }, { duration: 0 }); trailParticles.push(trail); game.addChild(trail); trailTimer = 0; } } playerLastX = player.x; playerLastY = player.y; } // Only run game logic when player exists if (!player) { return; } gameTime++; waveTime++; // Update kill streak timer if (killStreakTimer > 0) { killStreakTimer--; if (killStreakTimer <= 0) { killStreak = 0; } } // Update combo timer if (comboTimer > 0) { comboTimer--; if (comboTimer <= 0) { combo = 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) { // Update combo system combo++; comboTimer = 120; // 2 seconds to maintain combo if (combo > maxCombo) { maxCombo = combo; } // Add score with kill streak and combo multiplier var basePoints = zombie.points; var killStreakMultiplier = 1 + killStreak * 0.1; var comboMultiplier = 1 + Math.min(combo - 1, 10) * 0.2; // Max 3x from combo var points = basePoints * killStreakMultiplier * comboMultiplier; LK.setScore(LK.getScore() + Math.floor(points)); killStreak++; killStreakTimer = 180; // 3 seconds // Flash combo text when combo increases if (combo > 1) { tween(comboText, { tint: 0xFFFFFF }, { duration: 100, onFinish: function onFinish() { tween(comboText, { tint: 0xFFD700 }, { duration: 100 }); } }); } // 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 (150 seconds = 9000 frames at 60fps) if (gameTime >= 9000) { LK.showYouWin(); return; } // Update UI updateUI(); };
===================================================================
--- original.js
+++ change.js
@@ -293,10 +293,10 @@
self.maxLife = 30;
self.update = function () {
self.life--;
self.alpha = self.life / self.maxLife;
- self.scaleX = self.alpha * 0.8;
- self.scaleY = self.alpha * 0.8;
+ self.scaleX = self.alpha * trailSize;
+ self.scaleY = self.alpha * trailSize;
if (self.life <= 0) {
self.destroy();
}
};
@@ -361,8 +361,12 @@
var spawnTimer = 0;
var dragNode = null;
var killStreak = 0;
var killStreakTimer = 0;
+var combo = 0;
+var comboTimer = 0;
+var maxCombo = 0;
+var trailSize = 1.5; // Make trail bigger
// Wave configuration
var waveConfigs = [{
zombieCount: 8,
spawnDelay: 90,
@@ -418,15 +422,23 @@
timerText.anchor.set(1, 0);
timerText.x = -20;
timerText.y = 20;
LK.gui.topRight.addChild(timerText);
-var healthText = new Text2('Tap or swipe into the cubes for points', {
+var instructionText = new Text2('Tap the cubes to get points', {
size: 50,
fill: 0xFFFFFF
});
-healthText.anchor.set(0.5, 1);
-healthText.y = -20;
-LK.gui.bottom.addChild(healthText);
+instructionText.anchor.set(0.5, 1);
+instructionText.y = -20;
+LK.gui.bottom.addChild(instructionText);
+var comboText = new Text2('Combo: 0', {
+ size: 60,
+ fill: 0xFFD700
+});
+comboText.anchor.set(1, 0);
+comboText.x = -20;
+comboText.y = 100;
+LK.gui.topRight.addChild(comboText);
// Initialize game function
function initializeGame() {
// Initialize player
if (!player) {
@@ -557,9 +569,10 @@
// 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)));
+ timerText.setText('Time: ' + Math.max(0, Math.ceil((150 * 60 - gameTime) / 60)));
+ comboText.setText('Combo: ' + combo + (maxCombo > 0 ? ' (Best: ' + maxCombo + ')' : ''));
}
// Handle move events
function handleMove(x, y, obj) {
if (dragNode) {
@@ -643,8 +656,15 @@
if (killStreakTimer <= 0) {
killStreak = 0;
}
}
+ // Update combo timer
+ if (comboTimer > 0) {
+ comboTimer--;
+ if (comboTimer <= 0) {
+ combo = 0;
+ }
+ }
// Wave management
var config = waveConfigs[Math.min(currentWave - 1, waveConfigs.length - 1)];
// Spawn zombies
if (zombiesSpawned < config.zombieCount) {
@@ -685,13 +705,37 @@
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);
+ // Update combo system
+ combo++;
+ comboTimer = 120; // 2 seconds to maintain combo
+ if (combo > maxCombo) {
+ maxCombo = combo;
+ }
+ // Add score with kill streak and combo multiplier
+ var basePoints = zombie.points;
+ var killStreakMultiplier = 1 + killStreak * 0.1;
+ var comboMultiplier = 1 + Math.min(combo - 1, 10) * 0.2; // Max 3x from combo
+ var points = basePoints * killStreakMultiplier * comboMultiplier;
LK.setScore(LK.getScore() + Math.floor(points));
killStreak++;
killStreakTimer = 180; // 3 seconds
+ // Flash combo text when combo increases
+ if (combo > 1) {
+ tween(comboText, {
+ tint: 0xFFFFFF
+ }, {
+ duration: 100,
+ onFinish: function onFinish() {
+ tween(comboText, {
+ tint: 0xFFD700
+ }, {
+ duration: 100
+ });
+ }
+ });
+ }
// Create death particles
createParticles(zombie.x, zombie.y, 12, 0xffff00);
LK.getSound('zombieDeath').play();
zombie.destroy();
@@ -710,10 +754,10 @@
}
// Update collision tracking
zombie.lastCollidingWithPlayer = currentlyColliding;
}
- // Check win condition (90 seconds = 5400 frames at 60fps)
- if (gameTime >= 5400) {
+ // Check win condition (150 seconds = 9000 frames at 60fps)
+ if (gameTime >= 9000) {
LK.showYouWin();
return;
}
// Update UI