User prompt
Has que la papapum y el lanza guisantes se puedan fusionar y cuando dispare dispare proyectiles explosivos ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Has que cuando la papum este lista haga una animación, ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
No funciona la fusion de walnut y papapum
User prompt
No sé fusionan la wallnut y la papapum
User prompt
Has que la múxica suene en el uuego
User prompt
Has que la papapum y la wallnut se fusionen y que cuando destruyan esa fusion explote ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
La papapum no explota
User prompt
Has que la papapum tenga un coldawn de 10 segundos para que cuando un zombie la pise explote, osea los primeros 9 segundos la papapum no hace nada pero luego de esos 9 segundos la papapum explota ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Ahora hasme la planta papapum de plantas vs zombies, esa planta explota cuando un zombie la pisa osea es como una mina, ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Has que el armoredshooter tenga 350 de vida
User prompt
Añade la opción de fusionar una wallnut con un lanza guisante ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Has que cuando fuisiones el girasol con el girasol cambie de sprite ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Has que cuando elimines una planta con la pala se pueda poner otra
User prompt
Has que la wall nut cambie de sprite cuando tenga 670 de vida
User prompt
Has que la wallnut tenga 1500 de vida
User prompt
Has aue la wallnut tenga 550 de vida
User prompt
Añade una pala para quitar Plantas y colocar nuevas plantas
User prompt
Has que el wallnut se pueda fusionar con el wallnut para que se aga más fuerte y tenga otro sprite
User prompt
Has que el tank zombie dispare un proyectil que haga 100 de daño en área y que tenga 500 de vida aparezca después de 50 zombies eliminados y te de 450 puntos eliminarlo,
User prompt
Has que el lanza guisantes tenga un coldawn de 3.8 segundos
User prompt
Has que el lanza guisantes doble dispare el primer proyectil a los 1 segundos y el segundo a los 1.9 segundos y que tenga un coldawn de 3.5 segundos
User prompt
Has aue el lanza guisantes doble solo dispare 2 bolas por cada 4.5 segundos
User prompt
Has que el lanza guisantes dobles dispare 2 proyectiles por 2.5 segundos
User prompt
Así que cada 7 segundos el juego te da 7 puntos para las plantas.
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of null (reading 'type')' in or related to this line: 'if (existingPlant && existingPlant.type === 'peashooter' && selectedPlantType === 'peashooter') {' Line Number: 656
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Plant = Container.expand(function (type) { var self = Container.call(this); self.type = type; self.health = 100; self.maxHealth = 100; self.shootTimer = 0; self.shootCooldown = 60; // 1 second at 60fps if (type === 'peashooter') { self.graphics = self.attachAsset('peashooter', { anchorX: 0.5, anchorY: 0.5 }); self.damage = 25; self.range = 400; self.shootCooldown = 228; // 3.8 seconds at 60fps (3.8 * 60 = 228) } else if (type === 'doublepeashooter') { self.graphics = self.attachAsset('doublepeashooter', { anchorX: 0.5, anchorY: 0.5 }); self.damage = 50; self.range = 400; self.shootCooldown = 210; // Total cycle time: 3.5 seconds (3.5 * 60 = 210) self.firstShotTime = 60; // First shot at 1 second (1 * 60 = 60) self.secondShotTime = 114; // Second shot at 1.9 seconds (1.9 * 60 = 114) self.hasFiredFirst = false; self.hasFiredSecond = false; } else if (type === 'wallnut') { self.graphics = self.attachAsset('wallnut', { anchorX: 0.5, anchorY: 0.5 }); self.health = 1500; self.maxHealth = 1500; self.damage = 0; } else if (type === 'cherrybomb') { self.graphics = self.attachAsset('cherrybomb', { anchorX: 0.5, anchorY: 0.5 }); self.damage = 200; self.explosionRadius = 540; // 3 slots * 180px per slot self.fuseTimer = 180; // 3 seconds } else if (type === 'sunflower') { self.graphics = self.attachAsset('sunflower', { anchorX: 0.5, anchorY: 0.5 }); self.damage = 0; self.sunTimer = 0; self.sunInterval = 1200; // 20 seconds at 60fps } else if (type === 'pointshooter') { self.graphics = self.attachAsset('pointShooter', { anchorX: 0.5, anchorY: 0.5 }); self.health = 65; self.maxHealth = 65; self.damage = 0; // Doesn't damage, gives points instead self.range = 400; self.shootCooldown = 270; // Shoots every 4.5 seconds (270 frames at 60fps) } else if (type === 'doublesunflower') { self.graphics = self.attachAsset('sunflower', { anchorX: 0.5, anchorY: 0.5 }); self.damage = 0; self.sunTimer = 0; self.sunInterval = 330; // 5.5 seconds at 60fps (5.5 * 60 = 330) } self.update = function () { if (self.type === 'peashooter' || self.type === 'doublepeashooter' || self.type === 'pointshooter') { self.shootTimer++; if (self.type === 'doublepeashooter') { var target = self.findZombieInLane(); if (target) { // First shot at 1 second if (self.shootTimer >= self.firstShotTime && !self.hasFiredFirst) { self.shoot(target); self.hasFiredFirst = true; } // Second shot at 1.9 seconds if (self.shootTimer >= self.secondShotTime && !self.hasFiredSecond) { self.shoot(target); self.hasFiredSecond = true; } } // Reset cycle after total cooldown (3.5 seconds) if (self.shootTimer >= self.shootCooldown) { self.shootTimer = 0; self.hasFiredFirst = false; self.hasFiredSecond = false; } } else if (self.shootTimer >= self.shootCooldown) { var target = self.findZombieInLane(); if (target) { if (self.type === 'pointshooter') { self.shootPoints(target); } else { self.shoot(target); } } self.shootTimer = 0; } } else if (self.type === 'cherrybomb') { self.fuseTimer--; if (self.fuseTimer <= 0) { self.explode(); } } else if (self.type === 'sunflower') { self.sunTimer++; if (self.sunTimer >= self.sunInterval) { LK.setScore(LK.getScore() + 5); scoreText.setText('Score: ' + LK.getScore()); self.sunTimer = 0; } } else if (self.type === 'doublesunflower') { self.sunTimer++; if (self.sunTimer >= self.sunInterval) { LK.setScore(LK.getScore() + 15); scoreText.setText('Score: ' + LK.getScore()); self.sunTimer = 0; } } }; self.findZombieInLane = function () { for (var i = 0; i < zombies.length; i++) { var zombie = zombies[i]; // Check if zombie is in same lane (within 100px vertically) and to the right if (Math.abs(zombie.y - self.y) < 100 && zombie.x > self.x) { return zombie; } } return null; }; self.getDistanceTo = function (target) { var dx = target.x - self.x; var dy = target.y - self.y; return Math.sqrt(dx * dx + dy * dy); }; self.shoot = function (target) { // Shooting animation - scale and recoil effect tween(self.graphics, { scaleX: 1.3, scaleY: 1.3 }, { duration: 100 }); tween(self.graphics, { scaleX: 1, scaleY: 1 }, { duration: 200 }); tween(self.graphics, { x: -10 }, { duration: 100 }); tween(self.graphics, { x: 0 }, { duration: 200 }); var projectile = new Projectile(self.x, self.y, target, self.damage); projectiles.push(projectile); game.addChild(projectile); LK.getSound('shoot').play(); }; self.shootPoints = function (target) { // Golden shooting animation tween(self.graphics, { scaleX: 1.2, scaleY: 1.2, tint: 0xFFD700 }, { duration: 150 }); tween(self.graphics, { scaleX: 1, scaleY: 1, tint: 0xFFFFFF }, { duration: 250 }); var pointProjectile = new PointProjectile(self.x, self.y, target); projectiles.push(pointProjectile); game.addChild(pointProjectile); LK.getSound('shoot').play(); }; self.explode = function () { // Explosion animation - flash and scale up tween(self.graphics, { tint: 0xFF4444, scaleX: 3, scaleY: 3 }, { duration: 300, onFinish: function onFinish() { // Damage all zombies in explosion radius for (var i = zombies.length - 1; i >= 0; i--) { var zombie = zombies[i]; if (self.getDistanceTo(zombie) <= self.explosionRadius) { zombie.takeDamage(self.damage); } } LK.getSound('explosion').play(); self.destroy(); plants.splice(plants.indexOf(self), 1); } }); }; self.takeDamage = function (damage) { self.health -= damage; // Change wallnut sprite when health drops to 670 or below if (self.type === 'wallnut' && self.health <= 670 && self.health > 0) { // Remove current graphics self.removeChild(self.graphics); // Add damaged wallnut graphics self.graphics = self.attachAsset('wallnutDamaged', { anchorX: 0.5, anchorY: 0.5 }); } if (self.health <= 0) { self.destroy(); plants.splice(plants.indexOf(self), 1); } }; return self; }); var PlantButton = Container.expand(function (plantType, index) { var self = Container.call(this); self.plantType = plantType; self.button = self.attachAsset('plantButton', { anchorX: 0.5, anchorY: 0.5 }); var icon; if (plantType === 'peashooter') { icon = self.attachAsset('peashooter', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.6, scaleY: 0.6 }); } else if (plantType === 'wallnut') { icon = self.attachAsset('wallnut', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.6, scaleY: 0.6 }); } else if (plantType === 'cherrybomb') { icon = self.attachAsset('cherrybomb', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.6, scaleY: 0.6 }); } else if (plantType === 'sunflower') { icon = self.attachAsset('sunflower', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.6, scaleY: 0.6 }); } else if (plantType === 'shovel') { icon = self.attachAsset('shovel', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.6, scaleY: 0.6 }); } self.x = 1024 - plantTypes.length * 200 / 2 + index * 200; self.y = 2600; self.down = function (x, y, obj) { selectedPlantType = self.plantType; // Visual feedback for (var i = 0; i < plantButtons.length; i++) { plantButtons[i].button.tint = 0xFFFFFF; } self.button.tint = 0x00FF00; }; return self; }); var PointProjectile = Container.expand(function (startX, startY, target) { var self = Container.call(this); self.graphics = self.attachAsset('pointPea', { anchorX: 0.5, anchorY: 0.5 }); self.x = startX; self.y = startY; self.target = target; self.speed = 6; // Shoot straight horizontally to the right self.dirX = 1; self.dirY = 0; self.update = function () { self.x += self.dirX * self.speed; self.y += self.dirY * self.speed; // Golden sparkle animation if (LK.ticks % 10 === 0) { tween(self.graphics, { tint: 0xFFFF00 }, { duration: 100 }); tween(self.graphics, { tint: 0xFFD700 }, { duration: 100 }); } // Check collision with any zombie for (var i = 0; i < zombies.length; i++) { var zombie = zombies[i]; if (Math.abs(zombie.x - self.x) < 30 && Math.abs(zombie.y - self.y) < 30) { // Give 1 point instead of damage LK.setScore(LK.getScore() + 1); scoreText.setText('Score: ' + LK.getScore()); // Visual effect on hit tween(zombie.graphics, { tint: 0xFFD700 }, { duration: 200 }); tween(zombie.graphics, { tint: 0xFFFFFF }, { duration: 200 }); self.destroy(); projectiles.splice(projectiles.indexOf(self), 1); return; } } // Remove if off-screen if (self.x > 2100 || self.x < -50 || self.y > 2800 || self.y < -50) { self.destroy(); projectiles.splice(projectiles.indexOf(self), 1); } }; return self; }); var Projectile = Container.expand(function (startX, startY, target, damage) { var self = Container.call(this); self.graphics = self.attachAsset('pea', { anchorX: 0.5, anchorY: 0.5 }); self.x = startX; self.y = startY; self.target = target; self.damage = damage; self.speed = 8; // Shoot straight horizontally to the right self.dirX = 1; self.dirY = 0; self.update = function () { self.x += self.dirX * self.speed; self.y += self.dirY * self.speed; // Check collision with target or any zombie for (var i = 0; i < zombies.length; i++) { var zombie = zombies[i]; if (Math.abs(zombie.x - self.x) < 30 && Math.abs(zombie.y - self.y) < 30) { zombie.takeDamage(self.damage); self.destroy(); projectiles.splice(projectiles.indexOf(self), 1); return; } } // Remove if off-screen if (self.x > 2100 || self.x < -50 || self.y > 2800 || self.y < -50) { self.destroy(); projectiles.splice(projectiles.indexOf(self), 1); } }; return self; }); var TankProjectile = Container.expand(function (startX, startY, target) { var self = Container.call(this); self.graphics = self.attachAsset('pea', { anchorX: 0.5, anchorY: 0.5, scaleX: 2, scaleY: 2, tint: 0xFF4444 }); self.x = startX; self.y = startY; self.target = target; self.damage = 100; self.speed = 4; self.explosionRadius = 200; // Shoot straight horizontally to the left self.dirX = -1; self.dirY = 0; self.update = function () { self.x += self.dirX * self.speed; self.y += self.dirY * self.speed; // Check collision with any plant for (var i = 0; i < plants.length; i++) { var plant = plants[i]; if (Math.abs(plant.x - self.x) < 40 && Math.abs(plant.y - self.y) < 40) { self.explode(); return; } } // Remove if off-screen if (self.x < -50 || self.x > 2100 || self.y > 2800 || self.y < -50) { self.destroy(); projectiles.splice(projectiles.indexOf(self), 1); } }; self.explode = function () { // Explosion animation tween(self.graphics, { tint: 0xFF0000, scaleX: 4, scaleY: 4 }, { duration: 300, onFinish: function onFinish() { // Damage all plants in explosion radius for (var i = plants.length - 1; i >= 0; i--) { var plant = plants[i]; var dx = plant.x - self.x; var dy = plant.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance <= self.explosionRadius) { plant.takeDamage(self.damage); } } LK.getSound('explosion').play(); self.destroy(); projectiles.splice(projectiles.indexOf(self), 1); } }); }; return self; }); var Zombie = Container.expand(function (type, lane) { var self = Container.call(this); self.type = type; self.lane = lane; self.id = Math.random().toString(36).substr(2, 9); // Generate unique ID self.speed = 1; self.health = 100; self.maxHealth = 100; self.damage = 25; self.attackCooldown = 60; self.attackTimer = 0; self.isAttacking = false; if (type === 'basic') { self.graphics = self.attachAsset('basicZombie', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 0.5; self.health = 215; self.maxHealth = 215; } else if (type === 'fast') { self.graphics = self.attachAsset('fastZombie', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 1.2; self.health = 215; self.maxHealth = 215; } else if (type === 'tank') { self.graphics = self.attachAsset('tankZombie', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 0.3; self.health = 500; self.maxHealth = 500; self.damage = 50; self.shootTimer = 0; self.shootCooldown = 300; // 5 seconds at 60fps } self.x = 2048 + 50; // Start off-screen right self.y = 300 + lane * 250; // Position in lane // Play zombie sound when spawned LK.getSound('zombie').play(); self.update = function () { if (!self.isAttacking) { self.x -= self.speed; // Walking animation - bob up and down if (self.type === 'basic') { // Slower walking animation for basic zombie if (LK.ticks % 40 < 20) { tween(self.graphics, { y: 5 }, { duration: 200 }); } else { tween(self.graphics, { y: -5 }, { duration: 200 }); } } else if (self.type === 'fast') { // Faster walking animation for fast zombie if (LK.ticks % 20 < 10) { tween(self.graphics, { y: 8 }, { duration: 100 }); } else { tween(self.graphics, { y: -8 }, { duration: 100 }); } } else if (self.type === 'tank') { // Slow heavy walking animation for tank zombie if (LK.ticks % 60 < 30) { tween(self.graphics, { y: 3 }, { duration: 300 }); } else { tween(self.graphics, { y: -3 }, { duration: 300 }); } } // Tank zombie shooting logic if (self.type === 'tank') { self.shootTimer++; if (self.shootTimer >= self.shootCooldown) { var target = self.findPlantInLane(); if (target) { var tankProjectile = new TankProjectile(self.x, self.y, target); projectiles.push(tankProjectile); game.addChild(tankProjectile); LK.getSound('shoot').play(); } self.shootTimer = 0; } } // Check for plant collision var plantInWay = self.findPlantInWay(); if (plantInWay) { self.isAttacking = true; self.attackTimer = 0; } } else { self.attackTimer++; if (self.attackTimer >= self.attackCooldown) { var plantInWay = self.findPlantInWay(); if (plantInWay) { plantInWay.takeDamage(self.damage); self.attackTimer = 0; } else { self.isAttacking = false; } } } // Check if reached end if (self.x < -50) { zombiesReachedEnd++; self.destroy(); zombies.splice(zombies.indexOf(self), 1); } }; self.findPlantInWay = function () { for (var i = 0; i < plants.length; i++) { var plant = plants[i]; if (Math.abs(plant.x - self.x) < 80 && Math.abs(plant.y - self.y) < 80) { return plant; } } return null; }; self.findPlantInLane = function () { for (var i = 0; i < plants.length; i++) { var plant = plants[i]; // Check if plant is in same lane (within 100px vertically) and to the left if (Math.abs(plant.y - self.y) < 100 && plant.x < self.x) { return plant; } } return null; }; self.takeDamage = function (damage) { self.health -= damage; LK.getSound('zombieHit').play(); // Visual feedback tween(self.graphics, { tint: 0xFF0000 }, { duration: 200 }); tween(self.graphics, { tint: 0xFFFFFF }, { duration: 200 }); if (self.health <= 0) { // Give points based on zombie type if (self.type === 'tank') { LK.setScore(LK.getScore() + 450); zombiesKilled++; } else { zombiesKilled++; } scoreText.setText('Score: ' + LK.getScore()); // Clean up shots tracking for all plants for (var p = 0; p < plants.length; p++) { if (plants[p].shotsFired && plants[p].shotsFired[self.id]) { delete plants[p].shotsFired[self.id]; } } self.destroy(); zombies.splice(zombies.indexOf(self), 1); } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2E7D32 }); /**** * Game Code ****/ // Sounds // Grid and UI // Projectiles // Zombies // Plants // Game variables var plants = []; var zombies = []; var projectiles = []; var plantButtons = []; var gridCells = []; var selectedPlantType = null; var waveNumber = 1; var zombiesInWave = 5; var zombieSpawnTimer = 0; var zombieSpawnInterval = 120; // 2 seconds var zombiesSpawned = 0; var zombiesReachedEnd = 0; var maxZombiesAllowed = 5; var gameState = 'playing'; // 'playing', 'gameOver', 'victory' var autoPointTimer = 0; var autoPointInterval = 420; // 7 seconds at 60fps (7 * 60 = 420) var zombiesKilled = 0; // UI Elements // Set initial score to 100 LK.setScore(100); var scoreText = new Text2('Score: ' + LK.getScore(), { size: 40, fill: '#FFFFFF' }); scoreText.anchor.set(0, 0); scoreText.x = 150; scoreText.y = 20; LK.gui.topLeft.addChild(scoreText); var waveText = new Text2('Wave: 1', { size: 40, fill: '#FFFFFF' }); waveText.anchor.set(0.5, 0); waveText.x = 1024; waveText.y = 20; LK.gui.top.addChild(waveText); var livesText = new Text2('Lives: 5', { size: 40, fill: '#FF0000' }); livesText.anchor.set(1, 0); livesText.x = 1900; livesText.y = 20; LK.gui.topRight.addChild(livesText); // Create plant selection buttons var plantTypes = ['sunflower', 'peashooter', 'wallnut', 'cherrybomb', 'shovel']; for (var i = 0; i < plantTypes.length; i++) { var button = new PlantButton(plantTypes[i], i); plantButtons.push(button); game.addChild(button); } // Create grid - scale to use full screen var gridStartX = 150; var gridStartY = 300; var gridRows = 5; var gridCols = 8; for (var row = 0; row < gridRows; row++) { gridCells[row] = []; for (var col = 0; col < gridCols; col++) { var cell = LK.getAsset('gridCell', { anchorX: 0.5, anchorY: 0.5, alpha: 0.3 }); cell.x = gridStartX + col * 200; cell.y = gridStartY + row * 250; cell.row = row; cell.col = col; cell.occupied = false; gridCells[row][col] = cell; game.addChild(cell); } } // Game event handlers game.down = function (x, y, obj) { if (!selectedPlantType) return; // Check if clicking on grid for (var row = 0; row < gridRows; row++) { for (var col = 0; col < gridCols; col++) { var cell = gridCells[row][col]; if (Math.abs(x - cell.x) < 80 && Math.abs(y - cell.y) < 80) { // Check for fusion - peashooter + peashooter or sunflower + peashooter if (cell.occupied && (selectedPlantType === 'peashooter' || selectedPlantType === 'sunflower')) { // Find existing plant at this position var existingPlant = null; for (var p = 0; p < plants.length; p++) { if (Math.abs(plants[p].x - cell.x) < 40 && Math.abs(plants[p].y - cell.y) < 40) { existingPlant = plants[p]; break; } } // Peashooter + Peashooter = Double Peashooter if (existingPlant && existingPlant.type === 'peashooter' && selectedPlantType === 'peashooter') { var cost = 10; if (LK.getScore() < cost) { return; // Not enough points } // Remove existing peashooter existingPlant.destroy(); plants.splice(plants.indexOf(existingPlant), 1); // Create double peashooter var fusedPlant = new Plant('doublepeashooter'); fusedPlant.x = cell.x; fusedPlant.y = cell.y; plants.push(fusedPlant); game.addChild(fusedPlant); LK.setScore(LK.getScore() - cost); scoreText.setText('Score: ' + LK.getScore()); LK.getSound('plantPlace').play(); // Fusion animation tween(fusedPlant.graphics, { scaleX: 1.5, scaleY: 1.5, tint: 0x00FF00 }, { duration: 300, onFinish: function onFinish() { tween(fusedPlant.graphics, { scaleX: 1, scaleY: 1, tint: 0xFFFFFF }, { duration: 200 }); } }); // Reset selection selectedPlantType = null; for (var i = 0; i < plantButtons.length; i++) { plantButtons[i].button.tint = 0xFFFFFF; } return; } // Sunflower + Sunflower = Double Sunflower else if (existingPlant && existingPlant.type === 'sunflower' && selectedPlantType === 'sunflower') { var cost = 15; if (LK.getScore() < cost) { return; // Not enough points } // Remove existing sunflower existingPlant.destroy(); plants.splice(plants.indexOf(existingPlant), 1); // Create double sunflower var fusedPlant = new Plant('doublesunflower'); fusedPlant.x = cell.x; fusedPlant.y = cell.y; plants.push(fusedPlant); game.addChild(fusedPlant); LK.setScore(LK.getScore() - cost); scoreText.setText('Score: ' + LK.getScore()); LK.getSound('plantPlace').play(); // Golden fusion animation for double sun production tween(fusedPlant.graphics, { scaleX: 1.5, scaleY: 1.5, tint: 0xFFFF00 }, { duration: 300, onFinish: function onFinish() { tween(fusedPlant.graphics, { scaleX: 1, scaleY: 1, tint: 0xFFFFFF }, { duration: 200 }); } }); // Reset selection selectedPlantType = null; for (var i = 0; i < plantButtons.length; i++) { plantButtons[i].button.tint = 0xFFFFFF; } return; } // Sunflower + Peashooter = Point Shooter else if (existingPlant && (existingPlant.type === 'sunflower' && selectedPlantType === 'peashooter' || existingPlant.type === 'peashooter' && selectedPlantType === 'sunflower')) { var cost = selectedPlantType === 'peashooter' ? 10 : 15; if (LK.getScore() < cost) { return; // Not enough points } // Remove existing plant existingPlant.destroy(); plants.splice(plants.indexOf(existingPlant), 1); // Create point shooter var fusedPlant = new Plant('pointshooter'); fusedPlant.x = cell.x; fusedPlant.y = cell.y; plants.push(fusedPlant); game.addChild(fusedPlant); LK.setScore(LK.getScore() - cost); scoreText.setText('Score: ' + LK.getScore()); LK.getSound('plantPlace').play(); // Golden fusion animation tween(fusedPlant.graphics, { scaleX: 1.5, scaleY: 1.5, tint: 0xFFD700 }, { duration: 300, onFinish: function onFinish() { tween(fusedPlant.graphics, { scaleX: 1, scaleY: 1, tint: 0xFFFFFF }, { duration: 200 }); } }); // Reset selection selectedPlantType = null; for (var i = 0; i < plantButtons.length; i++) { plantButtons[i].button.tint = 0xFFFFFF; } return; } } // Handle shovel selection - remove existing plant if (selectedPlantType === 'shovel' && cell.occupied) { // Find and remove the plant at this position for (var p = plants.length - 1; p >= 0; p--) { if (Math.abs(plants[p].x - cell.x) < 40 && Math.abs(plants[p].y - cell.y) < 40) { plants[p].destroy(); plants.splice(p, 1); // Make sure to update the grid cell's occupied status gridCells[row][col].occupied = false; break; } } // Reset selection selectedPlantType = null; for (var i = 0; i < plantButtons.length; i++) { plantButtons[i].button.tint = 0xFFFFFF; } return; } if (!cell.occupied && selectedPlantType !== 'shovel') { var cost = 0; if (selectedPlantType === 'peashooter') cost = 10; if (selectedPlantType === 'sunflower') cost = 15; if (selectedPlantType === 'wallnut') cost = 20; if (selectedPlantType === 'cherrybomb') cost = 50; if (LK.getScore() < cost) { return; // Not enough points } var plant = new Plant(selectedPlantType); plant.x = cell.x; plant.y = cell.y; plants.push(plant); game.addChild(plant); // Update grid cell occupied status using row/col indices gridCells[row][col].occupied = true; if (cost > 0) { LK.setScore(LK.getScore() - cost); scoreText.setText('Score: ' + LK.getScore()); } LK.getSound('plantPlace').play(); // Reset selection selectedPlantType = null; for (var i = 0; i < plantButtons.length; i++) { plantButtons[i].button.tint = 0xFFFFFF; } return; } } } } }; function spawnZombie() { if (zombiesSpawned >= zombiesInWave) return; var lane = Math.floor(Math.random() * gridRows); var zombieTypes = ['basic', 'fast']; var type = zombieTypes[Math.floor(Math.random() * zombieTypes.length)]; // Tank zombies appear after 50 zombies killed if (zombiesKilled >= 50) { zombieTypes = ['basic', 'fast', 'tank']; } // Increase difficulty with wave number if (waveNumber > 3) { type = zombieTypes[Math.floor(Math.random() * zombieTypes.length)]; } else if (waveNumber > 1) { type = Math.random() < 0.7 ? 'basic' : 'fast'; } else { type = 'basic'; } var zombie = new Zombie(type, lane); zombies.push(zombie); game.addChild(zombie); zombiesSpawned++; } function checkWaveComplete() { if (zombiesSpawned >= zombiesInWave && zombies.length === 0) { // Wave complete waveNumber++; zombiesInWave += 2; zombiesSpawned = 0; waveText.setText('Wave: ' + waveNumber); if (waveNumber > 10) { gameState = 'victory'; LK.showYouWin(); } } } function checkGameOver() { if (zombiesReachedEnd >= 1) { gameState = 'gameOver'; LK.showGameOver(); } livesText.setText('Lives: ' + (maxZombiesAllowed - zombiesReachedEnd)); } // Main game loop game.update = function () { if (gameState !== 'playing') return; // Auto point generation - 7 points every 7 seconds autoPointTimer++; if (autoPointTimer >= autoPointInterval) { LK.setScore(LK.getScore() + 7); scoreText.setText('Score: ' + LK.getScore()); autoPointTimer = 0; } // Spawn zombies zombieSpawnTimer++; if (zombieSpawnTimer >= zombieSpawnInterval) { spawnZombie(); zombieSpawnTimer = 0; } // Update all objects for (var i = plants.length - 1; i >= 0; i--) { if (plants[i].update) { plants[i].update(); } } for (var i = zombies.length - 1; i >= 0; i--) { if (zombies[i].update) { zombies[i].update(); } } for (var i = projectiles.length - 1; i >= 0; i--) { if (projectiles[i].update) { projectiles[i].update(); } } checkWaveComplete(); checkGameOver(); };
===================================================================
--- original.js
+++ change.js
@@ -878,9 +878,10 @@
for (var p = plants.length - 1; p >= 0; p--) {
if (Math.abs(plants[p].x - cell.x) < 40 && Math.abs(plants[p].y - cell.y) < 40) {
plants[p].destroy();
plants.splice(p, 1);
- cell.occupied = false;
+ // Make sure to update the grid cell's occupied status
+ gridCells[row][col].occupied = false;
break;
}
}
// Reset selection
@@ -903,9 +904,10 @@
plant.x = cell.x;
plant.y = cell.y;
plants.push(plant);
game.addChild(plant);
- cell.occupied = true;
+ // Update grid cell occupied status using row/col indices
+ gridCells[row][col].occupied = true;
if (cost > 0) {
LK.setScore(LK.getScore() - cost);
scoreText.setText('Score: ' + LK.getScore());
}
Zombie básico del videojuego plantas vs zombies. In-Game asset. No shadows
Un lanza guisantes del videojuego plantas vs zombies. In-Game asset. No shadows
Fast zombie del videojuego plantas vs zombies. In-Game asset. No shadows
Cherrybomb del videojuego plantas vs zombies. In-Game asset. No shadows
Girasol de juego plantas vs zombies. In-Game asset
doublepeashooter del juego plantas vs zombies fusion. In-Game asset. No shadows
Un lanza guisantes fusionado cun un girasol de plantas vs zombies fusion. In-Game asset. No shadows
Cuadro rojo con azul para seleccionar algo. In-Game asset. No shadows
Wallnut del videojuego plantas vs zombies. In-Game asset. No shadows
Tank zombie del juego plantas vs zombies. In-Game asset. No shadows
Cuadrado de cesped con flores visto desde arriba. In-Game asset. No shadows
Shovel de plantas vs zombies. In-Game asset. 2d. No shadows
wallnutDamaged del videojuego de plantas vs zombies. In-Game asset. 2d. No shadows
doublesunflower de plantas vs zombies fusion. In-Game asset. 2d. No shadows
Una fusion del wallnut de plantas vs zombies con el lanza guisantes. In-Game asset. No shadows
Papapum de plantas vs zombies que sea tierna. In-Game asset. No shadows
explosivewallnut de plantas vs zombies fusion. In-Game asset. 2d. High contrast
explosivepeashooter de plantas vs zombie fusion. In-Game asset. 2d. High contrast
Triple girasol de plantas vs zombies. In-Game asset. 2d. High contrast
Triple lanza guisantes del videojuego plantas vs zombies fusion con cascos militares y boca de metralletas. In-Game asset. 2d. High contrast
Strong zombie de plantas vs zombies. In-Game asset. 2d. High contrast. No shadows
Crazy Dave del juego plantas vs zombies con cara alegre y con una pelota desinflada en la cabeza. In-Game asset. 2d. High contrast
Planta piraña de plantas vs zombies. In-Game asset. 2d. High contrast. No shadows
Piraña explosiva del plantas vs zombies. In-Game asset. 2d. High contrast