User prompt
make it so that when you start the game a menu appears in which two buttons can be selected, the first button says NORMAL and the second button says ENDLESS and when you press the button that says "normal" the game will start normally with waves and when you press the "endless" button the game will start but the waves will be infinite and little by little the zombie spawn will increase in this endless mode
User prompt
Make the slow effect not slow the zombie down as much.
User prompt
Make the zombie spawn rate higher on wave 5 and onwards and make the sound asset called zombie_eat play when a zombie damages a plant.
User prompt
Make the sound asset called zombie_freezed play when a zombie is slowed and the sound asset called explosion play when the jackInBoxZombie and cherry popper plant explode.
User prompt
Make the veteran newspaper zombie unstoppable and have the sound asset called zombie_hit play when a projectile hits a zombie and so that the sound when placing a plant is not so repetitive have a 50% chance that seedplant1 will play and another 50% chance that seedplant2 will play
User prompt
Haz que el zombie veterano del periódico no pueda ser frenado y haz que el activo de sonido llamado zombie_hit se reproduzca cuando un proyectil golpee a un zombie y para que el sonido al colocar una planta no sea tan repetitivo que haiga un 50% de que suene el seedplant1 y otro 50% de que suene el seedplant2
User prompt
Make one of these two assets sound when a plant is placed in the garden: seed_plant1 or seed_plant2
User prompt
Make one of these two assets sound when a plant is placed in the garden: seed_plant1 or seed_plant2
User prompt
Make the Ultimate Battle music asset the game's music.
User prompt
create an asset that is the game's music
User prompt
the music doesn't play
User prompt
The musical asset called "grasswalk" has been used as music for waves 1 to 10
User prompt
Make the asset veteranewspaperZombie a zombie and have double the life of a basiczombie and since it has the damage life, its speed and damage it does to plants are x5.
User prompt
creates a asset zombie called veteranewspaper that has twice the life of the newspaper and by having half its life its speed and damage that it does to plants is x5 more
User prompt
creates a zombie called veteranewspaper that has twice the life of the newspaper and by having half its life its speed and damage that it does to plants is x5 more
User prompt
Make the gargantuar when it has half health, the fastzombie that spawns appears in the third square of the garden
User prompt
Creates a plant called puffshroom that costs 0 suns and shoots spores and creates a separate resource for the spore and has a range to detect a zombie of 3 tiles and can only be used from wave 11 onwards and appears on page 2 of the plant selector ↪💡 Consider importing and using the following plugins: @upit/tween.v1
/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
/**** 
* Classes
****/ 
var BackwardPea = Container.expand(function () {
	var self = Container.call(this);
	var graphics = self.attachAsset('pea', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Tint green to show it's from splitpea
	graphics.tint = 0x44ff44;
	self.speed = -8; // Negative speed to go backwards 
	self.damage = 15;
	self.gridY = 0;
	self.update = function () {
		self.x += self.speed;
		// Check collision with zombies 
		for (var i = 0; i < zombies.length; i++) {
			var zombie = zombies[i];
			if (zombie.gridY === self.gridY && self.intersects(zombie)) {
				// Check if it's a JesterZombie 
				if (zombie.isJester) {
					// Create reflected pea going forward 
					var reflectedPea = new ReflectedPea();
					reflectedPea.x = zombie.x + 50;
					reflectedPea.y = zombie.y;
					reflectedPea.gridY = zombie.gridY;
					reflectedpeas.push(reflectedPea);
					game.addChild(reflectedPea);
					// Flash jester zombie to show deflection 
					LK.effects.flashObject(zombie, 0xffff00, 200);
				} else {
					zombie.takeDamage(self.damage, 'pea');
				}
				self.destroy();
				for (var j = 0; j < backwardpeas.length; j++) {
					if (backwardpeas[j] === self) {
						backwardpeas.splice(j, 1);
						break;
					}
				}
				return;
			}
		}
		// Remove if off screen (left side) 
		if (self.x < -100) {
			self.destroy();
			for (var k = 0; k < backwardpeas.length; k++) {
				if (backwardpeas[k] === self) {
					backwardpeas.splice(k, 1);
					break;
				}
			}
		}
	};
	return self;
});
var BasicZombie = Container.expand(function () {
	var self = Container.call(this);
	var graphics = self.attachAsset('basicZombie', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 0.5;
	self.health = 100;
	self.maxHealth = 100;
	self.damage = 40;
	self.gridY = 0;
	self.attackTimer = 0;
	self.attackDelay = 60;
	self.update = function () {
		// Check if there's a plant to attack
		var plantToAttack = null;
		for (var i = 0; i < plants.length; i++) {
			var plant = plants[i];
			if (plant.gridY === self.gridY && Math.abs(plant.x - self.x) < 80) {
				plantToAttack = plant;
				break;
			}
		}
		if (plantToAttack) {
			self.attackTimer++;
			if (self.attackTimer >= self.attackDelay) {
				if (plantToAttack.takeDamage) {
					plantToAttack.takeDamage(self.damage);
				}
				self.attackTimer = 0;
			}
		} else {
			self.x -= self.speed;
			self.attackTimer = 0;
		}
		// Check if reached house
		if (self.x < 150) {
			LK.showGameOver();
		}
	};
	self.takeDamage = function (damage) {
		self.health -= damage;
		LK.effects.flashObject(self, 0xff0000, 200);
		LK.getSound('zombie_hit').play();
		if (self.health <= 0) {
			self.destroy();
			for (var i = 0; i < zombies.length; i++) {
				if (zombies[i] === self) {
					zombies.splice(i, 1);
					break;
				}
			}
			zombiesKilled++;
		}
	};
	return self;
});
var Zomboni = BasicZombie.expand(function () {
	var self = BasicZombie.call(this);
	// Replace the graphics with zomboni asset
	self.removeChild(self.children[0]);
	var graphics = self.attachAsset('zomboni', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 1.5; // Fast movement
	self.health = 150;
	self.maxHealth = 150;
	self.damage = 100;
	self.gridY = 0;
	self.attackTimer = 0;
	self.attackDelay = 30; // Faster elimination
	self.update = function () {
		// Move forward continuously
		self.x -= self.speed;
		// Check for plants to eliminate (in a wider area due to size)
		for (var i = plants.length - 1; i >= 0; i--) {
			var plant = plants[i];
			if (plant.gridY === self.gridY && Math.abs(plant.x - self.x) < 100) {
				// Instantly eliminate the plant
				LK.effects.flashObject(plant, 0xff0000, 200);
				// Remove from plant grid
				var gridKey = plant.gridX + ',' + plant.gridY;
				delete plantGrid[gridKey];
				plant.destroy();
				plants.splice(i, 1);
			}
		}
		// Check if reached house
		if (self.x < 150) {
			LK.showGameOver();
		}
	};
	return self;
});
var VeteranNewspaperZombie = BasicZombie.expand(function () {
	var self = BasicZombie.call(this);
	// Replace the graphics with veteran newspaper zombie asset
	self.removeChild(self.children[0]);
	var graphics = self.attachAsset('veteranewspaperZombie', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 0.5;
	self.health = 200; // Double the life of basic zombie (100 * 2)
	self.maxHealth = 200;
	self.damage = 40;
	self.gridY = 0;
	self.attackTimer = 0;
	self.attackDelay = 60;
	self.hasRaged = false;
	self.takeDamage = function (damage) {
		self.health -= damage;
		LK.effects.flashObject(self, 0xff0000, 200);
		LK.getSound('zombie_hit').play();
		// Check if health dropped to half or below and hasn't raged yet
		if (self.health <= self.maxHealth / 2 && !self.hasRaged) {
			self.hasRaged = true;
			// Increase speed and damage by 5x
			self.speed = 2.5; // 0.5 * 5
			self.damage = 200; // 40 * 5
			// Visual effect for rage mode - flash red and change tint
			LK.effects.flashObject(self, 0xff0000, 500);
			tween(graphics, {
				tint: 0xff0000
			}, {
				duration: 300,
				easing: tween.easeOut
			});
		}
		if (self.health <= 0) {
			self.destroy();
			for (var i = 0; i < zombies.length; i++) {
				if (zombies[i] === self) {
					zombies.splice(i, 1);
					break;
				}
			}
			zombiesKilled++;
		}
	};
	return self;
});
var TankZombie = BasicZombie.expand(function () {
	var self = BasicZombie.call(this);
	// Replace the graphics with tank zombie asset
	self.removeChild(self.children[0]);
	var graphics = self.attachAsset('tankZombie', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 0.3;
	self.health = 200;
	self.maxHealth = 200;
	self.damage = 80;
	self.gridY = 0;
	self.attackTimer = 0;
	self.attackDelay = 60;
	return self;
});
var NewspaperZombie = BasicZombie.expand(function () {
	var self = BasicZombie.call(this);
	// Replace the graphics with newspaper zombie asset
	self.removeChild(self.children[0]);
	var graphics = self.attachAsset('newspaperZombie', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 0.5;
	self.health = 100;
	self.maxHealth = 100;
	self.damage = 40;
	self.gridY = 0;
	self.attackTimer = 0;
	self.attackDelay = 60;
	self.hasRaged = false;
	self.takeDamage = function (damage) {
		self.health -= damage;
		LK.effects.flashObject(self, 0xff0000, 200);
		LK.getSound('zombie_hit').play();
		// Check if health dropped to half or below and hasn't raged yet
		if (self.health <= self.maxHealth / 2 && !self.hasRaged) {
			self.hasRaged = true;
			// Increase speed and damage
			self.speed = 1.5;
			self.damage = 80;
			// Visual effect for rage mode - flash red and change tint
			LK.effects.flashObject(self, 0xff0000, 500);
			tween(graphics, {
				tint: 0xff4444
			}, {
				duration: 300,
				easing: tween.easeOut
			});
		}
		if (self.health <= 0) {
			self.destroy();
			for (var i = 0; i < zombies.length; i++) {
				if (zombies[i] === self) {
					zombies.splice(i, 1);
					break;
				}
			}
			zombiesKilled++;
		}
	};
	return self;
});
var MinerZombie = BasicZombie.expand(function () {
	var self = BasicZombie.call(this);
	// Replace the graphics with miner zombie asset (appears as normal zombie)
	self.removeChild(self.children[0]);
	var graphics = self.attachAsset('minerZombie', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 0.5;
	self.health = 80;
	self.maxHealth = 80;
	self.damage = 40;
	self.gridY = 0;
	self.attackTimer = 0;
	self.attackDelay = 60;
	self.teleportTimer = 0;
	self.teleportDelay = 300; // 5 seconds at 60fps
	self.hasTeleported = false;
	self.update = function () {
		// If not teleported yet, count down to teleport
		if (!self.hasTeleported) {
			self.teleportTimer++;
			if (self.teleportTimer >= self.teleportDelay) {
				self.teleport();
			} else {
				// Move normally before teleporting
				self.x -= self.speed;
			}
		} else {
			// After teleporting, behave like normal zombie but attacking from behind
			var plantToAttack = null;
			for (var i = 0; i < plants.length; i++) {
				var plant = plants[i];
				if (plant.gridY === self.gridY && Math.abs(plant.x - self.x) < 80) {
					plantToAttack = plant;
					break;
				}
			}
			if (plantToAttack) {
				self.attackTimer++;
				if (self.attackTimer >= self.attackDelay) {
					if (plantToAttack.takeDamage) {
						plantToAttack.takeDamage(self.damage);
					}
					self.attackTimer = 0;
				}
			} else {
				self.x += self.speed; // Move forward (right) after teleporting
				self.attackTimer = 0;
			}
		}
		// Check if reached house (only matters before teleporting)
		if (!self.hasTeleported && self.x < 150) {
			LK.showGameOver();
		}
		// Check if moved off screen after teleporting
		if (self.hasTeleported && self.x > 2200) {
			self.destroy();
			for (var i = 0; i < zombies.length; i++) {
				if (zombies[i] === self) {
					zombies.splice(i, 1);
					break;
				}
			}
		}
	};
	self.teleport = function () {
		if (self.hasTeleported) return;
		self.hasTeleported = true;
		// Flash effect before teleporting
		LK.effects.flashObject(self, 0xffff00, 300);
		// Teleport to the first column (leftmost position behind plants)
		var newX = gridStartX + gridWidth / 2;
		var newY = gridStartY + self.gridY * gridHeight + gridHeight / 2;
		// Animate teleportation with tween
		tween(self, {
			alpha: 0,
			scaleX: 0.5,
			scaleY: 0.5
		}, {
			duration: 500,
			easing: tween.easeIn,
			onFinish: function onFinish() {
				// Move to new position
				self.x = newX;
				self.y = newY;
				// Animate appearing at new location
				tween(self, {
					alpha: 1,
					scaleX: 1,
					scaleY: 1
				}, {
					duration: 500,
					easing: tween.easeOut
				});
				// Flash effect when appearing
				LK.effects.flashObject(self, 0x00ff00, 300);
			}
		});
	};
	return self;
});
var JesterZombie = BasicZombie.expand(function () {
	var self = BasicZombie.call(this);
	// Replace the graphics with jester zombie asset
	self.removeChild(self.children[0]);
	var graphics = self.attachAsset('jesterZombie', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 0.8;
	self.health = 120;
	self.maxHealth = 120;
	self.damage = 50;
	self.gridY = 0;
	self.attackTimer = 0;
	self.attackDelay = 60;
	self.isJester = true; // Flag to identify this zombie type
	// Override takeDamage to be immune to peas
	self.takeDamage = function (damage, source) {
		// Only take damage from non-pea sources
		if (source !== 'pea' && source !== 'frozenpea') {
			self.health -= damage;
			LK.effects.flashObject(self, 0xff0000, 200);
			LK.getSound('zombie_hit').play();
			if (self.health <= 0) {
				self.destroy();
				for (var i = 0; i < zombies.length; i++) {
					if (zombies[i] === self) {
						zombies.splice(i, 1);
						break;
					}
				}
				zombiesKilled++;
			}
		}
	};
	return self;
});
var JackInBoxZombie = BasicZombie.expand(function () {
	var self = BasicZombie.call(this);
	// Replace the graphics with jack in box zombie asset
	self.removeChild(self.children[0]);
	var graphics = self.attachAsset('jackInBoxZombie', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 0.7;
	self.health = 80;
	self.maxHealth = 80;
	self.damage = 60;
	self.hasExploded = false;
	self.explode = function () {
		if (self.hasExploded) return;
		self.hasExploded = true;
		// Flash the jack in box zombie white before exploding
		LK.effects.flashObject(self, 0xffffff, 200);
		// Scale up effect for explosion
		tween(graphics, {
			scaleX: 3,
			scaleY: 3,
			alpha: 0
		}, {
			duration: 500,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				// Remove from zombies array
				for (var i = 0; i < zombies.length; i++) {
					if (zombies[i] === self) {
						zombies.splice(i, 1);
						break;
					}
				}
				// Destroy the jack in box zombie
				self.destroy();
			}
		});
		// Eliminate plants in a 250 pixel radius
		var explosionRadius = 250;
		for (var i = plants.length - 1; i >= 0; i--) {
			var plant = plants[i];
			var distance = Math.sqrt(Math.pow(plant.x - self.x, 2) + Math.pow(plant.y - self.y, 2));
			if (distance <= explosionRadius) {
				// Flash plant red before destroying
				LK.effects.flashObject(plant, 0xff0000, 200);
				// Remove from plant grid
				var gridKey = plant.gridX + ',' + plant.gridY;
				delete plantGrid[gridKey];
				plant.destroy();
				plants.splice(i, 1);
			}
		}
	};
	self.update = function () {
		// Check if there's a plant to explode on
		var plantToExplode = null;
		for (var i = 0; i < plants.length; i++) {
			var plant = plants[i];
			if (plant.gridY === self.gridY && Math.abs(plant.x - self.x) < 80) {
				plantToExplode = plant;
				break;
			}
		}
		if (plantToExplode && !self.hasExploded) {
			self.explode();
		} else {
			self.x -= self.speed;
		}
		// Check if reached house
		if (self.x < 150) {
			LK.showGameOver();
		}
	};
	return self;
});
var Gargantuar = BasicZombie.expand(function () {
	var self = BasicZombie.call(this);
	// Replace the graphics with gargantuar asset
	self.removeChild(self.children[0]);
	var graphics = self.attachAsset('gargantuar', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 0.2; // Very slow
	self.health = 400; // Very resistant
	self.maxHealth = 400;
	self.damage = 200; // High damage to eliminate plants instantly
	self.gridY = 0;
	self.attackTimer = 0;
	self.attackDelay = 30; // Fast elimination
	self.hasSpawnedFastZombie = false;
	self.isResistantToExplosion = true; // Flag for cherry popper resistance
	self.update = function () {
		// Check if there's a plant to eliminate
		var plantToEliminate = null;
		for (var i = 0; i < plants.length; i++) {
			var plant = plants[i];
			if (plant.gridY === self.gridY && Math.abs(plant.x - self.x) < 120) {
				plantToEliminate = plant;
				break;
			}
		}
		if (plantToEliminate) {
			self.attackTimer++;
			if (self.attackTimer >= self.attackDelay) {
				// Instantly eliminate the plant
				LK.effects.flashObject(plantToEliminate, 0xff0000, 200);
				// Remove from plant grid
				var gridKey = plantToEliminate.gridX + ',' + plantToEliminate.gridY;
				delete plantGrid[gridKey];
				plantToEliminate.destroy();
				for (var j = 0; j < plants.length; j++) {
					if (plants[j] === plantToEliminate) {
						plants.splice(j, 1);
						break;
					}
				}
				self.attackTimer = 0;
			}
		} else {
			self.x -= self.speed;
			self.attackTimer = 0;
		}
		// Spawn FastZombie when at half health
		if (self.health <= self.maxHealth / 2 && !self.hasSpawnedFastZombie) {
			self.hasSpawnedFastZombie = true;
			var fastZombie = new FastZombie();
			// Spawn in the third square of the garden (gridStartX + 2 * gridWidth for third column)
			fastZombie.x = gridStartX + 2 * gridWidth + gridWidth / 2;
			fastZombie.y = gridStartY + self.gridY * gridHeight + gridHeight / 2;
			fastZombie.gridY = self.gridY;
			zombies.push(fastZombie);
			game.addChild(fastZombie);
			// Visual effect for spawning
			LK.effects.flashObject(self, 0xffff00, 500);
		}
		// Check if reached house
		if (self.x < 150) {
			LK.showGameOver();
		}
	};
	return self;
});
var FastZombie = BasicZombie.expand(function () {
	var self = BasicZombie.call(this);
	// Replace the graphics with fast zombie asset
	self.removeChild(self.children[0]);
	var graphics = self.attachAsset('fastZombie', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 1.2;
	self.health = 60;
	self.maxHealth = 60;
	self.damage = 40;
	self.gridY = 0;
	self.attackTimer = 0;
	self.attackDelay = 60;
	return self;
});
var CherryPopper = Container.expand(function () {
	var self = Container.call(this);
	var graphics = self.attachAsset('cherrypopper', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.cost = 150;
	self.gridX = 0;
	self.gridY = 0;
	self.hasExploded = false;
	self.explode = function () {
		if (self.hasExploded) return;
		self.hasExploded = true;
		// Flash the cherry popper white before exploding
		LK.effects.flashObject(self, 0xffffff, 200);
		// Scale up effect for explosion
		tween(graphics, {
			scaleX: 3,
			scaleY: 3,
			alpha: 0
		}, {
			duration: 500,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				// Remove from plants array
				for (var i = 0; i < plants.length; i++) {
					if (plants[i] === self) {
						plants.splice(i, 1);
						break;
					}
				}
				// Remove from plant grid
				var gridKey = self.gridX + ',' + self.gridY;
				delete plantGrid[gridKey];
				// Destroy the cherry popper
				self.destroy();
			}
		});
		// Eliminate zombies in a 300 pixel radius
		var explosionRadius = 300;
		for (var i = zombies.length - 1; i >= 0; i--) {
			var zombie = zombies[i];
			var distance = Math.sqrt(Math.pow(zombie.x - self.x, 2) + Math.pow(zombie.y - self.y, 2));
			if (distance <= explosionRadius) {
				// Special handling for Gargantuar
				if (zombie.constructor === Gargantuar) {
					// Flash zombie red
					LK.effects.flashObject(zombie, 0xff0000, 200);
					// If at full health or more than half, reduce to half
					if (zombie.health > zombie.maxHealth / 2) {
						zombie.health = zombie.maxHealth / 2;
						// Visual effect for being damaged but not destroyed
						tween(zombie, {
							tint: 0xff4444
						}, {
							duration: 500,
							easing: tween.easeOut
						});
					} else {
						// Second explosion - eliminate Gargantuar
						zombie.destroy();
						zombies.splice(i, 1);
						zombiesKilled++;
					}
				} else {
					// Normal zombies - eliminate immediately
					LK.effects.flashObject(zombie, 0xff0000, 200);
					zombie.destroy();
					zombies.splice(i, 1);
					zombiesKilled++;
				}
			}
		}
	};
	// Auto-explode when planted (immediately after placement)
	self.update = function () {
		if (!self.hasExploded) {
			self.explode();
		}
	};
	return self;
});
var Chomper = Container.expand(function () {
	var self = Container.call(this);
	var graphics = self.attachAsset('chomper', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.cost = 150;
	self.health = 100;
	self.maxHealth = 100;
	self.gridX = 0;
	self.gridY = 0;
	self.eatCooldown = 0;
	self.maxEatCooldown = 900; // 15 seconds at 60fps
	self.isOnCooldown = false;
	self.digestionTimer = 0;
	self.maxDigestionTime = 180; // 3 seconds to digest
	self.isDigesting = false;
	self.takeDamage = function (damage) {
		self.health -= damage;
		LK.effects.flashObject(self, 0xff0000, 200);
		if (self.health <= 0) {
			self.destroy();
			for (var i = 0; i < plants.length; i++) {
				if (plants[i] === self) {
					plants.splice(i, 1);
					break;
				}
			}
			var gridKey = self.gridX + ',' + self.gridY;
			delete plantGrid[gridKey];
		} else {
			// Visual damage feedback
			var damageRatio = self.health / self.maxHealth;
			graphics.alpha = 0.3 + damageRatio * 0.7;
		}
	};
	self.update = function () {
		// Handle digestion timer
		if (self.isDigesting) {
			self.digestionTimer++;
			if (self.digestionTimer >= self.maxDigestionTime) {
				self.isDigesting = false;
				self.digestionTimer = 0;
				// Reset color after digesting
				tween(graphics, {
					tint: 0xffffff
				}, {
					duration: 300,
					easing: tween.easeOut
				});
			}
			return; // Don't eat while digesting
		}
		// Handle cooldown
		if (self.isOnCooldown) {
			self.eatCooldown--;
			if (self.eatCooldown <= 0) {
				self.isOnCooldown = false;
				// Reset color when cooldown ends
				tween(graphics, {
					tint: 0xffffff
				}, {
					duration: 300,
					easing: tween.easeOut
				});
			} else {
				// Ensure black color is maintained during cooldown
				if (graphics.tint !== 0x000000) {
					tween(graphics, {
						tint: 0x000000
					}, {
						duration: 100,
						easing: tween.easeOut
					});
				}
			}
			return; // Don't eat while on cooldown
		}
		// Look for the nearest zombie in adjacent squares (two square range)
		var nearestZombie = null;
		var nearestDistance = Infinity;
		var nearestIndex = -1;
		for (var i = zombies.length - 1; i >= 0; i--) {
			var zombie = zombies[i];
			// Check if zombie is in same lane and within two grid square range
			var gridDistance = Math.abs(zombie.x - self.x) / gridWidth;
			if (zombie.gridY === self.gridY && gridDistance <= 2.2) {
				var distance = Math.abs(zombie.x - self.x);
				if (distance < nearestDistance) {
					nearestDistance = distance;
					nearestZombie = zombie;
					nearestIndex = i;
				}
			}
		}
		// Eat the nearest zombie if found
		if (nearestZombie) {
			self.eatZombie(nearestZombie, nearestIndex);
		}
	};
	self.eatZombie = function (zombie, zombieIndex) {
		// Check if zombie is a Gargantuar - cannot be eaten
		if (zombie.constructor === Gargantuar) {
			// Flash red to show chomper can't eat this zombie
			LK.effects.flashObject(self, 0xff0000, 300);
			return; // Exit without eating
		}
		// Flash white to show eating action
		LK.effects.flashObject(self, 0xffffff, 300);
		// Remove zombie immediately
		zombie.destroy();
		zombies.splice(zombieIndex, 1);
		zombiesKilled++;
		// Start digestion period
		self.isDigesting = true;
		self.digestionTimer = 0;
		// Visual feedback for digesting (green tint)
		tween(graphics, {
			tint: 0x44ff44
		}, {
			duration: 300,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				// Start cooldown after digestion
				self.isOnCooldown = true;
				self.eatCooldown = self.maxEatCooldown;
				// Visual feedback for cooldown (black tint)
				tween(graphics, {
					tint: 0x000000
				}, {
					duration: 300,
					easing: tween.easeOut
				});
			}
		});
	};
	return self;
});
var FrozenPea = Container.expand(function () {
	var self = Container.call(this);
	var graphics = self.attachAsset('frozenpea', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 8;
	self.damage = 15;
	self.gridY = 0;
	self.slowDuration = 300; // 5 seconds at 60fps
	self.slowFactor = 0.3; // Reduce speed to 30%
	self.update = function () {
		self.x += self.speed;
		// Check collision with zombies
		for (var i = 0; i < zombies.length; i++) {
			var zombie = zombies[i];
			if (zombie.gridY === self.gridY && self.intersects(zombie)) {
				// Check if it's a JesterZombie
				if (zombie.isJester) {
					// Create reflected frozen pea going back towards plants
					var reflectedFrozenPea = new ReflectedFrozenPea();
					reflectedFrozenPea.x = zombie.x - 50;
					reflectedFrozenPea.y = zombie.y;
					reflectedFrozenPea.gridY = zombie.gridY;
					reflectedfrozenpeas.push(reflectedFrozenPea);
					game.addChild(reflectedFrozenPea);
					// Flash jester zombie to show deflection
					LK.effects.flashObject(zombie, 0xffff00, 200);
				} else {
					zombie.takeDamage(self.damage, 'frozenpea');
					// Apply slow effect only if not a Zomboni or NewspaperZombie
					if (zombie.constructor !== Zomboni && zombie.constructor !== NewspaperZombie) {
						if (!zombie.originalSpeed) {
							zombie.originalSpeed = zombie.speed;
						}
						zombie.speed = zombie.originalSpeed * self.slowFactor;
						zombie.slowTimer = self.slowDuration;
						// Visual effect for slowed zombie
						tween(zombie, {
							tint: 0x87ceeb
						}, {
							duration: 300,
							easing: tween.easeOut
						});
					}
				}
				self.destroy();
				for (var j = 0; j < frozenpeas.length; j++) {
					if (frozenpeas[j] === self) {
						frozenpeas.splice(j, 1);
						break;
					}
				}
				return;
			}
		}
		// Remove if off screen
		if (self.x > 2200) {
			self.destroy();
			for (var k = 0; k < frozenpeas.length; k++) {
				if (frozenpeas[k] === self) {
					frozenpeas.splice(k, 1);
					break;
				}
			}
		}
	};
	return self;
});
var Pea = Container.expand(function () {
	var self = Container.call(this);
	var graphics = self.attachAsset('pea', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 8;
	self.damage = 15;
	self.gridY = 0;
	self.update = function () {
		self.x += self.speed;
		// Check collision with zombies
		for (var i = 0; i < zombies.length; i++) {
			var zombie = zombies[i];
			if (zombie.gridY === self.gridY && self.intersects(zombie)) {
				// Check if it's a JesterZombie
				if (zombie.isJester) {
					// Create reflected pea going back towards plants
					var reflectedPea = new ReflectedPea();
					reflectedPea.x = zombie.x - 50;
					reflectedPea.y = zombie.y;
					reflectedPea.gridY = zombie.gridY;
					reflectedpeas.push(reflectedPea);
					game.addChild(reflectedPea);
					// Flash jester zombie to show deflection
					LK.effects.flashObject(zombie, 0xffff00, 200);
				} else {
					zombie.takeDamage(self.damage, 'pea');
				}
				self.destroy();
				for (var j = 0; j < peas.length; j++) {
					if (peas[j] === self) {
						peas.splice(j, 1);
						break;
					}
				}
				return;
			}
		}
		// Remove if off screen
		if (self.x > 2200) {
			self.destroy();
			for (var k = 0; k < peas.length; k++) {
				if (peas[k] === self) {
					peas.splice(k, 1);
					break;
				}
			}
		}
	};
	return self;
});
var Peashooter = Container.expand(function () {
	var self = Container.call(this);
	var graphics = self.attachAsset('peashooter', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.cost = 100;
	self.health = 100;
	self.maxHealth = 100;
	self.shootTimer = 0;
	self.shootDelay = 90; // 1.5 seconds at 60fps
	self.gridX = 0;
	self.gridY = 0;
	self.takeDamage = function (damage) {
		self.health -= damage;
		LK.effects.flashObject(self, 0xff0000, 200);
		if (self.health <= 0) {
			self.destroy();
			for (var i = 0; i < plants.length; i++) {
				if (plants[i] === self) {
					plants.splice(i, 1);
					break;
				}
			}
			var gridKey = self.gridX + ',' + self.gridY;
			delete plantGrid[gridKey];
		} else {
			// Visual damage feedback
			var damageRatio = self.health / self.maxHealth;
			graphics.alpha = 0.3 + damageRatio * 0.7;
		}
	};
	self.update = function () {
		self.shootTimer++;
		if (self.shootTimer >= self.shootDelay) {
			// Check if there's a zombie in this lane
			var hasZombieInLane = false;
			for (var i = 0; i < zombies.length; i++) {
				if (zombies[i].gridY === self.gridY && zombies[i].x > self.x) {
					hasZombieInLane = true;
					break;
				}
			}
			if (hasZombieInLane) {
				self.shoot();
				self.shootTimer = 0;
			}
		}
	};
	self.shoot = function () {
		var pea = new Pea();
		pea.x = self.x + 60;
		pea.y = self.y;
		pea.gridY = self.gridY;
		peas.push(pea);
		game.addChild(pea);
		LK.getSound('shoot').play();
	};
	return self;
});
var Potatomine = Container.expand(function () {
	var self = Container.call(this);
	var graphics = self.attachAsset('potatomine', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.cost = 25;
	self.health = 100;
	self.maxHealth = 100;
	self.gridX = 0;
	self.gridY = 0;
	self.chargeTimer = 0;
	self.maxChargeTime = 900; // 15 seconds at 60fps
	self.isCharged = false;
	self.hasExploded = false;
	// Start with black color (charging state)
	graphics.tint = 0x000000;
	self.takeDamage = function (damage) {
		self.health -= damage;
		LK.effects.flashObject(self, 0xff0000, 200);
		if (self.health <= 0) {
			self.destroy();
			for (var i = 0; i < plants.length; i++) {
				if (plants[i] === self) {
					plants.splice(i, 1);
					break;
				}
			}
			var gridKey = self.gridX + ',' + self.gridY;
			delete plantGrid[gridKey];
		} else {
			// Visual damage feedback
			var damageRatio = self.health / self.maxHealth;
			graphics.alpha = 0.3 + damageRatio * 0.7;
		}
	};
	self.update = function () {
		// Handle charging timer
		if (!self.isCharged && !self.hasExploded) {
			self.chargeTimer++;
			if (self.chargeTimer >= self.maxChargeTime) {
				self.isCharged = true;
				// Change to normal color when charged
				tween(graphics, {
					tint: 0xffffff
				}, {
					duration: 500,
					easing: tween.easeOut
				});
			}
			return; // Don't explode while charging
		}
		// Check for zombies touching this potatomine
		if (self.isCharged && !self.hasExploded) {
			for (var i = 0; i < zombies.length; i++) {
				var zombie = zombies[i];
				if (zombie.gridY === self.gridY && self.intersects(zombie)) {
					self.explode();
					break;
				}
			}
		}
	};
	self.explode = function () {
		if (self.hasExploded) return;
		self.hasExploded = true;
		// Flash white before exploding
		LK.effects.flashObject(self, 0xffffff, 200);
		// Scale up effect for explosion
		tween(graphics, {
			scaleX: 3,
			scaleY: 3,
			alpha: 0
		}, {
			duration: 500,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				// Remove from plants array
				for (var i = 0; i < plants.length; i++) {
					if (plants[i] === self) {
						plants.splice(i, 1);
						break;
					}
				}
				// Remove from plant grid
				var gridKey = self.gridX + ',' + self.gridY;
				delete plantGrid[gridKey];
				// Destroy the potatomine
				self.destroy();
			}
		});
		// Eliminate zombies in a 200 pixel radius
		var explosionRadius = 200;
		for (var i = zombies.length - 1; i >= 0; i--) {
			var zombie = zombies[i];
			var distance = Math.sqrt(Math.pow(zombie.x - self.x, 2) + Math.pow(zombie.y - self.y, 2));
			if (distance <= explosionRadius) {
				// Special handling for Gargantuar and NewspaperZombie
				if (zombie.constructor === Gargantuar || zombie.constructor === NewspaperZombie) {
					// Flash zombie red
					LK.effects.flashObject(zombie, 0xff0000, 200);
					// Reduce to half health
					zombie.health = zombie.maxHealth / 2;
					// Visual effect for being damaged but not destroyed
					tween(zombie, {
						tint: 0xff4444
					}, {
						duration: 500,
						easing: tween.easeOut
					});
					// Check if zombie should be eliminated after damage
					if (zombie.health <= 0) {
						zombie.destroy();
						zombies.splice(i, 1);
						zombiesKilled++;
					}
				} else {
					// Normal zombies - eliminate immediately
					LK.effects.flashObject(zombie, 0xff0000, 200);
					zombie.destroy();
					zombies.splice(i, 1);
					zombiesKilled++;
				}
			}
		}
	};
	return self;
});
var Puffshroom = Container.expand(function () {
	var self = Container.call(this);
	var graphics = self.attachAsset('puffshroom', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.cost = 0;
	self.health = 100;
	self.maxHealth = 100;
	self.shootTimer = 0;
	self.shootDelay = 120; // 2 seconds at 60fps
	self.gridX = 0;
	self.gridY = 0;
	self.detectionRange = 3; // 3 tiles
	self.takeDamage = function (damage) {
		self.health -= damage;
		LK.effects.flashObject(self, 0xff0000, 200);
		if (self.health <= 0) {
			self.destroy();
			for (var i = 0; i < plants.length; i++) {
				if (plants[i] === self) {
					plants.splice(i, 1);
					break;
				}
			}
			var gridKey = self.gridX + ',' + self.gridY;
			delete plantGrid[gridKey];
		} else {
			// Visual damage feedback
			var damageRatio = self.health / self.maxHealth;
			graphics.alpha = 0.3 + damageRatio * 0.7;
		}
	};
	self.update = function () {
		self.shootTimer++;
		if (self.shootTimer >= self.shootDelay) {
			// Check if there's a zombie within 3 tiles in this lane
			var hasZombieInRange = false;
			for (var i = 0; i < zombies.length; i++) {
				var zombie = zombies[i];
				if (zombie.gridY === self.gridY && zombie.x > self.x) {
					var distance = Math.abs(zombie.x - self.x);
					var tileDistance = distance / gridWidth;
					if (tileDistance <= self.detectionRange) {
						hasZombieInRange = true;
						break;
					}
				}
			}
			if (hasZombieInRange) {
				self.shoot();
				self.shootTimer = 0;
			}
		}
	};
	self.shoot = function () {
		var spore = new Spore();
		spore.x = self.x + 40;
		spore.y = self.y;
		spore.gridY = self.gridY;
		spores.push(spore);
		game.addChild(spore);
		LK.getSound('shoot').play();
	};
	return self;
});
var ReflectedFrozenPea = Container.expand(function () {
	var self = Container.call(this);
	var graphics = self.attachAsset('frozenpea', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Tint dark red to show it's reflected
	graphics.tint = 0xaa2222;
	self.speed = -8; // Negative speed to go backwards
	self.damage = 20; // Slightly more damage than regular frozen peas
	self.gridY = 0;
	self.update = function () {
		self.x += self.speed;
		// Check collision with plants
		for (var i = 0; i < plants.length; i++) {
			var plant = plants[i];
			if (plant.gridY === self.gridY && self.intersects(plant)) {
				if (plant.takeDamage) {
					plant.takeDamage(self.damage);
				}
				self.destroy();
				for (var j = 0; j < reflectedfrozenpeas.length; j++) {
					if (reflectedfrozenpeas[j] === self) {
						reflectedfrozenpeas.splice(j, 1);
						break;
					}
				}
				return;
			}
		}
		// Remove if off screen (left side)
		if (self.x < -100) {
			self.destroy();
			for (var k = 0; k < reflectedfrozenpeas.length; k++) {
				if (reflectedfrozenpeas[k] === self) {
					reflectedfrozenpeas.splice(k, 1);
					break;
				}
			}
		}
	};
	return self;
});
var ReflectedPea = Container.expand(function () {
	var self = Container.call(this);
	var graphics = self.attachAsset('pea', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Tint red to show it's reflected
	graphics.tint = 0xff4444;
	self.speed = -8; // Negative speed to go backwards
	self.damage = 20; // Slightly more damage than regular peas
	self.gridY = 0;
	self.update = function () {
		self.x += self.speed;
		// Check collision with plants
		for (var i = 0; i < plants.length; i++) {
			var plant = plants[i];
			if (plant.gridY === self.gridY && self.intersects(plant)) {
				if (plant.takeDamage) {
					plant.takeDamage(self.damage);
				}
				self.destroy();
				for (var j = 0; j < reflectedpeas.length; j++) {
					if (reflectedpeas[j] === self) {
						reflectedpeas.splice(j, 1);
						break;
					}
				}
				return;
			}
		}
		// Remove if off screen (left side)
		if (self.x < -100) {
			self.destroy();
			for (var k = 0; k < reflectedpeas.length; k++) {
				if (reflectedpeas[k] === self) {
					reflectedpeas.splice(k, 1);
					break;
				}
			}
		}
	};
	return self;
});
var ReflectedSpore = Container.expand(function () {
	var self = Container.call(this);
	var graphics = self.attachAsset('spore', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Tint dark brown to show it's reflected
	graphics.tint = 0x654321;
	self.speed = -6;
	self.damage = 15;
	self.gridY = 0;
	self.update = function () {
		self.x += self.speed;
		// Check collision with plants
		for (var i = 0; i < plants.length; i++) {
			var plant = plants[i];
			if (plant.gridY === self.gridY && self.intersects(plant)) {
				if (plant.takeDamage) {
					plant.takeDamage(self.damage);
				}
				self.destroy();
				for (var j = 0; j < reflectedspores.length; j++) {
					if (reflectedspores[j] === self) {
						reflectedspores.splice(j, 1);
						break;
					}
				}
				return;
			}
		}
		// Remove if off screen (left side)
		if (self.x < -100) {
			self.destroy();
			for (var k = 0; k < reflectedspores.length; k++) {
				if (reflectedspores[k] === self) {
					reflectedspores.splice(k, 1);
					break;
				}
			}
		}
	};
	return self;
});
var Repeater = Container.expand(function () {
	var self = Container.call(this);
	var graphics = self.attachAsset('repeater', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.cost = 200;
	self.health = 100;
	self.maxHealth = 100;
	self.shootTimer = 0;
	self.shootDelay = 90; // 1.5 seconds at 60fps
	self.secondShotTimer = 0;
	self.secondShotDelay = 15; // 0.25 seconds delay between shots
	self.waitingForSecondShot = false;
	self.gridX = 0;
	self.gridY = 0;
	self.takeDamage = function (damage) {
		self.health -= damage;
		LK.effects.flashObject(self, 0xff0000, 200);
		if (self.health <= 0) {
			self.destroy();
			for (var i = 0; i < plants.length; i++) {
				if (plants[i] === self) {
					plants.splice(i, 1);
					break;
				}
			}
			var gridKey = self.gridX + ',' + self.gridY;
			delete plantGrid[gridKey];
		} else {
			// Visual damage feedback
			var damageRatio = self.health / self.maxHealth;
			graphics.alpha = 0.3 + damageRatio * 0.7;
		}
	};
	self.update = function () {
		// Handle second shot timing
		if (self.waitingForSecondShot) {
			self.secondShotTimer++;
			if (self.secondShotTimer >= self.secondShotDelay) {
				self.shoot(); // Fire second pea
				self.waitingForSecondShot = false;
				self.secondShotTimer = 0;
			}
		} else {
			self.shootTimer++;
			if (self.shootTimer >= self.shootDelay) {
				// Check if there's a zombie in this lane
				var hasZombieInLane = false;
				for (var i = 0; i < zombies.length; i++) {
					if (zombies[i].gridY === self.gridY && zombies[i].x > self.x) {
						hasZombieInLane = true;
						break;
					}
				}
				if (hasZombieInLane) {
					self.shoot(); // Fire first pea
					self.waitingForSecondShot = true; // Queue second shot
					self.shootTimer = 0;
				}
			}
		}
	};
	self.shoot = function () {
		var pea = new Pea();
		pea.x = self.x + 60;
		pea.y = self.y;
		pea.gridY = self.gridY;
		peas.push(pea);
		game.addChild(pea);
		LK.getSound('shoot').play();
	};
	return self;
});
var Snowshooter = Container.expand(function () {
	var self = Container.call(this);
	var graphics = self.attachAsset('snowshooter', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.cost = 175;
	self.health = 100;
	self.maxHealth = 100;
	self.shootTimer = 0;
	self.shootDelay = 90; // 1.5 seconds at 60fps
	self.gridX = 0;
	self.gridY = 0;
	self.takeDamage = function (damage) {
		self.health -= damage;
		LK.effects.flashObject(self, 0xff0000, 200);
		if (self.health <= 0) {
			self.destroy();
			for (var i = 0; i < plants.length; i++) {
				if (plants[i] === self) {
					plants.splice(i, 1);
					break;
				}
			}
			var gridKey = self.gridX + ',' + self.gridY;
			delete plantGrid[gridKey];
		} else {
			// Visual damage feedback
			var damageRatio = self.health / self.maxHealth;
			graphics.alpha = 0.3 + damageRatio * 0.7;
		}
	};
	self.update = function () {
		self.shootTimer++;
		if (self.shootTimer >= self.shootDelay) {
			// Check if there's a zombie in this lane
			var hasZombieInLane = false;
			for (var i = 0; i < zombies.length; i++) {
				if (zombies[i].gridY === self.gridY && zombies[i].x > self.x) {
					hasZombieInLane = true;
					break;
				}
			}
			if (hasZombieInLane) {
				self.shoot();
				self.shootTimer = 0;
			}
		}
	};
	self.shoot = function () {
		var frozenpea = new FrozenPea();
		frozenpea.x = self.x + 60;
		frozenpea.y = self.y;
		frozenpea.gridY = self.gridY;
		frozenpeas.push(frozenpea);
		game.addChild(frozenpea);
		LK.getSound('shoot').play();
	};
	return self;
});
var SplitPea = Container.expand(function () {
	var self = Container.call(this);
	var graphics = self.attachAsset('splitpea', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.cost = 125;
	self.health = 100;
	self.maxHealth = 100;
	self.shootTimer = 0;
	self.shootDelay = 90; // 1.5 seconds at 60fps 
	self.gridX = 0;
	self.gridY = 0;
	self.takeDamage = function (damage) {
		self.health -= damage;
		LK.effects.flashObject(self, 0xff0000, 200);
		if (self.health <= 0) {
			self.destroy();
			for (var i = 0; i < plants.length; i++) {
				if (plants[i] === self) {
					plants.splice(i, 1);
					break;
				}
			}
			var gridKey = self.gridX + ',' + self.gridY;
			delete plantGrid[gridKey];
		} else {
			// Visual damage feedback 
			var damageRatio = self.health / self.maxHealth;
			graphics.alpha = 0.3 + damageRatio * 0.7;
		}
	};
	self.update = function () {
		self.shootTimer++;
		if (self.shootTimer >= self.shootDelay) {
			// Check if there's a zombie in this lane (both front and back) 
			var hasZombieInLane = false;
			for (var i = 0; i < zombies.length; i++) {
				if (zombies[i].gridY === self.gridY) {
					hasZombieInLane = true;
					break;
				}
			}
			if (hasZombieInLane) {
				self.shoot();
				self.shootTimer = 0;
			}
		}
	};
	self.shoot = function () {
		// Shoot one pea forward 
		var forwardPea = new Pea();
		forwardPea.x = self.x + 60;
		forwardPea.y = self.y;
		forwardPea.gridY = self.gridY;
		peas.push(forwardPea);
		game.addChild(forwardPea);
		// Shoot two peas backward 
		var backwardPea1 = new BackwardPea();
		backwardPea1.x = self.x - 60;
		backwardPea1.y = self.y - 20;
		backwardPea1.gridY = self.gridY;
		backwardpeas.push(backwardPea1);
		game.addChild(backwardPea1);
		var backwardPea2 = new BackwardPea();
		backwardPea2.x = self.x - 60;
		backwardPea2.y = self.y + 20;
		backwardPea2.gridY = self.gridY;
		backwardpeas.push(backwardPea2);
		game.addChild(backwardPea2);
		LK.getSound('shoot').play();
	};
	return self;
});
var Spore = Container.expand(function () {
	var self = Container.call(this);
	var graphics = self.attachAsset('spore', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 6;
	self.damage = 10;
	self.gridY = 0;
	self.update = function () {
		self.x += self.speed;
		// Check collision with zombies
		for (var i = 0; i < zombies.length; i++) {
			var zombie = zombies[i];
			if (zombie.gridY === self.gridY && self.intersects(zombie)) {
				// Check if it's a JesterZombie
				if (zombie.isJester) {
					// Create reflected spore going back towards plants
					var reflectedSpore = new ReflectedSpore();
					reflectedSpore.x = zombie.x - 50;
					reflectedSpore.y = zombie.y;
					reflectedSpore.gridY = zombie.gridY;
					reflectedspores.push(reflectedSpore);
					game.addChild(reflectedSpore);
					// Flash jester zombie to show deflection
					LK.effects.flashObject(zombie, 0xffff00, 200);
				} else {
					zombie.takeDamage(self.damage, 'spore');
				}
				self.destroy();
				for (var j = 0; j < spores.length; j++) {
					if (spores[j] === self) {
						spores.splice(j, 1);
						break;
					}
				}
				return;
			}
		}
		// Remove if off screen
		if (self.x > 2200) {
			self.destroy();
			for (var k = 0; k < spores.length; k++) {
				if (spores[k] === self) {
					spores.splice(k, 1);
					break;
				}
			}
		}
	};
	return self;
});
var Sun = Container.expand(function () {
	var self = Container.call(this);
	var graphics = self.attachAsset('sun', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.value = 25;
	self.lifeTimer = 0;
	self.maxLife = 600; // 10 seconds
	self.update = function () {
		self.lifeTimer++;
		if (self.lifeTimer > self.maxLife) {
			self.destroy();
			for (var i = 0; i < suns.length; i++) {
				if (suns[i] === self) {
					suns.splice(i, 1);
					break;
				}
			}
		}
	};
	self.down = function (x, y, obj) {
		sunPoints += self.value;
		updateSunDisplay();
		self.destroy();
		for (var i = 0; i < suns.length; i++) {
			if (suns[i] === self) {
				suns.splice(i, 1);
				break;
			}
		}
		LK.getSound('collect').play();
	};
	return self;
});
var Sunflower = Container.expand(function () {
	var self = Container.call(this);
	var graphics = self.attachAsset('sunflower', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.cost = 50;
	self.health = 100;
	self.maxHealth = 100;
	self.sunTimer = 0;
	self.sunDelay = 600; // 10 seconds at 60fps
	self.gridX = 0;
	self.gridY = 0;
	self.takeDamage = function (damage) {
		self.health -= damage;
		LK.effects.flashObject(self, 0xff0000, 200);
		if (self.health <= 0) {
			self.destroy();
			for (var i = 0; i < plants.length; i++) {
				if (plants[i] === self) {
					plants.splice(i, 1);
					break;
				}
			}
			var gridKey = self.gridX + ',' + self.gridY;
			delete plantGrid[gridKey];
		} else {
			// Visual damage feedback
			var damageRatio = self.health / self.maxHealth;
			graphics.alpha = 0.3 + damageRatio * 0.7;
		}
	};
	self.update = function () {
		self.sunTimer++;
		if (self.sunTimer >= self.sunDelay) {
			self.produceSun();
			self.sunTimer = 0;
		}
	};
	self.produceSun = function () {
		var sun = new Sun();
		sun.x = self.x + (Math.random() - 0.5) * 50;
		sun.y = self.y + (Math.random() - 0.5) * 50;
		suns.push(sun);
		game.addChild(sun);
	};
	return self;
});
var WallNut = Container.expand(function () {
	var self = Container.call(this);
	var graphics = self.attachAsset('wallnut', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.cost = 50;
	self.health = 300;
	self.maxHealth = 300;
	self.gridX = 0;
	self.gridY = 0;
	self.takeDamage = function (damage) {
		self.health -= damage;
		if (self.health <= 0) {
			self.destroy();
			for (var i = 0; i < plants.length; i++) {
				if (plants[i] === self) {
					plants.splice(i, 1);
					break;
				}
			}
			var gridKey = self.gridX + ',' + self.gridY;
			delete plantGrid[gridKey];
		} else {
			// Visual damage feedback
			var damageRatio = self.health / self.maxHealth;
			graphics.alpha = 0.3 + damageRatio * 0.7;
		}
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x8BC34A
});
/**** 
* Game Code
****/ 
// Sounds
// Zombies
// Projectiles and collectibles
// Plants
// Game grid and UI elements
// Game variables
var sunPoints = 150;
var currentWave = 1;
var maxWaves = 20;
var waveTimer = 0;
var waveDelay = 1800; // 30 seconds
var zombieSpawnTimer = 0;
var zombieSpawnDelay = 240; // 4 seconds
var zombiesPerWave = 5;
var zombiesSpawned = 0;
var zombiesKilled = 0;
var totalZombiesToKill = 0;
var waveStarted = false;
var zombieSpawnQueue = [];
// Game arrays
var plants = [];
var zombies = [];
var peas = [];
var frozenpeas = [];
var reflectedpeas = [];
var reflectedfrozenpeas = [];
var backwardpeas = [];
var spores = [];
var reflectedspores = [];
var suns = [];
var plantGrid = {}; // Track occupied grid positions
// Grid settings
var gridStartX = 400;
var gridStartY = 400;
var gridWidth = 320;
var gridHeight = 227;
var gridCols = 5;
var gridRows = 5;
// Selected plant type
var selectedPlantType = null;
// Plant selector management
var currentSelectorPage = 1;
var maxSelectorPages = 2;
// Create lawn grid
for (var row = 0; row < gridRows; row++) {
	for (var col = 0; col < gridCols; col++) {
		var tile = game.addChild(LK.getAsset('grass', {
			x: gridStartX + col * gridWidth,
			y: gridStartY + row * gridHeight,
			anchorX: 0,
			anchorY: 0
		}));
	}
}
// Create paths (zombie lanes)
for (var lane = 0; lane < gridRows; lane++) {
	var pathTile = game.addChild(LK.getAsset('path', {
		x: gridStartX + gridCols * gridWidth,
		y: gridStartY + lane * gridHeight,
		anchorX: 0,
		anchorY: 0
	}));
}
// Create house
var house = game.addChild(LK.getAsset('house', {
	x: 50,
	y: gridStartY + gridRows * gridHeight / 2 - 200,
	anchorX: 0,
	anchorY: 0
}));
// UI Setup
var sunDisplay = new Text2(sunPoints.toString(), {
	size: 80,
	fill: 0xFFD700,
	stroke: 0x000000,
	strokeThickness: 3
});
sunDisplay.anchor.set(0, 0);
LK.gui.topLeft.addChild(sunDisplay);
sunDisplay.x = 120;
sunDisplay.y = 20;
var waveDisplay = new Text2('Wave: ' + currentWave + '/' + maxWaves, {
	size: 60,
	fill: 0x000000
});
waveDisplay.anchor.set(0.5, 0);
LK.gui.top.addChild(waveDisplay);
waveDisplay.y = 20;
// Plant selection buttons - repositioned for new order
var peashooterBtn = LK.getAsset('peashooter', {
	x: 250,
	y: 2500,
	scaleX: 0.8,
	scaleY: 0.8,
	anchorX: 0.5,
	anchorY: 0.5
});
game.addChild(peashooterBtn);
var sunflowerBtn = LK.getAsset('sunflower', {
	x: 450,
	y: 2500,
	scaleX: 0.8,
	scaleY: 0.8,
	anchorX: 0.5,
	anchorY: 0.5
});
game.addChild(sunflowerBtn);
var cherrypopperBtn = LK.getAsset('cherrypopper', {
	x: 650,
	y: 2500,
	scaleX: 0.8,
	scaleY: 0.8,
	anchorX: 0.5,
	anchorY: 0.5
});
game.addChild(cherrypopperBtn);
var wallnutBtn = LK.getAsset('wallnut', {
	x: 850,
	y: 2500,
	scaleX: 0.8,
	scaleY: 0.8,
	anchorX: 0.5,
	anchorY: 0.5
});
game.addChild(wallnutBtn);
var potatomineBtn = LK.getAsset('potatomine', {
	x: 1050,
	y: 2500,
	scaleX: 0.8,
	scaleY: 0.8,
	anchorX: 0.5,
	anchorY: 0.5
});
game.addChild(potatomineBtn);
var snowshooterBtn = LK.getAsset('snowshooter', {
	x: 1250,
	y: 2500,
	scaleX: 0.8,
	scaleY: 0.8,
	anchorX: 0.5,
	anchorY: 0.5
});
game.addChild(snowshooterBtn);
var chomperBtn = LK.getAsset('chomper', {
	x: 1450,
	y: 2500,
	scaleX: 0.8,
	scaleY: 0.8,
	anchorX: 0.5,
	anchorY: 0.5
});
game.addChild(chomperBtn);
var repeaterBtn = LK.getAsset('repeater', {
	x: 1650,
	y: 2500,
	scaleX: 0.8,
	scaleY: 0.8,
	anchorX: 0.5,
	anchorY: 0.5
});
game.addChild(repeaterBtn);
var splitpeaBtn = LK.getAsset('splitpea', {
	x: 250,
	y: 2500,
	scaleX: 0.8,
	scaleY: 0.8,
	anchorX: 0.5,
	anchorY: 0.5
});
game.addChild(splitpeaBtn);
var puffshroomBtn = LK.getAsset('puffshroom', {
	x: 450,
	y: 2500,
	scaleX: 0.8,
	scaleY: 0.8,
	anchorX: 0.5,
	anchorY: 0.5
});
game.addChild(puffshroomBtn);
var shovelBtn = LK.getAsset('shovel', {
	x: 1900,
	y: 150,
	scaleX: 1.5,
	scaleY: 1.5,
	anchorX: 0.5,
	anchorY: 0.5
});
game.addChild(shovelBtn);
// Cost display texts - updated positions to match new layout
var peaCostTxt = new Text2('100', {
	size: 70,
	fill: 0x000000
});
peaCostTxt.anchor.set(0.5, 0);
game.addChild(peaCostTxt);
peaCostTxt.x = 250;
peaCostTxt.y = 2580;
var sunCostTxt = new Text2('50', {
	size: 70,
	fill: 0x000000
});
sunCostTxt.anchor.set(0.5, 0);
game.addChild(sunCostTxt);
sunCostTxt.x = 450;
sunCostTxt.y = 2580;
var cherryCostTxt = new Text2('150', {
	size: 70,
	fill: 0x000000
});
cherryCostTxt.anchor.set(0.5, 0);
game.addChild(cherryCostTxt);
cherryCostTxt.x = 650;
cherryCostTxt.y = 2580;
var wallCostTxt = new Text2('50', {
	size: 70,
	fill: 0x000000
});
wallCostTxt.anchor.set(0.5, 0);
game.addChild(wallCostTxt);
wallCostTxt.x = 850;
wallCostTxt.y = 2580;
var potatomineCosTxt = new Text2('25', {
	size: 70,
	fill: 0x000000
});
potatomineCosTxt.anchor.set(0.5, 0);
game.addChild(potatomineCosTxt);
potatomineCosTxt.x = 1050;
potatomineCosTxt.y = 2580;
var snowCostTxt = new Text2('175', {
	size: 70,
	fill: 0x000000
});
snowCostTxt.anchor.set(0.5, 0);
game.addChild(snowCostTxt);
snowCostTxt.x = 1250;
snowCostTxt.y = 2580;
var chomperCostTxt = new Text2('150', {
	size: 70,
	fill: 0x000000
});
chomperCostTxt.anchor.set(0.5, 0);
game.addChild(chomperCostTxt);
chomperCostTxt.x = 1450;
chomperCostTxt.y = 2580;
var repeaterCostTxt = new Text2('200', {
	size: 70,
	fill: 0x000000
});
repeaterCostTxt.anchor.set(0.5, 0);
game.addChild(repeaterCostTxt);
repeaterCostTxt.x = 1650;
repeaterCostTxt.y = 2580;
var splitpeaCostTxt = new Text2('125', {
	size: 70,
	fill: 0x000000
});
splitpeaCostTxt.anchor.set(0.5, 0);
game.addChild(splitpeaCostTxt);
splitpeaCostTxt.x = 250;
splitpeaCostTxt.y = 2580;
var puffshroomCostTxt = new Text2('0', {
	size: 70,
	fill: 0x000000
});
puffshroomCostTxt.anchor.set(0.5, 0);
game.addChild(puffshroomCostTxt);
puffshroomCostTxt.x = 450;
puffshroomCostTxt.y = 2580;
var shovelCostTxt = new Text2('Free', {
	size: 70,
	fill: 0x000000
});
shovelCostTxt.anchor.set(0.5, 0);
game.addChild(shovelCostTxt);
shovelCostTxt.x = 1900;
shovelCostTxt.y = 230;
// Add left arrow for plant selector
var leftArrow = new Text2('<', {
	size: 120,
	fill: 0x000000
});
leftArrow.anchor.set(0.5, 0.5);
game.addChild(leftArrow);
leftArrow.x = 50;
leftArrow.y = 2500;
// Add right arrow for plant selector
var rightArrow = new Text2('>', {
	size: 120,
	fill: 0x000000
});
rightArrow.anchor.set(0.5, 0.5);
game.addChild(rightArrow);
rightArrow.x = 2000;
rightArrow.y = 2500;
// Calculate total zombies for victory condition
for (var w = 1; w <= maxWaves; w++) {
	totalZombiesToKill += zombiesPerWave + Math.floor(w / 2);
}
function updateSunDisplay() {
	sunDisplay.setText(sunPoints.toString());
}
function updatePlantSelector() {
	// Hide all plants first
	peashooterBtn.visible = false;
	sunflowerBtn.visible = false;
	wallnutBtn.visible = false;
	snowshooterBtn.visible = false;
	repeaterBtn.visible = false;
	cherrypopperBtn.visible = false;
	splitpeaBtn.visible = false;
	chomperBtn.visible = false;
	potatomineBtn.visible = false;
	puffshroomBtn.visible = false;
	// Hide all cost texts
	peaCostTxt.visible = false;
	sunCostTxt.visible = false;
	wallCostTxt.visible = false;
	snowCostTxt.visible = false;
	repeaterCostTxt.visible = false;
	cherryCostTxt.visible = false;
	splitpeaCostTxt.visible = false;
	chomperCostTxt.visible = false;
	potatomineCosTxt.visible = false;
	puffshroomCostTxt.visible = false;
	if (currentSelectorPage === 1) {
		// First page - show: Peashooter, Sunflower, Cherrypopper, Wallnut, Potatomine, Snowshooter, Chomper, and Repeater
		peashooterBtn.visible = true;
		sunflowerBtn.visible = true;
		cherrypopperBtn.visible = true;
		wallnutBtn.visible = true;
		potatomineBtn.visible = true;
		snowshooterBtn.visible = true;
		chomperBtn.visible = true;
		repeaterBtn.visible = true;
		// Show corresponding cost texts
		peaCostTxt.visible = true;
		sunCostTxt.visible = true;
		cherryCostTxt.visible = true;
		wallCostTxt.visible = true;
		potatomineCosTxt.visible = true;
		snowCostTxt.visible = true;
		chomperCostTxt.visible = true;
		repeaterCostTxt.visible = true;
	} else if (currentSelectorPage === 2) {
		// Second page - show splitpea and puffshroom (only from wave 11)
		splitpeaBtn.visible = true;
		splitpeaCostTxt.visible = true;
		if (currentWave >= 11) {
			puffshroomBtn.visible = true;
			puffshroomCostTxt.visible = true;
		}
	}
}
function getGridPosition(x, y) {
	var col = Math.floor((x - gridStartX) / gridWidth);
	var row = Math.floor((y - gridStartY) / gridHeight);
	if (col >= 0 && col < gridCols && row >= 0 && row < gridRows) {
		return {
			col: col,
			row: row,
			x: gridStartX + col * gridWidth + gridWidth / 2,
			y: gridStartY + row * gridHeight + gridHeight / 2
		};
	}
	return null;
}
function spawnZombie() {
	var lane = Math.floor(Math.random() * gridRows);
	var zombieType = Math.random();
	var zombie;
	// Higher spawn rates for special zombies from wave 15 onwards
	if (currentWave >= 15) {
		if (zombieType < 0.22) {
			zombie = new Gargantuar();
		} else if (zombieType < 0.44) {
			zombie = new Zomboni();
		} else if (zombieType < 0.58) {
			zombie = new JesterZombie();
		} else if (zombieType < 0.68) {
			zombie = new TankZombie();
		} else if (zombieType < 0.73) {
			zombie = new JackInBoxZombie();
		} else if (zombieType < 0.79) {
			zombie = new MinerZombie();
		} else if (zombieType < 0.85) {
			zombie = new FastZombie();
		} else if (zombieType < 0.91) {
			zombie = new NewspaperZombie();
		} else if (zombieType < 0.97) {
			zombie = new VeteranNewspaperZombie();
		} else {
			zombie = new BasicZombie();
		}
	} else {
		// Original spawn rates for waves before 15
		if (currentWave > 8 && zombieType < 0.05) {
			zombie = new Gargantuar();
		} else if (currentWave > 6 && zombieType < 0.15) {
			zombie = new Zomboni();
		} else if (currentWave > 5 && zombieType < 0.25) {
			zombie = new TankZombie();
		} else if (currentWave > 4 && zombieType < 0.35) {
			zombie = new JesterZombie();
		} else if (currentWave > 2 && zombieType < 0.45) {
			zombie = new JackInBoxZombie();
		} else if (currentWave > 3 && zombieType < 0.60) {
			zombie = new MinerZombie();
		} else if (currentWave > 3 && zombieType < 0.75) {
			zombie = new FastZombie();
		} else if (currentWave > 1 && zombieType < 0.85) {
			zombie = new NewspaperZombie();
		} else if (currentWave > 7 && zombieType < 0.95) {
			zombie = new VeteranNewspaperZombie();
		} else {
			zombie = new BasicZombie();
		}
	}
	zombie.x = gridStartX + gridCols * gridWidth + 100;
	zombie.y = gridStartY + lane * gridHeight + gridHeight / 2;
	zombie.gridY = lane;
	// Add spawn delay animation - zombie starts invisible and fades in
	zombie.alpha = 0;
	zombie.scaleX = 0.5;
	zombie.scaleY = 0.5;
	// Animate zombie spawning in
	tween(zombie, {
		alpha: 1,
		scaleX: 1,
		scaleY: 1
	}, {
		duration: 800,
		easing: tween.easeOut
	});
	zombies.push(zombie);
	game.addChild(zombie);
	zombiesSpawned++;
}
function startNextWave() {
	if (currentWave <= maxWaves) {
		zombiesPerWave = 5 + Math.floor(currentWave / 2);
		zombiesSpawned = 0;
		waveStarted = false;
		zombieSpawnQueue = [];
		waveDisplay.setText('Wave: ' + currentWave + '/' + maxWaves);
		// Play Ultimate Battle music for all waves
		LK.playMusic('ultimate_battle');
		// Change background color to dark blue from wave 11
		if (currentWave >= 11) {
			game.setBackgroundColor(0x191970); // Dark blue
		}
		// Flash screen red when wave increases
		LK.effects.flashScreen(0xff0000, 1000);
		// Add delay before wave actually starts spawning zombies
		// For wave 1, add 10 second delay. For other waves, 2 second delay
		var waveStartDelay = currentWave === 1 ? 10000 : 2000;
		LK.setTimeout(function () {
			waveStarted = true;
			// Pre-queue zombie spawn times with delays
			// Use faster spawn delay from wave 5 onwards, and even faster from wave 11
			var currentSpawnDelay;
			if (currentWave >= 11) {
				currentSpawnDelay = 80; // Even faster from wave 11 (1.33 seconds)
			} else if (currentWave >= 5) {
				currentSpawnDelay = 120; // Faster from wave 5 (2 seconds)
			} else {
				currentSpawnDelay = zombieSpawnDelay; // Normal speed (4 seconds)
			}
			for (var i = 0; i < zombiesPerWave; i++) {
				zombieSpawnQueue.push({
					spawnTime: LK.ticks + i * currentSpawnDelay + Math.random() * 60,
					// Add some randomness (reduced for faster waves)
					spawned: false
				});
			}
		}, waveStartDelay);
	}
}
// Generate sun periodically
var sunGenerationTimer = 0;
var sunGenerationDelay = 480; // 8 seconds
// Event handlers
peashooterBtn.down = function () {
	if (sunPoints >= 100) {
		selectedPlantType = 'peashooter';
		LK.effects.flashObject(peashooterBtn, 0x00ff00, 300);
	}
};
sunflowerBtn.down = function () {
	if (sunPoints >= 50) {
		selectedPlantType = 'sunflower';
		LK.effects.flashObject(sunflowerBtn, 0x00ff00, 300);
	}
};
wallnutBtn.down = function () {
	if (sunPoints >= 50) {
		selectedPlantType = 'wallnut';
		LK.effects.flashObject(wallnutBtn, 0x00ff00, 300);
	}
};
snowshooterBtn.down = function () {
	if (sunPoints >= 175) {
		selectedPlantType = 'snowshooter';
		LK.effects.flashObject(snowshooterBtn, 0x00ff00, 300);
	}
};
repeaterBtn.down = function () {
	if (sunPoints >= 200) {
		selectedPlantType = 'repeater';
		LK.effects.flashObject(repeaterBtn, 0x00ff00, 300);
	}
};
cherrypopperBtn.down = function () {
	if (sunPoints >= 150) {
		selectedPlantType = 'cherrypopper';
		LK.effects.flashObject(cherrypopperBtn, 0x00ff00, 300);
	}
};
splitpeaBtn.down = function () {
	if (sunPoints >= 125) {
		selectedPlantType = 'splitpea';
		LK.effects.flashObject(splitpeaBtn, 0x00ff00, 300);
	}
};
chomperBtn.down = function () {
	if (sunPoints >= 150) {
		selectedPlantType = 'chomper';
		LK.effects.flashObject(chomperBtn, 0x00ff00, 300);
	}
};
potatomineBtn.down = function () {
	if (sunPoints >= 25) {
		selectedPlantType = 'potatomine';
		LK.effects.flashObject(potatomineBtn, 0x00ff00, 300);
	}
};
puffshroomBtn.down = function () {
	if (currentWave >= 11) {
		selectedPlantType = 'puffshroom';
		LK.effects.flashObject(puffshroomBtn, 0x00ff00, 300);
	}
};
shovelBtn.down = function () {
	selectedPlantType = 'shovel';
	LK.effects.flashObject(shovelBtn, 0x00ff00, 300);
};
leftArrow.down = function () {
	if (currentSelectorPage > 1) {
		currentSelectorPage--;
		updatePlantSelector();
		LK.effects.flashObject(leftArrow, 0x00ff00, 200);
	} else {
		// Flash gray if can't go back further
		LK.effects.flashObject(leftArrow, 0x888888, 200);
	}
};
rightArrow.down = function () {
	if (currentSelectorPage < maxSelectorPages) {
		currentSelectorPage++;
		updatePlantSelector();
		LK.effects.flashObject(rightArrow, 0x00ff00, 200);
	} else {
		// Flash gray if can't go forward further
		LK.effects.flashObject(rightArrow, 0x888888, 200);
	}
};
game.down = function (x, y, obj) {
	var gridPos = getGridPosition(x, y);
	if (gridPos && selectedPlantType) {
		var gridKey = gridPos.col + ',' + gridPos.row;
		// Handle shovel - remove existing plant
		if (selectedPlantType === 'shovel') {
			if (plantGrid[gridKey]) {
				var plantToRemove = plantGrid[gridKey];
				// Remove from plants array
				for (var i = 0; i < plants.length; i++) {
					if (plants[i] === plantToRemove) {
						plants.splice(i, 1);
						break;
					}
				}
				// Remove from grid
				delete plantGrid[gridKey];
				// Destroy the plant
				plantToRemove.destroy();
				selectedPlantType = null;
			}
			return;
		}
		// Check if position is already occupied
		if (plantGrid[gridKey]) {
			return;
		}
		var plant = null;
		var cost = 0;
		if (selectedPlantType === 'peashooter' && sunPoints >= 100) {
			plant = new Peashooter();
			cost = 100;
		} else if (selectedPlantType === 'sunflower' && sunPoints >= 50) {
			plant = new Sunflower();
			cost = 50;
		} else if (selectedPlantType === 'wallnut' && sunPoints >= 50) {
			plant = new WallNut();
			cost = 50;
		} else if (selectedPlantType === 'snowshooter' && sunPoints >= 175) {
			plant = new Snowshooter();
			cost = 175;
		} else if (selectedPlantType === 'repeater' && sunPoints >= 200) {
			plant = new Repeater();
			cost = 200;
		} else if (selectedPlantType === 'cherrypopper' && sunPoints >= 150) {
			plant = new CherryPopper();
			cost = 150;
		} else if (selectedPlantType === 'splitpea' && sunPoints >= 125) {
			plant = new SplitPea();
			cost = 125;
		} else if (selectedPlantType === 'chomper' && sunPoints >= 150) {
			plant = new Chomper();
			cost = 150;
		} else if (selectedPlantType === 'potatomine' && sunPoints >= 25) {
			plant = new Potatomine();
			cost = 25;
		} else if (selectedPlantType === 'puffshroom' && currentWave >= 11) {
			plant = new Puffshroom();
			cost = 0;
		}
		if (plant) {
			plant.x = gridPos.x;
			plant.y = gridPos.y;
			plant.gridX = gridPos.col;
			plant.gridY = gridPos.row;
			plants.push(plant);
			game.addChild(plant);
			plantGrid[gridKey] = plant;
			sunPoints -= cost;
			updateSunDisplay();
			selectedPlantType = null;
			LK.getSound('seed_plant1').play();
		}
	}
};
game.update = function () {
	// Generate sun periodically
	sunGenerationTimer++;
	if (sunGenerationTimer >= sunGenerationDelay) {
		var sun = new Sun();
		sun.x = 200 + Math.random() * 1600;
		sun.y = -100; // Start above screen
		sun.targetY = 200 + Math.random() * 1000; // Final position
		sun.isFalling = true; // Mark as falling sun
		// Animate falling from top to bottom
		tween(sun, {
			y: sun.targetY
		}, {
			duration: 2000,
			easing: tween.easeOut,
			onFinish: function onFinish() {
				sun.isFalling = false;
			}
		});
		suns.push(sun);
		game.addChild(sun);
		sunGenerationTimer = 0;
	}
	// Wave management
	if (currentWave <= maxWaves) {
		waveTimer++;
		// Spawn zombies for current wave using queue system
		if (waveStarted && zombiesSpawned < zombiesPerWave) {
			for (var i = 0; i < zombieSpawnQueue.length; i++) {
				var queueItem = zombieSpawnQueue[i];
				if (!queueItem.spawned && LK.ticks >= queueItem.spawnTime) {
					spawnZombie();
					queueItem.spawned = true;
					break; // Only spawn one zombie per frame
				}
			}
		}
		// Start next wave
		if (zombiesSpawned >= zombiesPerWave && zombies.length === 0) {
			currentWave++;
			if (currentWave <= maxWaves) {
				startNextWave();
				waveTimer = 0;
			}
		}
	}
	// Check victory condition
	if (currentWave > maxWaves && zombies.length === 0) {
		LK.showYouWin();
	}
	// Handle slow effects on zombies
	for (var z = 0; z < zombies.length; z++) {
		var zombie = zombies[z];
		if (zombie.slowTimer) {
			zombie.slowTimer--;
			if (zombie.slowTimer <= 0) {
				// Restore original speed
				if (zombie.originalSpeed) {
					zombie.speed = zombie.originalSpeed;
				}
				// Remove slow tint
				tween(zombie, {
					tint: 0xffffff
				}, {
					duration: 300,
					easing: tween.easeOut
				});
				zombie.slowTimer = null;
			}
		}
	}
	// Update button availability
	peashooterBtn.alpha = sunPoints >= 100 ? 1.0 : 0.5;
	sunflowerBtn.alpha = sunPoints >= 50 ? 1.0 : 0.5;
	wallnutBtn.alpha = sunPoints >= 50 ? 1.0 : 0.5;
	snowshooterBtn.alpha = sunPoints >= 175 ? 1.0 : 0.5;
	repeaterBtn.alpha = sunPoints >= 200 ? 1.0 : 0.5;
	cherrypopperBtn.alpha = sunPoints >= 150 ? 1.0 : 0.5;
	splitpeaBtn.alpha = sunPoints >= 125 ? 1.0 : 0.5;
	chomperBtn.alpha = sunPoints >= 150 ? 1.0 : 0.5;
	potatomineBtn.alpha = sunPoints >= 25 ? 1.0 : 0.5;
	puffshroomBtn.alpha = currentWave >= 11 && sunPoints >= 0 ? 1.0 : 0.5;
	shovelBtn.alpha = 1.0; // Shovel is always available
	// Update arrow button availability
	updateArrowButtons();
};
// Initialize plant selector
updatePlantSelector();
// Update arrow button availability in main update loop
function updateArrowButtons() {
	leftArrow.alpha = currentSelectorPage > 1 ? 1.0 : 0.5;
	rightArrow.alpha = currentSelectorPage < maxSelectorPages ? 1.0 : 0.5;
}
// Start first wave
startNextWave(); ===================================================================
--- original.js
+++ change.js
@@ -1676,14 +1676,14 @@
 
 /**** 
 * Game Code
 ****/ 
-// Game variables
-// Game grid and UI elements
-// Plants
-// Projectiles and collectibles
-// Zombies
 // Sounds
+// Zombies
+// Projectiles and collectibles
+// Plants
+// Game grid and UI elements
+// Game variables
 var sunPoints = 150;
 var currentWave = 1;
 var maxWaves = 20;
 var waveTimer = 0;
@@ -2313,12 +2313,9 @@
 			plantGrid[gridKey] = plant;
 			sunPoints -= cost;
 			updateSunDisplay();
 			selectedPlantType = null;
-			// Play random plant placement sound
-			var plantSounds = ['seed_plant1', 'seed_plant2'];
-			var randomSound = plantSounds[Math.floor(Math.random() * plantSounds.length)];
-			LK.getSound(randomSound).play();
+			LK.getSound('seed_plant1').play();
 		}
 	}
 };
 game.update = function () {