User prompt
make the song grasswalk play loop
User prompt
Cherry bomb only does damage to one zombie, now make it do damage in a range of 3x3 squares.
User prompt
Chomper and the zombie jackinthebox are red, make them not red anymore. When chomper is recharging, make it black and after the recharging time, make it normal again. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Add more health to the zomboni, and make the game more difficult from wave 3 onwards.
User prompt
Make the skeletons have more life and be faster, make more zombies appear as the waves advance to make the game more difficult. add a new asset for the zomboni, which is a car with double the life of a normal zombie and a little faster crushing any plant killing it instantly, make it appear from wave 5 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
When it gets dark the background has to stay dark blue during the 5 waves until it turns green again when it gets daylight. Add a new plant, chomper, it kills any zombie that is one square ahead of it, in one bite, but it has to wait 20 seconds to kill another zombie. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Now make after 5 waves the background change to a dark blue color simulating night, and make more zombies appear after that, and after another 5 waves make it daytime again. now add a new asset for the Gargantuar zombie, which has too many health, is a bit slow and destroys any plant with a single bite. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
there is a bug when zombies eat a plant, they can no longer place plants in the square where they ate that plant, fix it.
User prompt
there is a bug with Cherrybomb, when you put it in a box and it explodes you can't place plants there anymore, fix it. increase a little bit the speed of jack in the box zombie, and reduce the reload time to use the plants. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Add a new asset for the Jack in the box zombie, which will appear from wave 4 and acts like a normal zombie but can explode in a random time of 8 to 15 seconds destroying plants in a range of 3x3 squares. make spikeweed completely ignored by the zombies, so that they do not eat it, going completely unnoticed. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
The spikeweed should not kill the zombies immediately, it has to do the same damage as a pea every 0.6 seconds. add the zombie all stars, which appears from the second wave, to be a new type of zombie that moves faster and has much more health points. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
The pruners don't work, fix whatever is going wrong and put them a little further ahead. add a new plant the spikeweed, the zombies don't eat it because it is on the ground while the grass spikeweed can hurt them when they are on top of it. add the zombie all stars, which has much more stamina and more speed than a normal zombei. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
The icons are too small make them much bigger, reduce the speed of the zombies, add a recharge time to use each plant, and add the pruners, which are 1 in each line, they are on the back paste of the map, and when a zombie touches a pruner it activates moving forward killing all the zombies in the line. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
The text to select the repeater is below the text to select the cherrybomb, fix it by changing that text to icons that below them show the price, and at the top add an icon to select the shovel, which is used to remove the plants.
User prompt
make the zombies take 25 seconds to appear initially, and add a new plant, the repeater, it is the same as the lanzaguizantes but shoots 2 peas and is worth 200 soles. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Make the suns of the sunflower bigger, make the zombies appear after 15 seconds at the start of the game and after that time sound an alert with the message zombies are coming. the space where the game takes place is still small, make it bigger without having more squares on the grid. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Now that the resources are called suns, and that the zombies do not produce them when they die, instead put a sunflower that is worth 50 and generates them in the garden to collect them, each sun is worth 25. the space where the game takes place is very small, make it bigger without having more squares in the grid. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Code edit (1 edits merged)
Please save this source code
User prompt
Garden Defense: Plants vs Undead
Initial prompt
Tower defense of plants vs undead on a grid
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var CherryBomb = Container.expand(function () { var self = Container.call(this); var bombGraphics = self.attachAsset('cherryBomb', { anchorX: 0.5, anchorY: 0.5 }); self.cost = 150; self.health = 50; self.maxHealth = 50; self.fuseTimer = 0; self.fuseDelay = 180; // 3 seconds self.update = function () { self.fuseTimer++; if (self.fuseTimer >= self.fuseDelay) { self.explode(); } }; self.explode = function () { var explosion = game.addChild(LK.getAsset('explosion', { anchorX: 0.5, anchorY: 0.5, x: self.x, y: self.y })); // Damage all enemies in 3x3 area for (var i = enemies.length - 1; i >= 0; i--) { var enemy = enemies[i]; var distance = Math.sqrt(Math.pow(enemy.x - self.x, 2) + Math.pow(enemy.y - self.y, 2)); if (distance <= 150) { enemy.takeDamage(100); } } LK.getSound('explode').play(); // Remove explosion after animation tween(explosion, { alpha: 0, scaleX: 2, scaleY: 2 }, { duration: 500, onFinish: function onFinish() { explosion.destroy(); } }); // Remove self for (var j = 0; j < plants.length; j++) { if (plants[j] === self) { plants.splice(j, 1); break; } } self.destroy(); }; 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; }; return self; }); var PeaShooter = Container.expand(function () { var self = Container.call(this); var shooterGraphics = 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.row = 0; self.update = function () { self.shootTimer++; if (self.shootTimer >= self.shootDelay) { // Check if there's an enemy in this row var hasEnemyInRow = false; for (var i = 0; i < enemies.length; i++) { if (enemies[i].row === self.row && enemies[i].x > self.x) { hasEnemyInRow = true; break; } } if (hasEnemyInRow) { var pea = new Pea(); pea.x = self.x + 50; pea.y = self.y; pea.row = self.row; projectiles.push(pea); game.addChild(pea); LK.getSound('shoot').play(); self.shootTimer = 0; } } }; return self; }); var Skeleton = Container.expand(function () { var self = Container.call(this); var skeletonGraphics = self.attachAsset('skeleton', { anchorX: 0.5, anchorY: 0.5 }); self.health = 60; self.maxHealth = 60; self.speed = -2; self.damage = 20; self.attackTimer = 0; self.attackDelay = 45; // Faster attack self.row = 0; self.attacking = false; self.update = function () { if (!self.attacking) { self.x += self.speed; } else { self.attackTimer++; if (self.attackTimer >= self.attackDelay) { self.attack(); self.attackTimer = 0; } } }; self.takeDamage = function (damage) { self.health -= damage; LK.effects.flashObject(self, 0xff0000, 200); LK.getSound('zombie_hit').play(); if (self.health <= 0) { // Remove from enemies array for (var i = 0; i < enemies.length; i++) { if (enemies[i] === self) { enemies.splice(i, 1); break; } } // Award resources resources += 30; updateResourcesDisplay(); self.destroy(); } }; self.attack = function () { // Find plant to attack for (var i = 0; i < plants.length; i++) { var plant = plants[i]; if (plant.row === self.row && Math.abs(plant.x - self.x) <= 50) { plant.health -= self.damage; LK.effects.flashObject(plant, 0xff0000, 200); if (plant.health <= 0) { plants.splice(i, 1); plant.destroy(); self.attacking = false; } break; } } }; return self; }); var WallNut = Container.expand(function () { var self = Container.call(this); var nutGraphics = self.attachAsset('wallNut', { anchorX: 0.5, anchorY: 0.5 }); self.cost = 50; self.health = 200; self.maxHealth = 200; return self; }); var Zombie = Container.expand(function () { var self = Container.call(this); var zombieGraphics = self.attachAsset('zombie', { anchorX: 0.5, anchorY: 0.5 }); self.health = 80; self.maxHealth = 80; self.speed = -1.5; self.damage = 25; self.attackTimer = 0; self.attackDelay = 60; // 1 second self.row = 0; self.attacking = false; self.update = function () { if (!self.attacking) { self.x += self.speed; } else { self.attackTimer++; if (self.attackTimer >= self.attackDelay) { self.attack(); self.attackTimer = 0; } } }; self.takeDamage = function (damage) { self.health -= damage; LK.effects.flashObject(self, 0xff0000, 200); LK.getSound('zombie_hit').play(); if (self.health <= 0) { // Remove from enemies array for (var i = 0; i < enemies.length; i++) { if (enemies[i] === self) { enemies.splice(i, 1); break; } } // Award resources resources += 25; updateResourcesDisplay(); self.destroy(); } }; self.attack = function () { // Find plant to attack for (var i = 0; i < plants.length; i++) { var plant = plants[i]; if (plant.row === self.row && Math.abs(plant.x - self.x) <= 50) { plant.health -= self.damage; LK.effects.flashObject(plant, 0xff0000, 200); if (plant.health <= 0) { plants.splice(i, 1); plant.destroy(); self.attacking = false; } break; } } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2d5016 }); /**** * Game Code ****/ // Grid setup var GRID_ROWS = 5; var GRID_COLS = 9; var CELL_SIZE = 100; var GRID_START_X = 324; // Center the grid: (2048 - 900) / 2 var GRID_START_Y = 800; // Game state var resources = 200; var currentWave = 1; var enemiesSpawned = 0; var enemiesPerWave = 5; var waveDelay = 300; // 5 seconds between waves var waveTimer = 0; var gameState = 'playing'; // 'playing', 'won', 'lost' // Game objects var grid = []; var plants = []; var enemies = []; var projectiles = []; var selectedPlantType = 'peaShooter'; // UI elements var resourcesText = new Text2('Resources: ' + resources, { size: 60, fill: 0xFFFFFF }); resourcesText.anchor.set(0, 0); resourcesText.x = 120; resourcesText.y = 50; LK.gui.topLeft.addChild(resourcesText); var waveText = new Text2('Wave: ' + currentWave, { size: 60, fill: 0xFFFFFF }); waveText.anchor.set(0.5, 0); waveText.x = 0; waveText.y = 50; LK.gui.top.addChild(waveText); var instructionText = new Text2('Tap grid to place plants', { size: 40, fill: 0xFFFF00 }); instructionText.anchor.set(0.5, 0); instructionText.x = 0; instructionText.y = 120; LK.gui.top.addChild(instructionText); // Plant selection buttons var peaShooterBtn = new Text2('Pea (100)', { size: 45, fill: 0x00FF00 }); peaShooterBtn.anchor.set(0, 1); peaShooterBtn.x = 50; peaShooterBtn.y = -50; LK.gui.bottomLeft.addChild(peaShooterBtn); var wallNutBtn = new Text2('Nut (50)', { size: 45, fill: 0x8B4513 }); wallNutBtn.anchor.set(0, 1); wallNutBtn.x = 250; wallNutBtn.y = -50; LK.gui.bottomLeft.addChild(wallNutBtn); var cherryBombBtn = new Text2('Bomb (150)', { size: 45, fill: 0xFF0000 }); cherryBombBtn.anchor.set(0, 1); cherryBombBtn.x = 450; cherryBombBtn.y = -50; LK.gui.bottomLeft.addChild(cherryBombBtn); // Create grid for (var row = 0; row < GRID_ROWS; row++) { grid[row] = []; for (var col = 0; col < GRID_COLS; col++) { var cell = game.addChild(LK.getAsset('gridCell', { anchorX: 0.5, anchorY: 0.5, x: GRID_START_X + col * CELL_SIZE + CELL_SIZE / 2, y: GRID_START_Y + row * CELL_SIZE + CELL_SIZE / 2, alpha: 0.3 })); cell.row = row; cell.col = col; cell.occupied = false; grid[row][col] = cell; } } function updateResourcesDisplay() { resourcesText.setText('Resources: ' + resources); } function updateWaveDisplay() { waveText.setText('Wave: ' + currentWave); } function getPlantCost(plantType) { switch (plantType) { case 'peaShooter': return 100; case 'wallNut': return 50; case 'cherryBomb': return 150; default: return 100; } } function canAffordPlant(plantType) { return resources >= getPlantCost(plantType); } function placePlant(row, col, plantType) { if (grid[row][col].occupied || !canAffordPlant(plantType)) { return false; } var plant; var cost = getPlantCost(plantType); switch (plantType) { case 'peaShooter': plant = new PeaShooter(); break; case 'wallNut': plant = new WallNut(); break; case 'cherryBomb': plant = new CherryBomb(); break; default: return false; } plant.x = GRID_START_X + col * CELL_SIZE + CELL_SIZE / 2; plant.y = GRID_START_Y + row * CELL_SIZE + CELL_SIZE / 2; plant.row = row; plant.col = col; plants.push(plant); game.addChild(plant); grid[row][col].occupied = true; resources -= cost; updateResourcesDisplay(); LK.getSound('plant').play(); return true; } function spawnEnemy(row) { var enemy; if (currentWave > 3 && Math.random() < 0.4) { enemy = new Skeleton(); } else { enemy = new Zombie(); } enemy.x = 2000; enemy.y = GRID_START_Y + row * CELL_SIZE + CELL_SIZE / 2; enemy.row = row; enemiesSpawned++; enemies.push(enemy); game.addChild(enemy); } function checkWaveComplete() { if (enemiesSpawned >= enemiesPerWave && enemies.length === 0) { currentWave++; updateWaveDisplay(); if (currentWave > 10) { gameState = 'won'; LK.showYouWin(); return; } enemiesSpawned = 0; enemiesPerWave = Math.min(5 + currentWave * 2, 20); waveTimer = 0; resources += 50; // Bonus resources between waves updateResourcesDisplay(); } } function checkGameOver() { for (var i = 0; i < enemies.length; i++) { if (enemies[i].x <= GRID_START_X - 50) { gameState = 'lost'; LK.showGameOver(); return; } } } // Button event handlers peaShooterBtn.down = function (x, y, obj) { selectedPlantType = 'peaShooter'; instructionText.setText('Selected: Pea Shooter (100)'); }; wallNutBtn.down = function (x, y, obj) { selectedPlantType = 'wallNut'; instructionText.setText('Selected: Wall Nut (50)'); }; cherryBombBtn.down = function (x, y, obj) { selectedPlantType = 'cherryBomb'; instructionText.setText('Selected: Cherry Bomb (150)'); }; // Grid click handler game.down = function (x, y, obj) { if (gameState !== 'playing') return; // Check if click is within grid bounds if (x >= GRID_START_X && x <= GRID_START_X + GRID_COLS * CELL_SIZE && y >= GRID_START_Y && y <= GRID_START_Y + GRID_ROWS * CELL_SIZE) { var col = Math.floor((x - GRID_START_X) / CELL_SIZE); var row = Math.floor((y - GRID_START_Y) / CELL_SIZE); if (row >= 0 && row < GRID_ROWS && col >= 0 && col < GRID_COLS) { placePlant(row, col, selectedPlantType); } } }; // Main game loop game.update = function () { if (gameState !== 'playing') return; // Spawn enemies waveTimer++; if (enemiesSpawned < enemiesPerWave && waveTimer % 120 === 0) { // Every 2 seconds var randomRow = Math.floor(Math.random() * GRID_ROWS); spawnEnemy(randomRow); } // Update projectiles for (var i = projectiles.length - 1; i >= 0; i--) { var projectile = projectiles[i]; // Check collision with enemies var hit = false; for (var j = 0; j < enemies.length; j++) { var enemy = enemies[j]; if (projectile.row === enemy.row && projectile.x >= enemy.x - 35 && projectile.x <= enemy.x + 35) { enemy.takeDamage(projectile.damage); hit = true; break; } } // Remove projectile if hit or off screen if (hit || projectile.x > 2100) { projectiles.splice(i, 1); projectile.destroy(); } } // Check enemy-plant collisions for (var k = 0; k < enemies.length; k++) { var enemy = enemies[k]; enemy.attacking = false; for (var l = 0; l < plants.length; l++) { var plant = plants[l]; if (enemy.row === plant.row && enemy.x >= plant.x - 50 && enemy.x <= plant.x + 50) { enemy.attacking = true; break; } } } checkWaveComplete(); checkGameOver(); };
===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,504 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+
+/****
+* Classes
+****/
+var CherryBomb = Container.expand(function () {
+ var self = Container.call(this);
+ var bombGraphics = self.attachAsset('cherryBomb', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.cost = 150;
+ self.health = 50;
+ self.maxHealth = 50;
+ self.fuseTimer = 0;
+ self.fuseDelay = 180; // 3 seconds
+ self.update = function () {
+ self.fuseTimer++;
+ if (self.fuseTimer >= self.fuseDelay) {
+ self.explode();
+ }
+ };
+ self.explode = function () {
+ var explosion = game.addChild(LK.getAsset('explosion', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: self.x,
+ y: self.y
+ }));
+ // Damage all enemies in 3x3 area
+ for (var i = enemies.length - 1; i >= 0; i--) {
+ var enemy = enemies[i];
+ var distance = Math.sqrt(Math.pow(enemy.x - self.x, 2) + Math.pow(enemy.y - self.y, 2));
+ if (distance <= 150) {
+ enemy.takeDamage(100);
+ }
+ }
+ LK.getSound('explode').play();
+ // Remove explosion after animation
+ tween(explosion, {
+ alpha: 0,
+ scaleX: 2,
+ scaleY: 2
+ }, {
+ duration: 500,
+ onFinish: function onFinish() {
+ explosion.destroy();
+ }
+ });
+ // Remove self
+ for (var j = 0; j < plants.length; j++) {
+ if (plants[j] === self) {
+ plants.splice(j, 1);
+ break;
+ }
+ }
+ self.destroy();
+ };
+ 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;
+ };
+ return self;
+});
+var PeaShooter = Container.expand(function () {
+ var self = Container.call(this);
+ var shooterGraphics = 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.row = 0;
+ self.update = function () {
+ self.shootTimer++;
+ if (self.shootTimer >= self.shootDelay) {
+ // Check if there's an enemy in this row
+ var hasEnemyInRow = false;
+ for (var i = 0; i < enemies.length; i++) {
+ if (enemies[i].row === self.row && enemies[i].x > self.x) {
+ hasEnemyInRow = true;
+ break;
+ }
+ }
+ if (hasEnemyInRow) {
+ var pea = new Pea();
+ pea.x = self.x + 50;
+ pea.y = self.y;
+ pea.row = self.row;
+ projectiles.push(pea);
+ game.addChild(pea);
+ LK.getSound('shoot').play();
+ self.shootTimer = 0;
+ }
+ }
+ };
+ return self;
+});
+var Skeleton = Container.expand(function () {
+ var self = Container.call(this);
+ var skeletonGraphics = self.attachAsset('skeleton', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.health = 60;
+ self.maxHealth = 60;
+ self.speed = -2;
+ self.damage = 20;
+ self.attackTimer = 0;
+ self.attackDelay = 45; // Faster attack
+ self.row = 0;
+ self.attacking = false;
+ self.update = function () {
+ if (!self.attacking) {
+ self.x += self.speed;
+ } else {
+ self.attackTimer++;
+ if (self.attackTimer >= self.attackDelay) {
+ self.attack();
+ self.attackTimer = 0;
+ }
+ }
+ };
+ self.takeDamage = function (damage) {
+ self.health -= damage;
+ LK.effects.flashObject(self, 0xff0000, 200);
+ LK.getSound('zombie_hit').play();
+ if (self.health <= 0) {
+ // Remove from enemies array
+ for (var i = 0; i < enemies.length; i++) {
+ if (enemies[i] === self) {
+ enemies.splice(i, 1);
+ break;
+ }
+ }
+ // Award resources
+ resources += 30;
+ updateResourcesDisplay();
+ self.destroy();
+ }
+ };
+ self.attack = function () {
+ // Find plant to attack
+ for (var i = 0; i < plants.length; i++) {
+ var plant = plants[i];
+ if (plant.row === self.row && Math.abs(plant.x - self.x) <= 50) {
+ plant.health -= self.damage;
+ LK.effects.flashObject(plant, 0xff0000, 200);
+ if (plant.health <= 0) {
+ plants.splice(i, 1);
+ plant.destroy();
+ self.attacking = false;
+ }
+ break;
+ }
+ }
+ };
+ return self;
+});
+var WallNut = Container.expand(function () {
+ var self = Container.call(this);
+ var nutGraphics = self.attachAsset('wallNut', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.cost = 50;
+ self.health = 200;
+ self.maxHealth = 200;
+ return self;
+});
+var Zombie = Container.expand(function () {
+ var self = Container.call(this);
+ var zombieGraphics = self.attachAsset('zombie', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.health = 80;
+ self.maxHealth = 80;
+ self.speed = -1.5;
+ self.damage = 25;
+ self.attackTimer = 0;
+ self.attackDelay = 60; // 1 second
+ self.row = 0;
+ self.attacking = false;
+ self.update = function () {
+ if (!self.attacking) {
+ self.x += self.speed;
+ } else {
+ self.attackTimer++;
+ if (self.attackTimer >= self.attackDelay) {
+ self.attack();
+ self.attackTimer = 0;
+ }
+ }
+ };
+ self.takeDamage = function (damage) {
+ self.health -= damage;
+ LK.effects.flashObject(self, 0xff0000, 200);
+ LK.getSound('zombie_hit').play();
+ if (self.health <= 0) {
+ // Remove from enemies array
+ for (var i = 0; i < enemies.length; i++) {
+ if (enemies[i] === self) {
+ enemies.splice(i, 1);
+ break;
+ }
+ }
+ // Award resources
+ resources += 25;
+ updateResourcesDisplay();
+ self.destroy();
+ }
+ };
+ self.attack = function () {
+ // Find plant to attack
+ for (var i = 0; i < plants.length; i++) {
+ var plant = plants[i];
+ if (plant.row === self.row && Math.abs(plant.x - self.x) <= 50) {
+ plant.health -= self.damage;
+ LK.effects.flashObject(plant, 0xff0000, 200);
+ if (plant.health <= 0) {
+ plants.splice(i, 1);
+ plant.destroy();
+ self.attacking = false;
+ }
+ break;
+ }
+ }
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x2d5016
+});
+
+/****
+* Game Code
+****/
+// Grid setup
+var GRID_ROWS = 5;
+var GRID_COLS = 9;
+var CELL_SIZE = 100;
+var GRID_START_X = 324; // Center the grid: (2048 - 900) / 2
+var GRID_START_Y = 800;
+// Game state
+var resources = 200;
+var currentWave = 1;
+var enemiesSpawned = 0;
+var enemiesPerWave = 5;
+var waveDelay = 300; // 5 seconds between waves
+var waveTimer = 0;
+var gameState = 'playing'; // 'playing', 'won', 'lost'
+// Game objects
+var grid = [];
+var plants = [];
+var enemies = [];
+var projectiles = [];
+var selectedPlantType = 'peaShooter';
+// UI elements
+var resourcesText = new Text2('Resources: ' + resources, {
+ size: 60,
+ fill: 0xFFFFFF
+});
+resourcesText.anchor.set(0, 0);
+resourcesText.x = 120;
+resourcesText.y = 50;
+LK.gui.topLeft.addChild(resourcesText);
+var waveText = new Text2('Wave: ' + currentWave, {
+ size: 60,
+ fill: 0xFFFFFF
+});
+waveText.anchor.set(0.5, 0);
+waveText.x = 0;
+waveText.y = 50;
+LK.gui.top.addChild(waveText);
+var instructionText = new Text2('Tap grid to place plants', {
+ size: 40,
+ fill: 0xFFFF00
+});
+instructionText.anchor.set(0.5, 0);
+instructionText.x = 0;
+instructionText.y = 120;
+LK.gui.top.addChild(instructionText);
+// Plant selection buttons
+var peaShooterBtn = new Text2('Pea (100)', {
+ size: 45,
+ fill: 0x00FF00
+});
+peaShooterBtn.anchor.set(0, 1);
+peaShooterBtn.x = 50;
+peaShooterBtn.y = -50;
+LK.gui.bottomLeft.addChild(peaShooterBtn);
+var wallNutBtn = new Text2('Nut (50)', {
+ size: 45,
+ fill: 0x8B4513
+});
+wallNutBtn.anchor.set(0, 1);
+wallNutBtn.x = 250;
+wallNutBtn.y = -50;
+LK.gui.bottomLeft.addChild(wallNutBtn);
+var cherryBombBtn = new Text2('Bomb (150)', {
+ size: 45,
+ fill: 0xFF0000
+});
+cherryBombBtn.anchor.set(0, 1);
+cherryBombBtn.x = 450;
+cherryBombBtn.y = -50;
+LK.gui.bottomLeft.addChild(cherryBombBtn);
+// Create grid
+for (var row = 0; row < GRID_ROWS; row++) {
+ grid[row] = [];
+ for (var col = 0; col < GRID_COLS; col++) {
+ var cell = game.addChild(LK.getAsset('gridCell', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: GRID_START_X + col * CELL_SIZE + CELL_SIZE / 2,
+ y: GRID_START_Y + row * CELL_SIZE + CELL_SIZE / 2,
+ alpha: 0.3
+ }));
+ cell.row = row;
+ cell.col = col;
+ cell.occupied = false;
+ grid[row][col] = cell;
+ }
+}
+function updateResourcesDisplay() {
+ resourcesText.setText('Resources: ' + resources);
+}
+function updateWaveDisplay() {
+ waveText.setText('Wave: ' + currentWave);
+}
+function getPlantCost(plantType) {
+ switch (plantType) {
+ case 'peaShooter':
+ return 100;
+ case 'wallNut':
+ return 50;
+ case 'cherryBomb':
+ return 150;
+ default:
+ return 100;
+ }
+}
+function canAffordPlant(plantType) {
+ return resources >= getPlantCost(plantType);
+}
+function placePlant(row, col, plantType) {
+ if (grid[row][col].occupied || !canAffordPlant(plantType)) {
+ return false;
+ }
+ var plant;
+ var cost = getPlantCost(plantType);
+ switch (plantType) {
+ case 'peaShooter':
+ plant = new PeaShooter();
+ break;
+ case 'wallNut':
+ plant = new WallNut();
+ break;
+ case 'cherryBomb':
+ plant = new CherryBomb();
+ break;
+ default:
+ return false;
+ }
+ plant.x = GRID_START_X + col * CELL_SIZE + CELL_SIZE / 2;
+ plant.y = GRID_START_Y + row * CELL_SIZE + CELL_SIZE / 2;
+ plant.row = row;
+ plant.col = col;
+ plants.push(plant);
+ game.addChild(plant);
+ grid[row][col].occupied = true;
+ resources -= cost;
+ updateResourcesDisplay();
+ LK.getSound('plant').play();
+ return true;
+}
+function spawnEnemy(row) {
+ var enemy;
+ if (currentWave > 3 && Math.random() < 0.4) {
+ enemy = new Skeleton();
+ } else {
+ enemy = new Zombie();
+ }
+ enemy.x = 2000;
+ enemy.y = GRID_START_Y + row * CELL_SIZE + CELL_SIZE / 2;
+ enemy.row = row;
+ enemiesSpawned++;
+ enemies.push(enemy);
+ game.addChild(enemy);
+}
+function checkWaveComplete() {
+ if (enemiesSpawned >= enemiesPerWave && enemies.length === 0) {
+ currentWave++;
+ updateWaveDisplay();
+ if (currentWave > 10) {
+ gameState = 'won';
+ LK.showYouWin();
+ return;
+ }
+ enemiesSpawned = 0;
+ enemiesPerWave = Math.min(5 + currentWave * 2, 20);
+ waveTimer = 0;
+ resources += 50; // Bonus resources between waves
+ updateResourcesDisplay();
+ }
+}
+function checkGameOver() {
+ for (var i = 0; i < enemies.length; i++) {
+ if (enemies[i].x <= GRID_START_X - 50) {
+ gameState = 'lost';
+ LK.showGameOver();
+ return;
+ }
+ }
+}
+// Button event handlers
+peaShooterBtn.down = function (x, y, obj) {
+ selectedPlantType = 'peaShooter';
+ instructionText.setText('Selected: Pea Shooter (100)');
+};
+wallNutBtn.down = function (x, y, obj) {
+ selectedPlantType = 'wallNut';
+ instructionText.setText('Selected: Wall Nut (50)');
+};
+cherryBombBtn.down = function (x, y, obj) {
+ selectedPlantType = 'cherryBomb';
+ instructionText.setText('Selected: Cherry Bomb (150)');
+};
+// Grid click handler
+game.down = function (x, y, obj) {
+ if (gameState !== 'playing') return;
+ // Check if click is within grid bounds
+ if (x >= GRID_START_X && x <= GRID_START_X + GRID_COLS * CELL_SIZE && y >= GRID_START_Y && y <= GRID_START_Y + GRID_ROWS * CELL_SIZE) {
+ var col = Math.floor((x - GRID_START_X) / CELL_SIZE);
+ var row = Math.floor((y - GRID_START_Y) / CELL_SIZE);
+ if (row >= 0 && row < GRID_ROWS && col >= 0 && col < GRID_COLS) {
+ placePlant(row, col, selectedPlantType);
+ }
+ }
+};
+// Main game loop
+game.update = function () {
+ if (gameState !== 'playing') return;
+ // Spawn enemies
+ waveTimer++;
+ if (enemiesSpawned < enemiesPerWave && waveTimer % 120 === 0) {
+ // Every 2 seconds
+ var randomRow = Math.floor(Math.random() * GRID_ROWS);
+ spawnEnemy(randomRow);
+ }
+ // Update projectiles
+ for (var i = projectiles.length - 1; i >= 0; i--) {
+ var projectile = projectiles[i];
+ // Check collision with enemies
+ var hit = false;
+ for (var j = 0; j < enemies.length; j++) {
+ var enemy = enemies[j];
+ if (projectile.row === enemy.row && projectile.x >= enemy.x - 35 && projectile.x <= enemy.x + 35) {
+ enemy.takeDamage(projectile.damage);
+ hit = true;
+ break;
+ }
+ }
+ // Remove projectile if hit or off screen
+ if (hit || projectile.x > 2100) {
+ projectiles.splice(i, 1);
+ projectile.destroy();
+ }
+ }
+ // Check enemy-plant collisions
+ for (var k = 0; k < enemies.length; k++) {
+ var enemy = enemies[k];
+ enemy.attacking = false;
+ for (var l = 0; l < plants.length; l++) {
+ var plant = plants[l];
+ if (enemy.row === plant.row && enemy.x >= plant.x - 50 && enemy.x <= plant.x + 50) {
+ enemy.attacking = true;
+ break;
+ }
+ }
+ }
+ checkWaveComplete();
+ checkGameOver();
+};
\ No newline at end of file
La Petacereza es un par de cerezas gemelas de un rojo intenso y brillante, unidas por sus delgados tallos que se juntan en una pequeña ramita coronada por tres hojas verdes oscuras. Cada fruto tiene rasgos agresivos: ojos amarillentos con iris rojizos y cejas fruncidas, y bocas torcidas en muecas de enfado que sugieren su inminente explosión. Sus superficies lucen suaves, con leves reflejos que acentúan su redondez perfecta.. In-Game asset. 2d. High contrast. No shadows
una planta de color verde brillante con forma de pistola vegetal: su “cañón” cilíndrico, ligeramente más ancho en la boca, luce un tono verde claro con un suave degradado y un brillo que le da volumen. Sus ojos son dos círculos lisos y oscuros, casi sin pupila, que le aportan un aire simpático y sencillo. El cuerpo descansa sobre un tallo delgado y flexible, sostenido por cuatro hojas arqueadas y onduladas en la base, de un verde más intenso, que sirven de “pies” y refuerzan su aparienciauna planta de color verde brillante con forma de pistola vegetal: su “cañón” cilíndrico, ligeramente más ancho en la boca, luce un tono verde claro con un suave degradado y un brillo que le da volumen. Sus ojos son dos círculos lisos y oscuros, casi sin pupila, que le aportan un aire simpático y sencillo. El cuerpo descansa sobre un tallo delgado y flexible, sostenido por cuatro hojas arqueadas y onduladas en la base, de un verde más intenso, que sirven de “pies” y refuerzan su apariencia. In-Game asset. High contrast. No shadows
Un girasol con una cabeza redonda y marrón con pétalos amarillos brillantes que lo rodean como una corona. Su tallo es verde y tiene dos hojas grandes y anchas que sobresalen a los lados. En su cara, tiene dos ojos pequeños y negros, y una boca curvada en una sonrisa amigable.. In-Game asset. High contrast. No shadows
varias nubes de Humo color rojo un poco oscuro saliendo de una explosión. In-Game asset. High contrast
Una planta de color verde brillante, con un cuerpo principal esférico que se estrecha hacia adelante para formar una boca grande y redonda. De la parte posterior de su cabeza, brotan varias hojas puntiagudas. Tiene dos ojos grandes y redondos, con pupilas negras, y su expresión es decidida. Su tallo es delgado y verde, anclado en un grupo de hojas más grandes en la base.. In-Game asset. High contrast. No shadows
Nuez de color marrón claro, con una textura rugosa que le da un aspecto robusto. Es de forma ovalada, ligeramente más ancha en la base. Tiene dos ojos grandes y blancos con pupilas negras, que miran hacia adelante, y una boca pequeña y sonriente que le da una expresión algo asustadiza o sorprendida.. In-Game asset. High contrast. No shadows
Una casilla de pasto con bordes color verde oscuro que cubra toda la imagen y unas pequeñas flores. In-Game asset. High contrast
Esqueleto zombi en cuerpo completo caminando. In-Game asset. 2d. High contrast. No shadows
Zombie de piel verdosa y pálida, con una cabeza ovalada y dos grandes ojos saltones con pupilas pequeñas y rojizas. Su boca está abierta, mostrando dientes irregulares. Viste un traje de negocios marrón claro, una camisa blanca y una corbata roja a rayas, todo rasgado y sucio. Sus pantalones azules están hechos jirones, dejando ver una pierna esquelética, y calza zapatos marrones desgastados. Sus brazos están extendidos ligeramente hacia adelante. In-Game asset. 2d. High contrast. No shadows
Un guisante. In-Game asset. 2d. High contrast. No shadows
Sol puntiagudo luminoso. In-Game asset. 2d. High contrast. No shadows
Zombi a cuerpo completo de piel verdosa y pálida, con cabello desordenado y ojos saltones, viste una camisa de fuerza con correas de cuero alrededor de sus brazos y torso. sostiene una caja de sorpresas roja y blanca con estrellas, que tiene una manivela en un lado. Su expresión es de una sonrisa macabra. In-Game asset. 2d. High contrast. No shadows
Una podadora de césped compacta y robusta, predominantemente de color rojo vibrante. Tiene un motor gris con una tapa roja en la parte superior. Cuenta con cuatro ruedas pequeñas y oscuras, y un mango largo y negro en forma de "U" invertida que se extiende hacia atrás.. In-Game asset. 2d. High contrast. No shadows
pequeña pala de acero, con mango de madera y un agarre de color rojo. In-Game asset. 2d. High contrast. No shadows
Un zombi gigante y musculoso de piel verdosa. Viste un chaleco marrón roto y pantalones oscuros desgarrados, dejando ver parte de sus piernas. En su mano derecha, blande un poste de luz improvisado con cuatro farolas, usándolo como arma. Sobre su espalda, lleva a un zombi pequeño, sujeto por unas correas. Sus ojos son grandes y saltones, y su boca está abierta mostrando una dentadura irregular, dándole una expresión de furia.. In-Game asset. 2d. High contrast. No shadows
Un zombi con piel verdosa y pálida, cabello rojizo despeinado y un gorro de lana rojo. Viste un chaleco de mezclilla sin mangas sobre una camiseta negra y pantalones de mezclilla. Está sentado en un vehículo de mantenimiento de hielo azul y gris, similar a una Zamboni, con una gran "Z" roja en el frente. El vehículo tiene ruedas pequeñas y negras, y el Zomboni lo conduce con una expresión de asombro y determinación, con la boca abierta.. In-Game asset. 2d. High contrast. No shadows
una planta que emerge del suelo como una masa de tierra marrón, semi-enterrada. De ella sobresalen una serie de púas afiladas de color beige, de diferentes tamaños y ángulos, dispuestas en varias filas. En el centro, asoman dos ojos pequeños y rojos, con una mirada intensa y ligeramente enojada.. In-Game asset. 2d. High contrast. No shadows
Planta Carnívora con una cabeza grande y ovalada de color púrpura oscuro, salpicada con manchas más claras del mismo tono. Su boca es enorme, bordeada por un labio verde lima y llena de dientes blancos y afilados. Dentro de su boca, se ve una lengua rosada y una garganta oscura. Un tallo delgado y púrpura sostiene la cabeza, y en su base, tiene varias hojas verdes que se curvan hacia abajo. Pequeñas hojas puntiagudas también brotan de la parte superior y trasera de su cabeza.. In-Game asset. 2d. High contrast. No shadows