User prompt
que la cantidad de zombies sean mil y que no alla tiempo limite
User prompt
no se supone que esta la sinta transportadora que siempre te dara nueces y con las nueces se las tiraras alos zombies ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
as que en el nivel 5 alla un minijuego estilo bolera con las nueses ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
añade minijuegos
User prompt
porque cuando te vas de los niveles de noche las plantas de la noche siguen hay?
User prompt
solucionalo
User prompt
as que el zombie lector pueda comer al estar enojado y que la probavilidad de que el lanzamais lanse mantequilla sea del 25 porciento
User prompt
no pero as un nuevo asset para el maiz y la mantequilla
User prompt
as que el lanza maiz dispare maiz que aleatoriamente lanse mantequilla que realentisa al enemigo por 10 segundos ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
as que siempre te de 1 maseta en la sinta transportadora y 2 plantas random
User prompt
as que siempre te de 1 maseta en la sinta transportadora y que las semillas no aparescan
User prompt
as que la transportadora pueda darte 3 plantas
User prompt
as un asset diferente para el zombiestain
User prompt
pero que la bola de fuego salga de la boca del jefe y que luego valla a donde se apunto ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
as que la bola de fuego aparesca de la boca de fuego y que no aparescan lapidas en la boss fight ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
as que solo dispare una bola de fuego
User prompt
as que el boss dispare en un lugar random y que las plantas lo puedan atacar ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
as la vida del jefe en la parde de abajo izquierda y que aparesca un circulo rojo en el lugar donde iba a caer la bola de fuego ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
as que la cinta transportadora me de todo menos productores de sol
User prompt
no estas haciendo nada no puedo poner la planta que me da pa cinta transportadora!
User prompt
as que me deje poner la planta de la sinta transportadora ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
as que se muestre en la sinta la planta
User prompt
puedes arreglarlo?
User prompt
no me deja poner plantas
User prompt
pues arreglalo ↪💡 Consider importing and using the following plugins: @upit/tween.v1
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var ConveyorBelt = Container.expand(function () { var self = Container.call(this); var beltGraphics = self.attachAsset('conveyorBelt', { anchorX: 0.5, anchorY: 0.5 }); self.seedTimer = 0; self.seedGenerateRate = 600; // 10 seconds at 60fps // Available seeds for boss level - excluding sun producers (sunflower, sunshroom) self.availableSeeds = ['wallnut', 'carnivorousplant', 'doomshroom', 'melonpulta', 'coltapulta', 'lanzamaiz']; // Create text display for seed feedback var seedText = new Text2('', { size: 40, fill: 0xFFFFFF }); seedText.anchor.set(0.5, 0.5); seedText.x = 0; seedText.y = -60; // Above the conveyor belt seedText.alpha = 0; // Start invisible self.addChild(seedText); // Create plant display on conveyor belt var plantDisplay = null; // Will hold the current plant image self.update = function () { self.seedTimer++; if (self.seedTimer >= self.seedGenerateRate) { self.seedTimer = 0; // Generate 3 different random seeds var generatedSeeds = []; for (var i = 0; i < 3; i++) { var randomSeed = self.availableSeeds[Math.floor(Math.random() * self.availableSeeds.length)]; generatedSeeds.push(randomSeed); // Reset cooldown for this seed type - properly reset it seedCooldowns[randomSeed] = 0; } // Automatically select the first plant type for placement selectedPlantType = generatedSeeds[0]; shovelSelected = false; // Remove previous plant display if it exists if (plantDisplay) { plantDisplay.destroy(); plantDisplay = null; } // Create display for all 3 plants side by side var plantDisplays = []; for (var j = 0; j < generatedSeeds.length; j++) { var plantSeed = generatedSeeds[j]; var display = LK.getAsset(plantSeed, { anchorX: 0.5, anchorY: 0.5, scaleX: 0.6, scaleY: 0.6, alpha: 0 }); display.x = (j - 1) * 100; // Space them out: -100, 0, 100 display.y = 0; self.addChild(display); plantDisplays.push(display); } // Show clear text feedback of which seeds were given var seedNames = []; for (var k = 0; k < generatedSeeds.length; k++) { var seedName = generatedSeeds[k].toUpperCase(); if (generatedSeeds[k] === 'carnivorousplant') seedName = 'CARNIVOROUS PLANT'; if (generatedSeeds[k] === 'doomshroom') seedName = 'DOOM SHROOM'; if (generatedSeeds[k] === 'melonpulta') seedName = 'MELON PULTA'; if (generatedSeeds[k] === 'coltapulta') seedName = 'COL TAPULTA'; if (generatedSeeds[k] === 'lanzamaiz') seedName = 'LANZA MAIZ'; seedNames.push(seedName); } seedText.setText('3 SEEDS: ' + seedNames.join(', ') + '!'); // Show plant images with fade in animation for (var l = 0; l < plantDisplays.length; l++) { tween(plantDisplays[l], { alpha: 1, scaleX: 0.8, scaleY: 0.8 }, { duration: 300, easing: tween.easeOut }); } // Show text with fade in animation tween(seedText, { alpha: 1, scaleX: 1.2, scaleY: 1.2 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { // Keep text visible for 3 seconds, then fade out tween(seedText, { alpha: 0, scaleX: 1, scaleY: 1 }, { duration: 1500, easing: tween.easeIn }); } }); // Fade out plant displays after 4 seconds LK.setTimeout(function () { for (var m = 0; m < plantDisplays.length; m++) { if (plantDisplays[m]) { tween(plantDisplays[m], { alpha: 0, scaleX: 0.4, scaleY: 0.4 }, { duration: 1000, easing: tween.easeIn, onFinish: function onFinish() { if (plantDisplays[m]) { plantDisplays[m].destroy(); } } }); } } }, 4000); // Visual flash effect to show seeds were given tween(self, { scaleX: 1.2, scaleY: 1.2, tint: 0x00ff00 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { scaleX: 1, scaleY: 1, tint: 0xffffff }, { duration: 300, easing: tween.easeIn }); } }); } }; return self; }); var Fireball = Container.expand(function () { var self = Container.call(this); var fireballGraphics = self.attachAsset('fireball', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -6; self.damage = 50; self.update = function () { // Use trajectory-based movement if speed components are set, otherwise use default if (self.speedX !== undefined && self.speedY !== undefined) { self.x += self.speedX; self.y += self.speedY; } else { self.x += self.speed; } self.rotation += 0.2; // Spinning effect // Fireball trail effect if (LK.ticks % 5 === 0) { tween(self, { tint: 0xff8c00 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { tint: 0xff4500 }, { duration: 100, easing: tween.easeIn }); } }); } // Check if fireball is off-screen (expanded bounds for trajectory-based movement) if (self.x < -100 || self.x > 2200 || self.y < -100 || self.y > 2800) { self.destroy(); } }; return self; }); var Lawnmower = Container.expand(function () { var self = Container.call(this); var lawnmowerGraphics = self.attachAsset('lawnmower', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 0; // Starts stationary self.activated = false; self.update = function () { if (self.activated) { self.x += 12; // Move fast when activated if (self.x > 2200) { self.destroy(); } } }; return self; }); var LevelButton = Container.expand(function (levelNumber) { var self = Container.call(this); // Level button background var buttonBg = LK.getAsset('gridCell', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.2, scaleY: 1.2 }); self.addChild(buttonBg); // Level number text var levelText = new Text2(levelNumber.toString(), { size: 60, fill: 0x000000 }); levelText.anchor.set(0.5, 0.5); self.addChild(levelText); self.levelNumber = levelNumber; self.down = function (x, y, obj) { // Start the selected level startLevel(self.levelNumber); }; return self; }); var LoadingScreen = Container.expand(function () { var self = Container.call(this); // Loading logo image var loadingLogo = self.attachAsset('loadingLogo', { anchorX: 0.5, anchorY: 0.5 }); loadingLogo.x = 1024; loadingLogo.y = 800; // Loading bar background var loadingBarBg = self.attachAsset('loadingBarBg', { anchorX: 0.5, anchorY: 0.5 }); loadingBarBg.x = 1024; loadingBarBg.y = 1400; // Loading bar fill var loadingBar = self.attachAsset('loadingBar', { anchorX: 0, anchorY: 0.5 }); loadingBar.x = 724; // Start at left edge of background loadingBar.y = 1400; loadingBar.width = 0; // Start with no fill // Loading text var loadingText = new Text2('CARGANDO...', { size: 80, fill: 0xFFFFFF }); loadingText.anchor.set(0.5, 0.5); loadingText.x = 1024; loadingText.y = 1200; self.addChild(loadingText); // Progress text var progressText = new Text2('0%', { size: 60, fill: 0xFFFFFF }); progressText.anchor.set(0.5, 0.5); progressText.x = 1024; progressText.y = 1500; self.addChild(progressText); self.progress = 0; self.maxProgress = 300; // 5 seconds at 60fps self.currentProgress = 0; self.update = function () { if (self.currentProgress < self.maxProgress) { self.currentProgress++; self.progress = self.currentProgress / self.maxProgress; // Update loading bar width loadingBar.width = 600 * self.progress; // Update progress text var percentage = Math.floor(self.progress * 100); progressText.setText(percentage + '%'); // Loading complete if (self.currentProgress >= self.maxProgress) { // Transition to level selection showLevelSelection(); } } }; return self; }); var Pea = Container.expand(function () { var self = Container.call(this); var peaGraphics = self.attachAsset('pea', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 8; self.damage = 20; self.update = function () { self.x += self.speed; if (self.x > 2200) { self.destroy(); } }; return self; }); var Plant = Container.expand(function (type) { var self = Container.call(this); self.type = type; self.health = 100; self.maxHealth = 100; self.shootCooldown = 0; self.sunTimer = 0; var plantGraphics; if (type === 'sunflower') { plantGraphics = self.attachAsset('sunflower', { anchorX: 0.5, anchorY: 0.5 }); self.sunGenerateRate = 300; // ticks between sun generation } else if (type === 'peashooter') { plantGraphics = self.attachAsset('peashooter', { anchorX: 0.5, anchorY: 0.5 }); self.shootRate = 90; // ticks between shots } else if (type === 'wallnut') { plantGraphics = self.attachAsset('wallnut', { anchorX: 0.5, anchorY: 0.5 }); self.health = 300; self.maxHealth = 300; } else if (type === 'potatomine') { plantGraphics = self.attachAsset('potatomine', { anchorX: 0.5, anchorY: 0.5 }); self.health = 50; self.maxHealth = 50; self.exploded = false; } else if (type === 'carnivorousplant') { plantGraphics = self.attachAsset('carnivorousplant', { anchorX: 0.5, anchorY: 0.5 }); self.health = 200; self.maxHealth = 200; self.attackCooldown = 0; self.attackRange = 100; } else if (type === 'doomshroom') { plantGraphics = self.attachAsset('doomshroom', { anchorX: 0.5, anchorY: 0.5 }); self.health = 100; self.maxHealth = 100; self.exploded = false; self.armingTime = 900; // 15 seconds to arm self.currentArmingTime = 0; } else if (type === 'repeater') { plantGraphics = self.attachAsset('repeater', { anchorX: 0.5, anchorY: 0.5 }); self.shootRate = 90; // Same as peashooter } else if (type === 'threepeater') { plantGraphics = self.attachAsset('threepeater', { anchorX: 0.5, anchorY: 0.5 }); self.shootRate = 120; // Slightly slower due to triple shot } else if (type === 'spikeweed') { plantGraphics = self.attachAsset('spikeweed', { anchorX: 0.5, anchorY: 0.5 }); self.health = 300; self.maxHealth = 300; } else if (type === 'splitpeater') { plantGraphics = self.attachAsset('splitpeater', { anchorX: 0.5, anchorY: 0.5 }); self.shootRate = 120; // Similar to threepeater } else if (type === 'lilypad') { plantGraphics = self.attachAsset('lilypad', { anchorX: 0.5, anchorY: 0.5 }); self.health = 50; self.maxHealth = 50; } else if (type === 'puffshroom') { plantGraphics = self.attachAsset('puffshroom', { anchorX: 0.5, anchorY: 0.5 }); self.shootRate = 60; // Faster than peashooter but shorter range self.range = 300; // Limited range } else if (type === 'sunshroom') { plantGraphics = self.attachAsset('sunshroom', { anchorX: 0.5, anchorY: 0.5 }); self.sunGenerateRate = 150; // Faster than sunflower but produces less self.sunValue = 15; // Produces less sun than sunflower } else if (type === 'fumeshroom') { plantGraphics = self.attachAsset('fumeshroom', { anchorX: 0.5, anchorY: 0.5 }); self.shootRate = 120; // Slower but affects multiple zombies } else if (type === 'gravebuster') { plantGraphics = self.attachAsset('gravebuster', { anchorX: 0.5, anchorY: 0.5 }); self.health = 1; // Dies after one use self.maxHealth = 1; } else if (type === 'hypnoshroom') { plantGraphics = self.attachAsset('hypnoshroom', { anchorX: 0.5, anchorY: 0.5 }); self.health = 50; self.maxHealth = 50; } else if (type === 'scaredyshroom') { plantGraphics = self.attachAsset('scaredyshroom', { anchorX: 0.5, anchorY: 0.5 }); self.shootRate = 60; } else if (type === 'iceshroom') { plantGraphics = self.attachAsset('iceshroom', { anchorX: 0.5, anchorY: 0.5 }); self.health = 1; self.maxHealth = 1; } else if (type === 'melonpulta') { plantGraphics = self.attachAsset('melonpulta', { anchorX: 0.5, anchorY: 0.5 }); self.shootRate = 180; // Slower but more powerful self.projectileDamage = 80; // High damage } else if (type === 'coltapulta') { plantGraphics = self.attachAsset('coltapulta', { anchorX: 0.5, anchorY: 0.5 }); self.shootRate = 240; // Slower rate self.projectileDamage = 60; // Medium damage } else if (type === 'lanzamaiz') { plantGraphics = self.attachAsset('lanzamaiz', { anchorX: 0.5, anchorY: 0.5 }); self.shootRate = 150; // Fast rate self.projectileDamage = 40; // Lower damage but faster } else if (type === 'pot') { plantGraphics = self.attachAsset('pot', { anchorX: 0.5, anchorY: 0.5 }); self.health = 50; self.maxHealth = 50; } self.takeDamage = function (damage) { self.health -= damage; if (self.health <= 0) { self.destroy(); return true; } return false; }; self.update = function () { if (self.type === 'sunflower') { self.sunTimer++; if (self.sunTimer >= self.sunGenerateRate) { self.sunTimer = 0; var newSun = new Sun(); newSun.x = self.x + Math.random() * 40 - 20; newSun.y = self.y + Math.random() * 40 - 20; game.addChild(newSun); suns.push(newSun); } } else if (self.type === 'peashooter') { self.shootCooldown++; if (self.shootCooldown >= self.shootRate) { // Check if there's a zombie in this row var myRow = Math.floor((self.y - 500) / 140); var hasZombieInRow = false; for (var i = 0; i < zombies.length; i++) { var zombie = zombies[i]; var zombieRow = Math.floor((zombie.y - 500) / 140); if (zombieRow === myRow && zombie.x > self.x) { hasZombieInRow = true; break; } } if (hasZombieInRow) { self.shootCooldown = 0; // Fisheye shooting effect tween(self, { scaleX: 1.3, scaleY: 0.7 }, { duration: 150, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 150, easing: tween.easeIn }); } }); var pea = new Pea(); pea.x = self.x + 60; pea.y = self.y; game.addChild(pea); peas.push(pea); LK.getSound('shoot').play(); } } } else if (self.type === 'repeater') { self.shootCooldown++; if (self.shootCooldown >= self.shootRate) { // Check if there's a zombie in this row var myRow = Math.floor((self.y - 500) / 140); var hasZombieInRow = false; for (var i = 0; i < zombies.length; i++) { var zombie = zombies[i]; var zombieRow = Math.floor((zombie.y - 500) / 140); if (zombieRow === myRow && zombie.x > self.x) { hasZombieInRow = true; break; } } if (hasZombieInRow) { self.shootCooldown = 0; // Fisheye shooting effect tween(self, { scaleX: 1.3, scaleY: 0.7 }, { duration: 150, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 150, easing: tween.easeIn }); } }); // Shoot two peas with slight delay var pea1 = new Pea(); pea1.x = self.x + 60; pea1.y = self.y; game.addChild(pea1); peas.push(pea1); // Second pea with slight delay LK.setTimeout(function () { var pea2 = new Pea(); pea2.x = self.x + 60; pea2.y = self.y; game.addChild(pea2); peas.push(pea2); }, 150); LK.getSound('shoot').play(); } } } else if (self.type === 'threepeater') { self.shootCooldown++; if (self.shootCooldown >= self.shootRate) { // Check if there's a zombie in any of the three rows (current, above, below) var myRow = Math.floor((self.y - 500) / 140); var hasZombieInAnyRow = false; for (var i = 0; i < zombies.length; i++) { var zombie = zombies[i]; var zombieRow = Math.floor((zombie.y - 500) / 140); if ((zombieRow === myRow || zombieRow === myRow - 1 || zombieRow === myRow + 1) && zombie.x > self.x) { hasZombieInAnyRow = true; break; } } if (hasZombieInAnyRow) { self.shootCooldown = 0; // Fisheye shooting effect tween(self, { scaleX: 1.3, scaleY: 0.7 }, { duration: 150, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 150, easing: tween.easeIn }); } }); // Shoot three peas - center, above, below var centerPea = new Pea(); centerPea.x = self.x + 60; centerPea.y = self.y; game.addChild(centerPea); peas.push(centerPea); // Above pea (if row exists) if (myRow > 0) { var abovePea = new Pea(); abovePea.x = self.x + 60; abovePea.y = self.y - 140; game.addChild(abovePea); peas.push(abovePea); } // Below pea (if row exists) if (myRow < gridRows - 1) { var belowPea = new Pea(); belowPea.x = self.x + 60; belowPea.y = self.y + 140; game.addChild(belowPea); peas.push(belowPea); } LK.getSound('shoot').play(); } } } else if (self.type === 'potatomine' && !self.exploded) { // Check for zombies stepping on the mine var myRow = Math.floor((self.y - 500) / 140); for (var i = 0; i < zombies.length; i++) { var zombie = zombies[i]; var zombieRow = Math.floor((zombie.y - 500) / 140); if (zombieRow === myRow && Math.abs(self.x - zombie.x) < 80) { // Explode! self.exploded = true; LK.getSound('explode').play(); // Create explosion visual effect tween(self, { scaleX: 3, scaleY: 3, alpha: 0 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { for (var k = plants.length - 1; k >= 0; k--) { if (plants[k] === self) { plants.splice(k, 1); self.destroy(); break; } } } }); LK.effects.flashObject(self, 0xFF4500, 500); // Damage all zombies in the area for (var j = zombies.length - 1; j >= 0; j--) { var targetZombie = zombies[j]; var distance = Math.sqrt(Math.pow(self.x - targetZombie.x, 2) + Math.pow(self.y - targetZombie.y, 2)); if (distance < 120) { if (targetZombie.takeDamage(200)) { targetZombie.destroy(); zombies.splice(j, 1); } } } break; } } } else if (self.type === 'carnivorousplant') { self.attackCooldown++; if (self.attackCooldown >= 180) { // Attack every 3 seconds var myRow = Math.floor((self.y - 500) / 140); var closestZombie = null; var closestDistance = Infinity; for (var i = 0; i < zombies.length; i++) { var zombie = zombies[i]; var zombieRow = Math.floor((zombie.y - 500) / 140); if (zombieRow === myRow) { var distance = Math.abs(self.x - zombie.x); if (distance < self.attackRange && distance < closestDistance) { closestDistance = distance; closestZombie = zombie; } } } if (closestZombie) { self.attackCooldown = 0; // Attack animation tween(self, { scaleX: 1.5, scaleY: 1.5 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 200, easing: tween.easeIn }); } }); if (closestZombie.takeDamage(100)) { for (var j = zombies.length - 1; j >= 0; j--) { if (zombies[j] === closestZombie) { closestZombie.destroy(); zombies.splice(j, 1); break; } } } } } } else if (self.type === 'doomshroom' && !self.exploded) { self.currentArmingTime++; if (self.currentArmingTime >= self.armingTime) { // Doom shroom is now armed and explodes self.exploded = true; LK.getSound('explode').play(); // Create massive explosion visual effect tween(self, { scaleX: 8, scaleY: 8, alpha: 0 }, { duration: 1000, easing: tween.easeOut, onFinish: function onFinish() { for (var k = plants.length - 1; k >= 0; k--) { if (plants[k] === self) { plants.splice(k, 1); self.destroy(); break; } } } }); LK.effects.flashScreen(0x4B0082, 1000); // Damage all zombies on screen for (var j = zombies.length - 1; j >= 0; j--) { var targetZombie = zombies[j]; if (targetZombie.takeDamage(300)) { targetZombie.destroy(); zombies.splice(j, 1); } } } } else if (self.type === 'spikeweed') { // Damage zombies walking over spikeweed - but don't stop them var myRow = Math.floor((self.y - 500) / 140); for (var i = 0; i < zombies.length; i++) { var zombie = zombies[i]; var zombieRow = Math.floor((zombie.y - 500) / 140); if (zombieRow === myRow && Math.abs(self.x - zombie.x) < 70) { // Only damage zombie if it hasn't been damaged by this spikeweed recently if (!zombie.lastSpikeweeedDamageTime || LK.ticks - zombie.lastSpikeweeedDamageTime > 30) { zombie.lastSpikeweeedDamageTime = LK.ticks; if (zombie.takeDamage(20)) { for (var j = zombies.length - 1; j >= 0; j--) { if (zombies[j] === zombie) { zombie.destroy(); zombies.splice(j, 1); break; } } } // Damage spikeweed when used if (self.takeDamage(1)) { for (var k = plants.length - 1; k >= 0; k--) { if (plants[k] === self) { plants.splice(k, 1); self.destroy(); break; } } } } } } } else if (self.type === 'splitpeater') { self.shootCooldown++; if (self.shootCooldown >= self.shootRate) { // Check if there's a zombie in front or behind var myRow = Math.floor((self.y - 500) / 140); var hasZombieInFront = false; var hasZombieBehind = false; for (var i = 0; i < zombies.length; i++) { var zombie = zombies[i]; var zombieRow = Math.floor((zombie.y - 500) / 140); if (zombieRow === myRow) { if (zombie.x > self.x) { hasZombieInFront = true; } else if (zombie.x < self.x) { hasZombieBehind = true; } } } if (hasZombieInFront || hasZombieBehind) { self.shootCooldown = 0; // Fisheye shooting effect tween(self, { scaleX: 1.3, scaleY: 0.7 }, { duration: 150, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 150, easing: tween.easeIn }); } }); // Shoot forward if zombie in front if (hasZombieInFront) { var forwardPea = new Pea(); forwardPea.x = self.x + 60; forwardPea.y = self.y; game.addChild(forwardPea); peas.push(forwardPea); } // Shoot backward if zombie behind if (hasZombieBehind) { var backwardPea = new Pea(); backwardPea.x = self.x - 60; backwardPea.y = self.y; backwardPea.speed = -8; // Negative speed for backward movement game.addChild(backwardPea); peas.push(backwardPea); } LK.getSound('shoot').play(); } } } else if (self.type === 'puffshroom') { self.shootCooldown++; if (self.shootCooldown >= self.shootRate) { var myRow = Math.floor((self.y - 500) / 140); var hasZombieInRange = false; for (var i = 0; i < zombies.length; i++) { var zombie = zombies[i]; var zombieRow = Math.floor((zombie.y - 500) / 140); if (zombieRow === myRow && zombie.x > self.x && zombie.x - self.x < self.range) { hasZombieInRange = true; break; } } if (hasZombieInRange) { self.shootCooldown = 0; var pea = new Pea(); pea.x = self.x + 60; pea.y = self.y; game.addChild(pea); peas.push(pea); LK.getSound('shoot').play(); } } } else if (self.type === 'sunshroom') { self.sunTimer++; if (self.sunTimer >= self.sunGenerateRate) { self.sunTimer = 0; var newSun = new Sun(); newSun.value = self.sunValue; newSun.x = self.x + Math.random() * 40 - 20; newSun.y = self.y + Math.random() * 40 - 20; game.addChild(newSun); suns.push(newSun); } } else if (self.type === 'gravebuster') { // Check for tombstones to destroy var myRow = Math.floor((self.y - gridStartY + cellSize / 2) / cellSize); var myCol = Math.floor((self.x - gridStartX + cellSize / 2) / cellSize); for (var i = tombstones.length - 1; i >= 0; i--) { var tombstone = tombstones[i]; var tombstoneRow = Math.floor((tombstone.y - gridStartY + cellSize / 2) / cellSize); var tombstoneCol = Math.floor((tombstone.x - gridStartX + cellSize / 2) / cellSize); if (tombstoneRow === myRow && tombstoneCol === myCol) { // Destroy tombstone tombstone.destroy(); tombstones.splice(i, 1); // Destroy gravebuster after use for (var j = plants.length - 1; j >= 0; j--) { if (plants[j] === self) { plants.splice(j, 1); self.destroy(); break; } } break; } } } else if (self.type === 'scaredyshroom') { self.shootCooldown++; if (self.shootCooldown >= self.shootRate) { var myRow = Math.floor((self.y - 500) / 140); var hasZombieInRow = false; var zombieTooClose = false; for (var i = 0; i < zombies.length; i++) { var zombie = zombies[i]; var zombieRow = Math.floor((zombie.y - 500) / 140); if (zombieRow === myRow && zombie.x > self.x) { hasZombieInRow = true; if (zombie.x - self.x < 200) { zombieTooClose = true; } break; } } if (hasZombieInRow && !zombieTooClose) { self.shootCooldown = 0; var pea = new Pea(); pea.x = self.x + 60; pea.y = self.y; game.addChild(pea); peas.push(pea); LK.getSound('shoot').play(); } } } else if (self.type === 'melonpulta' || self.type === 'coltapulta' || self.type === 'lanzamaiz') { self.shootCooldown++; if (self.shootCooldown >= self.shootRate) { // Check if there's a zombie in this row var myRow = Math.floor((self.y - 500) / 140); var hasZombieInRow = false; for (var i = 0; i < zombies.length; i++) { var zombie = zombies[i]; var zombieRow = Math.floor((zombie.y - 500) / 140); if (zombieRow === myRow && zombie.x > self.x) { hasZombieInRow = true; break; } } if (hasZombieInRow) { self.shootCooldown = 0; // Catapult shooting animation tween(self, { scaleX: 1.3, scaleY: 0.7 }, { duration: 150, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 150, easing: tween.easeIn }); } }); var pea = new Pea(); pea.damage = self.projectileDamage; // Use custom damage pea.x = self.x + 60; pea.y = self.y; game.addChild(pea); peas.push(pea); LK.getSound('shoot').play(); } } } }; return self; }); var RobotBoss = Container.expand(function () { var self = Container.call(this); var bossGraphics = self.attachAsset('robotBoss', { anchorX: 0.5, anchorY: 0.5 }); self.health = 1000; self.maxHealth = 1000; self.attackTimer = 0; self.attackRate = 240; // 4 seconds between attacks self.mouthOpen = false; self.takeDamage = function (damage) { self.health -= damage; // Flash red when taking damage tween(self, { tint: 0xff0000 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { tint: 0xffffff }, { duration: 200, easing: tween.easeIn }); } }); if (self.health <= 0) { // Boss death animation tween(self, { scaleX: 2, scaleY: 2, alpha: 0, rotation: Math.PI }, { duration: 2000, easing: tween.easeOut, onFinish: function onFinish() { self.destroy(); // Trigger win condition if (gameState === 'playing') { gameState = 'won'; LK.showYouWin(); } } }); return true; } return false; }; self.update = function () { self.attackTimer++; if (self.attackTimer >= self.attackRate) { self.attackTimer = 0; // Randomly choose between fireball attack or zombie spawn if (Math.random() < 0.6) { // Show red circle where fireball will land at random position var landingIndicators = []; var fireballTargets = []; // Store target position for fireball // Generate random target position within grid area var targetX = gridStartX + Math.random() * (gridCols * cellSize); var targetY = gridStartY + Math.random() * (gridRows * cellSize); fireballTargets.push({ x: targetX, y: targetY }); var indicator = LK.getAsset('fireball', { anchorX: 0.5, anchorY: 0.5, x: targetX, y: targetY, scaleX: 2, scaleY: 2, tint: 0xff0000, alpha: 0.7 }); game.addChild(indicator); landingIndicators.push(indicator); // Open mouth animation for fireball attack self.mouthOpen = true; tween(self, { scaleY: 1.3, tint: 0xff4500 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { // Remove landing indicator for (var k = 0; k < landingIndicators.length; k++) { landingIndicators[k].destroy(); } // Spit single fireball toward random target position from boss mouth var fireball = new Fireball(); // Set initial position at boss mouth fireball.x = self.x - 80; // Spawn from mouth area (further left from center) fireball.y = self.y - 50; // Spawn from mouth height (upper part of boss) // Calculate trajectory toward target var targetX = fireballTargets[0].x; var targetY = fireballTargets[0].y; var deltaX = targetX - fireball.x; var deltaY = targetY - fireball.y; var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY); // Set fireball direction and speed toward target fireball.speedX = deltaX / distance * 8; // Horizontal speed component fireball.speedY = deltaY / distance * 8; // Vertical speed component game.addChild(fireball); fireballs.push(fireball); // Close mouth tween(self, { scaleY: 1, tint: 0xffffff }, { duration: 300, easing: tween.easeIn, onFinish: function onFinish() { self.mouthOpen = false; } }); } }); } else { // Spawn zombies including Zombistein var zombieTypes = ['normal', 'fast', 'snailBucket', 'zombistein']; var randomType = zombieTypes[Math.floor(Math.random() * zombieTypes.length)]; var newZombie = new Zombie(randomType); newZombie.x = 2100; newZombie.y = gridStartY + Math.floor(Math.random() * gridRows) * cellSize; game.addChild(newZombie); zombies.push(newZombie); // Boss spawn effect tween(self, { tint: 0x8000ff }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { tint: 0xffffff }, { duration: 200, easing: tween.easeIn }); } }); } } // Update boss health display if (bossHealthDisplay) { bossHealthDisplay.setText('Boss Health: ' + self.health + '/' + self.maxHealth); } }; return self; }); var Sun = Container.expand(function () { var self = Container.call(this); var sunGraphics = self.attachAsset('sun', { anchorX: 0.5, anchorY: 0.5 }); self.value = 25; self.collected = false; self.lifeTimer = 0; self.maxLifeTime = 300; // 5 seconds at 60 FPS self.update = function () { if (!self.collected) { self.lifeTimer++; if (self.lifeTimer >= self.maxLifeTime) { self.collected = true; self.destroy(); } } }; self.down = function (x, y, obj) { if (!self.collected) { self.collected = true; sunPoints += self.value; updateSunDisplay(); LK.getSound('collect').play(); self.destroy(); } }; return self; }); var Tombstone = Container.expand(function () { var self = Container.call(this); var tombstoneGraphics = self.attachAsset('tombstone', { anchorX: 0.5, anchorY: 0.5 }); self.health = 100; self.maxHealth = 100; self.takeDamage = function (damage) { self.health -= damage; if (self.health <= 0) { self.destroy(); return true; } return false; }; return self; }); var Zombie = Container.expand(function (type) { var self = Container.call(this); self.type = type || 'normal'; self.health = 100; self.maxHealth = 100; self.speed = -1; self.attackDamage = 25; self.attackCooldown = 0; self.isAttacking = false; var zombieGraphics; if (self.type === 'fast') { zombieGraphics = self.attachAsset('fastZombie', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -2; self.health = 60; self.maxHealth = 60; } else if (self.type === 'snailBucket') { zombieGraphics = self.attachAsset('snailBucket', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -0.5; self.health = 250; self.maxHealth = 250; } else if (self.type === 'miner') { zombieGraphics = self.attachAsset('minerZombie', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -1.2; self.health = 120; self.maxHealth = 120; self.underground = false; self.surfaceTimer = 0; self.canAttack = true; // Can attack and be attacked when above ground } else if (self.type === 'cart') { zombieGraphics = self.attachAsset('cartZombie', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -0.7; self.health = 300; self.maxHealth = 300; self.cartHealth = 200; // Cart has its own health self.cartDestroyed = false; } else if (self.type === 'newspaper') { zombieGraphics = self.attachAsset('newspaperZombie', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -0.8; self.health = 150; self.maxHealth = 150; self.newspaperHealth = 75; // Newspaper has its own health self.newspaperDestroyed = false; self.enraged = false; } else if (self.type === 'zombistein') { zombieGraphics = self.attachAsset('minerZombie', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.8, scaleY: 1.8, tint: 0x00ff00 }); self.speed = -0.5; self.health = 500; self.maxHealth = 500; self.electricAttack = true; self.lastElectricAttack = 0; } else { zombieGraphics = self.attachAsset('zombie', { anchorX: 0.5, anchorY: 0.5 }); } self.takeDamage = function (damage) { // Cart zombie takes damage to cart first if (self.type === 'cart' && !self.cartDestroyed) { self.cartHealth -= damage; if (self.cartHealth <= 0) { self.cartDestroyed = true; self.speed = -1.5; // Move faster without cart zombieGraphics.tint = 0x888888; } return false; // Cart zombie doesn't die until cart is destroyed } else if (self.type === 'newspaper' && !self.newspaperDestroyed) { self.newspaperHealth -= damage; if (self.newspaperHealth <= 0) { self.newspaperDestroyed = true; self.enraged = true; self.speed = -2.5; // Move much faster when enraged zombieGraphics.tint = 0xff4444; // Red tint when angry } return false; // Newspaper zombie doesn't die until newspaper is destroyed } else { // Miner zombie cannot be damaged when underground if (self.type === 'miner' && self.underground) { return false; // Cannot be damaged underground } self.health -= damage; if (self.health <= 0) { // Death animation - fall to ground tween(self, { rotation: Math.PI / 2, y: self.y + 50, alpha: 0.7 }, { duration: 800, easing: tween.easeOut }); return true; } } return false; }; self.update = function () { // Miner zombie behavior if (self.type === 'miner') { var lastColumnX = gridStartX; // X position of the last (leftmost) grid column // Check if miner has reached or passed the last column var hasReachedLastColumn = self.x <= lastColumnX; if (!self.underground && self.x < 1500 && !hasReachedLastColumn) { // Go underground when reaching middle of screen, but only if hasn't reached last column yet self.underground = true; self.canAttack = false; // Cannot attack when underground self.alpha = 0.3; // Make more transparent when underground self.speed = -2; // Move faster underground } if (self.underground) { // When underground, cannot attack plants - just move through them // Check if reached the last column (leftmost grid column) to surface and turn around if (hasReachedLastColumn) { // Surface at last column and turn around self.underground = false; self.canAttack = true; // Can attack again when surfaced self.alpha = 1; self.speed = 1.2; // Move right (positive speed) to attack from behind self.surfaceTimer = 0; } } // Once surfaced at last column, continue moving right and cannot go underground again if (hasReachedLastColumn && !self.underground && self.speed > 0) { // Ensure miner continues moving right and cannot go underground self.canAttack = true; self.alpha = 1; } } // Zombistein electric attack behavior if (self.type === 'zombistein' && LK.ticks - self.lastElectricAttack > 300) { // Electric attack every 5 seconds self.lastElectricAttack = LK.ticks; // Damage all plants in a 200px radius for (var plantIdx = 0; plantIdx < plants.length; plantIdx++) { var plant = plants[plantIdx]; var distance = Math.sqrt(Math.pow(self.x - plant.x, 2) + Math.pow(self.y - plant.y, 2)); if (distance < 200) { // Electric visual effect tween(plant, { tint: 0x00ffff }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(plant, { tint: 0xffffff }, { duration: 200, easing: tween.easeIn }); } }); if (plant.takeDamage(30)) { for (var k = plants.length - 1; k >= 0; k--) { if (plants[k] === plant) { plants.splice(k, 1); plant.destroy(); break; } } } } } } // Cart zombie behavior if (self.type === 'cart' && !self.cartDestroyed) { // Check if cart should be destroyed (takes damage first before zombie) if (self.cartHealth <= 0) { self.cartDestroyed = true; self.speed = -1.5; // Move faster without cart // Change appearance to show cart is destroyed zombieGraphics.tint = 0x888888; } } if (!self.isAttacking) { self.x += self.speed; // Check if zombie reached the left side if (self.x < 100) { gameOver(); return; } // Check for plants to attack (ignore spikeweed) var myRow = Math.floor((self.y - 500) / 140); for (var i = 0; i < plants.length; i++) { var plant = plants[i]; var plantRow = Math.floor((plant.y - 500) / 140); // Ignore spikeweed plants - zombies walk over them // Miner zombie cannot attack when underground if (plantRow === myRow && Math.abs(self.x - plant.x) < 80 && plant.type !== 'spikeweed' && self.canAttack) { // Cart zombie instantly destroys plants except spikeweed if (self.type === 'cart') { plant.takeDamage(9999); // Instant destruction for (var plantIdx = plants.length - 1; plantIdx >= 0; plantIdx--) { if (plants[plantIdx] === plant) { plants.splice(plantIdx, 1); break; } } } else { self.isAttacking = true; } break; } } } else { // Attack mode self.attackCooldown++; if (self.attackCooldown >= 60) { // Attack every second self.attackCooldown = 0; // Find plant to attack (ignore spikeweed) var myRow = Math.floor((self.y - 500) / 140); var targetPlant = null; for (var i = 0; i < plants.length; i++) { var plant = plants[i]; var plantRow = Math.floor((plant.y - 500) / 140); // Ignore spikeweed plants - zombies walk over them // Miner zombie cannot attack when underground if (plantRow === myRow && Math.abs(self.x - plant.x) < 80 && plant.type !== 'spikeweed' && self.canAttack) { // Cart zombie instantly destroys plants except spikeweed if (self.type === 'cart') { plant.takeDamage(9999); // Instant destruction for (var plantIdx = plants.length - 1; plantIdx >= 0; plantIdx--) { if (plants[plantIdx] === plant) { plants.splice(plantIdx, 1); break; } } self.isAttacking = false; // Continue moving after instant destruction targetPlant = null; } else { targetPlant = plant; } break; } } if (targetPlant) { // Fisheye eating effect tween(self, { scaleX: 1.3, scaleY: 0.7 }, { duration: 150, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 150, easing: tween.easeIn }); } }); if (targetPlant.takeDamage(self.attackDamage)) { // Plant destroyed, remove from array for (var j = plants.length - 1; j >= 0; j--) { if (plants[j] === targetPlant) { plants.splice(j, 1); break; } } self.isAttacking = false; } } else { self.isAttacking = false; } } } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x228B22 }); /**** * Game Code ****/ // Night plants (mushrooms) // Game variables var sunPoints = 150; var currentWave = 1; var maxWaves = 5; var waveSpawnTimer = 0; var zombiesInWave = 0; var maxZombiesInWave = 30; var selectedPlantType = null; var shovelSelected = false; var gameState = 'loading'; // 'loading', 'levelSelect', 'playing', 'won', 'lost' var currentLevel = 1; var loadingScreen = null; var levelButtons = []; // Seed recharge system - 3 seconds = 180 ticks at 60 FPS var seedRechargeTime = 180; var seedCooldowns = { sunflower: 0, peashooter: 0, wallnut: 0, potatomine: 0, carnivorousplant: 0, doomshroom: 0, repeater: 0, threepeater: 0, spikeweed: 0, splitpeater: 0, lilypad: 0, puffshroom: 0, sunshroom: 0, fumeshroom: 0, gravebuster: 0, hypnoshroom: 0, scaredyshroom: 0, iceshroom: 0, melonpulta: 0, coltapulta: 0, lanzamaiz: 0, pot: 0 }; // Game arrays var plants = []; var zombies = []; var peas = []; var suns = []; var lawnmowers = []; var waterTiles = []; var tombstones = []; var conveyorBelt = null; var robotBoss = null; var fireballs = []; // Grid setup var gridStartX = 300; var gridStartY = 350; var gridCols = 12; var gridRows = 12; var cellSize = 140; // Plant costs var plantCosts = { sunflower: 50, peashooter: 100, wallnut: 50, potatomine: 25, carnivorousplant: 150, doomshroom: 125, repeater: 200, threepeater: 325, spikeweed: 100, splitpeater: 175, lilypad: 25, puffshroom: 0, sunshroom: 25, fumeshroom: 75, gravebuster: 75, hypnoshroom: 75, scaredyshroom: 25, iceshroom: 75, melonpulta: 300, coltapulta: 100, lanzamaiz: 100, pot: 25 }; // UI Elements var sunDisplay = new Text2('Sun: ' + sunPoints, { size: 60, fill: 0xFFFF00 }); sunDisplay.anchor.set(0, 0); LK.gui.topLeft.addChild(sunDisplay); sunDisplay.x = 120; sunDisplay.y = 20; var waveDisplay = new Text2('Wave: ' + currentWave + '/' + maxWaves, { size: 50, fill: 0xFFFFFF }); waveDisplay.anchor.set(0.5, 0); LK.gui.top.addChild(waveDisplay); waveDisplay.y = 20; // Plant selection buttons arranged vertically at bottom of screen var sunflowerButton = LK.getAsset('sunflower', { anchorX: 0.5, anchorY: 0.5, x: 200, y: 2100, scaleX: 0.6, scaleY: 0.6 }); game.addChild(sunflowerButton); var peashooterButton = LK.getAsset('peashooter', { anchorX: 0.5, anchorY: 0.5, x: 300, y: 2100, scaleX: 0.6, scaleY: 0.6 }); game.addChild(peashooterButton); var wallnutButton = LK.getAsset('wallnut', { anchorX: 0.5, anchorY: 0.5, x: 400, y: 2100, scaleX: 0.6, scaleY: 0.6 }); game.addChild(wallnutButton); var potatomineButton = LK.getAsset('potatomine', { anchorX: 0.5, anchorY: 0.5, x: 500, y: 2100, scaleX: 0.6, scaleY: 0.6 }); game.addChild(potatomineButton); var carnivorousplantButton = LK.getAsset('carnivorousplant', { anchorX: 0.5, anchorY: 0.5, x: 600, y: 2100, scaleX: 0.6, scaleY: 0.6 }); game.addChild(carnivorousplantButton); var doomshroomButton = LK.getAsset('doomshroom', { anchorX: 0.5, anchorY: 0.5, x: 700, y: 2100, scaleX: 0.6, scaleY: 0.6 }); game.addChild(doomshroomButton); var repeaterButton = LK.getAsset('repeater', { anchorX: 0.5, anchorY: 0.5, x: 800, y: 2100, scaleX: 0.6, scaleY: 0.6 }); game.addChild(repeaterButton); var threepeaterButton = LK.getAsset('threepeater', { anchorX: 0.5, anchorY: 0.5, x: 900, y: 2100, scaleX: 0.6, scaleY: 0.6 }); game.addChild(threepeaterButton); var spikeButton = LK.getAsset('spikeweed', { anchorX: 0.5, anchorY: 0.5, x: 1000, y: 2100, scaleX: 0.6, scaleY: 0.6 }); game.addChild(spikeButton); var splitpeaterButton = LK.getAsset('splitpeater', { anchorX: 0.5, anchorY: 0.5, x: 1100, y: 2100, scaleX: 0.6, scaleY: 0.6 }); game.addChild(splitpeaterButton); var lilypadButton = LK.getAsset('lilypad', { anchorX: 0.5, anchorY: 0.5, x: 1200, y: 2100, scaleX: 0.6, scaleY: 0.6 }); game.addChild(lilypadButton); // Restart button and shovel moved to right side of screen var restartButton = LK.getAsset('restartButton', { anchorX: 0.5, anchorY: 0.5, x: 1800, y: 120, scaleX: 0.8, scaleY: 0.8 }); game.addChild(restartButton); var shovelButton = LK.getAsset('shovel', { anchorX: 0.5, anchorY: 0.5, x: 1920, y: 120, scaleX: 0.6, scaleY: 0.6 }); game.addChild(shovelButton); // Plant cost labels - arranged horizontally at bottom next to buttons var sunflowerCost = new Text2('50', { size: 20, fill: 0xFFFFFF }); sunflowerCost.anchor.set(0.5, 0); sunflowerCost.x = 200; sunflowerCost.y = 2140; game.addChild(sunflowerCost); var peashooterCost = new Text2('100', { size: 20, fill: 0xFFFFFF }); peashooterCost.anchor.set(0.5, 0); peashooterCost.x = 300; peashooterCost.y = 2140; game.addChild(peashooterCost); var wallnutCost = new Text2('50', { size: 20, fill: 0xFFFFFF }); wallnutCost.anchor.set(0.5, 0); wallnutCost.x = 400; wallnutCost.y = 2140; game.addChild(wallnutCost); var potatomineeCost = new Text2('25', { size: 20, fill: 0xFFFFFF }); potatomineeCost.anchor.set(0.5, 0); potatomineeCost.x = 500; potatomineeCost.y = 2140; game.addChild(potatomineeCost); var carnivorousplantCost = new Text2('150', { size: 20, fill: 0xFFFFFF }); carnivorousplantCost.anchor.set(0.5, 0); carnivorousplantCost.x = 600; carnivorousplantCost.y = 2140; game.addChild(carnivorousplantCost); var doomshroomCost = new Text2('125', { size: 20, fill: 0xFFFFFF }); doomshroomCost.anchor.set(0.5, 0); doomshroomCost.x = 700; doomshroomCost.y = 2140; game.addChild(doomshroomCost); var repeaterCost = new Text2('200', { size: 20, fill: 0xFFFFFF }); repeaterCost.anchor.set(0.5, 0); repeaterCost.x = 800; repeaterCost.y = 2140; game.addChild(repeaterCost); var threepeaterCost = new Text2('325', { size: 20, fill: 0xFFFFFF }); threepeaterCost.anchor.set(0.5, 0); threepeaterCost.x = 900; threepeaterCost.y = 2140; game.addChild(threepeaterCost); var spikeCost = new Text2('100', { size: 20, fill: 0xFFFFFF }); spikeCost.anchor.set(0.5, 0); spikeCost.x = 1000; spikeCost.y = 2140; game.addChild(spikeCost); var splitpeaterCost = new Text2('175', { size: 20, fill: 0xFFFFFF }); splitpeaterCost.anchor.set(0.5, 0); splitpeaterCost.x = 1100; splitpeaterCost.y = 2140; game.addChild(splitpeaterCost); var lilypadCost = new Text2('25', { size: 20, fill: 0xFFFFFF }); lilypadCost.anchor.set(0.5, 0); lilypadCost.x = 1200; lilypadCost.y = 2140; game.addChild(lilypadCost); // Create separate catapult plant buttons for roof levels var melonpultaButton = LK.getAsset('melonpulta', { anchorX: 0.5, anchorY: 0.5, x: 800, y: 2100, scaleX: 0.6, scaleY: 0.6 }); game.addChild(melonpultaButton); melonpultaButton.visible = false; // Hidden by default var coltapultaButton = LK.getAsset('coltapulta', { anchorX: 0.5, anchorY: 0.5, x: 900, y: 2100, scaleX: 0.6, scaleY: 0.6 }); game.addChild(coltapultaButton); coltapultaButton.visible = false; // Hidden by default var lanzamaizButton = LK.getAsset('lanzamaiz', { anchorX: 0.5, anchorY: 0.5, x: 1100, y: 2100, scaleX: 0.6, scaleY: 0.6 }); game.addChild(lanzamaizButton); lanzamaizButton.visible = false; // Hidden by default // Create cost labels for catapult plants var melonpultaCost = new Text2('300', { size: 20, fill: 0xFFFFFF }); melonpultaCost.anchor.set(0.5, 0); melonpultaCost.x = 800; melonpultaCost.y = 2140; game.addChild(melonpultaCost); melonpultaCost.visible = false; // Hidden by default var coltapultaCost = new Text2('100', { size: 20, fill: 0xFFFFFF }); coltapultaCost.anchor.set(0.5, 0); coltapultaCost.x = 900; coltapultaCost.y = 2140; game.addChild(coltapultaCost); coltapultaCost.visible = false; // Hidden by default var lanzamaizCost = new Text2('100', { size: 20, fill: 0xFFFFFF }); lanzamaizCost.anchor.set(0.5, 0); lanzamaizCost.x = 1100; lanzamaizCost.y = 2140; game.addChild(lanzamaizCost); lanzamaizCost.visible = false; // Hidden by default // Create pot plant button for roof levels var potButton = LK.getAsset('pot', { anchorX: 0.5, anchorY: 0.5, x: 300, y: 2100, scaleX: 0.6, scaleY: 0.6 }); game.addChild(potButton); potButton.visible = false; // Hidden by default // Create cost label for pot plant var potCost = new Text2('25', { size: 20, fill: 0xFFFFFF }); potCost.anchor.set(0.5, 0); potCost.x = 300; potCost.y = 2140; game.addChild(potCost); potCost.visible = false; // Hidden by default // Boss health display var bossHealthDisplay = new Text2('Boss Health: 1000/1000', { size: 40, fill: 0xFF0000 }); bossHealthDisplay.anchor.set(0, 1); // Bottom left anchor bossHealthDisplay.x = 120; bossHealthDisplay.y = 2600; game.addChild(bossHealthDisplay); bossHealthDisplay.visible = false; // Hidden by default var restartText = new Text2('RESTART', { size: 16, fill: 0xFFFFFF }); restartText.anchor.set(0.5, 0); restartText.x = 1800; restartText.y = 90; game.addChild(restartText); // Exit level button - positioned next to restart button var exitLevelButton = LK.getAsset('restartButton', { anchorX: 0.5, anchorY: 0.5, x: 1650, y: 120, scaleX: 0.8, scaleY: 0.8 }); game.addChild(exitLevelButton); var exitText = new Text2('EXIT', { size: 16, fill: 0xFFFFFF }); exitText.anchor.set(0.5, 0); exitText.x = 1650; exitText.y = 90; game.addChild(exitText); // Draw grid var gridTiles = []; for (var row = 0; row < gridRows; row++) { for (var col = 0; col < gridCols; col++) { var gridCell = LK.getAsset('gridCell', { anchorX: 0.5, anchorY: 0.5, x: gridStartX + col * cellSize, y: gridStartY + row * cellSize, alpha: 0.3 }); game.addChild(gridCell); gridTiles.push(gridCell); } } // Add decorative bushes on the right to cover zombie spawn area - more bushes arranged at different depths var bushes = LK.getAsset('bushes', { anchorX: 0.5, anchorY: 0.5, x: 2000, y: 600, scaleX: 1.8, scaleY: 1.8 }); game.addChild(bushes); var bushes2 = LK.getAsset('bushes', { anchorX: 0.5, anchorY: 0.5, x: 2000, y: 900, scaleX: 1.6, scaleY: 1.6 }); game.addChild(bushes2); var bushes3 = LK.getAsset('bushes', { anchorX: 0.5, anchorY: 0.5, x: 2000, y: 1200, scaleX: 1.7, scaleY: 1.7 }); game.addChild(bushes3); var bushes4 = LK.getAsset('bushes', { anchorX: 0.5, anchorY: 0.5, x: 2000, y: 1500, scaleX: 1.5, scaleY: 1.5 }); game.addChild(bushes4); var bushes5 = LK.getAsset('bushes', { anchorX: 0.5, anchorY: 0.5, x: 2000, y: 1800, scaleX: 1.4, scaleY: 1.4 }); game.addChild(bushes5); var bushes6 = LK.getAsset('bushes', { anchorX: 0.5, anchorY: 0.5, x: 1900, y: 750, scaleX: 1.3, scaleY: 1.3 }); game.addChild(bushes6); var bushes7 = LK.getAsset('bushes', { anchorX: 0.5, anchorY: 0.5, x: 1900, y: 1350, scaleX: 1.2, scaleY: 1.2 }); game.addChild(bushes7); var bushes8 = LK.getAsset('bushes', { anchorX: 0.5, anchorY: 0.5, x: 1950, y: 450, scaleX: 1.6, scaleY: 1.6 }); game.addChild(bushes8); var bushes9 = LK.getAsset('bushes', { anchorX: 0.5, anchorY: 0.5, x: 1950, y: 1050, scaleX: 1.4, scaleY: 1.4 }); game.addChild(bushes9); var bushes10 = LK.getAsset('bushes', { anchorX: 0.5, anchorY: 0.5, x: 1950, y: 1650, scaleX: 1.5, scaleY: 1.5 }); game.addChild(bushes10); var bushes11 = LK.getAsset('bushes', { anchorX: 0.5, anchorY: 0.5, x: 1850, y: 600, scaleX: 1.1, scaleY: 1.1 }); game.addChild(bushes11); var bushes12 = LK.getAsset('bushes', { anchorX: 0.5, anchorY: 0.5, x: 1850, y: 1200, scaleX: 1.0, scaleY: 1.0 }); game.addChild(bushes12); var bushes13 = LK.getAsset('bushes', { anchorX: 0.5, anchorY: 0.5, x: 1850, y: 1800, scaleX: 1.3, scaleY: 1.3 }); game.addChild(bushes13); // Initialize lawnmowers for (var row = 0; row < gridRows; row++) { var lawnmower = new Lawnmower(); lawnmower.x = 220; lawnmower.y = gridStartY + row * cellSize; game.addChild(lawnmower); lawnmowers.push(lawnmower); } // Move all bushes to front to render above zombies bushes.parent.removeChild(bushes); game.addChild(bushes); bushes2.parent.removeChild(bushes2); game.addChild(bushes2); bushes3.parent.removeChild(bushes3); game.addChild(bushes3); bushes4.parent.removeChild(bushes4); game.addChild(bushes4); bushes5.parent.removeChild(bushes5); game.addChild(bushes5); bushes6.parent.removeChild(bushes6); game.addChild(bushes6); bushes7.parent.removeChild(bushes7); game.addChild(bushes7); bushes8.parent.removeChild(bushes8); game.addChild(bushes8); bushes9.parent.removeChild(bushes9); game.addChild(bushes9); bushes10.parent.removeChild(bushes10); game.addChild(bushes10); bushes11.parent.removeChild(bushes11); game.addChild(bushes11); bushes12.parent.removeChild(bushes12); game.addChild(bushes12); bushes13.parent.removeChild(bushes13); game.addChild(bushes13); // Initialize loading screen if (gameState === 'loading') { loadingScreen = new LoadingScreen(); game.addChild(loadingScreen); // Hide all game elements initially hideGameElements(); } function updateGridTiles(levelNumber) { // Destroy existing grid tiles for (var i = gridTiles.length - 1; i >= 0; i--) { gridTiles[i].destroy(); } gridTiles = []; // Determine tile type based on level var tileAsset = 'gridCell'; if (levelNumber > 15) { // Roof levels if (levelNumber === 19) { tileAsset = 'roofTileNight'; // Night roof } else { tileAsset = 'roofTileDay'; // Day roof } } // Create new grid with appropriate tiles for (var row = 0; row < gridRows; row++) { for (var col = 0; col < gridCols; col++) { var gridCell = LK.getAsset(tileAsset, { anchorX: 0.5, anchorY: 0.5, x: gridStartX + col * cellSize, y: gridStartY + row * cellSize, alpha: 0.3 }); game.addChild(gridCell); gridTiles.push(gridCell); } } } function updateSunDisplay() { sunDisplay.setText('Sun: ' + sunPoints); } function canAffordPlant(plantType) { return sunPoints >= plantCosts[plantType]; } function isSeedReady(plantType) { return seedCooldowns[plantType] <= 0; } function canPlant(plantType) { return canAffordPlant(plantType) && isSeedReady(plantType); } function getGridPosition(x, y) { var col = Math.floor((x - gridStartX + cellSize / 2) / cellSize); var row = Math.floor((y - gridStartY + cellSize / 2) / cellSize); if (col >= 0 && col < gridCols && row >= 0 && row < gridRows) { return { row: row, col: col, x: gridStartX + col * cellSize, y: gridStartY + row * cellSize }; } return null; } function isGridOccupied(row, col) { for (var i = 0; i < plants.length; i++) { var plant = plants[i]; var plantRow = Math.floor((plant.y - gridStartY + cellSize / 2) / cellSize); var plantCol = Math.floor((plant.x - gridStartX + cellSize / 2) / cellSize); if (plantRow === row && plantCol === col) { return true; } } return false; } function isPositionOnWater(row, col) { // Check if position is on water (pool levels 11-15, rows 4-8) var isPoolLevel = currentLevel > 10; if (isPoolLevel && row >= 4 && row <= 8) { return true; } return false; } function canPlantOnPosition(plantType, row, col) { // Check what's already at this position var hasLilypad = false; var hasPot = false; var isOccupied = false; for (var i = 0; i < plants.length; i++) { var plant = plants[i]; var plantRow = Math.floor((plant.y - gridStartY + cellSize / 2) / cellSize); var plantCol = Math.floor((plant.x - gridStartX + cellSize / 2) / cellSize); if (plantRow === row && plantCol === col) { if (plant.type === 'lilypad') { hasLilypad = true; } else if (plant.type === 'pot') { hasPot = true; } else { isOccupied = true; // Other plant types occupy space completely } } } // Check if this is a roof level var isRoofLevel = currentLevel > 15; // Check if this is a water position var isWaterPos = isPositionOnWater(row, col); // Handle roof level rules if (isRoofLevel) { if (plantType === 'pot') { return !isOccupied && !hasPot; // Pot needs empty space } else { return hasPot && !isOccupied; // Other plants need pot and no other plants } } // Handle water level rules if (isWaterPos) { if (plantType === 'lilypad') { return !isOccupied && !hasLilypad; // Lilypad needs empty water } else { return hasLilypad && !isOccupied; // Other plants need lilypad and no other plants } } // Handle regular ground rules if (plantType === 'lilypad') { return false; // Lilypad can only be on water } return !isOccupied && !hasLilypad && !hasPot; // Regular plants need completely empty space } function spawnTombstones() { // Spawn 3-5 tombstones randomly on the grid for night levels var tombstoneCount = 3 + Math.floor(Math.random() * 3); // Define vertical middle line at column 6 (middle of 12 columns) var middleColumn = Math.floor(gridCols / 2); for (var i = 0; i < tombstoneCount; i++) { var attempts = 0; var placed = false; while (!placed && attempts < 20) { var randomRow = Math.floor(Math.random() * gridRows); // Only spawn tombstones to the right of the middle line (behind middle) var randomCol = middleColumn + Math.floor(Math.random() * (gridCols - middleColumn - 1)); // Check if position is already occupied var occupied = false; for (var j = 0; j < tombstones.length; j++) { var tombstoneRow = Math.floor((tombstones[j].y - gridStartY + cellSize / 2) / cellSize); var tombstoneCol = Math.floor((tombstones[j].x - gridStartX + cellSize / 2) / cellSize); if (tombstoneRow === randomRow && tombstoneCol === randomCol) { occupied = true; break; } } if (!occupied) { var tombstone = new Tombstone(); tombstone.x = gridStartX + randomCol * cellSize; tombstone.y = gridStartY + randomRow * cellSize; game.addChild(tombstone); tombstones.push(tombstone); placed = true; } attempts++; } } } function spawnZombie() { var rand = Math.random(); var zombieType = 'normal'; if (rand < 0.15) { zombieType = 'fast'; } else if (rand < 0.25) { zombieType = 'snailBucket'; } else if (rand < 0.35) { zombieType = 'miner'; } else if (rand < 0.45) { zombieType = 'cart'; } else if (rand < 0.55) { zombieType = 'newspaper'; } var zombie = new Zombie(zombieType); zombie.x = 2100; zombie.y = gridStartY + Math.floor(Math.random() * gridRows) * cellSize; game.addChild(zombie); zombies.push(zombie); } function gameOver() { if (gameState === 'playing') { gameState = 'lost'; LK.showGameOver(); } } function checkWinCondition() { if (currentWave > maxWaves && zombies.length === 0) { if (gameState === 'playing') { gameState = 'won'; LK.showYouWin(); } } } function showLevelSelection() { gameState = 'levelSelect'; // Clear loading screen if (loadingScreen) { loadingScreen.destroy(); loadingScreen = null; } // Hide all game elements hideGameElements(); // Create day level buttons (1-5) var dayButtonSpacing = 150; var dayStartX = 1024 - 2 * dayButtonSpacing; for (var i = 1; i <= 5; i++) { var levelButton = new LevelButton(i); levelButton.x = dayStartX + (i - 1) * dayButtonSpacing; levelButton.y = 600; game.addChild(levelButton); levelButtons.push(levelButton); } // Create night level buttons (6-10) var nightButtonSpacing = 150; var nightStartX = 1024 - 2 * nightButtonSpacing; for (var j = 6; j <= 10; j++) { var nightLevelButton = new LevelButton(j); nightLevelButton.x = nightStartX + (j - 6) * nightButtonSpacing; nightLevelButton.y = 900; // Tint night buttons with dark blue nightLevelButton.tint = 0x000080; game.addChild(nightLevelButton); levelButtons.push(nightLevelButton); } // Create pool level buttons (11-15) var poolButtonSpacing = 150; var poolStartX = 1024 - 2 * poolButtonSpacing; for (var k = 11; k <= 15; k++) { var poolLevelButton = new LevelButton(k); poolLevelButton.x = poolStartX + (k - 11) * poolButtonSpacing; poolLevelButton.y = 1200; // Tint pool buttons with cyan/blue for water theme poolLevelButton.tint = 0x00FFFF; game.addChild(poolLevelButton); levelButtons.push(poolLevelButton); } // Create roof level buttons (16-18) - day roof levels var roofButtonSpacing = 150; var roofStartX = 1024 - 1 * roofButtonSpacing; for (var r = 16; r <= 18; r++) { var roofLevelButton = new LevelButton(r); roofLevelButton.x = roofStartX + (r - 16) * roofButtonSpacing; roofLevelButton.y = 1500; // Tint roof buttons with brown/gray for roof theme roofLevelButton.tint = 0x8B4513; game.addChild(roofLevelButton); levelButtons.push(roofLevelButton); } // Create night roof boss fight button (19) var bossLevelButton = new LevelButton(19); bossLevelButton.x = 1024; bossLevelButton.y = 1800; // Tint boss button with dark red for boss theme bossLevelButton.tint = 0x8B0000; // Make boss button bigger to indicate it's special bossLevelButton.scaleX = 1.5; bossLevelButton.scaleY = 1.5; game.addChild(bossLevelButton); levelButtons.push(bossLevelButton); } function hideDayPlants() { sunflowerButton.visible = false; peashooterButton.visible = false; wallnutButton.visible = false; potatomineButton.visible = false; carnivorousplantButton.visible = false; doomshroomButton.visible = false; repeaterButton.visible = false; threepeaterButton.visible = false; spikeButton.visible = false; splitpeaterButton.visible = false; lilypadButton.visible = false; melonpultaButton.visible = false; coltapultaButton.visible = false; lanzamaizButton.visible = false; sunflowerCost.visible = false; peashooterCost.visible = false; wallnutCost.visible = false; potatomineeCost.visible = false; carnivorousplantCost.visible = false; doomshroomCost.visible = false; repeaterCost.visible = false; threepeaterCost.visible = false; spikeCost.visible = false; splitpeaterCost.visible = false; lilypadCost.visible = false; melonpultaCost.visible = false; coltapultaCost.visible = false; lanzamaizCost.visible = false; potButton.visible = false; potCost.visible = false; } function showDayPlants() { sunflowerButton.visible = true; peashooterButton.visible = true; wallnutButton.visible = true; potatomineButton.visible = true; carnivorousplantButton.visible = true; doomshroomButton.visible = true; repeaterButton.visible = true; threepeaterButton.visible = true; spikeButton.visible = true; splitpeaterButton.visible = true; lilypadButton.visible = true; sunflowerCost.visible = true; peashooterCost.visible = true; wallnutCost.visible = true; potatomineeCost.visible = true; carnivorousplantCost.visible = true; doomshroomCost.visible = true; repeaterCost.visible = true; threepeaterCost.visible = true; spikeCost.visible = true; splitpeaterCost.visible = true; lilypadCost.visible = true; } function createNightPlantButtons() { // Create night plant buttons var puffshroomButton = LK.getAsset('puffshroom', { anchorX: 0.5, anchorY: 0.5, x: 200, y: 2100, scaleX: 0.8, scaleY: 0.8 }); game.addChild(puffshroomButton); var sunshroomButton = LK.getAsset('sunshroom', { anchorX: 0.5, anchorY: 0.5, x: 300, y: 2100, scaleX: 0.8, scaleY: 0.8 }); game.addChild(sunshroomButton); var fumeshroomButton = LK.getAsset('fumeshroom', { anchorX: 0.5, anchorY: 0.5, x: 400, y: 2100, scaleX: 0.8, scaleY: 0.8 }); game.addChild(fumeshroomButton); var gravebusterButton = LK.getAsset('gravebuster', { anchorX: 0.5, anchorY: 0.5, x: 500, y: 2100, scaleX: 0.8, scaleY: 0.8 }); game.addChild(gravebusterButton); var hypnoshroomButton = LK.getAsset('hypnoshroom', { anchorX: 0.5, anchorY: 0.5, x: 600, y: 2100, scaleX: 0.8, scaleY: 0.8 }); game.addChild(hypnoshroomButton); var scaredyshroomButton = LK.getAsset('scaredyshroom', { anchorX: 0.5, anchorY: 0.5, x: 700, y: 2100, scaleX: 0.8, scaleY: 0.8 }); game.addChild(scaredyshroomButton); var iceshroomButton = LK.getAsset('iceshroom', { anchorX: 0.5, anchorY: 0.5, x: 800, y: 2100, scaleX: 0.8, scaleY: 0.8 }); game.addChild(iceshroomButton); // Create night plant cost labels var puffshroomCost = new Text2('0', { size: 20, fill: 0xFFFFFF }); puffshroomCost.anchor.set(0.5, 0); puffshroomCost.x = 200; puffshroomCost.y = 2140; game.addChild(puffshroomCost); var sunshroomCost = new Text2('25', { size: 20, fill: 0xFFFFFF }); sunshroomCost.anchor.set(0.5, 0); sunshroomCost.x = 300; sunshroomCost.y = 2140; game.addChild(sunshroomCost); var fumeshroomCost = new Text2('75', { size: 20, fill: 0xFFFFFF }); fumeshroomCost.anchor.set(0.5, 0); fumeshroomCost.x = 400; fumeshroomCost.y = 2140; game.addChild(fumeshroomCost); var gravebusterCost = new Text2('75', { size: 20, fill: 0xFFFFFF }); gravebusterCost.anchor.set(0.5, 0); gravebusterCost.x = 500; gravebusterCost.y = 2140; game.addChild(gravebusterCost); var hypnoshroomCost = new Text2('75', { size: 20, fill: 0xFFFFFF }); hypnoshroomCost.anchor.set(0.5, 0); hypnoshroomCost.x = 600; hypnoshroomCost.y = 2140; game.addChild(hypnoshroomCost); var scaredyshroomCost = new Text2('25', { size: 20, fill: 0xFFFFFF }); scaredyshroomCost.anchor.set(0.5, 0); scaredyshroomCost.x = 700; scaredyshroomCost.y = 2140; game.addChild(scaredyshroomCost); var iceshroomCost = new Text2('75', { size: 20, fill: 0xFFFFFF }); iceshroomCost.anchor.set(0.5, 0); iceshroomCost.x = 800; iceshroomCost.y = 2140; game.addChild(iceshroomCost); // Add event handlers for night plant buttons puffshroomButton.down = function (x, y, obj) { if (canPlant('puffshroom')) { selectedPlantType = 'puffshroom'; shovelSelected = false; } }; sunshroomButton.down = function (x, y, obj) { if (canPlant('sunshroom')) { selectedPlantType = 'sunshroom'; shovelSelected = false; } }; fumeshroomButton.down = function (x, y, obj) { if (canPlant('fumeshroom')) { selectedPlantType = 'fumeshroom'; shovelSelected = false; } }; gravebusterButton.down = function (x, y, obj) { if (canPlant('gravebuster')) { selectedPlantType = 'gravebuster'; shovelSelected = false; } }; hypnoshroomButton.down = function (x, y, obj) { if (canPlant('hypnoshroom')) { selectedPlantType = 'hypnoshroom'; shovelSelected = false; } }; scaredyshroomButton.down = function (x, y, obj) { if (canPlant('scaredyshroom')) { selectedPlantType = 'scaredyshroom'; shovelSelected = false; } }; iceshroomButton.down = function (x, y, obj) { if (canPlant('iceshroom')) { selectedPlantType = 'iceshroom'; shovelSelected = false; } }; } function hideGameElements() { // Hide all UI elements sunDisplay.alpha = 0; waveDisplay.alpha = 0; // Hide all plant buttons sunflowerButton.alpha = 0; peashooterButton.alpha = 0; wallnutButton.alpha = 0; potatomineButton.alpha = 0; carnivorousplantButton.alpha = 0; doomshroomButton.alpha = 0; repeaterButton.alpha = 0; threepeaterButton.alpha = 0; spikeButton.alpha = 0; splitpeaterButton.alpha = 0; restartButton.alpha = 0; shovelButton.alpha = 0; // Hide cost labels sunflowerCost.alpha = 0; peashooterCost.alpha = 0; wallnutCost.alpha = 0; potatomineeCost.alpha = 0; carnivorousplantCost.alpha = 0; doomshroomCost.alpha = 0; repeaterCost.alpha = 0; threepeaterCost.alpha = 0; spikeCost.alpha = 0; splitpeaterCost.alpha = 0; lilypadCost.alpha = 0; restartText.alpha = 0; // Hide lilypad button lilypadButton.alpha = 0; // Hide exit button exitLevelButton.alpha = 0; exitText.alpha = 0; // Hide boss health display bossHealthDisplay.visible = false; } function showGameElements() { // Show all UI elements sunDisplay.alpha = 1; waveDisplay.alpha = 1; // Show all plant buttons sunflowerButton.alpha = 1; peashooterButton.alpha = 1; wallnutButton.alpha = 1; potatomineButton.alpha = 1; carnivorousplantButton.alpha = 1; doomshroomButton.alpha = 1; repeaterButton.alpha = 1; threepeaterButton.alpha = 1; spikeButton.alpha = 1; splitpeaterButton.alpha = 1; restartButton.alpha = 1; shovelButton.alpha = 1; // Show cost labels sunflowerCost.alpha = 1; peashooterCost.alpha = 1; wallnutCost.alpha = 1; potatomineeCost.alpha = 1; carnivorousplantCost.alpha = 1; doomshroomCost.alpha = 1; repeaterCost.alpha = 1; threepeaterCost.alpha = 1; spikeCost.alpha = 1; splitpeaterCost.alpha = 1; lilypadCost.alpha = 1; restartText.alpha = 1; // Show lilypad button lilypadButton.alpha = 1; // Show exit button exitLevelButton.alpha = 1; exitText.alpha = 1; } function startLevel(levelNumber) { currentLevel = levelNumber; gameState = 'playing'; // Clear level selection elements for (var i = levelButtons.length - 1; i >= 0; i--) { levelButtons[i].destroy(); } levelButtons = []; // Show game elements showGameElements(); // Reset game based on level resetGameForLevel(levelNumber); } function resetGameForLevel(levelNumber) { // Reset all game variables sunPoints = 150; currentWave = 1; maxZombiesInWave = 20 + (levelNumber - 1) * 10; // Increase difficulty per level maxWaves = 3 + levelNumber; // More waves for higher levels waveSpawnTimer = 0; zombiesInWave = 0; selectedPlantType = null; shovelSelected = false; // Set mode based on level number var isNightMode = levelNumber > 5 && levelNumber <= 10 || levelNumber === 19; var isPoolMode = levelNumber > 10 && levelNumber <= 15; var isRoofMode = levelNumber > 15; if (isRoofMode && levelNumber === 19) { // Night roof boss fight - only allow sunflower, doomshroom, wallnut, carnivorousplant, melonpulta, coltapulta, lanzamaiz game.setBackgroundColor(0x0F0F23); // Very dark night background sunPoints = 50; // Very little sun for boss fight hideDayPlants(); // Show only specific plants for roof levels sunflowerButton.visible = true; wallnutButton.visible = true; carnivorousplantButton.visible = true; doomshroomButton.visible = true; sunflowerCost.visible = true; wallnutCost.visible = true; carnivorousplantCost.visible = true; doomshroomCost.visible = true; // Show catapult plants for night roof boss level melonpultaButton.visible = true; coltapultaButton.visible = true; lanzamaizButton.visible = true; melonpultaCost.visible = true; coltapultaCost.visible = true; lanzamaizCost.visible = true; // Show pot plant for roof levels potButton.visible = true; potCost.visible = true; // Show boss health display bossHealthDisplay.visible = true; maxZombiesInWave = 50 + (levelNumber - 1) * 15; // Much harder boss fight maxWaves = 5 + levelNumber; // Many waves for boss } else if (isRoofMode) { // Day roof levels - only allow sunflower, doomshroom, wallnut, carnivorousplant, melonpulta, coltapulta, lanzamaiz game.setBackgroundColor(0x696969); // Gray roof background sunPoints = 125; // Medium-low sun for roof levels hideDayPlants(); // Show only specific plants for roof levels sunflowerButton.visible = true; wallnutButton.visible = true; carnivorousplantButton.visible = true; doomshroomButton.visible = true; sunflowerCost.visible = true; wallnutCost.visible = true; carnivorousplantCost.visible = true; doomshroomCost.visible = true; // Show catapult plants for day roof levels melonpultaButton.visible = true; coltapultaButton.visible = true; lanzamaizButton.visible = true; melonpultaCost.visible = true; coltapultaCost.visible = true; lanzamaizCost.visible = true; // Show pot plant for roof levels potButton.visible = true; potCost.visible = true; } else if (isPoolMode) { game.setBackgroundColor(0x006994); // Blue pool background sunPoints = 100; // Medium sun for pool levels showDayPlants(); // Pool levels use day plants } else if (isNightMode) { game.setBackgroundColor(0x1a1a2e); // Dark blue night background sunPoints = 75; // Start with less sun at night hideDayPlants(); // Hide day plants createNightPlantButtons(); // Show night plants } else { game.setBackgroundColor(0x228B22); // Green day background showDayPlants(); // Show day plants // Hide boss health display for non-boss levels bossHealthDisplay.visible = false; } // Clear all arrays and destroy objects for (var i = plants.length - 1; i >= 0; i--) { plants[i].destroy(); } plants = []; for (var j = zombies.length - 1; j >= 0; j--) { zombies[j].destroy(); } zombies = []; for (var k = peas.length - 1; k >= 0; k--) { peas[k].destroy(); } peas = []; for (var l = suns.length - 1; l >= 0; l--) { suns[l].destroy(); } suns = []; for (var m = lawnmowers.length - 1; m >= 0; m--) { lawnmowers[m].destroy(); } lawnmowers = []; for (var t = tombstones.length - 1; t >= 0; t--) { tombstones[t].destroy(); } tombstones = []; // Clear boss-specific objects if (conveyorBelt) { conveyorBelt.destroy(); conveyorBelt = null; } if (robotBoss) { robotBoss.destroy(); robotBoss = null; } for (var f = fireballs.length - 1; f >= 0; f--) { fireballs[f].destroy(); } fireballs = []; // Create boss-specific objects for level 19 if (isRoofMode && levelNumber === 19) { // Create conveyor belt for boss level conveyorBelt = new ConveyorBelt(); conveyorBelt.x = 1024; // Center of screen conveyorBelt.y = 200; // Top area game.addChild(conveyorBelt); // Create robot boss robotBoss = new RobotBoss(); robotBoss.x = 1800; // Right side of screen robotBoss.y = 1000; // Middle vertically game.addChild(robotBoss); } // Spawn tombstones for night levels after clearing existing ones (but not for boss fight) if (isNightMode && levelNumber !== 19) { spawnTombstones(); } // Reset seed cooldowns for (var seedType in seedCooldowns) { seedCooldowns[seedType] = 0; } // Reinitialize lawnmowers for (var row = 0; row < gridRows; row++) { var lawnmower = new Lawnmower(); lawnmower.x = 220; lawnmower.y = gridStartY + row * cellSize; game.addChild(lawnmower); lawnmowers.push(lawnmower); } // Add water tiles for pool levels (11-15) if (isPoolMode) { // Add water in the middle rows (approximately rows 4-8) for all columns for (var waterRow = 4; waterRow <= 8; waterRow++) { for (var waterCol = 0; waterCol < gridCols; waterCol++) { var waterTile = LK.getAsset('water', { anchorX: 0.5, anchorY: 0.5, x: gridStartX + waterCol * cellSize, y: gridStartY + waterRow * cellSize, alpha: 0.7 }); game.addChild(waterTile); waterTiles.push(waterTile); } } } // Update grid tiles for roof levels if (isRoofMode) { updateGridTiles(levelNumber); // Hide bushes for roof levels bushes.visible = false; bushes2.visible = false; bushes3.visible = false; bushes4.visible = false; bushes5.visible = false; bushes6.visible = false; bushes7.visible = false; bushes8.visible = false; bushes9.visible = false; bushes10.visible = false; bushes11.visible = false; bushes12.visible = false; bushes13.visible = false; } else { // Show bushes for non-roof levels bushes.visible = true; bushes2.visible = true; bushes3.visible = true; bushes4.visible = true; bushes5.visible = true; bushes6.visible = true; bushes7.visible = true; bushes8.visible = true; bushes9.visible = true; bushes10.visible = true; bushes11.visible = true; bushes12.visible = true; bushes13.visible = true; } // Add 3 vertical lines of pots for roof levels if (isRoofMode) { // Create 3 vertical lines of pots at the first 3 columns from the left (0, 1, 2) var potColumns = [0, 1, 2]; for (var potColIndex = 0; potColIndex < potColumns.length; potColIndex++) { var potCol = potColumns[potColIndex]; for (var potRow = 0; potRow < gridRows; potRow++) { var potPlant = new Plant('pot'); potPlant.x = gridStartX + potCol * cellSize; potPlant.y = gridStartY + potRow * cellSize; game.addChild(potPlant); plants.push(potPlant); } } } // Update displays updateSunDisplay(); waveDisplay.setText('Wave: ' + currentWave + '/' + maxWaves); } // Button event handlers sunflowerButton.down = function (x, y, obj) { if (canPlant('sunflower')) { selectedPlantType = 'sunflower'; shovelSelected = false; sunflowerButton.alpha = 1; sunflowerButton.tint = 0x808080; peashooterButton.alpha = isSeedReady('peashooter') ? 1 : 0.5; peashooterButton.tint = 0xffffff; wallnutButton.alpha = isSeedReady('wallnut') ? 1 : 0.5; wallnutButton.tint = 0xffffff; potatomineButton.alpha = isSeedReady('potatomine') ? 1 : 0.5; potatomineButton.tint = 0xffffff; carnivorousplantButton.alpha = isSeedReady('carnivorousplant') ? 1 : 0.5; carnivorousplantButton.tint = 0xffffff; doomshroomButton.alpha = isSeedReady('doomshroom') ? 1 : 0.5; doomshroomButton.tint = 0xffffff; repeaterButton.alpha = isSeedReady('repeater') ? 1 : 0.5; repeaterButton.tint = 0xffffff; threepeaterButton.alpha = isSeedReady('threepeater') ? 1 : 0.5; threepeaterButton.tint = 0xffffff; spikeButton.alpha = isSeedReady('spikeweed') ? 1 : 0.5; spikeButton.tint = 0xffffff; splitpeaterButton.alpha = isSeedReady('splitpeater') ? 1 : 0.5; splitpeaterButton.tint = 0xffffff; shovelButton.alpha = 1; shovelButton.tint = 0xffffff; } }; peashooterButton.down = function (x, y, obj) { if (canPlant('peashooter')) { selectedPlantType = 'peashooter'; shovelSelected = false; peashooterButton.alpha = 1; peashooterButton.tint = 0x808080; sunflowerButton.alpha = isSeedReady('sunflower') ? 1 : 0.5; sunflowerButton.tint = 0xffffff; wallnutButton.alpha = isSeedReady('wallnut') ? 1 : 0.5; wallnutButton.tint = 0xffffff; potatomineButton.alpha = isSeedReady('potatomine') ? 1 : 0.5; potatomineButton.tint = 0xffffff; carnivorousplantButton.alpha = isSeedReady('carnivorousplant') ? 1 : 0.5; carnivorousplantButton.tint = 0xffffff; doomshroomButton.alpha = isSeedReady('doomshroom') ? 1 : 0.5; doomshroomButton.tint = 0xffffff; repeaterButton.alpha = isSeedReady('repeater') ? 1 : 0.5; repeaterButton.tint = 0xffffff; threepeaterButton.alpha = isSeedReady('threepeater') ? 1 : 0.5; threepeaterButton.tint = 0xffffff; shovelButton.alpha = 1; shovelButton.tint = 0xffffff; } }; wallnutButton.down = function (x, y, obj) { if (canPlant('wallnut')) { selectedPlantType = 'wallnut'; shovelSelected = false; wallnutButton.alpha = 1; wallnutButton.tint = 0x808080; sunflowerButton.alpha = isSeedReady('sunflower') ? 1 : 0.5; sunflowerButton.tint = 0xffffff; peashooterButton.alpha = isSeedReady('peashooter') ? 1 : 0.5; peashooterButton.tint = 0xffffff; potatomineButton.alpha = isSeedReady('potatomine') ? 1 : 0.5; potatomineButton.tint = 0xffffff; carnivorousplantButton.alpha = isSeedReady('carnivorousplant') ? 1 : 0.5; carnivorousplantButton.tint = 0xffffff; doomshroomButton.alpha = isSeedReady('doomshroom') ? 1 : 0.5; doomshroomButton.tint = 0xffffff; repeaterButton.alpha = isSeedReady('repeater') ? 1 : 0.5; repeaterButton.tint = 0xffffff; threepeaterButton.alpha = isSeedReady('threepeater') ? 1 : 0.5; threepeaterButton.tint = 0xffffff; shovelButton.alpha = 1; shovelButton.tint = 0xffffff; } }; potatomineButton.down = function (x, y, obj) { if (canPlant('potatomine')) { selectedPlantType = 'potatomine'; shovelSelected = false; potatomineButton.alpha = 1; potatomineButton.tint = 0x808080; sunflowerButton.alpha = isSeedReady('sunflower') ? 1 : 0.5; sunflowerButton.tint = 0xffffff; peashooterButton.alpha = isSeedReady('peashooter') ? 1 : 0.5; peashooterButton.tint = 0xffffff; wallnutButton.alpha = isSeedReady('wallnut') ? 1 : 0.5; wallnutButton.tint = 0xffffff; carnivorousplantButton.alpha = isSeedReady('carnivorousplant') ? 1 : 0.5; carnivorousplantButton.tint = 0xffffff; doomshroomButton.alpha = isSeedReady('doomshroom') ? 1 : 0.5; doomshroomButton.tint = 0xffffff; repeaterButton.alpha = isSeedReady('repeater') ? 1 : 0.5; repeaterButton.tint = 0xffffff; threepeaterButton.alpha = isSeedReady('threepeater') ? 1 : 0.5; threepeaterButton.tint = 0xffffff; shovelButton.alpha = 1; shovelButton.tint = 0xffffff; } }; carnivorousplantButton.down = function (x, y, obj) { if (canPlant('carnivorousplant')) { selectedPlantType = 'carnivorousplant'; shovelSelected = false; carnivorousplantButton.alpha = 1; carnivorousplantButton.tint = 0x808080; sunflowerButton.alpha = isSeedReady('sunflower') ? 1 : 0.5; sunflowerButton.tint = 0xffffff; peashooterButton.alpha = isSeedReady('peashooter') ? 1 : 0.5; peashooterButton.tint = 0xffffff; wallnutButton.alpha = isSeedReady('wallnut') ? 1 : 0.5; wallnutButton.tint = 0xffffff; potatomineButton.alpha = isSeedReady('potatomine') ? 1 : 0.5; potatomineButton.tint = 0xffffff; doomshroomButton.alpha = isSeedReady('doomshroom') ? 1 : 0.5; doomshroomButton.tint = 0xffffff; repeaterButton.alpha = isSeedReady('repeater') ? 1 : 0.5; repeaterButton.tint = 0xffffff; threepeaterButton.alpha = isSeedReady('threepeater') ? 1 : 0.5; threepeaterButton.tint = 0xffffff; shovelButton.alpha = 1; shovelButton.tint = 0xffffff; } }; doomshroomButton.down = function (x, y, obj) { if (canPlant('doomshroom')) { selectedPlantType = 'doomshroom'; shovelSelected = false; doomshroomButton.alpha = 1; doomshroomButton.tint = 0x808080; sunflowerButton.alpha = isSeedReady('sunflower') ? 1 : 0.5; sunflowerButton.tint = 0xffffff; peashooterButton.alpha = isSeedReady('peashooter') ? 1 : 0.5; peashooterButton.tint = 0xffffff; wallnutButton.alpha = isSeedReady('wallnut') ? 1 : 0.5; wallnutButton.tint = 0xffffff; potatomineButton.alpha = isSeedReady('potatomine') ? 1 : 0.5; potatomineButton.tint = 0xffffff; carnivorousplantButton.alpha = isSeedReady('carnivorousplant') ? 1 : 0.5; carnivorousplantButton.tint = 0xffffff; repeaterButton.alpha = isSeedReady('repeater') ? 1 : 0.5; repeaterButton.tint = 0xffffff; threepeaterButton.alpha = isSeedReady('threepeater') ? 1 : 0.5; threepeaterButton.tint = 0xffffff; shovelButton.alpha = 1; shovelButton.tint = 0xffffff; } }; repeaterButton.down = function (x, y, obj) { if (canPlant('repeater')) { selectedPlantType = 'repeater'; shovelSelected = false; repeaterButton.alpha = 1; repeaterButton.tint = 0x808080; sunflowerButton.alpha = isSeedReady('sunflower') ? 1 : 0.5; sunflowerButton.tint = 0xffffff; peashooterButton.alpha = isSeedReady('peashooter') ? 1 : 0.5; peashooterButton.tint = 0xffffff; wallnutButton.alpha = isSeedReady('wallnut') ? 1 : 0.5; wallnutButton.tint = 0xffffff; potatomineButton.alpha = isSeedReady('potatomine') ? 1 : 0.5; potatomineButton.tint = 0xffffff; carnivorousplantButton.alpha = isSeedReady('carnivorousplant') ? 1 : 0.5; carnivorousplantButton.tint = 0xffffff; doomshroomButton.alpha = isSeedReady('doomshroom') ? 1 : 0.5; doomshroomButton.tint = 0xffffff; threepeaterButton.alpha = isSeedReady('threepeater') ? 1 : 0.5; threepeaterButton.tint = 0xffffff; shovelButton.alpha = 1; shovelButton.tint = 0xffffff; } }; threepeaterButton.down = function (x, y, obj) { if (canPlant('threepeater')) { selectedPlantType = 'threepeater'; shovelSelected = false; threepeaterButton.alpha = 1; threepeaterButton.tint = 0x808080; sunflowerButton.alpha = isSeedReady('sunflower') ? 1 : 0.5; sunflowerButton.tint = 0xffffff; peashooterButton.alpha = isSeedReady('peashooter') ? 1 : 0.5; peashooterButton.tint = 0xffffff; wallnutButton.alpha = isSeedReady('wallnut') ? 1 : 0.5; wallnutButton.tint = 0xffffff; potatomineButton.alpha = isSeedReady('potatomine') ? 1 : 0.5; potatomineButton.tint = 0xffffff; carnivorousplantButton.alpha = isSeedReady('carnivorousplant') ? 1 : 0.5; carnivorousplantButton.tint = 0xffffff; doomshroomButton.alpha = isSeedReady('doomshroom') ? 1 : 0.5; doomshroomButton.tint = 0xffffff; repeaterButton.alpha = isSeedReady('repeater') ? 1 : 0.5; repeaterButton.tint = 0xffffff; shovelButton.alpha = 1; shovelButton.tint = 0xffffff; } }; spikeButton.down = function (x, y, obj) { if (canPlant('spikeweed')) { selectedPlantType = 'spikeweed'; shovelSelected = false; spikeButton.alpha = 1; spikeButton.tint = 0x808080; sunflowerButton.alpha = isSeedReady('sunflower') ? 1 : 0.5; sunflowerButton.tint = 0xffffff; peashooterButton.alpha = isSeedReady('peashooter') ? 1 : 0.5; peashooterButton.tint = 0xffffff; wallnutButton.alpha = isSeedReady('wallnut') ? 1 : 0.5; wallnutButton.tint = 0xffffff; potatomineButton.alpha = isSeedReady('potatomine') ? 1 : 0.5; potatomineButton.tint = 0xffffff; carnivorousplantButton.alpha = isSeedReady('carnivorousplant') ? 1 : 0.5; carnivorousplantButton.tint = 0xffffff; doomshroomButton.alpha = isSeedReady('doomshroom') ? 1 : 0.5; doomshroomButton.tint = 0xffffff; repeaterButton.alpha = isSeedReady('repeater') ? 1 : 0.5; repeaterButton.tint = 0xffffff; threepeaterButton.alpha = isSeedReady('threepeater') ? 1 : 0.5; threepeaterButton.tint = 0xffffff; splitpeaterButton.alpha = isSeedReady('splitpeater') ? 1 : 0.5; splitpeaterButton.tint = 0xffffff; shovelButton.alpha = 1; shovelButton.tint = 0xffffff; } }; splitpeaterButton.down = function (x, y, obj) { if (canPlant('splitpeater')) { selectedPlantType = 'splitpeater'; shovelSelected = false; splitpeaterButton.alpha = 1; splitpeaterButton.tint = 0x808080; sunflowerButton.alpha = isSeedReady('sunflower') ? 1 : 0.5; sunflowerButton.tint = 0xffffff; peashooterButton.alpha = isSeedReady('peashooter') ? 1 : 0.5; peashooterButton.tint = 0xffffff; wallnutButton.alpha = isSeedReady('wallnut') ? 1 : 0.5; wallnutButton.tint = 0xffffff; potatomineButton.alpha = isSeedReady('potatomine') ? 1 : 0.5; potatomineButton.tint = 0xffffff; carnivorousplantButton.alpha = isSeedReady('carnivorousplant') ? 1 : 0.5; carnivorousplantButton.tint = 0xffffff; doomshroomButton.alpha = isSeedReady('doomshroom') ? 1 : 0.5; doomshroomButton.tint = 0xffffff; repeaterButton.alpha = isSeedReady('repeater') ? 1 : 0.5; repeaterButton.tint = 0xffffff; threepeaterButton.alpha = isSeedReady('threepeater') ? 1 : 0.5; threepeaterButton.tint = 0xffffff; spikeButton.alpha = isSeedReady('spikeweed') ? 1 : 0.5; spikeButton.tint = 0xffffff; shovelButton.alpha = 1; shovelButton.tint = 0xffffff; } }; restartButton.down = function (x, y, obj) { // Reset all game variables sunPoints = 150; currentWave = 1; maxZombiesInWave = 30; waveSpawnTimer = 0; zombiesInWave = 0; selectedPlantType = null; shovelSelected = false; gameState = 'playing'; // Clear all arrays and destroy objects for (var i = plants.length - 1; i >= 0; i--) { plants[i].destroy(); } plants = []; for (var j = zombies.length - 1; j >= 0; j--) { zombies[j].destroy(); } zombies = []; for (var k = peas.length - 1; k >= 0; k--) { peas[k].destroy(); } peas = []; for (var l = suns.length - 1; l >= 0; l--) { suns[l].destroy(); } suns = []; for (var m = lawnmowers.length - 1; m >= 0; m--) { lawnmowers[m].destroy(); } lawnmowers = []; for (var n = waterTiles.length - 1; n >= 0; n--) { waterTiles[n].destroy(); } waterTiles = []; for (var t = tombstones.length - 1; t >= 0; t--) { tombstones[t].destroy(); } tombstones = []; // Reset seed cooldowns for (var seedType in seedCooldowns) { seedCooldowns[seedType] = 0; } // Reinitialize lawnmowers for (var row = 0; row < gridRows; row++) { var lawnmower = new Lawnmower(); lawnmower.x = 220; lawnmower.y = gridStartY + row * cellSize; game.addChild(lawnmower); lawnmowers.push(lawnmower); } // Update displays updateSunDisplay(); waveDisplay.setText('Wave: ' + currentWave + '/' + maxWaves); // Reset button states sunflowerButton.alpha = 1; sunflowerButton.tint = 0xffffff; peashooterButton.alpha = 1; peashooterButton.tint = 0xffffff; wallnutButton.alpha = 1; wallnutButton.tint = 0xffffff; potatomineButton.alpha = 1; potatomineButton.tint = 0xffffff; carnivorousplantButton.alpha = 1; carnivorousplantButton.tint = 0xffffff; doomshroomButton.alpha = 1; doomshroomButton.tint = 0xffffff; repeaterButton.alpha = 1; repeaterButton.tint = 0xffffff; threepeaterButton.alpha = 1; threepeaterButton.tint = 0xffffff; spikeButton.alpha = 1; spikeButton.tint = 0xffffff; splitpeaterButton.alpha = 1; splitpeaterButton.tint = 0xffffff; shovelButton.alpha = 1; shovelButton.tint = 0xffffff; }; lilypadButton.down = function (x, y, obj) { if (canPlant('lilypad')) { selectedPlantType = 'lilypad'; shovelSelected = false; lilypadButton.alpha = 1; lilypadButton.tint = 0x808080; sunflowerButton.alpha = isSeedReady('sunflower') ? 1 : 0.5; sunflowerButton.tint = 0xffffff; peashooterButton.alpha = isSeedReady('peashooter') ? 1 : 0.5; peashooterButton.tint = 0xffffff; wallnutButton.alpha = isSeedReady('wallnut') ? 1 : 0.5; wallnutButton.tint = 0xffffff; potatomineButton.alpha = isSeedReady('potatomine') ? 1 : 0.5; potatomineButton.tint = 0xffffff; carnivorousplantButton.alpha = isSeedReady('carnivorousplant') ? 1 : 0.5; carnivorousplantButton.tint = 0xffffff; doomshroomButton.alpha = isSeedReady('doomshroom') ? 1 : 0.5; doomshroomButton.tint = 0xffffff; repeaterButton.alpha = isSeedReady('repeater') ? 1 : 0.5; repeaterButton.tint = 0xffffff; threepeaterButton.alpha = isSeedReady('threepeater') ? 1 : 0.5; threepeaterButton.tint = 0xffffff; spikeButton.alpha = isSeedReady('spikeweed') ? 1 : 0.5; spikeButton.tint = 0xffffff; splitpeaterButton.alpha = isSeedReady('splitpeater') ? 1 : 0.5; splitpeaterButton.tint = 0xffffff; shovelButton.alpha = 1; shovelButton.tint = 0xffffff; } }; shovelButton.down = function (x, y, obj) { shovelSelected = true; selectedPlantType = null; shovelButton.alpha = 1; shovelButton.tint = 0x808080; sunflowerButton.alpha = isSeedReady('sunflower') ? 1 : 0.5; sunflowerButton.tint = 0xffffff; peashooterButton.alpha = isSeedReady('peashooter') ? 1 : 0.5; peashooterButton.tint = 0xffffff; wallnutButton.alpha = isSeedReady('wallnut') ? 1 : 0.5; wallnutButton.tint = 0xffffff; potatomineButton.alpha = isSeedReady('potatomine') ? 1 : 0.5; potatomineButton.tint = 0xffffff; carnivorousplantButton.alpha = isSeedReady('carnivorousplant') ? 1 : 0.5; carnivorousplantButton.tint = 0xffffff; doomshroomButton.alpha = isSeedReady('doomshroom') ? 1 : 0.5; doomshroomButton.tint = 0xffffff; repeaterButton.alpha = isSeedReady('repeater') ? 1 : 0.5; repeaterButton.tint = 0xffffff; threepeaterButton.alpha = isSeedReady('threepeater') ? 1 : 0.5; threepeaterButton.tint = 0xffffff; spikeButton.alpha = 1; spikeButton.tint = 0xffffff; lilypadButton.alpha = 1; lilypadButton.tint = 0xffffff; }; // Add event handlers for catapult plant buttons melonpultaButton.down = function (x, y, obj) { if (canPlant('melonpulta')) { selectedPlantType = 'melonpulta'; shovelSelected = false; melonpultaButton.alpha = 1; melonpultaButton.tint = 0x808080; // Reset other buttons sunflowerButton.alpha = isSeedReady('sunflower') ? 1 : 0.5; sunflowerButton.tint = 0xffffff; wallnutButton.alpha = isSeedReady('wallnut') ? 1 : 0.5; wallnutButton.tint = 0xffffff; carnivorousplantButton.alpha = isSeedReady('carnivorousplant') ? 1 : 0.5; carnivorousplantButton.tint = 0xffffff; doomshroomButton.alpha = isSeedReady('doomshroom') ? 1 : 0.5; doomshroomButton.tint = 0xffffff; coltapultaButton.alpha = isSeedReady('coltapulta') ? 1 : 0.5; coltapultaButton.tint = 0xffffff; lanzamaizButton.alpha = isSeedReady('lanzamaiz') ? 1 : 0.5; lanzamaizButton.tint = 0xffffff; shovelButton.alpha = 1; shovelButton.tint = 0xffffff; } }; coltapultaButton.down = function (x, y, obj) { if (canPlant('coltapulta')) { selectedPlantType = 'coltapulta'; shovelSelected = false; coltapultaButton.alpha = 1; coltapultaButton.tint = 0x808080; // Reset other buttons sunflowerButton.alpha = isSeedReady('sunflower') ? 1 : 0.5; sunflowerButton.tint = 0xffffff; wallnutButton.alpha = isSeedReady('wallnut') ? 1 : 0.5; wallnutButton.tint = 0xffffff; carnivorousplantButton.alpha = isSeedReady('carnivorousplant') ? 1 : 0.5; carnivorousplantButton.tint = 0xffffff; doomshroomButton.alpha = isSeedReady('doomshroom') ? 1 : 0.5; doomshroomButton.tint = 0xffffff; melonpultaButton.alpha = isSeedReady('melonpulta') ? 1 : 0.5; melonpultaButton.tint = 0xffffff; lanzamaizButton.alpha = isSeedReady('lanzamaiz') ? 1 : 0.5; lanzamaizButton.tint = 0xffffff; shovelButton.alpha = 1; shovelButton.tint = 0xffffff; } }; lanzamaizButton.down = function (x, y, obj) { if (canPlant('lanzamaiz')) { selectedPlantType = 'lanzamaiz'; shovelSelected = false; lanzamaizButton.alpha = 1; lanzamaizButton.tint = 0x808080; // Reset other buttons sunflowerButton.alpha = isSeedReady('sunflower') ? 1 : 0.5; sunflowerButton.tint = 0xffffff; wallnutButton.alpha = isSeedReady('wallnut') ? 1 : 0.5; wallnutButton.tint = 0xffffff; carnivorousplantButton.alpha = isSeedReady('carnivorousplant') ? 1 : 0.5; carnivorousplantButton.tint = 0xffffff; doomshroomButton.alpha = isSeedReady('doomshroom') ? 1 : 0.5; doomshroomButton.tint = 0xffffff; melonpultaButton.alpha = isSeedReady('melonpulta') ? 1 : 0.5; melonpultaButton.tint = 0xffffff; coltapultaButton.alpha = isSeedReady('coltapulta') ? 1 : 0.5; coltapultaButton.tint = 0xffffff; shovelButton.alpha = 1; shovelButton.tint = 0xffffff; } }; // Add event handler for pot plant button potButton.down = function (x, y, obj) { if (canPlant('pot')) { selectedPlantType = 'pot'; shovelSelected = false; potButton.alpha = 1; potButton.tint = 0x808080; // Reset other buttons sunflowerButton.alpha = isSeedReady('sunflower') ? 1 : 0.5; sunflowerButton.tint = 0xffffff; wallnutButton.alpha = isSeedReady('wallnut') ? 1 : 0.5; wallnutButton.tint = 0xffffff; carnivorousplantButton.alpha = isSeedReady('carnivorousplant') ? 1 : 0.5; carnivorousplantButton.tint = 0xffffff; doomshroomButton.alpha = isSeedReady('doomshroom') ? 1 : 0.5; doomshroomButton.tint = 0xffffff; melonpultaButton.alpha = isSeedReady('melonpulta') ? 1 : 0.5; melonpultaButton.tint = 0xffffff; coltapultaButton.alpha = isSeedReady('coltapulta') ? 1 : 0.5; coltapultaButton.tint = 0xffffff; lanzamaizButton.alpha = isSeedReady('lanzamaiz') ? 1 : 0.5; lanzamaizButton.tint = 0xffffff; shovelButton.alpha = 1; shovelButton.tint = 0xffffff; } }; exitLevelButton.down = function (x, y, obj) { // Clear all game objects and return to level selection // Clear plants first to ensure they visually disappear for (var i = plants.length - 1; i >= 0; i--) { plants[i].destroy(); } plants = []; for (var j = zombies.length - 1; j >= 0; j--) { zombies[j].destroy(); } zombies = []; for (var k = peas.length - 1; k >= 0; k--) { peas[k].destroy(); } peas = []; for (var l = suns.length - 1; l >= 0; l--) { suns[l].destroy(); } suns = []; for (var m = lawnmowers.length - 1; m >= 0; m--) { lawnmowers[m].destroy(); } lawnmowers = []; for (var n = waterTiles.length - 1; n >= 0; n--) { waterTiles[n].destroy(); } waterTiles = []; for (var t = tombstones.length - 1; t >= 0; t--) { tombstones[t].destroy(); } tombstones = []; // Clear seed cooldowns for night mode for (var seedType in seedCooldowns) { seedCooldowns[seedType] = 0; } // Return to level selection showLevelSelection(); }; // Game event handlers game.down = function (x, y, obj) { if (shovelSelected) { // Remove plant functionality var gridPos = getGridPosition(x, y); if (gridPos) { for (var i = plants.length - 1; i >= 0; i--) { var plant = plants[i]; var plantRow = Math.floor((plant.y - gridStartY + cellSize / 2) / cellSize); var plantCol = Math.floor((plant.x - gridStartX + cellSize / 2) / cellSize); if (plantRow === gridPos.row && plantCol === gridPos.col) { plant.destroy(); plants.splice(i, 1); shovelSelected = false; // Reset button alphas and tints sunflowerButton.alpha = isSeedReady('sunflower') ? 1 : 0.5; sunflowerButton.tint = 0xffffff; peashooterButton.alpha = isSeedReady('peashooter') ? 1 : 0.5; peashooterButton.tint = 0xffffff; wallnutButton.alpha = isSeedReady('wallnut') ? 1 : 0.5; wallnutButton.tint = 0xffffff; potatomineButton.alpha = isSeedReady('potatomine') ? 1 : 0.5; potatomineButton.tint = 0xffffff; carnivorousplantButton.alpha = isSeedReady('carnivorousplant') ? 1 : 0.5; carnivorousplantButton.tint = 0xffffff; doomshroomButton.alpha = isSeedReady('doomshroom') ? 1 : 0.5; doomshroomButton.tint = 0xffffff; repeaterButton.alpha = isSeedReady('repeater') ? 1 : 0.5; repeaterButton.tint = 0xffffff; threepeaterButton.alpha = isSeedReady('threepeater') ? 1 : 0.5; threepeaterButton.tint = 0xffffff; shovelButton.alpha = 1; shovelButton.tint = 0xffffff; break; } } } } else if (selectedPlantType) { var gridPos = getGridPosition(x, y); if (gridPos && canPlantOnPosition(selectedPlantType, gridPos.row, gridPos.col)) { // For conveyor belt seeds (boss level), don't check sun cost or cooldown var isBossLevel = currentLevel === 19; var canPlaceFromBelt = isBossLevel && seedCooldowns[selectedPlantType] === 0; var canPlaceNormal = !isBossLevel && canPlant(selectedPlantType); if (canPlaceFromBelt || canPlaceNormal) { // Only deduct sun points for non-boss levels if (!isBossLevel) { sunPoints -= plantCosts[selectedPlantType]; updateSunDisplay(); // Start seed recharge for normal levels seedCooldowns[selectedPlantType] = seedRechargeTime; } var newPlant = new Plant(selectedPlantType); newPlant.x = gridPos.x; newPlant.y = gridPos.y; game.addChild(newPlant); plants.push(newPlant); LK.getSound('plant').play(); selectedPlantType = null; // Reset button alphas and tints based on cooldown status sunflowerButton.alpha = isSeedReady('sunflower') ? 1 : 0.5; sunflowerButton.tint = 0xffffff; peashooterButton.alpha = isSeedReady('peashooter') ? 1 : 0.5; peashooterButton.tint = 0xffffff; wallnutButton.alpha = isSeedReady('wallnut') ? 1 : 0.5; wallnutButton.tint = 0xffffff; potatomineButton.alpha = isSeedReady('potatomine') ? 1 : 0.5; potatomineButton.tint = 0xffffff; carnivorousplantButton.alpha = isSeedReady('carnivorousplant') ? 1 : 0.5; carnivorousplantButton.tint = 0xffffff; doomshroomButton.alpha = isSeedReady('doomshroom') ? 1 : 0.5; doomshroomButton.tint = 0xffffff; repeaterButton.alpha = isSeedReady('repeater') ? 1 : 0.5; repeaterButton.tint = 0xffffff; threepeaterButton.alpha = isSeedReady('threepeater') ? 1 : 0.5; threepeaterButton.tint = 0xffffff; shovelButton.alpha = 1; shovelButton.tint = 0xffffff; } } } }; // Main game update loop game.update = function () { if (gameState === 'loading') { // Loading screen handles its own updates return; } else if (gameState === 'levelSelect') { // Level selection screen - no game updates needed return; } else if (gameState !== 'playing') { return; } // Wave management waveSpawnTimer++; if (currentWave <= maxWaves) { // Only spawn zombies if not boss level (level 19) - boss will spawn them if (currentLevel !== 19 && waveSpawnTimer >= 1500 && zombiesInWave < maxZombiesInWave) { // Spawn 1 zombie every 25 seconds (1500 ticks) spawnZombie(); zombiesInWave++; waveSpawnTimer = 0; } else if (zombiesInWave >= maxZombiesInWave && zombies.length === 0) { // Wave completed currentWave++; zombiesInWave = 0; maxZombiesInWave += 5; // Increase difficulty more waveDisplay.setText('Wave: ' + currentWave + '/' + maxWaves); } } // Pea vs Zombie collision for (var i = peas.length - 1; i >= 0; i--) { var pea = peas[i]; var peaHit = false; for (var j = zombies.length - 1; j >= 0; j--) { var zombie = zombies[j]; if (Math.abs(pea.x - zombie.x) < 50 && Math.abs(pea.y - zombie.y) < 50) { if (zombie.takeDamage(pea.damage)) { zombie.destroy(); zombies.splice(j, 1); } pea.destroy(); peas.splice(i, 1); peaHit = true; break; } } if (!peaHit && pea.x > 2200) { pea.destroy(); peas.splice(i, 1); } } // Remove destroyed suns for (var k = suns.length - 1; k >= 0; k--) { if (suns[k].collected) { suns.splice(k, 1); } } // Update seed cooldowns for (var seedType in seedCooldowns) { if (seedCooldowns[seedType] > 0) { seedCooldowns[seedType]--; } } // Lawnmower activation - check if zombies reach the left side for (var m = zombies.length - 1; m >= 0; m--) { var zombie = zombies[m]; if (zombie.x < 250) { var zombieRow = Math.floor((zombie.y - gridStartY + cellSize / 2) / cellSize); if (zombieRow >= 0 && zombieRow < lawnmowers.length && !lawnmowers[zombieRow].activated) { lawnmowers[zombieRow].activated = true; // Remove zombie that triggered the lawnmower zombie.destroy(); zombies.splice(m, 1); } } } // Remove lawnmowers that are off screen for (var n = lawnmowers.length - 1; n >= 0; n--) { if (lawnmowers[n].x > 2200) { lawnmowers.splice(n, 1); } } // Lawnmower vs zombie collision for (var p = 0; p < lawnmowers.length; p++) { var lawnmower = lawnmowers[p]; if (lawnmower.activated) { for (var q = zombies.length - 1; q >= 0; q--) { var zombie = zombies[q]; if (Math.abs(lawnmower.x - zombie.x) < 60 && Math.abs(lawnmower.y - zombie.y) < 60) { zombie.destroy(); zombies.splice(q, 1); } } } } // Update button visual states based on cooldowns sunflowerButton.alpha = isSeedReady('sunflower') ? 1 : 0.5; peashooterButton.alpha = isSeedReady('peashooter') ? 1 : 0.5; wallnutButton.alpha = isSeedReady('wallnut') ? 1 : 0.5; potatomineButton.alpha = isSeedReady('potatomine') ? 1 : 0.5; carnivorousplantButton.alpha = isSeedReady('carnivorousplant') ? 1 : 0.5; doomshroomButton.alpha = isSeedReady('doomshroom') ? 1 : 0.5; repeaterButton.alpha = isSeedReady('repeater') ? 1 : 0.5; threepeaterButton.alpha = isSeedReady('threepeater') ? 1 : 0.5; spikeButton.alpha = isSeedReady('spikeweed') ? 1 : 0.5; // Fireball vs Plant collision (boss level only) if (currentLevel === 19 && fireballs && fireballs.length > 0) { for (var fb = fireballs.length - 1; fb >= 0; fb--) { var fireball = fireballs[fb]; if (fireball && fireball.x !== undefined) { var fireballHit = false; for (var pl = plants.length - 1; pl >= 0; pl--) { var plant = plants[pl]; if (Math.abs(fireball.x - plant.x) < 60 && Math.abs(fireball.y - plant.y) < 60) { if (plant.takeDamage(fireball.damage)) { plant.destroy(); plants.splice(pl, 1); } fireball.destroy(); fireballs.splice(fb, 1); fireballHit = true; break; } } if (!fireballHit && fireball.x < -100) { fireball.destroy(); fireballs.splice(fb, 1); } } } // Pea vs Robot Boss collision for (var peaIdx = peas.length - 1; peaIdx >= 0; peaIdx--) { var pea = peas[peaIdx]; if (robotBoss && Math.abs(pea.x - robotBoss.x) < 100 && Math.abs(pea.y - robotBoss.y) < 150) { if (robotBoss.takeDamage(pea.damage)) { // Boss defeated, handled in RobotBoss class } pea.destroy(); peas.splice(peaIdx, 1); } } } // Check win condition checkWinCondition(); };
===================================================================
--- original.js
+++ change.js
@@ -31,65 +31,63 @@
self.update = function () {
self.seedTimer++;
if (self.seedTimer >= self.seedGenerateRate) {
self.seedTimer = 0;
- // Generate random seed
- var randomSeed = self.availableSeeds[Math.floor(Math.random() * self.availableSeeds.length)];
- // Reset cooldown for this seed type - properly reset it
- seedCooldowns[randomSeed] = 0;
- // Automatically select this plant type for placement
- selectedPlantType = randomSeed;
+ // Generate 3 different random seeds
+ var generatedSeeds = [];
+ for (var i = 0; i < 3; i++) {
+ var randomSeed = self.availableSeeds[Math.floor(Math.random() * self.availableSeeds.length)];
+ generatedSeeds.push(randomSeed);
+ // Reset cooldown for this seed type - properly reset it
+ seedCooldowns[randomSeed] = 0;
+ }
+ // Automatically select the first plant type for placement
+ selectedPlantType = generatedSeeds[0];
shovelSelected = false;
// Remove previous plant display if it exists
if (plantDisplay) {
plantDisplay.destroy();
plantDisplay = null;
}
- // Create new plant display on conveyor belt
- plantDisplay = LK.getAsset(randomSeed, {
- anchorX: 0.5,
- anchorY: 0.5,
- scaleX: 0.8,
- scaleY: 0.8,
- alpha: 0
- });
- plantDisplay.x = 0;
- plantDisplay.y = 0; // Center on conveyor belt
- self.addChild(plantDisplay);
- // Show clear text feedback of which seed was given
- var seedDisplayName = randomSeed.toUpperCase();
- if (randomSeed === 'carnivorousplant') seedDisplayName = 'CARNIVOROUS PLANT';
- if (randomSeed === 'doomshroom') seedDisplayName = 'DOOM SHROOM';
- if (randomSeed === 'melonpulta') seedDisplayName = 'MELON PULTA';
- if (randomSeed === 'coltapulta') seedDisplayName = 'COL TAPULTA';
- if (randomSeed === 'lanzamaiz') seedDisplayName = 'LANZA MAIZ';
- seedText.setText(seedDisplayName + ' SEED!');
- // Show plant image with fade in animation
- tween(plantDisplay, {
- alpha: 1,
- scaleX: 1.0,
- scaleY: 1.0
- }, {
- duration: 300,
- easing: tween.easeOut,
- onFinish: function onFinish() {
- // Keep plant visible for 3 seconds, then fade out
- tween(plantDisplay, {
- alpha: 0,
- scaleX: 0.6,
- scaleY: 0.6
- }, {
- duration: 1500,
- easing: tween.easeIn,
- onFinish: function onFinish() {
- if (plantDisplay) {
- plantDisplay.destroy();
- plantDisplay = null;
- }
- }
- });
- }
- });
+ // Create display for all 3 plants side by side
+ var plantDisplays = [];
+ for (var j = 0; j < generatedSeeds.length; j++) {
+ var plantSeed = generatedSeeds[j];
+ var display = LK.getAsset(plantSeed, {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 0.6,
+ scaleY: 0.6,
+ alpha: 0
+ });
+ display.x = (j - 1) * 100; // Space them out: -100, 0, 100
+ display.y = 0;
+ self.addChild(display);
+ plantDisplays.push(display);
+ }
+ // Show clear text feedback of which seeds were given
+ var seedNames = [];
+ for (var k = 0; k < generatedSeeds.length; k++) {
+ var seedName = generatedSeeds[k].toUpperCase();
+ if (generatedSeeds[k] === 'carnivorousplant') seedName = 'CARNIVOROUS PLANT';
+ if (generatedSeeds[k] === 'doomshroom') seedName = 'DOOM SHROOM';
+ if (generatedSeeds[k] === 'melonpulta') seedName = 'MELON PULTA';
+ if (generatedSeeds[k] === 'coltapulta') seedName = 'COL TAPULTA';
+ if (generatedSeeds[k] === 'lanzamaiz') seedName = 'LANZA MAIZ';
+ seedNames.push(seedName);
+ }
+ seedText.setText('3 SEEDS: ' + seedNames.join(', ') + '!');
+ // Show plant images with fade in animation
+ for (var l = 0; l < plantDisplays.length; l++) {
+ tween(plantDisplays[l], {
+ alpha: 1,
+ scaleX: 0.8,
+ scaleY: 0.8
+ }, {
+ duration: 300,
+ easing: tween.easeOut
+ });
+ }
// Show text with fade in animation
tween(seedText, {
alpha: 1,
scaleX: 1.2,
@@ -97,20 +95,40 @@
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
- // Keep text visible for 2 seconds, then fade out
+ // Keep text visible for 3 seconds, then fade out
tween(seedText, {
alpha: 0,
scaleX: 1,
scaleY: 1
}, {
- duration: 1000,
+ duration: 1500,
easing: tween.easeIn
});
}
});
- // Visual flash effect to show seed was given
+ // Fade out plant displays after 4 seconds
+ LK.setTimeout(function () {
+ for (var m = 0; m < plantDisplays.length; m++) {
+ if (plantDisplays[m]) {
+ tween(plantDisplays[m], {
+ alpha: 0,
+ scaleX: 0.4,
+ scaleY: 0.4
+ }, {
+ duration: 1000,
+ easing: tween.easeIn,
+ onFinish: function onFinish() {
+ if (plantDisplays[m]) {
+ plantDisplays[m].destroy();
+ }
+ }
+ });
+ }
+ }
+ }, 4000);
+ // Visual flash effect to show seeds were given
tween(self, {
scaleX: 1.2,
scaleY: 1.2,
tint: 0x00ff00
@@ -1473,10 +1491,10 @@
/****
* Game Code
****/
-// Game variables
// Night plants (mushrooms)
+// Game variables
var sunPoints = 150;
var currentWave = 1;
var maxWaves = 5;
var waveSpawnTimer = 0;
Fullscreen modern App Store landscape banner, 16:9, high definition, for a game titled "Plant Defense: Zombie Wave" and with the description "Strategic tower defense game where players place plants to stop zombie waves from crossing their garden lawn.". No text on banner!
un lanzaguisantes. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
un girasol. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
un sol. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
guisante. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
La imagen muestra a una planta del videojuego "Plants vs. Zombies". Es una "Potato Mine" (Papa Mina), un tipo de planta explosiva. Características de la imagen: Forma: Tiene una forma redondeada y abultada, como la de una patata, que sobresale del suelo. Color: Es de color beige o marrón claro. Textura: Parece tener una superficie algo irregular, sugiriendo la textura de una patata o tierra. Cara: Posee dos ojos grandes y negros, de forma ovalada, y una pequeña boca sonriente con dos dientes frontales visibles. Esto le da una expresión amigable. Elemento superior: De la parte superior de la "patata" emerge un tallo gris delgado que sostiene una esfera roja brillante con un pequeño punto blanco en el centro. Esta esfera se asemeja al detonador de una mina o a una palanca de encendido. Base: Está rodeada por terrones de tierra o rocas pequeñas de color marrón oscuro, dando la impresión de que acaba de brotar del suelo o está parcialmente enterrada.. In-Game asset. 2d. High contrast. No shadows
Forma general: La planta tiene un cuerpo principal redondeado, similar a una cabeza, de donde emerge un tallo. Color: El cuerpo principal es de un vibrante color púrpura, salpicado con algunas manchas más oscuras del mismo tono. Boca: Posee una boca enorme y abierta que domina gran parte de su "cabeza". El borde de la boca es de un color verde lima brillante. Dientes: En el interior de la boca, se pueden ver numerosos dientes grandes, afilados y puntiagudos, de color blanco o crema, que sugieren su naturaleza carnívora. La encía visible dentro de la boca es de un tono rosa rojizo. Cuernos/Espinas: En la parte superior de su cabeza, tiene tres o cuatro protuberancias cónicas y afiladas, de color verde claro o blanquecino, que parecen espinas o cuernos. Tallo y hojas: Un tallo largo y curvado de color púrpura oscuro se extiende desde la parte inferior de la cabeza. Varias hojas verdes, con una forma ondulada o dentada, brotan del tallo, tanto cerca de la cabeza como en la base.. In-Game asset. 2d. High contrast. No shadows
Forma: Es una nuez grande y ovalada, con las dos mitades características de una nuez bien definidas y una hendidura central que las separa. Color: Predomina un color marrón dorado, típico de una nuez madura, con algunos matices más oscuros que sugieren textura y profundidad. Textura: La superficie parece rugosa y con imperfecciones, imitando la cáscara dura de una nuez real. Cara: A pesar de ser una nuez, tiene rasgos faciales humanoides en su parte frontal: Ojos: Dos ojos grandes, redondos y saltones con pupilas pequeñas y negras centradas. Los ojos tienen un borde blanco alrededor. Boca: Una pequeña línea horizontal que representa una boca sencilla y recta, dándole una expresión neutral o ligeramente sonriente, pero con una connotación de firmeza o determinación. Expresión: La combinación de los ojos grandes y la boca simple le otorgan una expresión de sorpresa o de estar alerta, lo que encaja con su función de muro defensivo. Fondo: El fondo es cuadriculado, lo que indica que. In-Game asset. 2d. High contrast. No shadows
un zombie de pvz. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
un zombie de pvz. In-Game asset. 2d. High contrast. No shadows
repetidora de pvz. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
una tripitidora de pvz 2 mirando a la derecha. In-Game asset. 2d. High contrast. No shadows
pala. In-Game asset. 2d. High contrast. No shadows
pincho roca pvz. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Forma general: Es una planta con un tallo central del que brotan hojas y, en la parte superior, tiene dos "cabezas" o vainas de guisante. Color: Predomina un color verde claro brillante en todo el cuerpo de la planta, con algunas sombras que le dan volumen y realismo. Las hojas y el tallo son de un verde ligeramente más oscuro. Cabezas/Vainas: Tiene dos vainas de guisante esféricas unidas, dispuestas una al lado de la otra. Cada una de ellas actúa como un cañón: Orificios de disparo: Ambas vainas tienen una abertura frontal redonda y oscura, que es por donde disparan los guisantes. Ojos: Cada vaina tiene dos pequeños ojos oscuros, similares a cuentas, que le dan una expresión curiosa o atenta. Hojas: En la base de las vainas y a lo largo del tallo, hay varias hojas grandes y ovaladas de color verde oscuro, con nervaduras visibles. Estilo artístico: La imagen tiene un estilo más renderizado y detallado que las ilustraciones típicas del juego, con un sombreado suave que le da una a. In-Game asset. 2d. High contrast. No shadows
lapida estilo PVZ. In-Game asset. 2d. High contrast. No shadows
podadora pvz. In-Game asset. 2d. High contrast. No shadows
El Zomboni es un zombi de tamaño considerable, vestido con un uniforme de trabajador y conduciendo un vehículo grande y robusto. La máquina suele ser de color azul o similar, con un rodillo en la parte trasera que es lo que esparce el hielo. Su aspecto es bastante imponente, señalando que no es un zombi común.. In-Game asset. 2d. High contrast. No shadows
petaseta de pvz en negro y gris con ojos rojos
arbustos grandes. In-Game asset. 2d. High contrast. No shadows
casilla de cesped en imagen completa con flores. In-Game asset. 2d. High contrast. No shadows
valla. In-Game asset. 2d. High contrast. No shadows
zombie minero pvz. In-Game asset. 2d. High contrast. No shadows
zombie leyendo un periodico con traje en cuerpo completo de pvz. In-Game asset. 2d. High contrast. No shadows
Uniforme Completo: Viste un uniforme de fútbol americano bastante completo, lo que le da una apariencia robusta y protegida. Casco de Fútbol: Lleva un casco de fútbol americano de color rojo brillante, adornado con dibujos de calaveras blancas y huesos cruzados, que son un distintivo de los zombis. Este casco no es solo estético, sino que le proporciona una defensa significativa en su cabeza. Hombreras y Camiseta: Tiene unas grandes hombreras blancas y una camiseta roja con el mismo patrón de calaveras y huesos en el pecho. Pantalones y Guantes: Sus pantalones son de color claro (crema o blanco roto) y lleva guantes rojos. Botas de Fútbol: Calza grandes botas de fútbol americano de color gris oscuro o negro. Boca Abierta y Cerebro: Típicamente, como muchos zombis, tiene la boca abierta, mostrando su deseo de cerebros. En tu imagen, parece tener algo verde (quizás una hoja o parte de una planta) sobresaliendo de su boca, lo que podría indicar que ya ha estado masticando algo.. In-Game asset. 2d. High contrast. No shadows
nenufar pvz. In-Game asset. 2d. High contrast. No shadows
Sombrero Púrpura: Tiene un sombrero grande y redondo de color púrpura oscuro o violeta, con manchas o puntos de un púrpura ligeramente más claro. Tallo Verde Claro: Su tallo es corto y robusto, de un color verde claro o menta. Ojos Grandes y Boquilla: Posee dos ojos grandes y redondos, y una "boca" o boquilla prominente en el frente, de color verde oscuro, desde donde expulsa sus proyectiles.. In-Game asset. 2d. High contrast. No shadows
Sombrero Anaranjado/Amarillo: Tiene un sombrero grande y redondo de color anaranjado o amarillo brillante, con manchas de un tono más oscuro o marrón-anaranjado. Los puntos grandes y luminosos en su sombrero le dan un aspecto amigable y sugieren su función solar. Tallo Beige/Crema: Su tallo es corto y regordete, de un color beige o crema claro. Cara Amigable: Posee dos ojos pequeños y redondos, y una pequeña sonrisa, dándole una expresión dulce y pasiva.. In-Game asset. 2d. High contrast. No shadows
Sombrero Iridiscente/Colorido: Su sombrero es la característica más llamativa, mostrando una gama de colores suaves y pastel que se mezclan como un arcoíris o un efecto iridiscente (rosas, azules, verdes claros, morados). Esto sugiere su naturaleza "hipnótica" o alucinógena. Tallo Púrpura Claro/Blanco: Su tallo es de un color púrpura muy claro o casi blanco. Ojos en Espiral/Hipnóticos: Sus "ojos" son dos grandes espirales rojas o rosadas, lo que claramente representa su capacidad de hipnotizar. Boca Triste/Somnolienta: Tiene una pequeña boca que parece un poco triste o somnolienta, lo que contrasta con la intensidad de sus ojos espirales.. In-Game asset. 2d. High contrast. No shadows
Cabeza (sombrero del hongo): Es grande, redonda y de color morado con manchas más oscuras. En el frente tiene una estructura que parece una boquilla o cañón, lo que da la impresión de que puede disparar algo. Cuerpo: Pequeño y de color verde claro, con una expresión facial seria o enojada. Tiene ojos grandes y cejas inclinadas hacia abajo, lo que resalta su actitud agresiva o decidida. Estilo: Es un diseño al estilo de caricatura o videojuego, similar a los personajes de Plants vs. Zombies.. In-Game asset. 2d. High contrast. No shadows
Cuerpo principal: Tiene forma de tronco cortado, de color gris oscuro con textura agrietada, lo que le da un aspecto envejecido o pétreo. La parte inferior tiene bordes irregulares que simulan raíces o madera desgastada. Ojos: Tiene dos ojos brillantes de color amarillo verdoso, con una expresión amenazante o intimidante. No tiene boca visible. Parte superior: Le crecen enredaderas verdes con hojas que sobresalen por arriba, dándole un toque vegetal y natural, como si la criatura estuviera conectada a la naturaleza o corrompida por ella. Estilo general: El diseño es oscuro y misterioso, probablemente representa a un enemigo o criatura poderosa en un juego tipo Plants vs. Zombies.. In-Game asset. 2d. High contrast. No shadows
Cristales de Hielo en la Parte Superior: Su característica más distintiva es la corona de cristales de hielo afilados y translúcidos de color azul brillante que cubren la parte superior de su cuerpo. Estos cristales le dan una apariencia gélida y punzante. Cuerpo Translúcido Azul/Turquesa: Su cuerpo principal es una masa translúcida de color azul claro o turquesa, que se asemeja al hielo o a un cuerpo gelatinoso congelado. Ojos Fruncidos y Fríos: Tiene dos ojos pequeños, oscuros y con las cejas fruncidas, lo que le da una expresión seria y gélida, a juego con su habilidad. Base Escarchada: La base de su cuerpo a menudo tiene un contorno escarchado o irregular, reforzando su temática de hielo.. In-Game asset. 2d. High contrast. No shadows
una lechuga. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
maseta mirando hacia arriba. In-Game asset. 2d. High contrast. No shadows
Cuerpo Robusto y Verde: El Zombot es una mole robótica de gran tamaño, con un cuerpo predominantemente de color verde oscuro, que le da un aspecto industrial y amenazante. Sus "hombros" y parte del torso están cubiertos por una armadura de color óxido o marrón rojizo, con remaches visibles. Cabeza de Zombi Grande: La cabeza del robot es grande y cuadrada, también de color verde, con mandíbulas inferiores prominentes que se abren para revelar dientes afilados. Tiene dos grandes ojos amarillos brillantes que emiten una luz siniestra, lo que lo hace parecer una versión robótica y gigantesca de un zombi común. Múltiples Mangueras y Cables: Varias mangueras o tuberías metálicas segmentadas sobresalen de sus hombros y otras partes del cuerpo, conectándose a sus brazos y cabeza, lo que sugiere un complejo sistema mecánico y de fluido. Brazos y Piernas Robóticas Grandes: Sus brazos son enormes y fornidos, con grandes manos que terminan en "dedos" gruesos y redondeados, capaces de infligir u. In-Game asset. 2d. High contrast. No shadows
Melón como Cuerpo: La planta en sí parece ser un melón grande y redondo, con las características rayas verdes oscuras y claras de una sandía. Cara y Hojas: Tiene dos ojos pequeños y una expresión que denota seriedad o concentración, propia de una planta de ataque. En su base, tiene hojas verdes que la asientan en el suelo. Brazos de Enredadera con Melón: De la parte superior de su cuerpo, salen dos enredaderas o tallos verdes y enrollados que sostienen un melón más pequeño. Este melón es el "proyectil" que lanza. El mecanismo sugiere que es una especie de honda o catapulta natural.. In-Game asset. 2d. High contrast. No shadows
casilla negra. In-Game asset. 2d. High contrast. No shadows
bola de cañon con fuego. In-Game asset. 2d. High contrast. No shadows
mantequilla. In-Game asset. 2d. High contrast. No shadows
grano de mais. In-Game asset. 2d. High contrast. No shadows
Un zombie grande ey fuerte eue sostiene un palo de electricidad. In-Game asset. 2d. High contrast. No shadows
Un botón de continuar al estilo lápida. In-Game asset. 2d. High contrast. No shadows
Tronco enojado con llamas arriba. In-Game asset. 2d. High contrast. No shadows