User prompt
The character is still very fast
User prompt
The character is very fast
User prompt
Remove the shop
User prompt
I can't leave the store, fix this
User prompt
I can't get anything from the store and I can't leave
User prompt
Enlarge text in the shop
User prompt
Make the buttons in the shop functional instead of non-functional
User prompt
Have a shop somewhere on the map ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Remove all animations
User prompt
Update
User prompt
The game lags a lot
User prompt
Optimize the game
User prompt
Add grass to the ground and a black barrier at the end of the map
User prompt
Add and expand the map to the game
User prompt
Make the game open world
User prompt
After 5 waves, the game over message should appear.
User prompt
I can't start the game please fix this
User prompt
Make main menu
User prompt
Please fix the bug: 'TypeError: tween.to is not a function' in or related to this line: 'tween.to(spawnParticle, {' Line Number: 244 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Update 1000 lines
User prompt
Correct the trajectory of bullets
User prompt
Add weapon to character
User prompt
Make it harder
User prompt
Make it harder
Code edit (1 edits merged)
Please save this source code
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.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 = 12; self.directionX = 0; self.directionY = 0; self.update = function () { // Store previous position for trail effect if (self.lastX === undefined) { self.lastX = self.x; self.lastY = self.y; } self.x += self.directionX * self.speed; self.y += self.directionY * self.speed; // Trail particles removed self.lastX = self.x; self.lastY = self.y; }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); // Add weapon to player var weaponGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5 }); weaponGraphics.x = 25; // Position weapon to the right of player weaponGraphics.y = 0; self.speed = 4; self.health = 1; self.lastShootTime = 0; self.shootInterval = 500; // milliseconds return self; }); var PowerUp = Container.expand(function () { var self = Container.call(this); var powerUpGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5, scaleX: 2, scaleY: 2, tint: 0x00FF00 }); self.type = 'speed'; // 'speed', 'damage', 'fireRate' self.duration = 600; // 10 seconds at 60fps self.bobOffset = Math.random() * Math.PI * 2; self.update = function () { // Bobbing animation removed }; return self; }); var Shop = Container.expand(function () { var self = Container.call(this); // Shop building graphics var shopGraphics = self.attachAsset('zombie', { anchorX: 0.5, anchorY: 0.5, scaleX: 2, scaleY: 2, tint: 0x8B4513 }); // Shop sign var shopSign = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5, scaleX: 3, scaleY: 1, tint: 0xFFFFFF }); shopSign.y = -200; self.addChild(shopSign); self.isPlayerNear = false; self.lastPlayerNear = false; self.update = function () { if (player) { var dx = player.x - self.x; var dy = player.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); self.isPlayerNear = distance < 200; // Check if player just entered shop range if (!self.lastPlayerNear && self.isPlayerNear) { showShopUI(); } // Check if player just left shop range else if (self.lastPlayerNear && !self.isPlayerNear) { hideShopUI(); } self.lastPlayerNear = self.isPlayerNear; } }; 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 = 2; self.health = 1; self.maxHealth = 1; // Create health bar background var healthBarBg = LK.getAsset('bullet', { anchorX: 0.5, anchorY: 0.5, scaleX: 3, scaleY: 0.5, tint: 0x333333 }); healthBarBg.y = -140; self.addChild(healthBarBg); // Create health bar fill var healthBarFill = LK.getAsset('bullet', { anchorX: 0.5, anchorY: 0.5, scaleX: 3, scaleY: 0.5, tint: 0xFF0000 }); healthBarFill.y = -140; self.addChild(healthBarFill); self.healthBarFill = healthBarFill; self.update = function () { if (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; } // Pulsing and tint effects removed } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2E2E2E }); /**** * Game Code ****/ // Game state management var gameState = 'menu'; // 'menu', 'playing', 'gameOver' var menuContainer; var playButton; // Game variables var player; var zombies = []; var bullets = []; var powerUps = []; var dragNode = null; var gameTime = 0; var zombieSpawnRate = 50; // frames between spawns var zombieSpeed = 4; var zombiesKilled = 0; var waveNumber = 1; var comboCount = 0; var comboTimer = 0; var comboDecayTime = 180; // 3 seconds at 60fps var scoreMultiplier = 1; var playerFireRate = 60; // frames between shots var playerDamage = 1; var playerSpeed = 4; // Map system variables var mapWidth = 6144; // 3x wider than screen var mapHeight = 8196; // 3x taller than screen var cameraOffsetX = 0; var cameraOffsetY = 0; var gameContainer; // Minimap variables var minimap; var minimapContainer; var minimapPlayer; var minimapZombies = []; var minimapSize = 200; var minimapScale = minimapSize / Math.max(mapWidth, mapHeight); // Shop variables var shop; var shopUI; var shopVisible = false; var coins = storage.coins || 0; var shopUpgrades = { damage: storage.damageUpgrade || 0, speed: storage.speedUpgrade || 0, fireRate: storage.fireRateUpgrade || 0 }; // Shop UI elements var shopContainer; var coinsTxt; var shopTitle; var upgradeButtons = []; // Create game container for camera system gameContainer = new Container(); game.addChild(gameContainer); // Create main menu menuContainer = new Container(); game.addChild(menuContainer); // Menu title var titleTxt = new Text2('ZOMBIE SHOOTER', { size: 120, fill: 0xFF4444 }); titleTxt.anchor.set(0.5, 0.5); titleTxt.x = 2048 / 2; titleTxt.y = 2732 / 2 - 200; menuContainer.addChild(titleTxt); // Play button background var playButtonBg = LK.getAsset('zombie', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 0.8, tint: 0x44AA44 }); playButtonBg.x = 2048 / 2; playButtonBg.y = 2732 / 2 + 50; menuContainer.addChild(playButtonBg); // Play button text var playButtonTxt = new Text2('PLAY', { size: 80, fill: 0xFFFFFF }); playButtonTxt.anchor.set(0.5, 0.5); playButtonTxt.x = 2048 / 2; playButtonTxt.y = 2732 / 2 + 50; menuContainer.addChild(playButtonTxt); // Store reference to play button for event handling playButton = playButtonBg; // Make sure menu is visible at start menuContainer.visible = true; gameState = 'menu'; // Game UI Elements (initially hidden) var scoreTxt = new Text2('Score: 0', { size: 60, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); scoreTxt.visible = false; LK.gui.top.addChild(scoreTxt); var waveTxt = new Text2('Wave: 1', { size: 50, fill: 0xFFFFFF }); waveTxt.anchor.set(0, 0); waveTxt.x = 120; waveTxt.y = 20; waveTxt.visible = false; LK.gui.top.addChild(waveTxt); var timeTxt = new Text2('Time: 0s', { size: 50, fill: 0xFFFFFF }); timeTxt.anchor.set(1, 0); timeTxt.x = -20; timeTxt.y = 20; timeTxt.visible = false; LK.gui.topRight.addChild(timeTxt); var comboTxt = new Text2('', { size: 80, fill: 0xFFAA00 }); comboTxt.anchor.set(0.5, 0.5); comboTxt.visible = false; LK.gui.center.addChild(comboTxt); // Coins display coinsTxt = new Text2('Coins: ' + coins, { size: 50, fill: 0xFFD700 }); coinsTxt.anchor.set(0, 0); coinsTxt.x = 120; coinsTxt.y = 80; coinsTxt.visible = false; LK.gui.top.addChild(coinsTxt); // Shop UI creation function createShopUI() { // Clear existing shop container if it exists if (shopContainer) { shopContainer.destroy(); } // Reset upgrade buttons array upgradeButtons = []; shopContainer = new Container(); // Shop background var shopBg = LK.getAsset('zombie', { anchorX: 0.5, anchorY: 0.5, scaleX: 8, scaleY: 6, tint: 0x2A2A2A, alpha: 0.9 }); shopBg.x = 2048 / 2; shopBg.y = 2732 / 2; shopContainer.addChild(shopBg); // Shop title shopTitle = new Text2('SHOP', { size: 150, fill: 0xFFFFFF }); shopTitle.anchor.set(0.5, 0.5); shopTitle.x = 2048 / 2; shopTitle.y = 2732 / 2 - 400; shopContainer.addChild(shopTitle); // Coins display in shop var shopCoinsTxt = new Text2('Coins: ' + coins, { size: 80, fill: 0xFFD700 }); shopCoinsTxt.anchor.set(0.5, 0.5); shopCoinsTxt.x = 2048 / 2; shopCoinsTxt.y = 2732 / 2 - 300; shopContainer.addChild(shopCoinsTxt); // Create upgrade buttons var upgradeTypes = [{ name: 'Damage +1', type: 'damage', cost: 100, y: -150 }, { name: 'Speed +1', type: 'speed', cost: 150, y: -50 }, { name: 'Fire Rate +1', type: 'fireRate', cost: 200, y: 50 }]; for (var i = 0; i < upgradeTypes.length; i++) { var upgrade = upgradeTypes[i]; var currentLevel = shopUpgrades[upgrade.type]; var cost = upgrade.cost + currentLevel * 50; // Button background var buttonBg = LK.getAsset('bullet', { anchorX: 0.5, anchorY: 0.5, scaleX: 20, scaleY: 4, tint: coins >= cost ? 0x44AA44 : 0xAA4444 }); buttonBg.x = 2048 / 2; buttonBg.y = 2732 / 2 + upgrade.y; shopContainer.addChild(buttonBg); // Button text var buttonTxt = new Text2(upgrade.name + ' (Lv.' + currentLevel + ') - ' + cost + ' coins', { size: 70, fill: 0xFFFFFF }); buttonTxt.anchor.set(0.5, 0.5); buttonTxt.x = 2048 / 2; buttonTxt.y = 2732 / 2 + upgrade.y; shopContainer.addChild(buttonTxt); upgradeButtons.push({ bg: buttonBg, txt: buttonTxt, type: upgrade.type, cost: cost }); } // Close button var closeBtn = LK.getAsset('bullet', { anchorX: 0.5, anchorY: 0.5, scaleX: 8, scaleY: 2, tint: 0xAA4444 }); closeBtn.x = 2048 / 2; closeBtn.y = 2732 / 2 + 200; shopContainer.addChild(closeBtn); var closeTxt = new Text2('CLOSE', { size: 80, fill: 0xFFFFFF }); closeTxt.anchor.set(0.5, 0.5); closeTxt.x = 2048 / 2; closeTxt.y = 2732 / 2 + 200; shopContainer.addChild(closeTxt); upgradeButtons.push({ bg: closeBtn, txt: closeTxt, type: 'close', cost: 0 }); shopContainer.visible = false; game.addChild(shopContainer); } function showShopUI() { if (!shopContainer) { createShopUI(); } shopContainer.visible = true; shopVisible = true; } function hideShopUI() { if (shopContainer) { shopContainer.visible = false; } shopVisible = false; } function purchaseUpgrade(type) { var currentLevel = shopUpgrades[type]; var baseCost = type === 'damage' ? 100 : type === 'speed' ? 150 : 200; var cost = baseCost + currentLevel * 50; if (coins >= cost) { coins -= cost; shopUpgrades[type]++; // Save to storage storage.coins = coins; storage[type + 'Upgrade'] = shopUpgrades[type]; // Update UI coinsTxt.setText('Coins: ' + coins); // Apply upgrade immediately applyUpgrades(); // Refresh shop UI hideShopUI(); showShopUI(); return true; } return false; } function applyUpgrades() { // Apply damage upgrade playerDamage = 1 + shopUpgrades.damage; // Apply speed upgrade if (player) { player.speed = 4 + shopUpgrades.speed; } // Apply fire rate upgrade playerFireRate = Math.max(20, 60 - shopUpgrades.fireRate * 10); } // Game initialization function function initializeGame() { // Reset game variables gameTime = 0; zombiesKilled = 0; waveNumber = 1; comboCount = 0; comboTimer = 0; scoreMultiplier = 1; zombieSpawnRate = 50; zombieSpeed = 4; // Clear existing game objects if (player) { player.destroy(); } for (var i = 0; i < zombies.length; i++) { zombies[i].destroy(); } for (var j = 0; j < bullets.length; j++) { bullets[j].destroy(); } zombies = []; bullets = []; // Initialize player player = gameContainer.addChild(new Player()); player.x = mapWidth / 2; player.y = mapHeight / 2; // Create map boundary indicators var mapBounds = []; // Top boundary var topBound = LK.getAsset('bullet', { anchorX: 0, anchorY: 0, scaleX: mapWidth / 16, scaleY: 2, tint: 0x444444 }); topBound.x = 0; topBound.y = 0; gameContainer.addChild(topBound); mapBounds.push(topBound); // Bottom boundary var bottomBound = LK.getAsset('bullet', { anchorX: 0, anchorY: 0, scaleX: mapWidth / 16, scaleY: 2, tint: 0x444444 }); bottomBound.x = 0; bottomBound.y = mapHeight - 32; gameContainer.addChild(bottomBound); mapBounds.push(bottomBound); // Left boundary var leftBound = LK.getAsset('bullet', { anchorX: 0, anchorY: 0, scaleX: 2, scaleY: mapHeight / 16, tint: 0x444444 }); leftBound.x = 0; leftBound.y = 0; gameContainer.addChild(leftBound); mapBounds.push(leftBound); // Right boundary var rightBound = LK.getAsset('bullet', { anchorX: 0, anchorY: 0, scaleX: 2, scaleY: mapHeight / 16, tint: 0x444444 }); rightBound.x = mapWidth - 32; rightBound.y = 0; gameContainer.addChild(rightBound); mapBounds.push(rightBound); // Reset camera position cameraOffsetX = 0; cameraOffsetY = 0; // Reset score LK.setScore(0); scoreTxt.setText('Score: 0'); // Show game UI scoreTxt.visible = true; waveTxt.visible = true; timeTxt.visible = true; comboTxt.visible = true; coinsTxt.visible = true; // Create and position shop shop = gameContainer.addChild(new Shop()); shop.x = mapWidth / 4; // Place shop in the left quarter of the map shop.y = mapHeight / 4; // Apply purchased upgrades applyUpgrades(); // Update coins display coinsTxt.setText('Coins: ' + coins); // Create minimap minimapContainer = new Container(); minimap = LK.getAsset('bullet', { anchorX: 0, anchorY: 0, scaleX: minimapSize / 16, scaleY: minimapSize / 16, tint: 0x333333, alpha: 0.8 }); minimap.x = 0; minimap.y = 0; minimapContainer.addChild(minimap); // Create minimap player indicator minimapPlayer = LK.getAsset('bullet', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.8, tint: 0x00FF00 }); minimapContainer.addChild(minimapPlayer); // Position minimap in bottom right minimapContainer.x = -minimapSize - 20; minimapContainer.y = -minimapSize - 20; LK.gui.bottomRight.addChild(minimapContainer); // Clear existing minimap zombies minimapZombies = []; // Show minimap if (minimapContainer) { minimapContainer.visible = true; } // Hide menu menuContainer.visible = false; // Set game state gameState = 'playing'; } // Don't initialize player immediately - wait for menu interaction // Helper functions function spawnZombie() { var zombie = new Zombie(); var side = Math.floor(Math.random() * 4); switch (side) { case 0: // top zombie.x = Math.random() * mapWidth; zombie.y = -50; break; case 1: // right zombie.x = mapWidth + 50; zombie.y = Math.random() * mapHeight; break; case 2: // bottom zombie.x = Math.random() * mapWidth; zombie.y = mapHeight + 50; break; case 3: // left zombie.x = -50; zombie.y = Math.random() * mapHeight; break; } // Create different zombie types based on level var zombieType = Math.random(); if (waveNumber >= 3 && zombieType < 0.3) { // Fast zombie zombie.speed = zombieSpeed * 1.8; zombie.health = 1; zombie.maxHealth = 1; zombie.tint = 0xFF8888; zombie.scaleX = 0.8; zombie.scaleY = 0.8; } else if (waveNumber >= 5 && zombieType < 0.5) { // Tank zombie zombie.speed = zombieSpeed * 0.6; zombie.health = 3; zombie.maxHealth = 3; zombie.tint = 0x888888; zombie.scaleX = 1.3; zombie.scaleY = 1.3; } else { // Normal zombie zombie.speed = zombieSpeed; zombie.health = 1; zombie.maxHealth = 1; } // Spawn effects removed zombies.push(zombie); gameContainer.addChild(zombie); // Add zombie to minimap if (minimapContainer) { var minimapZombie = LK.getAsset('bullet', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.4, scaleY: 0.4, tint: 0xFF4444 }); minimapZombie.x = zombie.x * minimapScale; minimapZombie.y = zombie.y * minimapScale; minimapContainer.addChild(minimapZombie); minimapZombies.push(minimapZombie); zombie.minimapRef = minimapZombie; } } function findNearestZombie() { var nearestZombie = null; var nearestDistance = Infinity; for (var i = 0; i < zombies.length; i++) { var zombie = zombies[i]; var dx = zombie.x - player.x; var dy = zombie.y - player.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < nearestDistance) { nearestDistance = distance; nearestZombie = zombie; } } return nearestZombie; } function shootBullet() { var target = findNearestZombie(); if (!target) return; var bullet = new Bullet(); bullet.x = player.x; bullet.y = player.y; // Calculate zombie's movement direction var zombieDx = player.x - target.x; var zombieDy = player.y - target.y; var zombieDistance = Math.sqrt(zombieDx * zombieDx + zombieDy * zombieDy); var zombieDirectionX = zombieDistance > 0 ? zombieDx / zombieDistance : 0; var zombieDirectionY = zombieDistance > 0 ? zombieDy / zombieDistance : 0; // Predict where zombie will be var timeToTarget = zombieDistance / bullet.speed; var predictedX = target.x + zombieDirectionX * target.speed * timeToTarget; var predictedY = target.y + zombieDirectionY * target.speed * timeToTarget; // Aim at predicted position var dx = predictedX - player.x; var dy = predictedY - player.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 0) { bullet.directionX = dx / distance; bullet.directionY = dy / distance; } // Muzzle flash effect removed bullets.push(bullet); gameContainer.addChild(bullet); LK.getSound('shoot').play(); } function updateDifficulty() { waveNumber = Math.floor(gameTime / 1200) + 1; // New wave every 20 seconds zombieSpawnRate = Math.max(15, 50 - waveNumber * 8); zombieSpeed = 4 + (waveNumber - 1) * 1.2; waveTxt.setText('Wave: ' + waveNumber); } // Event handlers function handleMove(x, y, obj) { if (dragNode) { // Convert screen coordinates to world coordinates var worldX = x - cameraOffsetX; var worldY = y - cameraOffsetY; // Keep player within map bounds dragNode.x = Math.max(75, Math.min(mapWidth - 75, worldX)); dragNode.y = Math.max(75, Math.min(mapHeight - 75, worldY)); } } game.move = handleMove; game.down = function (x, y, obj) { if (gameState === 'menu') { // Check if play button was clicked var buttonBounds = playButton.getBounds(); var buttonCenterX = playButton.x; var buttonCenterY = playButton.y; var buttonWidth = buttonBounds.width; var buttonHeight = buttonBounds.height; // Simple bounds check if (x >= buttonCenterX - buttonWidth / 2 && x <= buttonCenterX + buttonWidth / 2 && y >= buttonCenterY - buttonHeight / 2 && y <= buttonCenterY + buttonHeight / 2) { initializeGame(); } } else if (gameState === 'playing') { // Check if shop UI is visible and handle shop clicks if (shopVisible && shopContainer && shopContainer.visible) { // Check upgrade button clicks for (var i = 0; i < upgradeButtons.length; i++) { var button = upgradeButtons[i]; var buttonCenterX = button.bg.x; var buttonCenterY = button.bg.y; var buttonWidth = button.bg.width; var buttonHeight = button.bg.height; if (x >= buttonCenterX - buttonWidth / 2 && x <= buttonCenterX + buttonWidth / 2 && y >= buttonCenterY - buttonHeight / 2 && y <= buttonCenterY + buttonHeight / 2) { if (button.type === 'close') { hideShopUI(); } else { purchaseUpgrade(button.type); } return; } } } else { // Normal gameplay - allow player movement dragNode = player; handleMove(x, y, obj); } } }; game.up = function (x, y, obj) { dragNode = null; }; // Main game loop game.update = function () { // Only update game logic when playing if (gameState !== 'playing') { return; } gameTime++; // Update UI timeTxt.setText('Time: ' + Math.floor(gameTime / 60) + 's'); // Update combo system if (comboTimer > 0) { comboTimer--; if (comboTimer <= 0) { comboCount = 0; scoreMultiplier = 1; comboTxt.setText(''); } } // Continuously increase difficulty based on score instead of waves var currentScore = LK.getScore(); zombieSpawnRate = Math.max(10, 50 - Math.floor(currentScore / 100) * 2); zombieSpeed = 4 + Math.floor(currentScore / 200) * 0.5; waveNumber = Math.floor(currentScore / 500) + 1; waveTxt.setText('Level: ' + waveNumber); // Spawn zombies with dynamic frequency based on score if (gameTime % zombieSpawnRate === 0) { spawnZombie(); // Spawn additional zombies based on current level var additionalSpawns = Math.floor(waveNumber / 2); for (var spawn = 0; spawn < additionalSpawns; spawn++) { if (gameTime % (zombieSpawnRate * (spawn + 2)) === 0) { spawnZombie(); } } } // Update camera to follow player if (player) { var targetCameraX = -(player.x - 2048 / 2); var targetCameraY = -(player.y - 2732 / 2); // Smooth camera movement cameraOffsetX += (targetCameraX - cameraOffsetX) * 0.1; cameraOffsetY += (targetCameraY - cameraOffsetY) * 0.1; // Keep camera within map bounds cameraOffsetX = Math.max(-(mapWidth - 2048), Math.min(0, cameraOffsetX)); cameraOffsetY = Math.max(-(mapHeight - 2732), Math.min(0, cameraOffsetY)); // Apply camera offset to game container gameContainer.x = cameraOffsetX; gameContainer.y = cameraOffsetY; // Update minimap player position if (minimapPlayer) { minimapPlayer.x = player.x * minimapScale; minimapPlayer.y = player.y * minimapScale; } } // Spawn power-ups occasionally if (gameTime % 1800 === 0) { // Every 30 seconds var powerUp = new PowerUp(); powerUp.x = Math.random() * (mapWidth - 200) + 100; powerUp.y = Math.random() * (mapHeight - 200) + 100; var powerTypes = ['speed', 'damage', 'fireRate']; powerUp.type = powerTypes[Math.floor(Math.random() * powerTypes.length)]; switch (powerUp.type) { case 'speed': powerUp.tint = 0x00FF00; break; case 'damage': powerUp.tint = 0xFF0000; break; case 'fireRate': powerUp.tint = 0x0000FF; break; } powerUps.push(powerUp); gameContainer.addChild(powerUp); } // Auto-shoot with dynamic fire rate if (gameTime % playerFireRate === 0) { shootBullet(); } // Update minimap zombie positions for (var mz = 0; mz < zombies.length; mz++) { var zombie = zombies[mz]; if (zombie.minimapRef) { zombie.minimapRef.x = zombie.x * minimapScale; zombie.minimapRef.y = zombie.y * minimapScale; } } // Update bullets for (var i = bullets.length - 1; i >= 0; i--) { var bullet = bullets[i]; // Remove bullets that are off screen (expanded map) if (bullet.x < -200 || bullet.x > mapWidth + 200 || bullet.y < -200 || bullet.y > mapHeight + 200) { bullet.destroy(); bullets.splice(i, 1); continue; } // Check bullet-zombie collisions for (var j = zombies.length - 1; j >= 0; j--) { var zombie = zombies[j]; if (bullet.intersects(zombie)) { // Zombie hit LK.getSound('zombieHit').play(); zombie.health -= playerDamage; // Update health bar if (zombie.healthBarFill) { zombie.healthBarFill.scaleX = 3 * (zombie.health / zombie.maxHealth); } // Only destroy zombie if health reaches 0 if (zombie.health <= 0) { // Update combo system comboCount++; comboTimer = comboDecayTime; scoreMultiplier = Math.min(5, 1 + Math.floor(comboCount / 3)); // Show combo text if (comboCount > 2) { comboTxt.setText('COMBO x' + scoreMultiplier); comboTxt.alpha = 1; comboTxt.scaleX = 1; comboTxt.scaleY = 1; // Combo text animation removed } // Explosion particles removed // Clean up minimap reference if (zombie.minimapRef) { zombie.minimapRef.destroy(); var minimapIndex = minimapZombies.indexOf(zombie.minimapRef); if (minimapIndex !== -1) { minimapZombies.splice(minimapIndex, 1); } } zombie.destroy(); zombies.splice(j, 1); zombiesKilled++; LK.setScore(LK.getScore() + 10 * scoreMultiplier + Math.floor(gameTime / 60)); scoreTxt.setText('Score: ' + LK.getScore()); // Award coins for killing zombies var coinsAwarded = 5 + Math.floor(waveNumber / 2); coins += coinsAwarded; storage.coins = coins; coinsTxt.setText('Coins: ' + coins); // Flash effects removed } else { // Zombie damaged but not destroyed // Flash effects removed } bullet.destroy(); bullets.splice(i, 1); break; } } } // Check power-up collection for (var p = powerUps.length - 1; p >= 0; p--) { var powerUp = powerUps[p]; if (player.intersects(powerUp)) { // Apply power-up effect switch (powerUp.type) { case 'speed': player.speed = Math.min(8, player.speed + 1); break; case 'damage': playerDamage += 1; break; case 'fireRate': playerFireRate = Math.max(20, playerFireRate - 10); break; } // Power-up collection effect removed powerUp.destroy(); powerUps.splice(p, 1); LK.setScore(LK.getScore() + 50); scoreTxt.setText('Score: ' + LK.getScore()); } } // Check player-zombie collisions for (var k = 0; k < zombies.length; k++) { var zombie = zombies[k]; if (player.intersects(zombie)) { // Player hit - game over // Screen shake effect removed LK.effects.flashScreen(0xFF0000, 1000); // Reset to menu state gameState = 'menu'; menuContainer.visible = true; scoreTxt.visible = false; waveTxt.visible = false; timeTxt.visible = false; comboTxt.visible = false; coinsTxt.visible = false; if (minimapContainer) { minimapContainer.visible = false; } if (shopContainer) { shopContainer.visible = false; } shopVisible = false; LK.showGameOver(); return; } } // Remove zombies that are too far off screen (cleanup) for (var l = zombies.length - 1; l >= 0; l--) { var zombie = zombies[l]; if (zombie.x < -400 || zombie.x > mapWidth + 400 || zombie.y < -400 || zombie.y > mapHeight + 400) { zombie.destroy(); zombies.splice(l, 1); } } }; // Start background music LK.playMusic('bgmusic');
===================================================================
--- original.js
+++ change.js
@@ -747,12 +747,9 @@
if (x >= buttonCenterX - buttonWidth / 2 && x <= buttonCenterX + buttonWidth / 2 && y >= buttonCenterY - buttonHeight / 2 && y <= buttonCenterY + buttonHeight / 2) {
if (button.type === 'close') {
hideShopUI();
} else {
- // Check if player has enough coins
- if (coins >= button.cost) {
- purchaseUpgrade(button.type);
- }
+ purchaseUpgrade(button.type);
}
return;
}
}