User prompt
7th to south by 15 pixels 8th to south by 100 pixels 9th north by 50 pixels
User prompt
5th tower to left a little bit more 7th tower to south significantly 8th tower to north by half of its size
User prompt
move 4th and 5th towers from start slightly to left
User prompt
ensure all towers will allow a level 1 wizard to shoot to the enemy path. top 3 towers seems to be misplaced.
User prompt
avoid putting tower on enemy path. all towers shall be outside of enemy path to home base
User prompt
place all towers again so all towers will be able to let a level 1 wizard to hit an enemy
User prompt
towers shall not intersect with enemy path assets. no tower asset shall be touching enemy path asset
User prompt
revert all tower placements
User prompt
tower assets shall not intersect with enemy path assets
User prompt
place towers just near the enemy path but not intersecting with the path
User prompt
place each tower apart from the enemy path asset with an exact distance of half of the width of path asset
User prompt
place towers completely out of enemy path assets. however each tower shall allow a level 1 wizard to be able to shoot to the path.
User prompt
towers placement shall not interfere with enemy path. they can be close but not intersecting with enemy path.
User prompt
tunnels are not like i want. i want the path that enemies travel a continious route like a road.
User prompt
show enemy path as a open top tunnel
User prompt
make maze more complex so it is not a simple zigzag pattern
User prompt
decrease enemy kill gold bonus by dividing it to 10. make background an cobblestone road asset. make enemy path a dark colored road instead of lines.
User prompt
border maze with lines so it will be more visible
User prompt
arrange placement of each tower so even a level 1 wizard can shoot in the maze
User prompt
decrease the number of towers increase home base hp to 1000 increase enemy HP remove main menu, tutorial and select level buttons and make wave start button to start the game allow player to place wizards on towers before starting the wave have only one type of enemy for each wave
User prompt
waves shall follow each other automatically with 5 second difference. which means 5 seconds after last enemy of wave 1 enters, first enemy of wave 2 shall enter without clicking start wave button.
User prompt
wave system is completely broken. only two wave enters and at the same time interval. also you may remove below wizard selecting menu as now we are clicking on tower to select wizard type. also show wizards' shooting range.
User prompt
second wave still enters while first wave is entering. do not send any enemy from following wave until first wave's last enemy enters the maze and 5 second passes. let's forget about drag and drop of wizards. when i click a wizard, pause the game, show me a pop-up menu so i can select type and level of wizard and then unpause the game when i select the tower to place the wizard.
User prompt
thing to modify: 1. level shall start when player clicks start 2. there shall be a main menu to let player to start game, to read tutorial or to select level. 3. wizards cannot be dragged into towers 4. each wave shall enter the maze 5 seconds after the last character of previous wave enters the maze 5. maze shall be more visible by line borders 6. number of enemies in each wave is wrong. each wave also have 10-20 random number of enemies from level 1 to 5, 15-25 random number of enemies for level 6-10, 20-35 for levels 11-15 and 35-50 for levels 16-20.
Code edit (1 edits merged)
Please save this source code
/**** * 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; 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) { var self = Container.call(this); self.x = x; self.y = y; self.isEmpty = true; self.wizard = null; var slotGraphics = self.attachAsset('tower_slot', { anchorX: 0.5, anchorY: 0.5 }); 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 ****/ // 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: 400 }, { x: 200, y: 400 }, { x: 200, y: 600 }, { x: 400, y: 600 }, { x: 400, y: 800 }, { x: 600, y: 800 }, { x: 600, y: 1000 }, { x: 800, y: 1000 }, { x: 800, y: 1200 }, { x: 1000, y: 1200 }, { x: 1000, y: 1400 }, { x: 1200, y: 1400 }, { x: 1200, y: 1600 }, { x: 1400, y: 1600 }, { x: 1400, y: 1800 }, { x: 1600, y: 1800 }]; // UI elements var goldText = new Text2('Gold: ' + gold, { size: 40, fill: 0xFFFFFF }); goldText.anchor.set(0, 0); goldText.x = 100; goldText.y = 50; game.addChild(goldText); var baseHPText = new Text2('Base HP: ' + baseHP, { size: 40, fill: 0xFFFFFF }); baseHPText.anchor.set(0, 0); baseHPText.x = 100; baseHPText.y = 100; game.addChild(baseHPText); var waveText = new Text2('Wave: ' + currentWave + '/' + maxWaves, { size: 40, fill: 0xFFFFFF }); waveText.anchor.set(0, 0); waveText.x = 100; waveText.y = 150; game.addChild(waveText); // Initialize path currentPath = pathPoints; // Create path visualization with borders for (var i = 0; i < currentPath.length; i++) { var pathTile = game.addChild(LK.getAsset('path_tile', { anchorX: 0.5, anchorY: 0.5 })); pathTile.x = currentPath[i].x; pathTile.y = currentPath[i].y; // Add border var border = game.addChild(LK.getAsset('ui_background', { width: 64, height: 64, anchorX: 0.5, anchorY: 0.5 })); border.tint = 0x000000; border.x = currentPath[i].x; border.y = currentPath[i].y; border.alpha = 0.3; } // 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 var towerPositions = [{ x: 300, y: 500 }, { x: 700, y: 500 }, { x: 900, y: 900 }, { x: 1100, y: 900 }, { x: 1300, y: 900 }, { x: 1100, y: 1300 }, { x: 1500, y: 1300 }, { x: 1700, y: 1500 }]; for (var i = 0; i < towerPositions.length; i++) { var slot = new TowerSlot(towerPositions[i].x, towerPositions[i].y); 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 var popupBg = LK.getAsset('ui_background', { width: 800, height: 600, 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', { size: 50, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0.5); titleText.x = 1024; titleText.y = 1150; wizardSelectionPopup.addChild(titleText); // Wizard type buttons var wizardTypes = ['fire', 'ice', 'nature', 'dark', 'light']; 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.wizardType = wizardTypes[i]; wizardBtn.down = function () { placeWizardOnSelectedSlot(this.wizardType, 1); }; wizardSelectionPopup.addChild(wizardBtn); } // 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; 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
@@ -15,17 +15,17 @@
self.pathProgress = 0;
self.speed = 2;
switch (self.enemyType) {
case 'basic':
- self.maxHP = 100 + level * 50;
+ self.maxHP = (100 + level * 50) * 5;
self.speed = 2;
break;
case 'fast':
- self.maxHP = 50 + level * 25;
+ self.maxHP = (50 + level * 25) * 5;
self.speed = 4;
break;
case 'tank':
- self.maxHP = 300 + level * 100;
+ self.maxHP = (300 + level * 100) * 5;
self.speed = 1;
break;
}
self.hp = self.maxHP;
@@ -153,9 +153,9 @@
anchorX: 0.5,
anchorY: 0.5
});
self.down = function (x, y, obj) {
- if (self.isEmpty && gameState === 'playing') {
+ if (self.isEmpty && (gameState === 'setup' || gameState === 'playing')) {
selectedTowerSlot = self;
gameState = 'wizard_selection';
createWizardSelectionPopup();
}
@@ -263,10 +263,10 @@
var currentLevel = 1;
var currentWave = 1;
var maxWaves = 10;
var gold = 1000;
-var baseHP = 100;
-var gameState = 'menu'; // 'menu', 'playing', 'paused', 'between_waves', 'wizard_selection'
+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;
@@ -280,8 +280,9 @@
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 = [];
@@ -394,78 +395,30 @@
homeBase.y = currentPath[currentPath.length - 1].y;
// Create tower slots
var towerPositions = [{
x: 300,
- y: 300
-}, {
- x: 500,
- y: 300
-}, {
- x: 700,
- y: 300
-}, {
- x: 300,
y: 500
}, {
- x: 500,
- y: 500
-}, {
x: 700,
y: 500
}, {
- x: 300,
- y: 700
-}, {
- x: 500,
- y: 700
-}, {
- x: 700,
- y: 700
-}, {
x: 900,
- y: 700
-}, {
- x: 1100,
- y: 700
-}, {
- x: 1300,
- y: 700
-}, {
- x: 900,
y: 900
}, {
x: 1100,
y: 900
}, {
x: 1300,
y: 900
}, {
- x: 900,
- y: 1100
-}, {
x: 1100,
- y: 1100
+ y: 1300
}, {
- x: 1300,
- y: 1100
-}, {
x: 1500,
- y: 1100
-}, {
- x: 1700,
- y: 1100
-}, {
- x: 1500,
y: 1300
}, {
x: 1700,
- y: 1300
-}, {
- x: 1500,
y: 1500
-}, {
- x: 1700,
- y: 1500
}];
for (var i = 0; i < towerPositions.length; i++) {
var slot = new TowerSlot(towerPositions[i].x, towerPositions[i].y);
towerSlots.push(slot);
@@ -477,67 +430,8 @@
anchorY: 1
}));
uiPanel.x = 0;
uiPanel.y = 2732;
-// Create main menu
-var mainMenu = new Container();
-var menuTitle = new Text2('Elemental Tower Defense', {
- size: 80,
- fill: 0xFFFFFF
-});
-menuTitle.anchor.set(0.5, 0.5);
-menuTitle.x = 1024;
-menuTitle.y = 800;
-mainMenu.addChild(menuTitle);
-var startButton = LK.getAsset('ui_background', {
- width: 400,
- height: 80,
- anchorX: 0.5,
- anchorY: 0.5
-});
-startButton.tint = 0x00AA00;
-startButton.x = 1024;
-startButton.y = 1000;
-var startText = new Text2('Start Game', {
- size: 40,
- fill: 0xFFFFFF
-});
-startText.anchor.set(0.5, 0.5);
-startButton.addChild(startText);
-mainMenu.addChild(startButton);
-var levelButton = LK.getAsset('ui_background', {
- width: 400,
- height: 80,
- anchorX: 0.5,
- anchorY: 0.5
-});
-levelButton.tint = 0x0066CC;
-levelButton.x = 1024;
-levelButton.y = 1100;
-var levelText = new Text2('Select Level', {
- size: 40,
- fill: 0xFFFFFF
-});
-levelText.anchor.set(0.5, 0.5);
-levelButton.addChild(levelText);
-mainMenu.addChild(levelButton);
-var tutorialButton = LK.getAsset('ui_background', {
- width: 400,
- height: 80,
- anchorX: 0.5,
- anchorY: 0.5
-});
-tutorialButton.tint = 0xAA6600;
-tutorialButton.x = 1024;
-tutorialButton.y = 1200;
-var tutorialText = new Text2('Tutorial', {
- size: 40,
- fill: 0xFFFFFF
-});
-tutorialText.anchor.set(0.5, 0.5);
-tutorialButton.addChild(tutorialText);
-mainMenu.addChild(tutorialButton);
-game.addChild(mainMenu);
// Create start wave button
var startWaveButton = LK.getAsset('ui_background', {
width: 200,
height: 60,
@@ -546,40 +440,32 @@
});
startWaveButton.tint = 0x00AA00;
startWaveButton.x = 1024;
startWaveButton.y = 200;
-var startWaveText = new Text2('Start Wave', {
+var startWaveText = new Text2('Start Game', {
size: 30,
fill: 0xFFFFFF
});
startWaveText.anchor.set(0.5, 0.5);
startWaveButton.addChild(startWaveText);
-startWaveButton.visible = false;
+startWaveButton.visible = true;
game.addChild(startWaveButton);
// Wizard icons removed - now handled by tower slot clicks
// Add click handlers
-startButton.down = function () {
- gameState = 'playing';
- mainMenu.visible = false;
- 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;
-};
startWaveButton.down = function () {
- if (gameState === 'playing' && !waveInProgress) {
- waveStartTime = LK.ticks;
+ 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;
- startWaveButton.visible = false;
}
};
// Create wizard selection popup
function createWizardSelectionPopup() {
@@ -645,9 +531,9 @@
if (wizardSelectionPopup) {
wizardSelectionPopup.destroy();
wizardSelectionPopup = null;
selectedTowerSlot = null;
- gameState = 'playing';
+ gameState = gameStarted ? 'playing' : 'setup';
}
}
function placeWizardOnSelectedSlot(wizardType, level) {
if (selectedTowerSlot && selectedTowerSlot.isEmpty) {
@@ -689,12 +575,14 @@
function updateWaveDisplay() {
waveText.setText('Wave: ' + currentWave + '/' + maxWaves);
}
function spawnEnemy() {
- var enemyType = 'basic';
- if (Math.random() < 0.3) enemyType = 'fast';
- if (Math.random() < 0.1) enemyType = 'tank';
- var enemy = new Enemy(enemyType, currentLevel);
+ // 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);
@@ -724,14 +612,15 @@
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 menu or wizard selection
- if (gameState === 'menu' || gameState === 'wizard_selection') {
+ // 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) {
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