User prompt
Please make the following two visual layout changes: 1. Castle Position: - Move the castle slightly **upward on the screen**, so that it is no longer positioned too close to the bottom. - Ensure it remains centered horizontally, but has some padding or space between it and the tower selection panel. 2. Tower Selection Panel Background: - Set the background of the tower selection panel to a **solid black color**. - The panel should be fully opaque (not transparent), so that the game area behind it is not visible. - This helps visually separate the UI from the gameplay area and improves readability. These changes will make the UI clearer and improve overall game presentation.
User prompt
Please adjust the game layout to prevent the tower selection panel from overlapping the game map. - The tower selection panel is currently positioned at the bottom of the screen, but part of the map is still visible behind it. - This causes some of the map area and potential build zones to be covered or hidden by the panel. Please fix it by: 1. Resizing or repositioning the game map so that it **ends exactly where the panel begins**. 2. Ensure that **no part of the playable area (enemy paths, tower zones, castle, etc.) is hidden under the panel**. 3. The panel and the map should be visually and functionally **separated**, without any overlap. This will improve clarity and avoid placing or seeing towers behind the panel.
Code edit (1 edits merged)
Please save this source code
User prompt
Please update the tower selection panel and tower placement system as follows: 1. Panel Position: - Move the fixed tower selection panel to the **left-center area of the screen**, - Specifically, place it **just above the health bar** (the "health" section) to keep UI organized. 2. Tower Clickability: - Make sure each tower icon/button inside the panel is fully **clickable and interactive**. - Clicking a tower icon should **select** that tower for placement. 3. Tower Placement: - After selecting a tower from the panel, the player should be able to **click on a valid build zone on the map** to place the tower. - Upon valid placement, deduct the tower cost and update the game state. - If the build zone is invalid or the player lacks gold, do not place the tower and show a message. 4. Ensure no UI elements or layers block clicks on tower icons. 5. Test that clicking towers in the panel properly registers the selection and triggers placement on the map. This will improve usability and fix the issue where tower icons were visible but unclickable.
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading '0')' in or related to this line: 'obj.children[0].tint = 0xAA0000; // Show red if can't afford' Line Number: 1067
User prompt
Please position the fixed tower selection panel at the **top of the game screen**, spanning horizontally. - The panel should be clearly visible but not cover important gameplay elements. - Towers in the panel should be displayed as clickable icons/buttons with their costs visible. - The panel remains static and accessible at all times during gameplay. - When a tower is selected from this top panel, the player can click on a valid build zone on the map to place the tower.
User prompt
Please revert the tower selection system back to the previous, simpler method: 1. Provide a fixed tower selection panel **outside the main game map area** (e.g., side or bottom panel). 2. Player selects a tower from this panel first. 3. After selecting, the player clicks on a valid build zone on the map to place the chosen tower. 4. If the build zone is valid and the player has enough gold, place the tower there and deduct the cost. 5. If the build zone is invalid or the player lacks gold, show an appropriate message and do not place the tower. 6. After placement, clear the selection (so player must choose again for next tower). This method avoids issues with contextual pop-up panels not registering clicks, and is easier for players to understand and for developers to implement.
User prompt
There is a problem with the tower selection panel's interactivity: - The panel opens correctly and is visible. - However, clicking anywhere inside the panel does not trigger any response. - It seems that the panel or its buttons are not receiving input events. Please check and fix the following: 1. Ensure that the panel and all buttons inside it have their "Interactable" or equivalent property enabled. 2. Verify that no other UI elements or invisible overlays block the panel, preventing clicks from reaching it. 3. Confirm that the OnClick events of each tower button are properly connected to the functions that handle tower placement. 4. Test that clicks on tower options trigger the appropriate placement logic and UI updates. This fix is crucial to enable tower placement through the selection panel.
User prompt
There is a critical issue with tower placement after selecting from the build zone panel: - When the player clicks on a tower build zone, the tower selection panel appears correctly, showing tower options in green. - However, clicking on a tower icon in the panel does not place the tower on the selected build zone. - The tower placement logic is missing or not triggered upon clicking the tower option. Please fix this by implementing the following steps: 1. Store the reference to the currently selected build zone when its panel is opened. 2. When the player clicks a tower option inside the panel: - Check if the player has enough gold. - If yes, **instantiate/place the selected tower object exactly at the stored build zone’s position**. - Deduct the appropriate gold amount. - Mark the build zone as occupied (disable further placements there). - Close/hide the tower selection panel. 3. If the player doesn’t have enough gold, do not place the tower and show an appropriate message or disable the button. 4. Ensure the click event on the tower options buttons properly triggers the above logic. 5. Test and confirm that clicking a tower icon in the panel results in immediate tower placement at the intended build zone. This will fix the disconnect between tower selection UI and tower placement action.
User prompt
The current tower selection panel still doesn't respond correctly when clicking tower options. Please fix and enhance the interaction as follows: --- 1. Tower Selection Panel Behavior: - When a build zone is clicked, display a small tower selection panel above the zone. - Each tower option should visually show its status: • ✅ If the tower **can be placed** (build zone is valid and the player has enough gold): - Display the button in **green** - Show the tower cost - Allow the player to click and place it • 🔴 If the **player has insufficient gold**, but the zone is valid: - Display the button in **red** - Show the tower cost - Add a message like “Not enough gold” • ⛔ If the **zone is not eligible** for that tower (wrong type or already occupied): - Display the button in **red** - Show a message like “Cannot build here” - When a valid tower is selected: • Place the tower at the clicked zone • Deduct the gold from the player • Hide the panel • Mark the build zone as used (no more towers can be placed there) --- 2. Castle HP Bar: - Add a horizontal health bar directly **below the castle** on the screen. - This bar should show the castle's remaining health as a percentage. - The bar color should change based on current health: • Green = full or near full HP • Yellow = mid-range HP • Red = low HP - The bar should update live as the castle takes damage. --- These improvements will make the tower placement system clearer and give players immediate visual feedback, while improving the UI clarity and gameplay experience.
User prompt
There is an issue with the contextual tower selection panel: - When I click on a build zone, the tower selection panel appears correctly. - However, clicking on a tower option inside the panel does nothing. - The selected tower is not placed on the build zone, and gold is not deducted. Please fix the following: 1. Make sure each tower button in the selection panel correctly registers click events. 2. When a tower is selected: - If the player has enough gold, place the selected tower at that specific build zone. - Deduct the correct amount of gold based on the selected tower's cost. - Close the panel after successful placement. 3. If the player doesn't have enough gold, disable or gray out the button and prevent placement. Also, ensure each build zone only accepts one tower and becomes inactive after a tower is placed.
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'destroy')' in or related to this line: 'obj.menuParent.destroy();' Line Number: 1074
User prompt
Please replace the current tower selection system with the following interaction model: 1. No Fixed UI Panel: - Remove the fixed UI panel used to select towers from outside the map. 2. Interactive Build Zones: - When the player clicks on a valid tower build zone on the map, open a small contextual menu **above that specific zone**. - This menu should display all currently unlocked tower types that the player can build **at that moment**, along with their **gold costs**. - For example: • Archer Tower – 100 gold • Cannon Tower – 150 gold • Magic Tower – 200 gold 3. Tower Placement: - When the player selects a tower from that local menu and has enough gold, the tower should be **instantly placed in that location**, and the gold deducted. - If the player does not have enough gold, the selection should be greyed out or show a "not enough gold" warning. 4. Clean UI Behavior: - Once a tower is placed, the contextual menu should disappear. - This system should work consistently for all build zones, improving clarity and reducing unnecessary clicks. This system makes tower placement more intuitive and minimizes screen clutter while providing precise control.
User prompt
Please apply the following interface and map layout improvements: 1. Tower Selection UI: - The UI panel where players select which tower to build (e.g., archer, cannon, magic) **should not cover or be part of the game map**. - Place this UI in a separate, fixed section of the screen (e.g., top or side panel) that does not interfere with the battlefield view. - This will ensure full visibility of the map during tower selection. 2. Tower Build Zone Placement: - All tower placement zones should be located **immediately adjacent to enemy paths**. - Avoid placing zones too far from the road — towers must be able to reach passing enemies with their default attack range. - Ensure that the shortest path between enemy movement and tower attack range is visually and functionally optimized. - Prefer to position towers along curves or turns for maximum coverage if possible. These changes will improve clarity, usability, and tactical tower placement efficiency.
User prompt
Please apply the following layout and visibility changes to the game map: 1. Enemy Path Visibility: - All three enemy paths should be **fully visible from the beginning of the game**, even before any enemies spawn. - Clearly draw and display the entire path routes so the player can plan their tower placements ahead of time. - Paths should follow winding, curved routes that travel across different parts of the map — not just straight lines. 2. Castle Placement: - Move the castle to the **bottom center** of the screen. - All enemy paths should converge and end at this bottom-central location. - Ensure there is enough space between the castle and the merging paths to allow for last-minute defense opportunities. 3. Path Design: - Paths should feel natural and strategic, weaving through the terrain before reaching the castle. - Keep each path visually distinct and allow tower zones to be positioned along the curves for better engagement. These changes will enhance strategic gameplay, give players more preparation time, and improve the visual structure of the battlefield.
User prompt
Please redesign the enemy paths on the map with the following conditions: 1. Path Shapes: - Make each of the 3 enemy paths **longer and more curved**, avoiding straight lines. - Add multiple turns and segments so the enemies travel a longer distance before reaching the castle. - This gives players more opportunities to place towers and strategize. 2. Path Intersections: - Paths 1 and 2 should **intersect around the middle of the map**, forming a shared section before splitting or continuing. - Path 3 should take a **longer, winding route from the far corner of the map**, and only **merge with the others very close to the castle**. - This staggered path structure helps create more tension and challenge in late waves. 3. Design Goals: - Ensure all paths have unique shapes and routes, but end at the same castle destination. - Give enough time and distance for towers to engage enemies along each route. - Maintain visual clarity, avoiding overcrowded overlapping routes. These changes will improve pacing, allow more strategic tower placement, and create a more dynamic and interesting battlefield.
User prompt
Please adjust the positioning of tower build zones as follows: - Move the tower build areas **closer to the enemy paths**. - Currently, enemies often pass outside the towers’ attack range, especially in early waves. - Ensure that all build zones are positioned close enough so that basic tower range can effectively reach and attack enemies as they pass by. - Avoid placing build zones too far from the path, especially in early areas of the map. - Ideally, at least 70–80% of enemies should enter at least one tower's range during their path. This change is essential for fair gameplay balance and to allow towers to function effectively without requiring excessive upgrades early on.
User prompt
Please make the following gameplay and map layout changes: 1. Tower Upgrade Mechanics: - When a player upgrades a tower, in addition to increased attack power, also increase the tower's attack **range by 10%** per upgrade level. - This range increase should stack with each upgrade level (e.g., at level 3, range is 30% higher than base). - Visually reflect the upgraded range if possible (e.g., larger targeting radius or effect area). 2. Enemy Path Adjustment: - The 3rd enemy path is currently too short, making gameplay unbalanced and too difficult. - Please redesign the 3rd path to start from a **far corner of the map**, giving players more time to react. - This 3rd path should **merge with Path 1** at a midpoint or junction area before reaching the castle. - Ensure the path looks natural, and maintain balance between all three enemy entry routes. These changes will help improve gameplay pacing and tower strategy.
User prompt
Please add a full set of 10 distinct enemy types with unique names and scaled strength levels. Also, reduce their overall power by about 30% compared to previous settings for better game balance. Here is the list of enemy types, from weakest to strongest: 1. Goblin Scout • Very fast, low health, low damage • Appears in early waves (1–5) 2. Bone Crawler • Slightly slower, tougher than goblins • Low-medium damage • Appears in waves 3–8 3. Shadow Bandit • Medium speed, stealthy appearance • Deals higher damage than expected • Appears in waves 5–10 4. Rock Golem • High health, very slow • Can take a lot of hits • Appears in waves 7–12 5. Flame Imp • Fast movement, medium health • Deals fire damage over time (DOT) • Appears in waves 9–14 6. Iron Knight • Balanced stats, wears armor • Resistant to basic tower types • Appears in waves 11–18 7. Swamp Beast • High health, regenerates slowly • Moderate damage, poisonous aura • Appears in waves 13–20 8. Void Mage • Medium health, casts debuffs on towers • Temporarily disables nearby towers • Appears in waves 15–25 9. Sky Reaver *(flying unit)* • High speed, can only be targeted by anti-air towers • Medium health, ignores ground defenses • Appears starting from wave 17 onward 10. Doom Bringer • Boss-type enemy • Very high health and damage • Immune to slow and poison effects • Appears in final waves (e.g., 45–50) Each wave should include a mix of enemy types depending on the wave number, gradually introducing stronger ones as waves progress. This structure ensures strategic variety, proper difficulty scaling, and gives the player enough time to react and build defenses accordingly.
User prompt
Please design the game map and enemy wave system with the following specifications: 1. Map Layout: - The battlefield should include exactly 3 distinct enemy paths (routes) from which enemies will approach the castle. - Each enemy path must have clearly marked tower build zones placed strategically along the route. - Players can place towers only on these designated build zones. 2. Enemy Waves: - There are a total of 50 waves (rounds) of enemies. - Enemies come in 10 different strength levels, numbered 1 (weakest) to 10 (strongest). - Wave 1 includes only the weakest enemies (strength level 1). - Every 2 waves, introduce a stronger enemy tier: • Wave 3 includes enemies of strength level 2, • Wave 5 includes enemies of strength level 3, • ... and so on, increasing enemy strength proportionally with the wave number. - Later waves contain mixed groups of enemies, gradually increasing the challenge. - Enemy attributes such as health, speed, and abilities should scale with their strength level. 3. Gameplay Balance: - Ensure that the distribution of tower placement zones and enemy paths encourages strategic tower placement. - The increasing enemy strength should require players to upgrade towers and diversify strategies over time. This system aims to provide a progressively challenging experience over many waves, with clear strategic choices for tower placement.
User prompt
Please revert the game’s camera perspective back to a classic 2D top-down view. - Remove the isometric or angled diagonal view. - Use a flat, straight overhead camera angle looking directly down on the battlefield. - Ensure that tower placement zones and enemy paths align correctly with this top-down perspective. - This change should fix any positioning or placement issues caused by the previous 3D-like camera angle.
User prompt
Please implement the following tower placement rules: 1. Towers must be placed strictly inside designated build zones only. 2. When the player clicks inside a valid build zone, the tower should be placed exactly within that zone. 3. Prevent towers from being placed outside these build zones — clicks outside build zones should not create towers. 4. Each build zone can contain only one tower. 5. Once a tower is placed in a build zone, that zone becomes unavailable for additional towers. 6. Provide visual feedback to clearly mark build zones that are already occupied and no longer available for tower placement. 7. Ensure the tower is positioned neatly and fully within the boundaries of the build zone. These rules ensure organized tower placement and prevent multiple towers stacking in the same zone.
User prompt
Please update the tower placement system as follows: - Towers can only be placed on designated build zones. - When the player clicks somewhere outside these allowed build areas, no tower should be placed. - The tower placement should be strictly restricted to marked build zones, preventing placement anywhere else. - Ensure that clicking on a valid build zone places the tower exactly at that location. - If the clicked location is invalid, provide appropriate feedback (e.g., no action or an error sound).
User prompt
Please implement the following detailed gameplay and tower mechanics: 1. Tower Placement: - When the player clicks on a valid build spot, the tower must be created exactly at the clicked location. - After placing a tower, the build zone indicator at that location should immediately revert to normal map visuals (no tower placement highlight). - The player cannot place another tower on the same spot after a tower is built there. 2. Upgrade System: - Each tower type has a total of 10 upgrade levels. - Upgrading requires coins, with increasing costs per level: 50, 100, 150, 200, 250, 300, 350, 400, 450, 500 gold respectively. - Upgrades improve tower stats (damage, range, special effects) and visually change the tower model. 3. Tower Types: Type 1: Infantry Tower (Soldier) - Basic tower that starts as a soldier shooting rifle bullets. - Upgrade path (10 levels): 1. Rifleman 2. Marksman 3. Sharpshooter 4. Machine Gunner 5. Grenadier 6. Mortar Operator 7. Tank Commander 8. Bazooka Specialist 9. Rocket Launcher 10. Missile Battery Type 2: Slow & Area Damage Tower - Tower that slows enemies and deals area damage. - Upgrade path (10 levels) with progressive fantasy-themed names: 1. Frost Spire 2. Ice Shard Tower 3. Blizzard Bastion 4. Cryo Cannon 5. Glacier Fortress 6. Snowstorm Citadel 7. Avalanche Keep 8. Frozen Maelstrom 9. Arctic Warden 10. Absolute Zero Type 3: Anti-Air Defense Tower - Specifically targets flying enemies, ground units cannot attack air. - Upgrade path (5 levels): 1. Flak Cannon 2. Surface-to-Air Missile (SAM) Launcher 3. Radar-Guided Missile Battery 4. Laser Air Defense 5. Plasma Barrier Type 4: [Your Choice Tower - Suggestion: Poison & Debuff Tower] - Applies poison damage over time and weakens enemy defenses. - Upgrade path (5 levels): 1. Venom Sprayer 2. Toxic Spitter 3. Acid Dart Tower 4. Corrosive Spire 5. Plague Altar Type 5: [Your Choice Tower - Suggestion: Tesla/Chain Lightning Tower] - Deals chain lightning damage hitting multiple enemies. - Upgrade path (5 levels): 1. Static Coil 2. Dual Coil 3. Arc Emitter 4. Thunderstorm Core 5. Lightning God 4. Additional Notes: - Ensure that upgrade costs and effects scale logically. - When clicking on a tower, show its upgrade status and cost clearly. - Upgrade can be performed only if the player has enough gold. - Prevent tower placement on already occupied build zones. This detailed system aims to provide strategic variety and a satisfying progression experience.
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of null (reading 'destroy')' in or related to this line: 'upgradeText.destroy();' Line Number: 203
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Enemy = Container.expand(function (type, wave, pathIndex, strengthLevel) { var self = Container.call(this); self.type = type; self.wave = wave; self.pathIndex = pathIndex || 1; self.strengthLevel = strengthLevel || 1; self.currentPath = self.pathIndex === 1 ? enemyPath1 : self.pathIndex === 2 ? enemyPath2 : enemyPath3; // Define base stats for each enemy type (reduced by 30% for balance) var baseStats = { goblin: { speed: 2.1, health: 28, coins: 7, flying: false }, crawler: { speed: 1.4, health: 42, coins: 10, flying: false }, bandit: { speed: 1.75, health: 35, coins: 12, flying: false }, golem: { speed: 0.7, health: 105, coins: 18, flying: false }, imp: { speed: 1.9, health: 49, coins: 15, flying: false }, knight: { speed: 1.05, health: 70, coins: 20, flying: false }, beast: { speed: 0.9, health: 84, coins: 22, flying: false }, mage: { speed: 1.2, health: 56, coins: 25, flying: false }, reaver: { speed: 2.3, health: 63, coins: 28, flying: true }, doom: { speed: 0.8, health: 140, coins: 35, flying: false } }; var stats = baseStats[type] || baseStats.goblin; // Scale stats by strength level var strengthMultiplier = 1 + (self.strengthLevel - 1) * 0.4; var speedMultiplier = 1 + (self.strengthLevel - 1) * 0.08; self.speed = stats.speed * speedMultiplier; self.maxHealth = Math.floor(stats.health * strengthMultiplier); self.health = self.maxHealth; self.pathStep = 0; self.coinValue = Math.floor(stats.coins * strengthMultiplier); self.flying = stats.flying; self.regeneration = type === 'beast' ? 0.5 : 0; self.poisonResistant = type === 'doom'; self.slowResistant = type === 'doom'; var graphics = self.attachAsset('enemy_' + type, { anchorX: 0.5, anchorY: 0.5 }); self.x = self.currentPath[0].x; self.y = self.currentPath[0].y; self.takeDamage = function (damage) { self.health -= damage; LK.effects.flashObject(self, 0xFF0000, 200); if (self.health <= 0) { LK.getSound('enemy_hit').play(); return true; } return false; }; self.update = function () { if (self.pathStep < self.currentPath.length - 1) { var target = self.currentPath[self.pathStep + 1]; var dx = target.x - self.x; var dy = target.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 5) { self.pathStep++; if (self.pathStep >= self.currentPath.length - 1) { self.reachedCastle = true; } } else { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } } }; return self; }); var Projectile = Container.expand(function (type, startX, startY, targetX, targetY, damage) { var self = Container.call(this); self.type = type; self.damage = damage; self.targetX = targetX; self.targetY = targetY; self.speed = type === 'arrow' ? 8 : type === 'cannonball' ? 5 : 6; var graphics = self.attachAsset('projectile_' + type, { anchorX: 0.5, anchorY: 0.5 }); self.x = startX; self.y = startY; var dx = targetX - startX; var dy = targetY - startY; var distance = Math.sqrt(dx * dx + dy * dy); self.velocityX = dx / distance * self.speed; self.velocityY = dy / distance * self.speed; self.update = function () { self.x += self.velocityX; self.y += self.velocityY; var distToTarget = Math.sqrt((self.x - self.targetX) * (self.x - self.targetX) + (self.y - self.targetY) * (self.y - self.targetY)); if (distToTarget < 10) { self.hasReachedTarget = true; } }; return self; }); var Tower = Container.expand(function (type) { var self = Container.call(this); self.type = type; self.level = 1; self.lastShotTime = 0; self.maxLevel = type === 'antiair' || type === 'poison' || type === 'tesla' ? 5 : 10; // Initialize tower stats based on type if (type === 'infantry') { self.damage = 20; self.range = 100; self.attackSpeed = 600; self.cost = 80; self.projectileType = 'arrow'; } else if (type === 'frost') { self.damage = 15; self.range = 90; self.attackSpeed = 800; self.cost = 120; self.projectileType = 'magic'; self.slowEffect = true; } else if (type === 'antiair') { self.damage = 40; self.range = 130; self.attackSpeed = 1000; self.cost = 150; self.projectileType = 'magic'; self.antiAir = true; } else if (type === 'poison') { self.damage = 10; self.range = 80; self.attackSpeed = 1200; self.cost = 100; self.projectileType = 'magic'; self.poisonEffect = true; } else if (type === 'tesla') { self.damage = 35; self.range = 95; self.attackSpeed = 900; self.cost = 180; self.projectileType = 'magic'; self.chainLightning = true; } var graphics = self.attachAsset('tower_' + type, { anchorX: 0.5, anchorY: 0.5 }); self.getUpgradeNames = function () { if (self.type === 'infantry') { return ['Rifleman', 'Marksman', 'Sharpshooter', 'Machine Gunner', 'Grenadier', 'Mortar Operator', 'Tank Commander', 'Bazooka Specialist', 'Rocket Launcher', 'Missile Battery']; } else if (self.type === 'frost') { return ['Frost Spire', 'Ice Shard Tower', 'Blizzard Bastion', 'Cryo Cannon', 'Glacier Fortress', 'Snowstorm Citadel', 'Avalanche Keep', 'Frozen Maelstrom', 'Arctic Warden', 'Absolute Zero']; } else if (self.type === 'antiair') { return ['Flak Cannon', 'SAM Launcher', 'Radar Missile Battery', 'Laser Air Defense', 'Plasma Barrier']; } else if (self.type === 'poison') { return ['Venom Sprayer', 'Toxic Spitter', 'Acid Dart Tower', 'Corrosive Spire', 'Plague Altar']; } else if (self.type === 'tesla') { return ['Static Coil', 'Dual Coil', 'Arc Emitter', 'Thunderstorm Core', 'Lightning God']; } }; self.canShoot = function () { return LK.ticks - self.lastShotTime > self.attackSpeed / (1000 / 60); }; self.findTarget = function () { var closestEnemy = null; var closestDistance = Infinity; for (var i = 0; i < enemies.length; i++) { var enemy = enemies[i]; var distance = Math.sqrt((enemy.x - self.x) * (enemy.x - self.x) + (enemy.y - self.y) * (enemy.y - self.y)); if (distance <= self.range && distance < closestDistance) { closestDistance = distance; closestEnemy = enemy; } } return closestEnemy; }; self.shoot = function (target) { if (!self.canShoot()) return; self.lastShotTime = LK.ticks; var projectile = new Projectile(self.projectileType, self.x, self.y, target.x, target.y, self.damage); projectile.towerType = self.type; projectile.slowEffect = self.slowEffect; projectile.poisonEffect = self.poisonEffect; projectile.chainLightning = self.chainLightning; projectiles.push(projectile); isoContainer.addChild(projectile); LK.getSound('shoot_arrow').play(); }; self.getUpgradeCost = function () { var baseCosts = [50, 100, 150, 200, 250, 300, 350, 400, 450, 500]; return baseCosts[self.level - 1] || 500; }; self.upgrade = function () { if (self.level < self.maxLevel) { self.level++; self.damage = Math.floor(self.damage * 1.3); self.range = Math.floor(self.range * (1 + (self.level - 1) * 0.1)); // 10% range increase per level self.attackSpeed = Math.max(200, Math.floor(self.attackSpeed * 0.95)); // Visual upgrade indicators var tintColors = [0xFFFFFF, 0xFFD700, 0xFF6347, 0xFF4500, 0x8A2BE2, 0x00FF00, 0x00FFFF, 0xFF69B4, 0xFFFF00, 0xFF0000]; graphics.tint = tintColors[self.level - 1] || 0xFF0000; // Show range indicator for upgraded towers if (self.level > 1 && !self.rangeIndicator) { self.rangeIndicator = LK.getAsset('build_zone', { anchorX: 0.5, anchorY: 0.5, alpha: 0.1, scaleX: self.range / 40, scaleY: self.range / 40 }); self.rangeIndicator.x = self.x; self.rangeIndicator.y = self.y; self.rangeIndicator.tint = 0x00FF00; isoContainer.addChild(self.rangeIndicator); } else if (self.rangeIndicator) { self.rangeIndicator.scaleX = self.range / 40; self.rangeIndicator.scaleY = self.range / 40; } } }; self.down = function (x, y, obj) { selectedTower = self; if (upgradeText && upgradeText.destroy) { upgradeText.destroy(); } if (self.level < self.maxLevel) { var cost = self.getUpgradeCost(); var names = self.getUpgradeNames(); var nextName = names[self.level - 1] || 'Max Level'; upgradeText = new Text2(nextName + ': ' + cost + ' gold', { size: 24, fill: coins >= cost ? 0x00FF00 : 0xFF0000 }); upgradeText.anchor.set(0.5, 1); upgradeText.x = self.x; upgradeText.y = self.y - 40; isoContainer.addChild(upgradeText); if (coins >= cost) { upgradeText.down = function () { coins -= cost; coinsText.setText('Gold: ' + coins); self.upgrade(); if (upgradeText && upgradeText.destroy) { upgradeText.destroy(); } upgradeText = null; selectedTower = null; }; } } else { upgradeText = new Text2('MAX LEVEL', { size: 30, fill: 0xFFFFFF }); upgradeText.anchor.set(0.5, 1); upgradeText.x = self.x; upgradeText.y = self.y - 40; isoContainer.addChild(upgradeText); } }; self.update = function () { var target = self.findTarget(); if (target) { self.shoot(target); } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x228B22 }); /**** * Game Code ****/ // Use game container directly for top-down view var isoContainer = game; var gameState = 'setup'; var castleType = 'square'; var difficulty = 'easy'; var currentWave = 0; var maxWaves = 50; var waveEnemies = []; var enemies = []; var towers = []; var projectiles = []; var coins = 300; var castleHealth = 100; var waveInProgress = false; var nextWaveTimer = 0; var selectedTowerType = null; var selectedTower = null; var upgradeText = null; // Enemy path 1: Northern route - direct path from left to castle var enemyPath1 = [{ x: 0, y: 400 }, { x: 200, y: 400 }, { x: 400, y: 450 }, { x: 600, y: 500 }, { x: 800, y: 550 }, { x: 1000, y: 600 }, { x: 1200, y: 650 }, { x: 1400, y: 700 }, { x: 1600, y: 750 }, { x: 1800, y: 800 }, { x: 1900, y: 850 }, { x: 1950, y: 900 }, { x: 1950, y: 1000 }]; // Enemy path 2: Southern route - curved path from bottom var enemyPath2 = [{ x: 0, y: 1800 }, { x: 300, y: 1750 }, { x: 600, y: 1700 }, { x: 900, y: 1650 }, { x: 1200, y: 1600 }, { x: 1400, y: 1500 }, { x: 1600, y: 1400 }, { x: 1750, y: 1250 }, { x: 1850, y: 1100 }, { x: 1950, y: 1000 }]; // Enemy path 3: Northwestern route - starts from far corner and merges with path 1 var enemyPath3 = [{ x: 0, y: 0 }, { x: 150, y: 50 }, { x: 300, y: 100 }, { x: 450, y: 150 }, { x: 600, y: 200 }, { x: 750, y: 250 }, { x: 900, y: 300 }, { x: 1000, y: 350 }, { x: 1100, y: 400 }, { x: 1200, y: 450 }, { x: 1300, y: 500 }, { x: 1400, y: 550 }, { x: 1500, y: 600 }, { x: 1600, y: 650 }, { x: 1700, y: 700 }, { x: 1800, y: 750 }, { x: 1900, y: 800 }, { x: 1950, y: 850 }, { x: 1950, y: 900 }, { x: 1950, y: 1000 }]; var buildZones = []; var terrainFeatures = []; function createPath() { // Create path 1 for (var i = 0; i < enemyPath1.length; i++) { var pathTile = isoContainer.addChild(LK.getAsset('path_tile', { anchorX: 0.5, anchorY: 0.5, x: enemyPath1[i].x, y: enemyPath1[i].y, alpha: 0.7 })); } // Create path 2 (for waves 3+) if (currentWave >= 3) { for (var i = 0; i < enemyPath2.length; i++) { var pathTile = isoContainer.addChild(LK.getAsset('path_tile', { anchorX: 0.5, anchorY: 0.5, x: enemyPath2[i].x, y: enemyPath2[i].y, alpha: 0.7 })); } } // Create path 3 (for waves 6+) if (currentWave >= 6) { for (var i = 0; i < enemyPath3.length; i++) { var pathTile = isoContainer.addChild(LK.getAsset('path_tile', { anchorX: 0.5, anchorY: 0.5, x: enemyPath3[i].x, y: enemyPath3[i].y, alpha: 0.7 })); } } // Create build zones around paths createBuildZones(); // Create terrain features createTerrain(); } function createBuildZones() { var zones = [ // Build zones closer to path 1 (northern route) { x: 120, y: 380 }, { x: 120, y: 420 }, { x: 280, y: 430 }, { x: 280, y: 470 }, { x: 480, y: 470 }, { x: 480, y: 510 }, { x: 680, y: 520 }, { x: 680, y: 560 }, { x: 880, y: 570 }, { x: 880, y: 610 }, { x: 1080, y: 620 }, { x: 1080, y: 660 }, { x: 1280, y: 670 }, { x: 1280, y: 710 }, { x: 1480, y: 720 }, { x: 1480, y: 760 }, { x: 1680, y: 770 }, { x: 1680, y: 810 }, // Build zones closer to path 2 (southern route) { x: 180, y: 1730 }, { x: 180, y: 1770 }, { x: 380, y: 1710 }, { x: 380, y: 1750 }, { x: 580, y: 1680 }, { x: 580, y: 1720 }, { x: 780, y: 1630 }, { x: 780, y: 1670 }, { x: 1080, y: 1580 }, { x: 1080, y: 1620 }, { x: 1280, y: 1480 }, { x: 1280, y: 1520 }, { x: 1480, y: 1380 }, { x: 1480, y: 1420 }, { x: 1630, y: 1320 }, { x: 1630, y: 1360 }, { x: 1730, y: 1180 }, { x: 1730, y: 1220 }, // Build zones closer to path 3 (northwestern route) { x: 80, y: 80 }, { x: 200, y: 120 }, { x: 350, y: 160 }, { x: 500, y: 180 }, { x: 650, y: 220 }, { x: 800, y: 260 }, { x: 950, y: 320 }, { x: 1050, y: 370 }, { x: 1150, y: 420 }, { x: 1250, y: 470 }, { x: 1350, y: 520 }, { x: 1450, y: 570 }, { x: 1550, y: 620 }, { x: 1650, y: 670 }, { x: 1750, y: 720 }, // Central strategic positions near castle { x: 1850, y: 950 }, { x: 1800, y: 1050 }, { x: 1700, y: 1100 }, { x: 1600, y: 1050 }]; for (var i = 0; i < zones.length; i++) { var zone = isoContainer.addChild(LK.getAsset('build_zone', { anchorX: 0.5, anchorY: 0.5, x: zones[i].x, y: zones[i].y, alpha: 0.3 })); zone.zoneData = { x: zones[i].x, y: zones[i].y, occupied: false, originalAlpha: 0.3 }; buildZones.push(zone); } } function updateBuildZoneVisuals() { for (var i = 0; i < buildZones.length; i++) { var zone = buildZones[i]; if (zone.zoneData.occupied) { // Occupied zones are invisible zone.alpha = 0; } else if (selectedTowerType) { // Available zones are highlighted when a tower is selected zone.alpha = 0.6; zone.tint = 0x00FF00; // Green highlight for available zones } else { // Normal state when no tower is selected zone.alpha = zone.zoneData.originalAlpha; zone.tint = 0xFFFFFF; // Reset tint } } } function createTerrain() { // Add rocks var rocks = [{ x: 150, y: 300 }, { x: 350, y: 450 }, { x: 550, y: 550 }, { x: 750, y: 650 }, { x: 950, y: 750 }, { x: 1150, y: 850 }, { x: 1350, y: 950 }, { x: 1550, y: 1050 }, { x: 250, y: 1600 }, { x: 450, y: 1500 }, { x: 650, y: 1400 }]; for (var i = 0; i < rocks.length; i++) { var rock = isoContainer.addChild(LK.getAsset('terrain_rock', { anchorX: 0.5, anchorY: 0.5, x: rocks[i].x, y: rocks[i].y, alpha: 0.8 })); terrainFeatures.push(rock); } // Add trees var trees = [{ x: 180, y: 350 }, { x: 380, y: 480 }, { x: 580, y: 580 }, { x: 780, y: 680 }, { x: 980, y: 780 }, { x: 1180, y: 880 }, { x: 280, y: 1550 }, { x: 480, y: 1450 }]; for (var i = 0; i < trees.length; i++) { var tree = isoContainer.addChild(LK.getAsset('terrain_tree', { anchorX: 0.5, anchorY: 0.5, x: trees[i].x, y: trees[i].y, alpha: 0.9 })); terrainFeatures.push(tree); } // Add ruins var ruins = [{ x: 220, y: 380 }, { x: 420, y: 510 }, { x: 620, y: 610 }, { x: 820, y: 710 }, { x: 320, y: 1580 }]; for (var i = 0; i < ruins.length; i++) { var ruin = isoContainer.addChild(LK.getAsset('terrain_ruins', { anchorX: 0.5, anchorY: 0.5, x: ruins[i].x, y: ruins[i].y, alpha: 0.7 })); terrainFeatures.push(ruin); } } function createCastle() { var castle = isoContainer.addChild(LK.getAsset('castle_' + castleType, { anchorX: 0.5, anchorY: 0.5, x: enemyPath1[enemyPath1.length - 1].x, y: enemyPath1[enemyPath1.length - 1].y })); } function createShop() { var shopBg = LK.gui.bottom.addChild(LK.getAsset('shop_bg', { anchorX: 0.5, anchorY: 1, alpha: 0.8 })); var infantryBtn = LK.gui.bottom.addChild(LK.getAsset('tower_infantry', { anchorX: 0.5, anchorY: 1, x: -400, y: -100 })); var frostBtn = LK.gui.bottom.addChild(LK.getAsset('tower_frost', { anchorX: 0.5, anchorY: 1, x: -200, y: -100 })); var antiairBtn = LK.gui.bottom.addChild(LK.getAsset('tower_antiair', { anchorX: 0.5, anchorY: 1, x: 0, y: -100 })); var poisonBtn = LK.gui.bottom.addChild(LK.getAsset('tower_poison', { anchorX: 0.5, anchorY: 1, x: 200, y: -100 })); var teslaBtn = LK.gui.bottom.addChild(LK.getAsset('tower_tesla', { anchorX: 0.5, anchorY: 1, x: 400, y: -100 })); // Add cost labels var infantryCost = LK.gui.bottom.addChild(new Text2('80g', { size: 20, fill: 0xFFFFFF })); infantryCost.anchor.set(0.5, 1); infantryCost.x = -400; infantryCost.y = -130; var frostCost = LK.gui.bottom.addChild(new Text2('120g', { size: 20, fill: 0xFFFFFF })); frostCost.anchor.set(0.5, 1); frostCost.x = -200; frostCost.y = -130; var antiairCost = LK.gui.bottom.addChild(new Text2('150g', { size: 20, fill: 0xFFFFFF })); antiairCost.anchor.set(0.5, 1); antiairCost.x = 0; antiairCost.y = -130; var poisonCost = LK.gui.bottom.addChild(new Text2('100g', { size: 20, fill: 0xFFFFFF })); poisonCost.anchor.set(0.5, 1); poisonCost.x = 200; poisonCost.y = -130; var teslaCost = LK.gui.bottom.addChild(new Text2('180g', { size: 20, fill: 0xFFFFFF })); teslaCost.anchor.set(0.5, 1); teslaCost.x = 400; teslaCost.y = -130; infantryBtn.down = function () { if (coins >= 80) { selectedTowerType = 'infantry'; updateBuildZoneVisuals(); } }; frostBtn.down = function () { if (coins >= 120) { selectedTowerType = 'frost'; updateBuildZoneVisuals(); } }; antiairBtn.down = function () { if (coins >= 150) { selectedTowerType = 'antiair'; updateBuildZoneVisuals(); } }; poisonBtn.down = function () { if (coins >= 100) { selectedTowerType = 'poison'; updateBuildZoneVisuals(); } }; teslaBtn.down = function () { if (coins >= 180) { selectedTowerType = 'tesla'; updateBuildZoneVisuals(); } }; } function createWave() { if (currentWave >= maxWaves) { LK.showYouWin(); return; } currentWave++; waveEnemies = []; var enemyCount = 3 + Math.floor(currentWave / 2); if (enemyCount > 20) enemyCount = 20; // Calculate available enemy strength levels based on wave var maxStrengthLevel = Math.min(10, Math.floor((currentWave + 1) / 2)); var minStrengthLevel = Math.max(1, maxStrengthLevel - 2); for (var i = 0; i < enemyCount; i++) { // Define which enemies can appear based on wave number var availableEnemies = []; if (currentWave >= 1 && currentWave <= 5) availableEnemies.push('goblin'); if (currentWave >= 3 && currentWave <= 8) availableEnemies.push('crawler'); if (currentWave >= 5 && currentWave <= 10) availableEnemies.push('bandit'); if (currentWave >= 7 && currentWave <= 12) availableEnemies.push('golem'); if (currentWave >= 9 && currentWave <= 14) availableEnemies.push('imp'); if (currentWave >= 11 && currentWave <= 18) availableEnemies.push('knight'); if (currentWave >= 13 && currentWave <= 20) availableEnemies.push('beast'); if (currentWave >= 15 && currentWave <= 25) availableEnemies.push('mage'); if (currentWave >= 17) availableEnemies.push('reaver'); if (currentWave >= 45) availableEnemies.push('doom'); // Select random enemy from available types var enemyType = availableEnemies[Math.floor(Math.random() * availableEnemies.length)]; // Assign strength level within available range var strengthLevel = minStrengthLevel + Math.floor(Math.random() * (maxStrengthLevel - minStrengthLevel + 1)); var pathChoice = 1; if (currentWave >= 6) { pathChoice = Math.floor(Math.random() * 3) + 1; } else if (currentWave >= 3) { pathChoice = Math.floor(Math.random() * 2) + 1; } waveEnemies.push({ type: enemyType, pathIndex: pathChoice, strengthLevel: strengthLevel, spawnTime: LK.ticks + i * 90 }); } waveInProgress = true; LK.getSound('wave_start').play(); createPath(); // Recreate paths with new ones visible } var coinsText = new Text2('Gold: 300', { size: 60, fill: 0xFFD700 }); coinsText.anchor.set(0.5, 0); LK.gui.top.addChild(coinsText); coinsText.y = 60; var waveText = new Text2('Wave: 0/50', { size: 40, fill: 0xFFFFFF }); waveText.anchor.set(0.5, 0); LK.gui.top.addChild(waveText); var healthText = new Text2('Health: 100', { size: 40, fill: 0xFF0000 }); healthText.anchor.set(0, 0); LK.gui.left.addChild(healthText); createPath(); createCastle(); createShop(); game.down = function (x, y, obj) { // Clear any existing upgrade text when clicking elsewhere if (upgradeText && upgradeText.destroy && selectedTower && obj && !selectedTower.intersects(obj)) { upgradeText.destroy(); upgradeText = null; selectedTower = null; } // Use screen coordinates directly for top-down view var isoPos = { x: x, y: y }; if (selectedTowerType && gameState === 'playing') { // Check if clicking on a valid, unoccupied build zone var validBuildZone = null; for (var i = 0; i < buildZones.length; i++) { if (!buildZones[i].zoneData.occupied) { var distance = Math.sqrt((buildZones[i].x - isoPos.x) * (buildZones[i].x - isoPos.x) + (buildZones[i].y - isoPos.y) * (buildZones[i].y - isoPos.y)); if (distance < 40) { validBuildZone = buildZones[i]; break; } } } // Only place tower if clicking on a valid build zone and player has enough coins if (validBuildZone) { var tower = new Tower(selectedTowerType); if (coins >= tower.cost) { // Place tower exactly at build zone center tower.x = validBuildZone.x; tower.y = validBuildZone.y; towers.push(tower); isoContainer.addChild(tower); coins -= tower.cost; coinsText.setText('Gold: ' + coins); selectedTowerType = null; // Mark build zone as occupied validBuildZone.zoneData.occupied = true; updateBuildZoneVisuals(); } } else { // Clear selection if clicking outside build zones selectedTowerType = null; updateBuildZoneVisuals(); } } }; if (gameState === 'setup') { gameState = 'playing'; createWave(); } game.update = function () { if (gameState !== 'playing') return; if (waveInProgress) { for (var i = waveEnemies.length - 1; i >= 0; i--) { var enemyData = waveEnemies[i]; if (LK.ticks >= enemyData.spawnTime) { var enemy = new Enemy(enemyData.type, currentWave, enemyData.pathIndex, enemyData.strengthLevel); enemies.push(enemy); isoContainer.addChild(enemy); waveEnemies.splice(i, 1); } } if (waveEnemies.length === 0 && enemies.length === 0) { waveInProgress = false; nextWaveTimer = LK.ticks + 180; } } if (!waveInProgress && LK.ticks >= nextWaveTimer && enemies.length === 0) { createWave(); } for (var i = enemies.length - 1; i >= 0; i--) { var enemy = enemies[i]; if (enemy.reachedCastle) { castleHealth -= 15; healthText.setText('Health: ' + castleHealth); enemy.destroy(); enemies.splice(i, 1); if (castleHealth <= 0) { LK.showGameOver(); return; } } } for (var i = projectiles.length - 1; i >= 0; i--) { var projectile = projectiles[i]; if (projectile.hasReachedTarget) { if (projectile.type === 'cannonball') { for (var j = 0; j < enemies.length; j++) { var enemy = enemies[j]; var distance = Math.sqrt((enemy.x - projectile.x) * (enemy.x - projectile.x) + (enemy.y - projectile.y) * (enemy.y - projectile.y)); if (distance <= 50) { if (enemy.takeDamage(projectile.damage)) { coins += enemy.coinValue; coinsText.setText('Gold: ' + coins); enemy.destroy(); enemies.splice(j, 1); j--; } } } } else { for (var j = 0; j < enemies.length; j++) { var enemy = enemies[j]; var distance = Math.sqrt((enemy.x - projectile.x) * (enemy.x - projectile.x) + (enemy.y - projectile.y) * (enemy.y - projectile.y)); if (distance <= 25) { if (enemy.takeDamage(projectile.damage)) { coins += enemy.coinValue; coinsText.setText('Gold: ' + coins); enemy.destroy(); enemies.splice(j, 1); } break; } } } projectile.destroy(); projectiles.splice(i, 1); } else if (projectile.x < -50 || projectile.x > 2098 || projectile.y < -50 || projectile.y > 2782) { projectile.destroy(); projectiles.splice(i, 1); } } waveText.setText('Wave: ' + currentWave + '/' + maxWaves); };
===================================================================
--- original.js
+++ change.js
@@ -525,153 +525,180 @@
createTerrain();
}
function createBuildZones() {
var zones = [
- // Build zones along path 1 (northern route)
+ // Build zones closer to path 1 (northern route)
{
- x: 150,
- y: 300
+ x: 120,
+ y: 380
}, {
- x: 150,
- y: 500
+ x: 120,
+ y: 420
}, {
- x: 350,
- y: 350
+ x: 280,
+ y: 430
}, {
- x: 350,
- y: 550
+ x: 280,
+ y: 470
}, {
- x: 550,
- y: 400
+ x: 480,
+ y: 470
}, {
- x: 550,
- y: 600
+ x: 480,
+ y: 510
}, {
- x: 750,
- y: 450
+ x: 680,
+ y: 520
}, {
- x: 750,
- y: 650
+ x: 680,
+ y: 560
}, {
- x: 950,
- y: 500
+ x: 880,
+ y: 570
}, {
- x: 950,
- y: 700
+ x: 880,
+ y: 610
}, {
- x: 1150,
- y: 550
+ x: 1080,
+ y: 620
}, {
- x: 1150,
- y: 750
+ x: 1080,
+ y: 660
}, {
- x: 1350,
- y: 600
+ x: 1280,
+ y: 670
}, {
- x: 1350,
- y: 800
+ x: 1280,
+ y: 710
}, {
- x: 1550,
- y: 650
+ x: 1480,
+ y: 720
}, {
- x: 1550,
- y: 850
+ x: 1480,
+ y: 760
+ }, {
+ x: 1680,
+ y: 770
+ }, {
+ x: 1680,
+ y: 810
},
- // Build zones along path 2 (southern route)
+ // Build zones closer to path 2 (southern route)
{
- x: 250,
- y: 1650
+ x: 180,
+ y: 1730
}, {
- x: 250,
- y: 1850
+ x: 180,
+ y: 1770
}, {
- x: 450,
- y: 1600
+ x: 380,
+ y: 1710
}, {
- x: 450,
- y: 1800
+ x: 380,
+ y: 1750
}, {
- x: 750,
- y: 1550
+ x: 580,
+ y: 1680
}, {
- x: 750,
- y: 1750
+ x: 580,
+ y: 1720
}, {
- x: 1050,
- y: 1500
+ x: 780,
+ y: 1630
}, {
- x: 1050,
- y: 1700
+ x: 780,
+ y: 1670
}, {
- x: 1350,
- y: 1400
+ x: 1080,
+ y: 1580
}, {
- x: 1350,
- y: 1600
+ x: 1080,
+ y: 1620
}, {
- x: 1550,
- y: 1300
+ x: 1280,
+ y: 1480
}, {
- x: 1550,
- y: 1500
+ x: 1280,
+ y: 1520
}, {
- x: 1700,
- y: 1200
+ x: 1480,
+ y: 1380
}, {
- x: 1700,
- y: 1400
+ x: 1480,
+ y: 1420
+ }, {
+ x: 1630,
+ y: 1320
+ }, {
+ x: 1630,
+ y: 1360
+ }, {
+ x: 1730,
+ y: 1180
+ }, {
+ x: 1730,
+ y: 1220
},
- // Build zones along path 3 (northwestern route)
+ // Build zones closer to path 3 (northwestern route)
{
- x: 100,
- y: 150
+ x: 80,
+ y: 80
}, {
- x: 250,
- y: 200
+ x: 200,
+ y: 120
}, {
- x: 400,
- y: 250
+ x: 350,
+ y: 160
}, {
- x: 550,
- y: 300
+ x: 500,
+ y: 180
}, {
- x: 700,
- y: 350
+ x: 650,
+ y: 220
}, {
- x: 850,
- y: 400
+ x: 800,
+ y: 260
}, {
- x: 1000,
- y: 450
+ x: 950,
+ y: 320
}, {
+ x: 1050,
+ y: 370
+ }, {
x: 1150,
- y: 500
+ y: 420
}, {
- x: 1300,
- y: 550
+ x: 1250,
+ y: 470
}, {
+ x: 1350,
+ y: 520
+ }, {
x: 1450,
- y: 600
+ y: 570
}, {
- x: 1600,
- y: 650
+ x: 1550,
+ y: 620
}, {
+ x: 1650,
+ y: 670
+ }, {
x: 1750,
- y: 700
+ y: 720
},
- // Central strategic positions
+ // Central strategic positions near castle
{
- x: 1750,
- y: 1000
+ x: 1850,
+ y: 950
}, {
- x: 1750,
+ x: 1800,
+ y: 1050
+ }, {
+ x: 1700,
y: 1100
}, {
x: 1600,
- y: 1150
- }, {
- x: 1450,
- y: 1150
+ y: 1050
}];
for (var i = 0; i < zones.length; i++) {
var zone = isoContainer.addChild(LK.getAsset('build_zone', {
anchorX: 0.5,
A lake with a 3d view. In-Game asset. 2d. High contrast. No shadows
tree. In-Game asset. 2d. High contrast. No shadows
house. In-Game asset. 2d. High contrast. No shadows
magic ball. In-Game asset. 2d. High contrast. No shadows
arrow bullet. In-Game asset. 2d. High contrast. No shadows
realistic majestic castle. In-Game asset. 2d. High contrast. No shadows
dirt road. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
This is a button, the outer part is red, the middle circle is red, the 2nd circle is dark gray. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
village house. In-Game asset. 2d. High contrast. No shadows
poisonous tower realistic. In-Game asset. 2d. High contrast. No shadows
freezing tower realistic. In-Game asset. 2d. High contrast. No shadows
goblin. In-Game asset. 2d. High contrast. No shadows
goblin emperor. In-Game asset. 2d. High contrast. No shadows
haydut goblin. In-Game asset. 2d. High contrast. No shadows
titan goblin. In-Game asset. 2d. High contrast. No shadows
goblin tazısı. In-Game asset. 2d. High contrast. No shadows
gezgin goblin. In-Game asset. 2d. High contrast. No shadows
kıyamet canavarı goblin. In-Game asset. 2d. High contrast. No shadows
kemikli iskelet goblin. In-Game asset. 2d. High contrast. No shadows
buzul goblin. In-Game asset. 2d. High contrast. No shadows
golem goblin. In-Game asset. 2d. High contrast. No shadows
kadın goblin imparatoru. In-Game asset. 2d. High contrast. No shadows
demir goblin. In-Game asset. 2d. High contrast. No shadows
şövalye goblin. In-Game asset. 2d. High contrast. No shadows
obsidyen dev goblin. In-Game asset. 2d. High contrast. No shadows
üzerinde okçu olan, ahşap, okçu kulesi. In-Game asset. 2d. High contrast. No shadows
ahşap hava savunma kulesi, üstünde arbalet olsun. In-Game asset. 2d. High contrast. No shadows
antik elektrik atıcı kule. In-Game asset. 2d. High contrast. No shadows
goblin canavar. In-Game asset. 2d. High contrast. No shadows
volkanik gezgini goblin. In-Game asset. 2d. High contrast. No shadows
kahverengi gezgin eli bıçaklı goblin. In-Game asset. 2d. High contrast. No shadows
büyücü goblin. In-Game asset. 2d. High contrast. No shadows
paslı böcek goblin. In-Game asset. 2d. High contrast. No shadows
spektral yıkıcı goblin. In-Game asset. 2d. High contrast. No shadows
taş goblin. In-Game asset. 2d. High contrast. No shadows
kimyasalcı goblin, boydan. In-Game asset. 2d. High contrast. No shadows
yuvarlak havan topu mermisi. In-Game asset. 2d. High contrast. No shadows
karanlık büyücü goblin. In-Game asset. 2d. High contrast. No shadows
yeşil yapraklı dövüşçü goblin. In-Game asset. 2d. High contrast. No shadows
kayalık. In-Game asset. 2d. High contrast. No shadows
uçan küllü goblin. In-Game asset. 2d. High contrast. No shadows
uçan goblin yılan. In-Game asset. 2d. High contrast. No shadows
kırmızı kaslı uçan goblin. In-Game asset. 2d. High contrast. No shadows
uçan karanlık goblin. In-Game asset. 2d. High contrast. No shadows
uçan goblin yağmacı. In-Game asset. 2d. High contrast. No shadows
uçan fırtına golem. In-Game asset. 2d. High contrast. No shadows