User prompt
allow wizard upgrades on towers
User prompt
increase wizard range by 15% increase wizard shooting frequency by 10%
User prompt
on pop-up menu, instead of "elemental" text show which elemental damage that wizard deals also instead of 5 have 10 levels of wizards
User prompt
display elemental and magic damages seperately increase pop-up menu background size by doubling it but aligning it to the middle of the screen
User prompt
show each wizard's damage stats in selection menu
User prompt
show each wizards name, cost and level on pop-up menu
User prompt
in wizard selection pop-up menu, line all wizards from top to bottom
User prompt
allow player to select wizard level while hiring
User prompt
remove scoreboard background and make scoreboard text black and bold
User prompt
background of scoreboard is still small. arrange it properly.
User prompt
make scoreboard background to cover the text inside dynamically
User prompt
arrange scoreboard background according to text size
User prompt
make top left scoreboard in black background and move it to right top corner with bigger text size
User prompt
5th tower to east by 5 pixels and to north by 5 pixels
User prompt
5th tower to east by 50 pixels 7th tower to east by 5 pixels 8th tower to west by 5 pixels
User prompt
5th tower to south by 100 pixels and to west by 200 pixels 9th tower to south by 5 pixels 3th tower to north by 5 pixels 12th tower to west by 5 pixels 11th tower to east by 10 pixels
User prompt
3rd tower to north by 5 pixels 7th tower to east by 5 pixels move 5th tower to 200 pixels west of 10th tower 12th tower to east by 60 pixels and north by 60 pixels 11th tower to north by 10 pixels
User prompt
1st tower to north by 15 pixels 2nd tower to east by 80 pixels and to south by 40 pixels 3rd tower to north by 10 pixels 6th tower to west by 10 pixels 7th tower to east by 10 pixels
User prompt
remove 1st tower and renumber towers
User prompt
11th tower to east by 5 pixels 12th tower to north by 15 pixels 13th tower to east by 150 pixels and also to north by 150 pixels
User prompt
9th tower to south by 20 pixels 11th tower to east by 20 pixels 12th tower to south by 150 pixels add a 13th tower to the east of 12th tower
User prompt
1st tower to south by 30 pixels 2nd tower to south by 5 pixels and to west also by 10 pixels
User prompt
1st tower to south by 30 pixels 2nd tower to south by 20 pixels and west by 10 pixels 3rd tower to south by 10 pixels 5th tower to south by 15 pixels 6th tower to south by 100 pixels 8th tower to north by 15 pixels 10 tower to south by 5 pixels 9th tower to south by 20 pixels and to west by 10 pixels
User prompt
6th tower to south by 150 pixels 7th tower to north by 40 pixels 8th tower to north by 70 pixels 9th tower to south by 70 pixels 10th tower north by 30 pixels
User prompt
show tower number on each tower
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Enemy = Container.expand(function (enemyType, level) { var self = Container.call(this); self.enemyType = enemyType || 'basic'; self.level = level || 1; self.pathIndex = 0; self.pathProgress = 0; self.speed = 2; switch (self.enemyType) { case 'basic': self.maxHP = (100 + level * 50) * 5; self.speed = 2; break; case 'fast': self.maxHP = (50 + level * 25) * 5; self.speed = 4; break; case 'tank': self.maxHP = (300 + level * 100) * 5; self.speed = 1; break; } self.hp = self.maxHP; self.goldValue = self.maxHP; var enemyGraphics = self.attachAsset('enemy_' + self.enemyType, { anchorX: 0.5, anchorY: 0.5 }); var hpBar = new Container(); var hpBackground = LK.getAsset('ui_background', { width: 60, height: 8, anchorX: 0.5, anchorY: 0.5 }); hpBackground.tint = 0x000000; hpBar.addChild(hpBackground); var hpFill = LK.getAsset('ui_background', { width: 60, height: 8, anchorX: 0, anchorY: 0.5 }); hpFill.tint = 0x00ff00; hpFill.x = -30; hpBar.addChild(hpFill); hpBar.y = -40; self.addChild(hpBar); self.update = function () { if (currentPath && currentPath.length > 0) { self.followPath(); } // Update HP bar var hpPercent = self.hp / self.maxHP; hpFill.width = 60 * hpPercent; hpFill.tint = hpPercent > 0.5 ? 0x00ff00 : hpPercent > 0.25 ? 0xffff00 : 0xff0000; }; self.followPath = function () { if (self.pathIndex >= currentPath.length) { self.reachBase(); return; } var targetPoint = currentPath[self.pathIndex]; var dx = targetPoint.x - self.x; var dy = targetPoint.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 5) { self.pathIndex++; return; } self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; }; self.takeDamage = function (damage) { self.hp -= damage; LK.getSound('enemyHit').play(); if (self.hp <= 0) { self.die(); } }; self.die = function () { gold += self.goldValue / 10; updateGoldDisplay(); LK.getSound('enemyDeath').play(); for (var i = 0; i < enemies.length; i++) { if (enemies[i] === self) { enemies.splice(i, 1); break; } } self.destroy(); }; self.reachBase = function () { baseHP -= 10; updateBaseHPDisplay(); if (baseHP <= 0) { LK.showGameOver(); } for (var i = 0; i < enemies.length; i++) { if (enemies[i] === self) { enemies.splice(i, 1); break; } } self.destroy(); }; return self; }); var Projectile = Container.expand(function (startX, startY, target, damage) { var self = Container.call(this); self.x = startX; self.y = startY; self.target = target; self.damage = damage; self.speed = 8; var projectileGraphics = self.attachAsset('projectile', { anchorX: 0.5, anchorY: 0.5 }); self.update = function () { if (!self.target || self.target.destroyed) { self.destroy(); return; } var dx = self.target.x - self.x; var dy = self.target.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 10) { self.target.takeDamage(self.damage); self.destroy(); return; } self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; }; return self; }); var TowerSlot = Container.expand(function (x, y, towerNumber) { var self = Container.call(this); self.x = x; self.y = y; self.isEmpty = true; self.wizard = null; self.towerNumber = towerNumber; var slotGraphics = self.attachAsset('tower_slot', { anchorX: 0.5, anchorY: 0.5 }); var towerNumberText = new Text2(self.towerNumber.toString(), { size: 20, fill: 0xFFFFFF }); towerNumberText.anchor.set(0.5, 0.5); towerNumberText.y = 0; self.addChild(towerNumberText); self.down = function (x, y, obj) { if (self.isEmpty && (gameState === 'setup' || gameState === 'playing')) { selectedTowerSlot = self; gameState = 'wizard_selection'; createWizardSelectionPopup(); } }; self.placeWizard = function (wizardType) { var cost = 500; if (gold >= cost) { gold -= cost; updateGoldDisplay(); self.wizard = new Wizard(wizardType, 1); self.wizard.x = self.x; self.wizard.y = self.y; self.isEmpty = false; game.addChild(self.wizard); wizards.push(self.wizard); draggedWizard = null; } }; return self; }); var Wizard = Container.expand(function (elementType, level) { var self = Container.call(this); self.elementType = elementType || 'fire'; self.level = level || 1; self.elementalDamage = 100 * self.level; self.magicDamage = 100 * self.level; self.range = 150 + self.level * 20; self.attackSpeed = 1000 - self.level * 50; // ms between attacks self.lastAttackTime = 0; self.cost = 500 * Math.pow(1.8, self.level - 1); var wizardGraphics = self.attachAsset('wizard_' + self.elementType, { anchorX: 0.5, anchorY: 0.5 }); var levelText = new Text2(self.level.toString(), { size: 24, fill: 0xFFFFFF }); levelText.anchor.set(0.5, 0.5); levelText.y = -10; self.addChild(levelText); self.update = function () { if (LK.ticks - self.lastAttackTime > self.attackSpeed / 16.67) { var target = self.findTarget(); if (target) { self.attack(target); self.lastAttackTime = LK.ticks; } } }; 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(Math.pow(enemy.x - self.x, 2) + Math.pow(enemy.y - self.y, 2)); if (distance <= self.range && distance < closestDistance) { closestDistance = distance; closestEnemy = enemy; } } return closestEnemy; }; self.attack = function (target) { var projectile = new Projectile(self.x, self.y, target, self.elementalDamage + self.magicDamage); projectiles.push(projectile); game.addChild(projectile); LK.getSound('shoot').play(); }; return self; }); var WizardIcon = Container.expand(function (elementType) { var self = Container.call(this); self.elementType = elementType; var iconGraphics = self.attachAsset('wizard_' + elementType, { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.8 }); var costText = new Text2('500', { size: 20, fill: 0xFFFFFF }); costText.anchor.set(0.5, 0); costText.y = 45; self.addChild(costText); self.down = function (x, y, obj) { // Wizard icons are now handled by tower slots }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x228B22 }); /**** * Game Code ****/ // Add cobblestone background var cobblestoneBackground = game.addChild(LK.getAsset('cobblestone_bg', { anchorX: 0, anchorY: 0 })); cobblestoneBackground.x = 0; cobblestoneBackground.y = 0; // Game state variables var currentLevel = 1; var currentWave = 1; var maxWaves = 10; var gold = 1000; var baseHP = 1000; var gameState = 'setup'; // 'setup', 'playing', 'paused', 'between_waves', 'wizard_selection' var waveSpawnTimer = 0; var enemiesSpawnedThisWave = 0; var enemiesPerWave = 10; var draggedWizard = null; var gameStarted = false; var waveStartTime = 0; var lastWaveEndTime = 0; var lastEnemySpawnTime = 0; var selectedTowerSlot = null; var wizardSelectionPopup = null; var waveInProgress = false; var allEnemiesEnteredMaze = false; var lastEnemyEnteredTime = 0; var enemySpawnDelay = 60; // 1 second at 60fps var lastSpawnTime = 0; var currentWaveEnemyType; // Game object arrays var enemies = []; var wizards = []; var projectiles = []; var towerSlots = []; var wizardIcons = []; // Path system var currentPath = []; var pathPoints = [{ x: 50, y: 350 }, { x: 200, y: 350 }, { x: 200, y: 500 }, { x: 350, y: 500 }, { x: 350, y: 650 }, { x: 150, y: 650 }, { x: 150, y: 800 }, { x: 450, y: 800 }, { x: 450, y: 950 }, { x: 650, y: 950 }, { x: 650, y: 750 }, { x: 800, y: 750 }, { x: 800, y: 1100 }, { x: 550, y: 1100 }, { x: 550, y: 1250 }, { x: 900, y: 1250 }, { x: 900, y: 1400 }, { x: 700, y: 1400 }, { x: 700, y: 1550 }, { x: 1050, y: 1550 }, { x: 1050, y: 1200 }, { x: 1200, y: 1200 }, { x: 1200, y: 1700 }, { x: 1000, y: 1700 }, { x: 1000, y: 1850 }, { x: 1350, y: 1850 }, { x: 1350, y: 1500 }, { x: 1500, y: 1500 }, { x: 1500, y: 2000 }, { x: 1700, y: 2000 }]; // UI elements - Create scoreboard container without background var scoreboardContainer = new Container(); var goldText = new Text2('Gold: ' + gold, { size: 60, fill: 0x000000, font: "'GillSans-Bold',Impact,'Arial Black',Tahoma" }); goldText.anchor.set(1, 0); goldText.x = 2048 - 40; // 40px from right edge goldText.y = 40; scoreboardContainer.addChild(goldText); var baseHPText = new Text2('Base HP: ' + baseHP, { size: 60, fill: 0x000000, font: "'GillSans-Bold',Impact,'Arial Black',Tahoma" }); baseHPText.anchor.set(1, 0); baseHPText.x = 2048 - 40; // 40px from right edge baseHPText.y = 110; scoreboardContainer.addChild(baseHPText); var waveText = new Text2('Wave: ' + currentWave + '/' + maxWaves, { size: 60, fill: 0x000000, font: "'GillSans-Bold',Impact,'Arial Black',Tahoma" }); waveText.anchor.set(1, 0); waveText.x = 2048 - 40; // 40px from right edge waveText.y = 180; scoreboardContainer.addChild(waveText); game.addChild(scoreboardContainer); // Initialize path currentPath = pathPoints; // Create continuous road path between waypoints for (var i = 0; i < currentPath.length - 1; i++) { var startPoint = currentPath[i]; var endPoint = currentPath[i + 1]; // Calculate distance and direction between points var dx = endPoint.x - startPoint.x; var dy = endPoint.y - startPoint.y; var distance = Math.sqrt(dx * dx + dy * dy); var steps = Math.ceil(distance / 50); // Place road tiles every 50 pixels // Create road tiles along the path for (var j = 0; j <= steps; j++) { var progress = j / steps; var roadX = startPoint.x + dx * progress; var roadY = startPoint.y + dy * progress; var roadTile = game.addChild(LK.getAsset('road_tile', { anchorX: 0.5, anchorY: 0.5 })); roadTile.x = roadX; roadTile.y = roadY; roadTile.tint = 0x444444; // Darker road color } } // Create home base var homeBase = game.addChild(LK.getAsset('home_base', { anchorX: 0.5, anchorY: 0.5 })); homeBase.x = currentPath[currentPath.length - 1].x; homeBase.y = currentPath[currentPath.length - 1].y; // Create tower slots - positioned outside enemy path but within level 1 wizard range (170px) of enemy path var towerPositions = [{ x: 270, y: 285 }, { x: 430, y: 440 }, { x: 70, y: 730 }, { x: 520, y: 730 }, { x: 780, y: 1475 }, { x: 390, y: 1025 }, { x: 720, y: 1005 }, { x: 1125, y: 1110 }, { x: 750, y: 1175 }, { x: 1125, y: 1380 }, { x: 1110, y: 1775 }, { x: 1425, y: 1590 }]; for (var i = 0; i < towerPositions.length; i++) { var slot = new TowerSlot(towerPositions[i].x, towerPositions[i].y, i + 1); towerSlots.push(slot); game.addChild(slot); } // Create UI bottom panel var uiPanel = game.addChild(LK.getAsset('ui_background', { anchorX: 0, anchorY: 1 })); uiPanel.x = 0; uiPanel.y = 2732; // Create start wave button var startWaveButton = LK.getAsset('ui_background', { width: 200, height: 60, anchorX: 0.5, anchorY: 0.5 }); startWaveButton.tint = 0x00AA00; startWaveButton.x = 1024; startWaveButton.y = 200; var startWaveText = new Text2('Start Game', { size: 30, fill: 0xFFFFFF }); startWaveText.anchor.set(0.5, 0.5); startWaveButton.addChild(startWaveText); startWaveButton.visible = true; game.addChild(startWaveButton); // Wizard icons removed - now handled by tower slot clicks // Add click handlers startWaveButton.down = function () { if (gameState === 'menu' || gameState === 'setup') { gameState = 'playing'; startWaveButton.visible = false; gameStarted = true; // Calculate max waves based on level var wavesPerLevel = [7, 8, 10, 11, 13, 14, 16, 17, 19, 20, 22, 23, 25, 26, 28, 29, 31, 32, 34, 35]; maxWaves = wavesPerLevel[currentLevel - 1] || 10; enemiesPerWave = getEnemiesPerWave(); updateWaveDisplay(); // Start first wave automatically waveInProgress = true; allEnemiesEnteredMaze = false; lastSpawnTime = 0; } }; // Create wizard selection popup function createWizardSelectionPopup() { wizardSelectionPopup = new Container(); // Background - make it larger to accommodate level selection var popupBg = LK.getAsset('ui_background', { width: 1000, height: 800, anchorX: 0.5, anchorY: 0.5 }); popupBg.tint = 0x222222; popupBg.x = 1024; popupBg.y = 1366; wizardSelectionPopup.addChild(popupBg); // Title var titleText = new Text2('Select Wizard & Level', { size: 50, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0.5); titleText.x = 1024; titleText.y = 1050; wizardSelectionPopup.addChild(titleText); // Add selected wizard type and level tracking wizardSelectionPopup.selectedWizardType = 'fire'; wizardSelectionPopup.selectedLevel = 1; // Wizard type buttons var wizardTypes = ['fire', 'ice', 'nature', 'dark', 'light']; var wizardTypeButtons = []; for (var i = 0; i < wizardTypes.length; i++) { var wizardBtn = LK.getAsset('wizard_' + wizardTypes[i], { anchorX: 0.5, anchorY: 0.5 }); wizardBtn.x = 600 + i % 3 * 120; wizardBtn.y = 1200 + Math.floor(i / 3) * 120; wizardBtn.wizardType = wizardTypes[i]; wizardBtn.alpha = wizardTypes[i] === 'fire' ? 1.0 : 0.6; // Highlight selected wizardBtn.down = function () { // Update selected wizard type wizardSelectionPopup.selectedWizardType = this.wizardType; // Update button highlighting for (var j = 0; j < wizardTypeButtons.length; j++) { wizardTypeButtons[j].alpha = wizardTypeButtons[j].wizardType === this.wizardType ? 1.0 : 0.6; } // Update cost display updateCostDisplay(); }; wizardSelectionPopup.addChild(wizardBtn); wizardTypeButtons.push(wizardBtn); } // Level selection section var levelTitleText = new Text2('Level:', { size: 40, fill: 0xFFFFFF }); levelTitleText.anchor.set(0.5, 0.5); levelTitleText.x = 1024; levelTitleText.y = 1420; wizardSelectionPopup.addChild(levelTitleText); // Level buttons (1-5) var levelButtons = []; for (var i = 1; i <= 5; i++) { var levelBtn = LK.getAsset('ui_background', { width: 80, height: 60, anchorX: 0.5, anchorY: 0.5 }); levelBtn.tint = i === 1 ? 0x00AA00 : 0x666666; // Highlight level 1 levelBtn.x = 700 + (i - 1) * 100; levelBtn.y = 1500; levelBtn.level = i; var levelText = new Text2(i.toString(), { size: 30, fill: 0xFFFFFF }); levelText.anchor.set(0.5, 0.5); levelBtn.addChild(levelText); levelBtn.down = function () { // Update selected level wizardSelectionPopup.selectedLevel = this.level; // Update button highlighting for (var j = 0; j < levelButtons.length; j++) { levelButtons[j].tint = levelButtons[j].level === this.level ? 0x00AA00 : 0x666666; } // Update cost display updateCostDisplay(); }; wizardSelectionPopup.addChild(levelBtn); levelButtons.push(levelBtn); } // Cost display var costText = new Text2('Cost: 500', { size: 35, fill: 0xFFFF00 }); costText.anchor.set(0.5, 0.5); costText.x = 1024; costText.y = 1580; wizardSelectionPopup.addChild(costText); // Function to update cost display function updateCostDisplay() { var cost = 500 * Math.pow(1.8, wizardSelectionPopup.selectedLevel - 1); costText.setText('Cost: ' + Math.floor(cost)); costText.tint = gold >= cost ? 0xFFFF00 : 0xFF0000; // Yellow if affordable, red if not } // Hire button var hireBtn = LK.getAsset('ui_background', { width: 200, height: 60, anchorX: 0.5, anchorY: 0.5 }); hireBtn.tint = 0x00AA00; hireBtn.x = 924; hireBtn.y = 1650; var hireText = new Text2('Hire', { size: 30, fill: 0xFFFFFF }); hireText.anchor.set(0.5, 0.5); hireBtn.addChild(hireText); hireBtn.down = function () { placeWizardOnSelectedSlot(wizardSelectionPopup.selectedWizardType, wizardSelectionPopup.selectedLevel); }; wizardSelectionPopup.addChild(hireBtn); // Close button var closeBtn = LK.getAsset('ui_background', { width: 100, height: 50, anchorX: 0.5, anchorY: 0.5 }); closeBtn.tint = 0xff0000; closeBtn.x = 1400; closeBtn.y = 1050; var closeText = new Text2('X', { size: 30, fill: 0xFFFFFF }); closeText.anchor.set(0.5, 0.5); closeBtn.addChild(closeText); closeBtn.down = function () { closeWizardSelectionPopup(); }; wizardSelectionPopup.addChild(closeBtn); game.addChild(wizardSelectionPopup); } function closeWizardSelectionPopup() { if (wizardSelectionPopup) { wizardSelectionPopup.destroy(); wizardSelectionPopup = null; selectedTowerSlot = null; gameState = gameStarted ? 'playing' : 'setup'; } } function placeWizardOnSelectedSlot(wizardType, level) { if (selectedTowerSlot && selectedTowerSlot.isEmpty) { var cost = 500 * Math.pow(1.8, level - 1); if (gold >= cost) { gold -= cost; updateGoldDisplay(); var wizard = new Wizard(wizardType, level); wizard.x = selectedTowerSlot.x; wizard.y = selectedTowerSlot.y; selectedTowerSlot.wizard = wizard; selectedTowerSlot.isEmpty = false; // Add range visualization var rangeCircle = LK.getAsset('tower_slot', { anchorX: 0.5, anchorY: 0.5, scaleX: wizard.range / 45, scaleY: wizard.range / 45 }); rangeCircle.tint = 0x00ff00; rangeCircle.alpha = 0.2; rangeCircle.x = wizard.x; rangeCircle.y = wizard.y; game.addChild(rangeCircle); wizard.rangeCircle = rangeCircle; game.addChild(wizard); wizards.push(wizard); closeWizardSelectionPopup(); } } } // Helper functions function updateGoldDisplay() { goldText.setText('Gold: ' + gold); } function updateBaseHPDisplay() { baseHPText.setText('Base HP: ' + baseHP); } function updateWaveDisplay() { waveText.setText('Wave: ' + currentWave + '/' + maxWaves); } function spawnEnemy() { // Determine enemy type for this wave - same type for all enemies in wave if (currentWaveEnemyType === undefined) { var rand = Math.random(); if (rand < 0.6) currentWaveEnemyType = 'basic';else if (rand < 0.85) currentWaveEnemyType = 'fast';else currentWaveEnemyType = 'tank'; } var enemy = new Enemy(currentWaveEnemyType, currentLevel); enemy.x = currentPath[0].x; enemy.y = currentPath[0].y; enemies.push(enemy); game.addChild(enemy); } function getEnemiesPerWave() { var min, max; if (currentLevel >= 1 && currentLevel <= 5) { min = 10; max = 20; } else if (currentLevel >= 6 && currentLevel <= 10) { min = 15; max = 25; } else if (currentLevel >= 11 && currentLevel <= 15) { min = 20; max = 35; } else if (currentLevel >= 16 && currentLevel <= 20) { min = 35; max = 50; } else { min = 50; max = 70; } return Math.floor(Math.random() * (max - min + 1)) + min; } function startNextWave() { currentWave++; enemiesSpawnedThisWave = 0; enemiesPerWave = getEnemiesPerWave(); lastWaveEndTime = LK.ticks; gameState = 'playing'; currentWaveEnemyType = undefined; // Reset enemy type for new wave updateWaveDisplay(); } // Game update loop game.update = function () { // Only update game logic if not in setup or wizard selection if (gameState === 'setup' || gameState === 'wizard_selection') { return; } // Spawn enemies with proper timing if (gameState === 'playing' && waveInProgress && enemiesSpawnedThisWave < enemiesPerWave) { // Only spawn if enough time has passed since last spawn if (LK.ticks - lastSpawnTime >= enemySpawnDelay) { spawnEnemy(); enemiesSpawnedThisWave++; lastSpawnTime = LK.ticks; // Check if all enemies have been spawned for this wave if (enemiesSpawnedThisWave >= enemiesPerWave) { allEnemiesEnteredMaze = true; lastEnemyEnteredTime = LK.ticks; } } } // Check if wave is complete - all enemies spawned and all enemies cleared if (waveInProgress && allEnemiesEnteredMaze && enemies.length === 0) { // Wait 5 seconds after last enemy entered before allowing next wave if (LK.ticks - lastEnemyEnteredTime >= 300) { // 5 seconds at 60fps waveInProgress = false; allEnemiesEnteredMaze = false; enemiesSpawnedThisWave = 0; gameState = 'between_waves'; lastWaveEndTime = LK.ticks; waveStartTime = 0; if (currentWave < maxWaves) { // Automatically start next wave after 5 seconds startNextWave(); waveInProgress = true; allEnemiesEnteredMaze = false; lastSpawnTime = 0; } else { // Level complete currentLevel++; currentWave = 0; // Will be incremented in startNextWave var wavesPerLevel = [7, 8, 10, 11, 13, 14, 16, 17, 19, 20, 22, 23, 25, 26, 28, 29, 31, 32, 34, 35]; maxWaves = wavesPerLevel[currentLevel - 1] || 10; enemiesPerWave = getEnemiesPerWave(); if (currentLevel > 20) { LK.showYouWin(); return; } // Automatically start next level startNextWave(); waveInProgress = true; allEnemiesEnteredMaze = false; lastSpawnTime = 0; } } } // Update projectiles for (var i = projectiles.length - 1; i >= 0; i--) { var projectile = projectiles[i]; if (projectile.destroyed) { projectiles.splice(i, 1); } } // Clean up destroyed enemies for (var i = enemies.length - 1; i >= 0; i--) { if (enemies[i].destroyed) { enemies.splice(i, 1); } } // Clean up destroyed wizards for (var i = wizards.length - 1; i >= 0; i--) { if (wizards[i].destroyed) { wizards.splice(i, 1); } } };
===================================================================
--- original.js
+++ change.js
@@ -546,53 +546,142 @@
};
// Create wizard selection popup
function createWizardSelectionPopup() {
wizardSelectionPopup = new Container();
- // Background
+ // Background - make it larger to accommodate level selection
var popupBg = LK.getAsset('ui_background', {
- width: 800,
- height: 600,
+ width: 1000,
+ height: 800,
anchorX: 0.5,
anchorY: 0.5
});
popupBg.tint = 0x222222;
popupBg.x = 1024;
popupBg.y = 1366;
wizardSelectionPopup.addChild(popupBg);
// Title
- var titleText = new Text2('Select Wizard', {
+ var titleText = new Text2('Select Wizard & Level', {
size: 50,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
- titleText.y = 1150;
+ titleText.y = 1050;
wizardSelectionPopup.addChild(titleText);
+ // Add selected wizard type and level tracking
+ wizardSelectionPopup.selectedWizardType = 'fire';
+ wizardSelectionPopup.selectedLevel = 1;
// Wizard type buttons
var wizardTypes = ['fire', 'ice', 'nature', 'dark', 'light'];
+ var wizardTypeButtons = [];
for (var i = 0; i < wizardTypes.length; i++) {
var wizardBtn = LK.getAsset('wizard_' + wizardTypes[i], {
anchorX: 0.5,
anchorY: 0.5
});
- wizardBtn.x = 700 + i % 3 * 120;
- wizardBtn.y = 1300 + Math.floor(i / 3) * 120;
+ wizardBtn.x = 600 + i % 3 * 120;
+ wizardBtn.y = 1200 + Math.floor(i / 3) * 120;
wizardBtn.wizardType = wizardTypes[i];
+ wizardBtn.alpha = wizardTypes[i] === 'fire' ? 1.0 : 0.6; // Highlight selected
wizardBtn.down = function () {
- placeWizardOnSelectedSlot(this.wizardType, 1);
+ // Update selected wizard type
+ wizardSelectionPopup.selectedWizardType = this.wizardType;
+ // Update button highlighting
+ for (var j = 0; j < wizardTypeButtons.length; j++) {
+ wizardTypeButtons[j].alpha = wizardTypeButtons[j].wizardType === this.wizardType ? 1.0 : 0.6;
+ }
+ // Update cost display
+ updateCostDisplay();
};
wizardSelectionPopup.addChild(wizardBtn);
+ wizardTypeButtons.push(wizardBtn);
}
+ // Level selection section
+ var levelTitleText = new Text2('Level:', {
+ size: 40,
+ fill: 0xFFFFFF
+ });
+ levelTitleText.anchor.set(0.5, 0.5);
+ levelTitleText.x = 1024;
+ levelTitleText.y = 1420;
+ wizardSelectionPopup.addChild(levelTitleText);
+ // Level buttons (1-5)
+ var levelButtons = [];
+ for (var i = 1; i <= 5; i++) {
+ var levelBtn = LK.getAsset('ui_background', {
+ width: 80,
+ height: 60,
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ levelBtn.tint = i === 1 ? 0x00AA00 : 0x666666; // Highlight level 1
+ levelBtn.x = 700 + (i - 1) * 100;
+ levelBtn.y = 1500;
+ levelBtn.level = i;
+ var levelText = new Text2(i.toString(), {
+ size: 30,
+ fill: 0xFFFFFF
+ });
+ levelText.anchor.set(0.5, 0.5);
+ levelBtn.addChild(levelText);
+ levelBtn.down = function () {
+ // Update selected level
+ wizardSelectionPopup.selectedLevel = this.level;
+ // Update button highlighting
+ for (var j = 0; j < levelButtons.length; j++) {
+ levelButtons[j].tint = levelButtons[j].level === this.level ? 0x00AA00 : 0x666666;
+ }
+ // Update cost display
+ updateCostDisplay();
+ };
+ wizardSelectionPopup.addChild(levelBtn);
+ levelButtons.push(levelBtn);
+ }
+ // Cost display
+ var costText = new Text2('Cost: 500', {
+ size: 35,
+ fill: 0xFFFF00
+ });
+ costText.anchor.set(0.5, 0.5);
+ costText.x = 1024;
+ costText.y = 1580;
+ wizardSelectionPopup.addChild(costText);
+ // Function to update cost display
+ function updateCostDisplay() {
+ var cost = 500 * Math.pow(1.8, wizardSelectionPopup.selectedLevel - 1);
+ costText.setText('Cost: ' + Math.floor(cost));
+ costText.tint = gold >= cost ? 0xFFFF00 : 0xFF0000; // Yellow if affordable, red if not
+ }
+ // Hire button
+ var hireBtn = LK.getAsset('ui_background', {
+ width: 200,
+ height: 60,
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ hireBtn.tint = 0x00AA00;
+ hireBtn.x = 924;
+ hireBtn.y = 1650;
+ var hireText = new Text2('Hire', {
+ size: 30,
+ fill: 0xFFFFFF
+ });
+ hireText.anchor.set(0.5, 0.5);
+ hireBtn.addChild(hireText);
+ hireBtn.down = function () {
+ placeWizardOnSelectedSlot(wizardSelectionPopup.selectedWizardType, wizardSelectionPopup.selectedLevel);
+ };
+ wizardSelectionPopup.addChild(hireBtn);
// Close button
var closeBtn = LK.getAsset('ui_background', {
width: 100,
height: 50,
anchorX: 0.5,
anchorY: 0.5
});
closeBtn.tint = 0xff0000;
- closeBtn.x = 1300;
- closeBtn.y = 1150;
+ closeBtn.x = 1400;
+ closeBtn.y = 1050;
var closeText = new Text2('X', {
size: 30,
fill: 0xFFFFFF
});
Fort to defend. In-Game asset. 2d. High contrast. No shadows
bulky warrior like a tank. In-Game asset. 2d. High contrast. No shadows
fast and slim warrior to represent speed. In-Game asset. 2d. High contrast. No shadows
in game asset, colored, 2d warrior, face covered with helmet
dark wizard 2d in game asset. In-Game asset. 2d. High contrast. No shadows
mostly transparent grey circle. In-Game asset. 2d. High contrast. No shadows
top view, stone high tower.. In-Game asset. 2d. High contrast. No shadows
a fire wizard. In-Game asset. 2d. High contrast. No shadows
cornerstone 2d in game asset from top view
2d in game asset ice wizard. In-Game asset. 2d. High contrast. No shadows
2d in game asset nature (green) wizard.
2d in game asset light (yellow) wizard.
magic bolt traveling in air
2d, top view, very light grey, very very very small tiled (at least 1000 tiles), cobblestone road texture