User prompt
Make the omega plant shoot if there is pest in any of the lanes
User prompt
Make the MegaRat spawn only regular pest instead of Partyrats
User prompt
If you finish all the levels then make so there is a extra 5 that has different plants and pest
User prompt
Well make so I can place a seed producer plant on top of a mega plant
User prompt
Make so that in order to make the omega plant you have to put a seed producer plant on top of a mega plant
User prompt
Make a new plant called omega plant it shoots in every lane the only way to make it is bye putting a seed producer plant on top of a mega plant. Also you can only make one also make a asset for it
User prompt
Make the mega rat rapidly spawn partyRats in all the lanes
User prompt
Make the max wave 20
User prompt
Make a new pest called the “mega rat” that has the most health in the whole game and instantly kills plants when he touches them it also is very big and takes up to lanes lastly make a asset for it
User prompt
Make the waves go up to 30
User prompt
Don’t make the mega plants bullets pierce
User prompt
I ment on the left of it
User prompt
Make my resources next to the seed shop
User prompt
Make the amount of seed bigger and black
User prompt
Move the seed shop to the bottom of the screen
User prompt
Put the price of each plant under there icon
User prompt
Make so you can only place a shooter on the trap
User prompt
Make so that if there is a trap plant on the one of the grids then you can place a plant on top of it to turn it into mega plant ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Make so you can put the plant on top of the trap to make a mega plant ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Make a secret plant called the mega plant. You can spawn it by putting a trap on a plant. also make it have a asset ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Can I make party rat’s spawn cooldown from 4 to 4.5 seconds
User prompt
Put the seed shop were it used to be
User prompt
Move the seed shop to the bottom right corner
User prompt
Call it the seed shop
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Fast, tough pest that spawns on wave 3 var FastPest = Container.expand(function () { var self = Container.call(this); var sprite = self.attachAsset('fastPest', { anchorX: 0.5, anchorY: 0.5, width: 120, height: 120 }); self.lane = null; self.hp = 5; // More health than basic pest self.speed = 4.5; // Much faster than basic pest self.destroyed = false; self.update = function () { if (self.destroyed) return; // Initialize lastX for transition checks if (self.lastX === undefined) self.lastX = self.x; // If currently eating a plant, handle eating logic if (self.eatingPlant && !self.eatingPlant._destroyed) { // Only bite every 30 frames if (self.eatCooldown === undefined) self.eatCooldown = 0; if (self._chewTweening !== true) { self._chewTweening = true; tween(self, { scaleX: 1.2 }, { duration: 80, yoyo: true, repeat: 2, onFinish: function onFinish() { self.scaleX = 1.0; self._chewTweening = false; } }); } if (self.eatCooldown > 0) { self.eatCooldown--; } else { // Damage the plant if (typeof self.eatingPlant.hp === "number") { self.eatingPlant.hp -= 1; // Optional: flash or animate plant here if (self.eatingPlant.hp <= 0) { self.eatingPlant._destroyed = true; if (typeof self.eatingPlant.destroy === "function") self.eatingPlant.destroy(); // Remove from plants array in main update self.eatingPlant = null; self.scaleX = 1.0; self._chewTweening = false; } } self.eatCooldown = 30; } // Don't move while eating } else { // Not eating, move left self.x -= self.speed; // Check for collision with plant in same lane var foundPlant = null; for (var i = 0; i < plants.length; i++) { var plant = plants[i]; if (plant.lane === self.lane && !plant._destroyed && Math.abs(self.x - plant.x) < 60) { foundPlant = plant; break; } } if (foundPlant) { self.eatingPlant = foundPlant; self.eatCooldown = 0; } } // Update lastX self.lastX = self.x; }; self.hit = function (dmg) { if (self.destroyed) return; self.hp -= dmg; if (self.hp <= 0) { self.destroyed = true; } }; return self; }); // Mega plant - secret powerful plant created by placing trap on existing plant var MegaPlant = Container.expand(function () { var self = Container.call(this); var sprite = self.attachAsset('megaPlant', { anchorX: 0.5, anchorY: 0.5, width: 180, height: 180 }); self.fireCooldown = 20; // Very fast firing self.cooldown = 0; self.lane = null; self.column = null; self.hp = 20; // Very high health self._destroyed = false; self._pulseTimer = 0; self.update = function () { if (self.cooldown > 0) self.cooldown--; if (self.hp <= 0 && !self._destroyed) { self._destroyed = true; if (typeof self.destroy === "function") self.destroy(); } // Pulse animation every 60 frames self._pulseTimer++; if (self._pulseTimer >= 60) { self._pulseTimer = 0; tween(sprite, { scaleX: 1.2, scaleY: 1.2, tint: 0xFF69B4 }, { duration: 300, yoyo: true, repeat: 1, onFinish: function onFinish() { sprite.tint = 0xFFFFFF; } }); } }; self.tryFire = function () { if (self.cooldown <= 0) { self.cooldown = self.fireCooldown; return true; } return false; }; return self; }); // --- Pest Classes --- // Party Rat - high health pest that spawns other pests in 4 directions every 6 seconds var PartyRat = Container.expand(function () { var self = Container.call(this); var sprite = self.attachAsset('partyRat', { anchorX: 0.5, anchorY: 0.5, width: 140, height: 140 }); self.lane = null; self.hp = 15; // Very high health self.speed = 1.5; // Slower than other pests self.destroyed = false; self.spawnCooldown = 270; // 4.5 seconds at 60fps self.spawnTimer = 0; self.update = function () { if (self.destroyed) return; // Initialize lastX for transition checks if (self.lastX === undefined) self.lastX = self.x; // Handle spawning timer self.spawnTimer++; if (self.spawnTimer >= self.spawnCooldown) { self.spawnTimer = 0; self.spawnPests(); } // If currently eating a plant, handle eating logic if (self.eatingPlant && !self.eatingPlant._destroyed) { // Only bite every 30 frames if (self.eatCooldown === undefined) self.eatCooldown = 0; if (self._chewTweening !== true) { self._chewTweening = true; tween(self, { scaleX: 1.3 }, { duration: 100, yoyo: true, repeat: 2, onFinish: function onFinish() { self.scaleX = 1.0; self._chewTweening = false; } }); } if (self.eatCooldown > 0) { self.eatCooldown--; } else { // Damage the plant if (typeof self.eatingPlant.hp === "number") { self.eatingPlant.hp -= 2; // Party rat does more damage if (self.eatingPlant.hp <= 0) { self.eatingPlant._destroyed = true; if (typeof self.eatingPlant.destroy === "function") self.eatingPlant.destroy(); self.eatingPlant = null; self.scaleX = 1.0; self._chewTweening = false; } } self.eatCooldown = 30; } } else { // Not eating, move left self.x -= self.speed; // Check for collision with plant in same lane var foundPlant = null; for (var i = 0; i < plants.length; i++) { var plant = plants[i]; if (plant.lane === self.lane && !plant._destroyed && Math.abs(self.x - plant.x) < 60) { foundPlant = plant; break; } } if (foundPlant) { self.eatingPlant = foundPlant; self.eatCooldown = 0; } } // Update lastX self.lastX = self.x; }; self.spawnPests = function () { // Spawn pests in 4 directions: front, back, up lane, down lane var spawnPositions = [{ x: self.x + 100, lane: self.lane }, // Front (right) { x: self.x - 100, lane: self.lane }, // Behind (left) { x: self.x, lane: Math.max(0, self.lane - 1) }, // Up lane { x: self.x, lane: Math.min(LANE_COUNT - 1, self.lane + 1) } // Down lane ]; for (var i = 0; i < spawnPositions.length; i++) { var pos = spawnPositions[i]; // Don't spawn if position is off-screen or invalid if (pos.x > 50 && pos.x < GAME_WIDTH - 50) { var newPest = new Pest(); newPest.lane = pos.lane; newPest.x = pos.x; newPest.y = LANE_Y[pos.lane]; pests.push(newPest); game.addChild(newPest); // Visual effect for spawning LK.effects.flashObject(newPest, 0xFF69B4, 300); } } // Visual effect on the party rat when it spawns LK.effects.flashObject(self, 0xFFFF00, 500); }; self.hit = function (dmg) { if (self.destroyed) return; self.hp -= dmg; if (self.hp <= 0) { self.destroyed = true; } }; return self; }); // Basic pest that moves left and can be hit by seeds var Pest = Container.expand(function () { var self = Container.call(this); var sprite = self.attachAsset('pest', { anchorX: 0.5, anchorY: 0.5, width: 100, height: 100 }); self.lane = null; self.hp = 2; self.speed = 2.0; self.destroyed = false; self.update = function () { if (self.destroyed) return; // Initialize lastX for transition checks if (self.lastX === undefined) self.lastX = self.x; // If currently eating a plant, handle eating logic if (self.eatingPlant && !self.eatingPlant._destroyed) { // Only bite every 30 frames if (self.eatCooldown === undefined) self.eatCooldown = 0; if (self._chewTweening !== true) { self._chewTweening = true; tween(self, { scaleX: 1.2 }, { duration: 80, yoyo: true, repeat: 2, onFinish: function onFinish() { self.scaleX = 1.0; self._chewTweening = false; } }); } if (self.eatCooldown > 0) { self.eatCooldown--; } else { // Damage the plant if (typeof self.eatingPlant.hp === "number") { self.eatingPlant.hp -= 1; // Optional: flash or animate plant here if (self.eatingPlant.hp <= 0) { self.eatingPlant._destroyed = true; if (typeof self.eatingPlant.destroy === "function") self.eatingPlant.destroy(); // Remove from plants array in main update self.eatingPlant = null; self.scaleX = 1.0; self._chewTweening = false; } } self.eatCooldown = 30; } // Don't move while eating } else { // Not eating, move left self.x -= self.speed; // Check for collision with plant in same lane var foundPlant = null; for (var i = 0; i < plants.length; i++) { var plant = plants[i]; if (plant.lane === self.lane && !plant._destroyed && Math.abs(self.x - plant.x) < 60) { foundPlant = plant; break; } } if (foundPlant) { self.eatingPlant = foundPlant; self.eatCooldown = 0; } } // Update lastX self.lastX = self.x; }; self.hit = function (dmg) { if (self.destroyed) return; self.hp -= dmg; if (self.hp <= 0) { self.destroyed = true; } }; return self; }); // --- Plant Classes --- // Basic shooter plant var Plant = Container.expand(function () { var self = Container.call(this); var sprite = self.attachAsset('plant', { anchorX: 0.5, anchorY: 0.5, width: 120, height: 120 }); self.fireCooldown = 60; // frames between shots self.cooldown = 0; self.lane = null; self.column = null; self.hp = 5; // Plant health self._destroyed = false; self.update = function () { if (self.cooldown > 0) self.cooldown--; if (self.hp <= 0 && !self._destroyed) { self._destroyed = true; if (typeof self.destroy === "function") self.destroy(); } }; self.tryFire = function () { if (self.cooldown <= 0) { self.cooldown = self.fireCooldown; return true; } return false; }; return self; }); // --- Seed Class --- // Seed projectile fired by shooter plants var Seed = Container.expand(function () { var self = Container.call(this); var sprite = self.attachAsset('seed', { anchorX: 0.5, anchorY: 0.5, width: 40, height: 40 }); self.lane = null; self.speed = 10; self.update = function () { self.x += self.speed; }; return self; }); // Plant that generates resources var SeedProducerPlant = Container.expand(function () { var self = Container.call(this); var sprite = self.attachAsset('seedProducerPlant', { anchorX: 0.5, anchorY: 0.5, width: 120, height: 120 }); self.resourceCooldown = 90; // frames between resource generation (was 180, now 90 for faster seed gain) self.cooldown = 0; self.lane = null; self.column = null; self.hp = 5; // Plant health self._destroyed = false; self._seedsProduced = 0; self.update = function () { if (self.cooldown > 0) { self.cooldown--; } else { // Give resource and reset cooldown resources += 1; resourceTxt.setText(resources + ''); self.cooldown = self.resourceCooldown; self._seedsProduced = (self._seedsProduced || 0) + 1; if (self._seedsProduced % 2 === 0) { // Glow pink using tween (tint to pink, then back to normal) tween.stop(sprite, { tint: true }); var originalTint = sprite.tint; tween(sprite, { tint: 0xFF69B4 }, { duration: 120, yoyo: true, repeat: 1, onFinish: function onFinish() { sprite.tint = originalTint; } }); } } if (self.hp <= 0 && !self._destroyed) { self._destroyed = true; if (typeof self.destroy === "function") self.destroy(); } }; return self; }); // Trap plant that eats any pest that touches it, then disappears var TrapPlant = Container.expand(function () { var self = Container.call(this); var sprite = self.attachAsset('trapPlant', { anchorX: 0.5, anchorY: 0.5, width: 120, height: 120 }); self.lane = null; self.column = null; self.hp = 1; // Dies after eating one pest self._destroyed = false; self.hasEaten = false; self.cooldownTime = 6000; // 6 second cooldown in milliseconds self.cooldownRemaining = 0; self.onCooldown = false; self.update = function () { if (self._destroyed || self.hasEaten) return; // Handle cooldown if (self.onCooldown) { self.cooldownRemaining -= 16; // Approximately 16ms per frame at 60fps if (self.cooldownRemaining <= 0) { self.onCooldown = false; // Reset visual appearance when cooldown ends sprite.tint = 0xffffff; sprite.alpha = 1.0; } return; // Don't check for collisions while on cooldown } // Check for collision with any pest in same lane - improved collision detection for (var i = pests.length - 1; i >= 0; i--) { var pest = pests[i]; // Check if pest is in same lane and within touching distance if (pest.lane === self.lane && !pest.destroyed && Math.abs(self.x - pest.x) < 80 && Math.abs(self.y - pest.y) < 60) { // Instantly kill the pest - set HP to 0 and destroy immediately pest.hp = 0; pest.destroyed = true; pest.destroy(); // Remove from pests array immediately pests.splice(i, 1); // Start cooldown instead of destroying plant self.onCooldown = true; self.cooldownRemaining = self.cooldownTime; // Visual feedback for cooldown - make plant greyish and semi-transparent sprite.tint = 0x666666; sprite.alpha = 0.6; // Flash effect on successful kill LK.effects.flashObject(self, 0x00ff00, 200); break; } } if (self.hp <= 0 && !self._destroyed) { self._destroyed = true; if (typeof self.destroy === "function") self.destroy(); } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x7ec850 // Light green garden }); /**** * Game Code ****/ // Add background image var background = LK.getAsset('background', { anchorX: 0, anchorY: 0, x: 0, y: 0, width: 2048, height: 2732 }); game.addChild(background); // --- Constants --- // Unique sprite for fast, tough pest var GAME_WIDTH = 2048; var GAME_HEIGHT = 2732; var LANE_COUNT = 7; var LANE_HEIGHT = Math.floor(GAME_HEIGHT / LANE_COUNT); var LANE_Y = []; for (var i = 0; i < LANE_COUNT; i++) { LANE_Y[i] = Math.floor((i + 0.5) * LANE_HEIGHT); } var PLANT_COST = 10; var START_RESOURCES = 20; var MAX_BREACHES = 5; var TOTAL_WAVES = 10; var COLUMN_COUNT = 5; // Number of plant columns var COLUMN_WIDTH = 160; // Distance between columns var COLUMN_START_X = 200; // X position of first column // --- Asset Initialization --- // --- Game State --- var plants = []; // All plant objects var pests = []; // All pest objects var seeds = []; // All seed objects var rockets = []; // All rocket objects (initialized in global game state) var resources = START_RESOURCES; var breaches = 0; var wave = 1; var waveInProgress = false; var waveTimer = 0; var nextPestTick = 0; var selectedLane = null; // Lane index for planting var selectedColumn = null; // Column index for planting var plantPreview = null; // Preview asset for planting // --- Lane Markers (for touch feedback) --- var laneMarkers = []; for (var i = 0; i < LANE_COUNT; i++) { for (var col = 0; col < COLUMN_COUNT; col++) { // Use a unique grid sprite for the grid cell background var marker = LK.getAsset('grid', { anchorX: 0.5, anchorY: 0.5, x: COLUMN_START_X + col * COLUMN_WIDTH, y: LANE_Y[i], alpha: 0.8, width: 180, height: LANE_HEIGHT - 10, tint: 0xD2B48C }); game.addChild(marker); laneMarkers.push(marker); } } // --- UI Elements --- // Plant selection UI var plantTypes = [{ id: 'plant', name: 'Shooter', asset: 'plant', desc: 'Shoots seeds', classRef: Plant }, { id: 'seedProducer', name: 'Producer', asset: 'seedProducerPlant', desc: 'Generates seeds', classRef: SeedProducerPlant }, { id: 'trapPlant', name: 'Trap', asset: 'trapPlant', desc: 'Eats one pest', classRef: TrapPlant }, { id: 'megaPlant', name: 'Mega', asset: 'megaPlant', desc: 'Secret plant', classRef: MegaPlant }]; var selectedPlantType = plantTypes[0]; // Default to shooter var plantSelectButtons = []; var plantSelectY = 120; var plantSelectSpacing = 220; for (var i = 0; i < plantTypes.length; i++) { var btnX = 200 + i * plantSelectSpacing; var btn = LK.getAsset(plantTypes[i].asset, { anchorX: 0.5, anchorY: 0.5, x: btnX, y: plantSelectY, width: 120, height: 120, alpha: 0.9 }); btn._plantTypeIndex = i; btn.interactive = true; btn.buttonMode = true; // Add a border to show selection btn._border = LK.getAsset(plantTypes[i].asset, { anchorX: 0.5, anchorY: 0.5, x: btnX, y: plantSelectY, width: 140, height: 140, alpha: 0.0 // Will set to visible for selected }); LK.gui.top.addChild(btn._border); LK.gui.top.addChild(btn); plantSelectButtons.push(btn); // Add label var label = new Text2(plantTypes[i].name, { size: 40, fill: "#222" }); label.anchor.set(0.5, 0); label.x = btnX; label.y = plantSelectY + 70; LK.gui.top.addChild(label); // Add price label var priceLabel = new Text2(PLANT_COST + ' seeds', { size: 30, fill: "#444" }); priceLabel.anchor.set(0.5, 0); priceLabel.x = btnX; priceLabel.y = plantSelectY + 110; LK.gui.top.addChild(priceLabel); } // Helper to update plant selection UI function updatePlantSelectUI() { for (var i = 0; i < plantSelectButtons.length; i++) { if (plantTypes[i] === selectedPlantType) { plantSelectButtons[i]._border.alpha = 0.7; plantSelectButtons[i]._border.tint = 0xFFD700; } else { plantSelectButtons[i]._border.alpha = 0.0; } } } updatePlantSelectUI(); // Add Seed Shop title var seedShopTitle = new Text2('Seed Shop', { size: 60, fill: "#333", font: "Impact" }); seedShopTitle.anchor.set(0.5, 0); seedShopTitle.x = GAME_WIDTH / 2; seedShopTitle.y = 40; LK.gui.top.addChild(seedShopTitle); // Add touch handler for plant selection for (var i = 0; i < plantSelectButtons.length; i++) { (function (idx) { plantSelectButtons[idx].down = function (x, y, obj) { selectedPlantType = plantTypes[idx]; updatePlantSelectUI(); // Hide preview if showing if (plantPreview) { plantPreview.destroy(); plantPreview = null; } showPlantPreview(null, null); selectedLane = null; selectedColumn = null; }; })(i); } var resourceTxt = new Text2(resources + '', { size: 90, fill: 0xFFF700 }); resourceTxt.anchor.set(0.5, 0); LK.gui.top.addChild(resourceTxt); var waveTxt = new Text2('Wave 1/' + TOTAL_WAVES, { size: 70, fill: 0xFFFFFF }); waveTxt.anchor.set(0.5, 0); LK.gui.top.addChild(waveTxt); var breachTxt = new Text2('Breaches: 0/' + MAX_BREACHES, { size: 70, fill: 0xFF4444 }); breachTxt.anchor.set(0.5, 0); LK.gui.top.addChild(breachTxt); // Position UI resourceTxt.x = 1100; // Position next to seed shop resourceTxt.y = plantSelectY; // Same height as plant selection buttons waveTxt.x = GAME_WIDTH / 2; waveTxt.y = 20; breachTxt.x = GAME_WIDTH - 400; breachTxt.y = 20; // --- Plant Preview (shows where plant will be placed) --- function showPlantPreview(lane, column) { if (plantPreview) { plantPreview.visible = false; } if (lane === null || column === null) return; if (plantPreview) { plantPreview.destroy(); plantPreview = null; } if (!plantPreview) { // Use correct asset for preview var assetId = selectedPlantType ? selectedPlantType.asset : 'plant'; plantPreview = LK.getAsset(assetId, { anchorX: 0.5, anchorY: 0.5, alpha: 0.5, width: 120, height: 120 }); game.addChild(plantPreview); } plantPreview.x = COLUMN_START_X + column * COLUMN_WIDTH; plantPreview.y = LANE_Y[lane]; plantPreview.visible = true; } // --- Plant Placement Handler --- function canPlacePlant(lane, column) { // Check if there's enough resources first if (resources < PLANT_COST) return false; // Check for existing plants at this position for (var i = 0; i < plants.length; i++) { if (plants[i].lane === lane && plants[i].column === column && !plants[i]._destroyed) { // Allow placement if existing plant is a trap AND selected plant is a shooter (for mega plant transformation) if (plants[i].constructor === TrapPlant && selectedPlantType.classRef === Plant) { return true; } // Block placement for all other plant types return false; } } return true; } function placePlant(lane, column) { // Check if placing any plant on existing trap to create mega plant for (var i = 0; i < plants.length; i++) { if (plants[i].lane === lane && plants[i].column === column && !plants[i]._destroyed) { // Check if existing plant is a trap if (plants[i].constructor === TrapPlant) { // Transform trap into mega plant var existingTrap = plants[i]; existingTrap.destroy(); plants.splice(i, 1); var megaPlant = new MegaPlant(); megaPlant.lane = lane; megaPlant.column = column; megaPlant.x = COLUMN_START_X + column * COLUMN_WIDTH; megaPlant.y = LANE_Y[lane]; plants.push(megaPlant); game.addChild(megaPlant); // Special transformation effect LK.effects.flashObject(megaPlant, 0xFFD700, 800); tween(megaPlant, { scaleX: 0.5, scaleY: 0.5 }, { duration: 200, yoyo: true, repeat: 1 }); resources -= PLANT_COST; resourceTxt.setText(resources + ''); return true; } } } if (!canPlacePlant(lane, column)) return false; var plant; if (selectedPlantType && selectedPlantType.classRef) { plant = new selectedPlantType.classRef(); } else { // fallback plant = new Plant(); } plant.lane = lane; plant.column = column; plant.x = COLUMN_START_X + column * COLUMN_WIDTH; plant.y = LANE_Y[lane]; plants.push(plant); game.addChild(plant); resources -= PLANT_COST; resourceTxt.setText(resources + ''); return true; } // --- Touch Handler for Planting --- game.down = function (x, y, obj) { // Ignore top 100px (menu area) if (y < 100) return; // Find lane var lane = Math.floor(y / LANE_HEIGHT); if (lane < 0 || lane >= LANE_COUNT) return; // Find column var column = Math.floor((x - COLUMN_START_X + COLUMN_WIDTH / 2) / COLUMN_WIDTH); if (column < 0 || column >= COLUMN_COUNT) return; selectedLane = lane; selectedColumn = column; showPlantPreview(lane, column); }; game.move = function (x, y, obj) { if (y < 100) { showPlantPreview(null); selectedLane = null; selectedColumn = null; return; } var lane = Math.floor(y / LANE_HEIGHT); var column = Math.floor((x - COLUMN_START_X + COLUMN_WIDTH / 2) / COLUMN_WIDTH); if (lane < 0 || lane >= LANE_COUNT || column < 0 || column >= COLUMN_COUNT) { showPlantPreview(null); selectedLane = null; selectedColumn = null; return; } selectedLane = lane; selectedColumn = column; showPlantPreview(lane, column); }; game.up = function (x, y, obj) { if (selectedLane !== null && selectedColumn !== null) { if (canPlacePlant(selectedLane, selectedColumn)) { placePlant(selectedLane, selectedColumn); } } showPlantPreview(null); selectedLane = null; selectedColumn = null; }; // --- Resource Generation --- var resourceTimer = LK.setInterval(function () { resources += 1; resourceTxt.setText(resources + ''); }, 500); // Increased resource gain rate (was 1000ms, now 500ms) // --- Wave System --- function startWave() { waveInProgress = true; waveTimer = 0; nextPestTick = 0; waveTxt.setText('Wave ' + wave + '/' + TOTAL_WAVES); // Show wave banner if (!game._waveBanner) { var banner = new Text2('Wave ' + wave, { size: 200, fill: 0xFFF700, font: "Impact", stroke: "#222", strokeThickness: 10 }); banner.anchor.set(0.5, 0.5); banner.x = GAME_WIDTH / 2; banner.y = GAME_HEIGHT / 2; banner.alpha = 0.0; game._waveBanner = banner; game.addChild(banner); } else { game._waveBanner.setText('Wave ' + wave); } game._waveBanner.alpha = 1.0; game._waveBanner.visible = true; // Fade out after 1.2s tween(game._waveBanner, { alpha: 0 }, { duration: 900, delay: 1200, onFinish: function onFinish() { game._waveBanner.visible = false; } }); } function endWave() { waveInProgress = false; wave++; if (wave > TOTAL_WAVES) { LK.showYouWin(); } else { // Short pause before next wave LK.setTimeout(function () { startWave(); }, 1800); } } // --- Pest Spawning --- function spawnPest() { var lane = Math.floor(Math.random() * LANE_COUNT); var pest; // Spawn different pest types based on wave if (wave >= 5 && wave <= 15 && Math.random() < 0.15) { // 15% chance to spawn PartyRat from wave 5-15 pest = new PartyRat(); } else if (wave >= 3 && wave <= 15) { pest = new FastPest(); } else { pest = new Pest(); } pest.lane = lane; pest.x = GAME_WIDTH - 100; pest.y = LANE_Y[lane]; pests.push(pest); game.addChild(pest); } // --- Main Game Update --- game.update = function () { // --- Wave logic --- if (!waveInProgress) { startWave(); return; } waveTimer++; // Pest spawn logic: spawn a pest every 60-90 ticks, up to 6+wave pests per wave if (nextPestTick <= 0) { if (waveTimer < (6 + wave) * 80) { spawnPest(); nextPestTick = 60 + Math.floor(Math.random() * 30); } } else { nextPestTick--; } // End wave if all pests spawned and none left if (waveTimer > (6 + wave) * 80 && pests.length === 0) { endWave(); return; } // --- Plants fire seeds --- for (var i = plants.length - 1; i >= 0; i--) { var plant = plants[i]; plant.update(); // Remove destroyed plants if (plant._destroyed) { plant.destroy(); plants.splice(i, 1); continue; } // Only shooter plants fire seeds if (typeof plant.tryFire === "function") { // Fire if pest in lane and cooldown ready var pestInLane = false; for (var j = 0; j < pests.length; j++) { if (pests[j].lane === plant.lane && pests[j].x > plant.x) { pestInLane = true; break; } } if (pestInLane && plant.tryFire()) { // Mega plant fires 3 seeds in spread pattern if (plant.constructor === MegaPlant) { for (var k = -1; k <= 1; k++) { var targetLane = plant.lane + k; if (targetLane >= 0 && targetLane < LANE_COUNT) { var seed = new Seed(); seed.x = plant.x + 60; seed.y = plant.y; seed.lane = targetLane; seed.speed = 12; // Faster seeds seeds.push(seed); game.addChild(seed); } } // Fire effect on mega plant tween(plant, { scaleX: 1.3, scaleY: 1.3 }, { duration: 100, yoyo: true, repeat: 1 }); } else { var seed = new Seed(); seed.x = plant.x + 60; seed.y = plant.y; seed.lane = plant.lane; seeds.push(seed); game.addChild(seed); } } } } // --- Seeds move and hit pests --- for (var s = seeds.length - 1; s >= 0; s--) { var seed = seeds[s]; seed.update(); var hit = false; for (var p = 0; p < pests.length; p++) { var pest = pests[p]; if (pest.lane === seed.lane && !pest.destroyed && Math.abs(seed.x - pest.x) < 60) { pest.hit(1); hit = true; break; } } if (hit || seed.x > GAME_WIDTH + 50) { seed.destroy(); seeds.splice(s, 1); } } // --- Pests move and check for breach or death --- for (var p = pests.length - 1; p >= 0; p--) { var pest = pests[p]; if (pest.destroyed) { pest.destroy(); pests.splice(p, 1); continue; } pest.update(); if (pest.x < 80) { // Breach! breaches++; breachTxt.setText('Breaches: ' + breaches + '/' + MAX_BREACHES); LK.effects.flashScreen(0xff0000, 400); pest.destroy(); pests.splice(p, 1); if (breaches >= MAX_BREACHES) { LK.showGameOver(); return; } } } }; // --- Clean up on game over/win --- game.on('destroy', function () { LK.clearInterval(resourceTimer); plants = []; pests = []; seeds = []; breaches = 0; resources = START_RESOURCES; wave = 1; waveInProgress = false; if (plantPreview) { plantPreview.destroy(); plantPreview = null; } if (game._waveBanner) { game._waveBanner.visible = false; game._waveBanner.alpha = 0; } }); // --- Initial UI update --- resourceTxt.setText(resources + ''); waveTxt.setText('Wave 1/' + TOTAL_WAVES); breachTxt.setText('Breaches: 0/' + MAX_BREACHES); // --- Start background music --- LK.playMusic('Hi1234');
===================================================================
--- original.js
+++ change.js
@@ -607,9 +607,9 @@
classRef: MegaPlant
}];
var selectedPlantType = plantTypes[0]; // Default to shooter
var plantSelectButtons = [];
-var plantSelectY = -120;
+var plantSelectY = 120;
var plantSelectSpacing = 220;
for (var i = 0; i < plantTypes.length; i++) {
var btnX = 200 + i * plantSelectSpacing;
var btn = LK.getAsset(plantTypes[i].asset, {
@@ -633,29 +633,29 @@
width: 140,
height: 140,
alpha: 0.0 // Will set to visible for selected
});
- LK.gui.bottom.addChild(btn._border);
- LK.gui.bottom.addChild(btn);
+ LK.gui.top.addChild(btn._border);
+ LK.gui.top.addChild(btn);
plantSelectButtons.push(btn);
// Add label
var label = new Text2(plantTypes[i].name, {
size: 40,
fill: "#222"
});
- label.anchor.set(0.5, 1);
+ label.anchor.set(0.5, 0);
label.x = btnX;
- label.y = plantSelectY - 70;
- LK.gui.bottom.addChild(label);
+ label.y = plantSelectY + 70;
+ LK.gui.top.addChild(label);
// Add price label
var priceLabel = new Text2(PLANT_COST + ' seeds', {
- size: 50,
- fill: 0x000000
+ size: 30,
+ fill: "#444"
});
- priceLabel.anchor.set(0.5, 1);
+ priceLabel.anchor.set(0.5, 0);
priceLabel.x = btnX;
- priceLabel.y = plantSelectY - 110;
- LK.gui.bottom.addChild(priceLabel);
+ priceLabel.y = plantSelectY + 110;
+ LK.gui.top.addChild(priceLabel);
}
// Helper to update plant selection UI
function updatePlantSelectUI() {
for (var i = 0; i < plantSelectButtons.length; i++) {
@@ -673,12 +673,12 @@
size: 60,
fill: "#333",
font: "Impact"
});
-seedShopTitle.anchor.set(0.5, 1);
+seedShopTitle.anchor.set(0.5, 0);
seedShopTitle.x = GAME_WIDTH / 2;
-seedShopTitle.y = -40;
-LK.gui.bottom.addChild(seedShopTitle);
+seedShopTitle.y = 40;
+LK.gui.top.addChild(seedShopTitle);
// Add touch handler for plant selection
for (var i = 0; i < plantSelectButtons.length; i++) {
(function (idx) {
plantSelectButtons[idx].down = function (x, y, obj) {
@@ -713,10 +713,10 @@
});
breachTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(breachTxt);
// Position UI
-resourceTxt.x = 400;
-resourceTxt.y = 20;
+resourceTxt.x = 1100; // Position next to seed shop
+resourceTxt.y = plantSelectY; // Same height as plant selection buttons
waveTxt.x = GAME_WIDTH / 2;
waveTxt.y = 20;
breachTxt.x = GAME_WIDTH - 400;
breachTxt.y = 20;
@@ -815,10 +815,10 @@
return true;
}
// --- Touch Handler for Planting ---
game.down = function (x, y, obj) {
- // Ignore bottom 300px (menu area)
- if (y > GAME_HEIGHT - 300) return;
+ // Ignore top 100px (menu area)
+ if (y < 100) return;
// Find lane
var lane = Math.floor(y / LANE_HEIGHT);
if (lane < 0 || lane >= LANE_COUNT) return;
// Find column
@@ -828,9 +828,9 @@
selectedColumn = column;
showPlantPreview(lane, column);
};
game.move = function (x, y, obj) {
- if (y > GAME_HEIGHT - 300) {
+ if (y < 100) {
showPlantPreview(null);
selectedLane = null;
selectedColumn = null;
return;
Pixelated sun . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Flip it around
Make the background white
Make it angry
Make a dirty patch of dirt. In-Game asset. 2d. High contrast. No shadows
Make the background red
Make the background green
Make it shiny
Looks like a gargantuar from plants vs zombies but a rat. In-Game asset. 2d. High contrast. No shadows
Make the background blue