User prompt
5 damage per second
User prompt
Howtoplaydeki kulenin hasarını saniyede şukadar hasar olarak değiştir
User prompt
Howtoplay deki bactomenun yu aşağı al
User prompt
Howtoplay deki ni aşağı al
User prompt
Back to menü yü aşağı al
User prompt
How to play deki yazıları çok az aşağı al
User prompt
Howtoplay de nasıl oynanılıcağı karakterlerin sağlığı ,hasarı falan herşey yazsın
User prompt
Howtoplay i güncelle
User prompt
Her işçi farklı coine yönelsin
User prompt
Her işçi farklı coine yönetsin
User prompt
Karekter düşman karakterleri öldürdükten sonra kuleye saldırsınlar
User prompt
Zombi modunda zombiler başlangıçtan 30 saniye sonra çıksınlar
User prompt
Dalga lar daha yavaş gelsin ve kule yakındaki sadece 1 karektere hasar verebilsin
User prompt
En üstte yazsın
User prompt
Her wave de ekranda kaçıncı wave olduğu yazsın
User prompt
Zombi modunda zombiler tek tek değil dalga halinde gelsinler her dalga bir öncekinden güçlü olsun
User prompt
Sadece zombie Mode yi aşağı al
User prompt
Normal modu daha üste al
User prompt
ZombieMode yerine "ZombieMode " olsun
User prompt
Normalmode yerine "normalmode" assetini kullan
User prompt
Normal Mode yerine Normalmode Zombi Mode yerine ZombieMode olsun
User prompt
Dragon ,saldırı yaparken dragonattack olsun
User prompt
Düşmanları öldürdüklerinde ise kuleye saldırsınlar
User prompt
Karakterlerin tek amacı kuleyi yıkmak değil aynı zamanda düşman savaşçıları öldürmek olsun
/**** * Plugins ****/ var storage = LK.import("@upit/storage.v1"); var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Arrow = Container.expand(function (team, startX, startY, targetX, targetY, damage) { var self = Container.call(this); var graphics = self.attachAsset('Arrow', { anchorX: 0.5, anchorY: 0.5 }); self.team = team; self.damage = damage; self.speed = 8; self.target = null; // Calculate direction var dx = targetX - startX; var dy = targetY - startY; var distance = Math.sqrt(dx * dx + dy * dy); self.directionX = dx / distance; self.directionY = dy / distance; // Set rotation to point toward target self.rotation = Math.atan2(dy, dx); // Position arrow at start self.x = startX; self.y = startY; self.update = function () { // Move arrow self.x += self.directionX * self.speed; self.y += self.directionY * self.speed; // Check if arrow is off screen if (self.x < -100 || self.x > 2148 || self.y < -100 || self.y > 2832) { self.destroy(); // Remove from arrows array for (var i = arrows.length - 1; i >= 0; i--) { if (arrows[i] === self) { arrows.splice(i, 1); break; } } } // Check collision with enemy units var enemyUnits = self.team === 'player' ? aiUnits : playerUnits; for (var i = 0; i < enemyUnits.length; i++) { var enemy = enemyUnits[i]; if (self.intersects(enemy)) { enemy.health -= self.damage; if (enemy.health <= 0) { enemyUnits.splice(i, 1); enemy.destroy(); } self.destroy(); // Remove from arrows array for (var j = arrows.length - 1; j >= 0; j--) { if (arrows[j] === self) { arrows.splice(j, 1); break; } } return; } } // Check collision with enemy towers var enemyTowers = self.team === 'player' ? aiTowers : playerTowers; for (var i = 0; i < enemyTowers.length; i++) { var tower = enemyTowers[i]; if (self.intersects(tower)) { tower.health -= self.damage; if (tower.health <= 0) { enemyTowers.splice(i, 1); tower.destroy(); LK.getSound('towerDestroyed').play(); } self.destroy(); // Remove from arrows array for (var j = arrows.length - 1; j >= 0; j--) { if (arrows[j] === self) { arrows.splice(j, 1); break; } } return; } } }; return self; }); var Coin = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('coin', { anchorX: 0.5, anchorY: 0.5 }); self.value = 1; self.collected = false; return self; }); var CombatUnit = Container.expand(function (team, unitType) { var self = Container.call(this); var assetName = team === 'player' ? unitType : 'ai' + unitType.charAt(0).toUpperCase() + unitType.slice(1); var graphics = self.attachAsset(assetName, { anchorX: 0.5, anchorY: 0.5 }); self.team = team; self.unitType = unitType; self.speed = unitType === 'dragon' ? 3 : unitType === 'wizard' ? 1.5 : unitType === 'archer' ? 2.5 : 2; self.damage = unitType === 'dragon' ? 40 : unitType === 'wizard' ? 30 : unitType === 'archer' ? 20 : 10; self.health = unitType === 'dragon' ? 50 : unitType === 'wizard' ? 40 : unitType === 'archer' ? 30 : unitType === 'warrior' ? 20 : 10; self.maxHealth = self.health; self.attackRange = unitType === 'wizard' ? 100 : unitType === 'archer' ? 200 : 50; self.attackCooldown = 0; self.target = null; self.isWaiting = !zombieMode && team === 'player'; // Only player units wait in normal mode // Create health bar background (black) self.healthBarBg = LK.getAsset('blackBackground', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 0.75 }); self.healthBarBg.x = 0; self.healthBarBg.y = -120; self.healthBarBg.tint = team === 'player' ? 0x0000ff : 0x000000; self.addChild(self.healthBarBg); // Create health bar (green for player, red for AI) self.healthBar = LK.getAsset('blackBackground', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 0.75 }); self.healthBar.x = 0; self.healthBar.y = -120; self.healthBar.tint = team === 'player' ? 0x00ff00 : 0xff0000; self.addChild(self.healthBar); self.healthText = new Text2(self.health.toString(), { size: 50, fill: '#ffffff' }); self.healthText.anchor.set(0.5, 0.5); self.addChild(self.healthText); self.healthText.x = 0; self.healthText.y = -120; self.update = function () { if (self.attackCooldown > 0) { self.attackCooldown--; } // In zombie mode, player units prioritize attacking zombies if (zombieMode && self.team === 'player' && self.unitType !== 'worker') { self.attackZombies(); } else if (!zombieMode && self.team === 'player' && self.isWaiting) { // In normal mode, player units wait unless attack is triggered // Stay in position and don't move } else { if (!self.target) { self.findNearestEnemyTower(); } else { self.moveToTarget(); } // Combat with nearby enemy units self.combatNearbyEnemies(); } self.healthText.setText(self.health.toString()); // Update health bar scale based on health percentage var healthPercentage = self.health / self.maxHealth; tween(self.healthBar, { scaleX: 1.5 * healthPercentage }, { duration: 200 }); }; self.findNearestEnemyTower = function () { // In zombie mode, player units should prioritize attacking zombies if (zombieMode && self.team === 'player' && self.unitType !== 'worker') { var nearestZombie = null; var nearestDistance = Infinity; for (var i = 0; i < zombies.length; i++) { var zombie = zombies[i]; var distance = Math.sqrt(Math.pow(zombie.x - self.x, 2) + Math.pow(zombie.y - self.y, 2)); if (distance < nearestDistance) { nearestDistance = distance; nearestZombie = zombie; } } // If we found a zombie, target it if (nearestZombie) { self.target = nearestZombie; return; } } // Find nearest target - prioritize ALL enemy units first (including workers), then towers var nearestTarget = null; var nearestDistance = Infinity; // First check all enemy units (including workers) var enemyUnits = self.team === 'player' ? aiUnits : playerUnits; for (var i = 0; i < enemyUnits.length; i++) { var enemy = enemyUnits[i]; // Target all enemy units now, including workers if (self.unitType !== 'worker') { var distance = Math.sqrt(Math.pow(enemy.x - self.x, 2) + Math.pow(enemy.y - self.y, 2)); if (distance < nearestDistance) { nearestDistance = distance; nearestTarget = enemy; } } } // Only target towers if no enemy units remain if (!nearestTarget) { var enemyTowers = self.team === 'player' ? aiTowers : playerTowers; for (var i = 0; i < enemyTowers.length; i++) { var tower = enemyTowers[i]; var distance = Math.sqrt(Math.pow(tower.x - self.x, 2) + Math.pow(tower.y - self.y, 2)); if (distance < nearestDistance) { nearestDistance = distance; nearestTarget = tower; } } } self.target = nearestTarget; }; self.moveToTarget = function () { if (!self.target) { 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 < self.attackRange) { self.attackTarget(); } else { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } }; self.attackTarget = function () { if (self.attackCooldown <= 0 && self.target) { if (self.unitType === 'archer') { // Archer shoots arrow var arrow = new Arrow(self.team, self.x, self.y, self.target.x, self.target.y, self.damage); arrows.push(arrow); game.addChild(arrow); } else if (self.unitType === 'wizard') { // Wizard shoots magic var magic = new Magic(self.team, self.x, self.y, self.target.x, self.target.y, self.damage); magics.push(magic); game.addChild(magic); } else if (self.unitType === 'dragon') { // Change to attack asset for all dragon attacks self.removeChild(graphics); var assetName = 'DragonAttack'; graphics = self.attachAsset(assetName, { anchorX: 0.5, anchorY: 0.5 }); // Dragon shoots fire with 1 damage var fire = new Fire(self.team, self.x, self.y, self.target.x, self.target.y, 1); fires.push(fire); game.addChild(fire); } else { // Melee attack self.target.health -= self.damage; if (self.target.health <= 0) { // Check if target is a unit or tower if (self.target.unitType) { // Target is a unit self.destroyUnit(); } else { // Target is a tower self.destroyTower(); } } } // Set dragon attack cooldown to 3 frames (0.05 seconds) if (self.unitType === 'dragon') { self.attackCooldown = 3; } else { self.attackCooldown = 60; } LK.getSound('attack').play(); } }; self.destroyUnit = function () { var units = self.team === 'player' ? aiUnits : playerUnits; var index = units.indexOf(self.target); if (index > -1) { units.splice(index, 1); self.target.destroy(); self.target = null; } }; self.destroyTower = function () { var towers = self.team === 'player' ? aiTowers : playerTowers; var index = towers.indexOf(self.target); if (index > -1) { towers.splice(index, 1); self.target.destroy(); LK.getSound('towerDestroyed').play(); self.target = null; } }; self.attackZombies = function () { // Find nearest zombie to target var nearestZombie = null; var nearestDistance = Infinity; for (var i = 0; i < zombies.length; i++) { var zombie = zombies[i]; var dx = zombie.x - self.x; var dy = zombie.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < nearestDistance) { nearestDistance = distance; nearestZombie = zombie; } } // Move toward and attack nearest zombie if (nearestZombie) { var dx = nearestZombie.x - self.x; var dy = nearestZombie.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); // Move toward zombie if not in attack range if (distance > self.attackRange) { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } else if (self.attackCooldown <= 0) { // Attack zombie based on unit type if (self.unitType === 'archer') { // Archer shoots arrow at zombie var arrow = new Arrow(self.team, self.x, self.y, nearestZombie.x, nearestZombie.y, self.damage); arrows.push(arrow); game.addChild(arrow); } else if (self.unitType === 'wizard') { // Wizard shoots magic at zombie var magic = new Magic(self.team, self.x, self.y, nearestZombie.x, nearestZombie.y, self.damage); magics.push(magic); game.addChild(magic); } else if (self.unitType === 'dragon') { // Change to attack asset for dragon zombie attacks self.removeChild(graphics); var assetName = 'DragonAttack'; graphics = self.attachAsset(assetName, { anchorX: 0.5, anchorY: 0.5 }); // Dragon shoots fire at zombie var fire = new Fire(self.team, self.x, self.y, nearestZombie.x, nearestZombie.y, self.damage); fires.push(fire); game.addChild(fire); } else { // Melee attack (warrior) nearestZombie.health -= self.damage; if (nearestZombie.health <= 0) { for (var j = 0; j < zombies.length; j++) { if (zombies[j] === nearestZombie) { zombies.splice(j, 1); nearestZombie.destroy(); break; } } } } self.attackCooldown = 60; // 1 second cooldown LK.getSound('attack').play(); } } }; self.combatNearbyEnemies = function () { if (self.attackCooldown <= 0) { var enemyUnits = self.team === 'player' ? aiUnits : playerUnits; var meleeRange = 60; // Close combat range for (var i = 0; i < enemyUnits.length; i++) { var enemy = enemyUnits[i]; // Skip workers in combat if (enemy.unitType === 'worker') { continue; } var dx = enemy.x - self.x; var dy = enemy.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); // If enemy unit is within melee range, attack it if (distance <= meleeRange) { enemy.health -= self.damage; self.attackCooldown = 60; // 1 second cooldown LK.getSound('attack').play(); // Check if enemy is destroyed if (enemy.health <= 0) { enemyUnits.splice(i, 1); enemy.destroy(); } break; // Only attack one enemy per cycle } } } }; return self; }); var Fire = Container.expand(function (team, startX, startY, targetX, targetY, damage) { var self = Container.call(this); var graphics = self.attachAsset('Magic', { anchorX: 0.5, anchorY: 0.5 }); self.team = team; self.damage = damage; self.speed = 4; self.target = null; // Calculate direction var dx = targetX - startX; var dy = targetY - startY; var distance = Math.sqrt(dx * dx + dy * dy); self.directionX = dx / distance; self.directionY = dy / distance; // Position fire at start self.x = startX; self.y = startY; // Add fire effect - orange/red tint and scaling graphics.tint = 0xff4500; // Orange-red fire color tween(graphics, { scaleX: 1.5, scaleY: 1.5 }, { duration: 200, easing: tween.easeOut }); self.update = function () { // Move fire self.x += self.directionX * self.speed; self.y += self.directionY * self.speed; // Add fire flicker rotation graphics.rotation += 0.15; // Check if fire is off screen if (self.x < -100 || self.x > 2148 || self.y < -100 || self.y > 2832) { self.destroy(); // Remove from fires array for (var i = fires.length - 1; i >= 0; i--) { if (fires[i] === self) { fires.splice(i, 1); break; } } } // Check collision with enemy units var enemyUnits = self.team === 'player' ? aiUnits : playerUnits; for (var i = 0; i < enemyUnits.length; i++) { var enemy = enemyUnits[i]; if (self.intersects(enemy)) { enemy.health -= self.damage; if (enemy.health <= 0) { enemyUnits.splice(i, 1); enemy.destroy(); } self.destroy(); // Remove from fires array for (var j = fires.length - 1; j >= 0; j--) { if (fires[j] === self) { fires.splice(j, 1); break; } } return; } } // Check collision with enemy towers var enemyTowers = self.team === 'player' ? aiTowers : playerTowers; for (var i = 0; i < enemyTowers.length; i++) { var tower = enemyTowers[i]; if (self.intersects(tower)) { tower.health -= self.damage; if (tower.health <= 0) { enemyTowers.splice(i, 1); tower.destroy(); LK.getSound('towerDestroyed').play(); } self.destroy(); // Remove from fires array for (var j = fires.length - 1; j >= 0; j--) { if (fires[j] === self) { fires.splice(j, 1); break; } } return; } } }; return self; }); var Magic = Container.expand(function (team, startX, startY, targetX, targetY, damage) { var self = Container.call(this); var graphics = self.attachAsset('Magic', { anchorX: 0.5, anchorY: 0.5 }); self.team = team; self.damage = damage; self.speed = 6; self.target = null; // Calculate direction var dx = targetX - startX; var dy = targetY - startY; var distance = Math.sqrt(dx * dx + dy * dy); self.directionX = dx / distance; self.directionY = dy / distance; // Position magic at start self.x = startX; self.y = startY; // Add magical glow effect tween(graphics, { tint: 0x9966ff }, { duration: 500, easing: tween.easeInOut }); tween(graphics, { scaleX: 1.2, scaleY: 1.2 }, { duration: 300, easing: tween.easeOut }); self.update = function () { // Move magic self.x += self.directionX * self.speed; self.y += self.directionY * self.speed; // Add sparkle rotation graphics.rotation += 0.1; // Check if magic is off screen if (self.x < -100 || self.x > 2148 || self.y < -100 || self.y > 2832) { self.destroy(); // Remove from magics array for (var i = magics.length - 1; i >= 0; i--) { if (magics[i] === self) { magics.splice(i, 1); break; } } } // Check collision with enemy units var enemyUnits = self.team === 'player' ? aiUnits : playerUnits; for (var i = 0; i < enemyUnits.length; i++) { var enemy = enemyUnits[i]; if (self.intersects(enemy)) { enemy.health -= self.damage; if (enemy.health <= 0) { enemyUnits.splice(i, 1); enemy.destroy(); } self.destroy(); // Remove from magics array for (var j = magics.length - 1; j >= 0; j--) { if (magics[j] === self) { magics.splice(j, 1); break; } } return; } } // Check collision with enemy towers var enemyTowers = self.team === 'player' ? aiTowers : playerTowers; for (var i = 0; i < enemyTowers.length; i++) { var tower = enemyTowers[i]; if (self.intersects(tower)) { tower.health -= self.damage; if (tower.health <= 0) { enemyTowers.splice(i, 1); tower.destroy(); LK.getSound('towerDestroyed').play(); } self.destroy(); // Remove from magics array for (var j = magics.length - 1; j >= 0; j--) { if (magics[j] === self) { magics.splice(j, 1); break; } } return; } } }; return self; }); var Tower = Container.expand(function (team) { var self = Container.call(this); var assetName = team === 'player' ? 'playerTower' : 'aiTower'; var graphics = self.attachAsset(assetName, { anchorX: 0.5, anchorY: 1.0 }); self.team = team; self.health = 500; self.maxHealth = 500; // Create health bar background (black) self.healthBarBg = LK.getAsset('blackBackground', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.08, scaleY: 0.625 }); self.healthBarBg.x = 0; self.healthBarBg.y = -262.5; self.healthBarBg.tint = 0x0000ff; self.addChild(self.healthBarBg); // Create health bar (green for player, red for AI) self.healthBar = LK.getAsset('blackBackground', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.08, scaleY: 0.625 }); self.healthBar.x = 0; self.healthBar.y = -262.5; self.healthBar.tint = team === 'player' ? 0x00ff00 : 0xff0000; self.addChild(self.healthBar); self.healthText = new Text2(self.health.toString(), { size: 42, fill: '#ffffff' }); self.healthText.anchor.set(0.5, 0.5); self.addChild(self.healthText); self.healthText.x = 0; self.healthText.y = -262.5; self.attackCooldown = 0; self.attackRange = 400; // Damage area outline removed as requested self.update = function () { if (self.attackCooldown > 0) { self.attackCooldown--; } self.attackNearbyEnemies(); self.healthText.setText(self.health.toString()); // Update health bar scale based on health percentage var healthPercentage = self.health / self.maxHealth; tween(self.healthBar, { scaleX: 2.08 * healthPercentage }, { duration: 200 }); }; self.attackNearbyEnemies = function () { if (self.attackCooldown <= 0) { var enemyUnits = self.team === 'player' ? aiUnits : playerUnits; var nearestEnemy = null; var nearestDistance = Infinity; // Find nearest enemy unit within attack range for (var i = 0; i < enemyUnits.length; i++) { var enemy = enemyUnits[i]; var dx = enemy.x - self.x; var dy = enemy.y - (self.y - 131.25); // Adjust for tower center position var distance = Math.sqrt(dx * dx + dy * dy); // Only consider units within the attack range if (distance <= self.attackRange && distance < nearestDistance) { nearestDistance = distance; nearestEnemy = enemy; } } // Attack only the nearest enemy if found if (nearestEnemy) { nearestEnemy.health -= 1; // Deal 1 damage as specified self.attackCooldown = 3; // 0.05 seconds at 60 FPS LK.getSound('attack').play(); if (nearestEnemy.health <= 0) { var index = enemyUnits.indexOf(nearestEnemy); if (index > -1) { self.destroyUnit(nearestEnemy, enemyUnits, index); } } } // In zombie mode, player towers also attack zombies (find nearest zombie) if (zombieMode && self.team === 'player') { var nearestZombie = null; var nearestZombieDistance = Infinity; for (var i = 0; i < zombies.length; i++) { var zombie = zombies[i]; var dx = zombie.x - self.x; var dy = zombie.y - (self.y - 131.25); var distance = Math.sqrt(dx * dx + dy * dy); if (distance <= self.attackRange && distance < nearestZombieDistance) { nearestZombieDistance = distance; nearestZombie = zombie; } } // Attack only the nearest zombie if found if (nearestZombie && !nearestEnemy) { // Only attack zombie if no enemy unit was attacked nearestZombie.health -= 1; self.attackCooldown = 3; LK.getSound('attack').play(); if (nearestZombie.health <= 0) { var index = zombies.indexOf(nearestZombie); if (index > -1) { zombies.splice(index, 1); nearestZombie.destroy(); } } } } } }; self.showDamageArea = function () { // No visual effects when towers attack }; self.destroyUnit = function (unit, unitsArray, index) { unitsArray.splice(index, 1); unit.destroy(); }; return self; }); var Worker = Container.expand(function (team) { var self = Container.call(this); var assetName = team === 'player' ? 'worker' : 'aiWorker'; var graphics = self.attachAsset(assetName, { anchorX: 0.5, anchorY: 0.5 }); self.team = team; self.speed = 4; self.target = null; self.collectRange = 40; self.health = 10; self.maxHealth = 10; // Create health bar background (black) self.healthBarBg = LK.getAsset('blackBackground', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 0.75 }); self.healthBarBg.x = 0; self.healthBarBg.y = -120; self.healthBarBg.tint = 0x000000; self.addChild(self.healthBarBg); // Create health bar (green for player, red for AI) self.healthBar = LK.getAsset('blackBackground', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 0.75 }); self.healthBar.x = 0; self.healthBar.y = -120; self.healthBar.tint = team === 'player' ? 0x00ff00 : 0xff0000; self.addChild(self.healthBar); self.healthText = new Text2(self.health.toString(), { size: 50, fill: '#ffffff' }); self.healthText.anchor.set(0.5, 0.5); self.addChild(self.healthText); self.healthText.x = 0; self.healthText.y = -120; self.update = function () { if (!self.target) { self.findNearestCoin(); } else { self.moveToTarget(); } // Workers can defend themselves self.defendSelf(); self.healthText.setText(self.health.toString()); // Update health bar scale based on health percentage var healthPercentage = self.health / self.maxHealth; tween(self.healthBar, { scaleX: 1.5 * healthPercentage }, { duration: 200 }); }; self.findNearestCoin = function () { var targetCoins = self.team === 'player' ? playerCoins_array : aiCoins_array; var teamWorkers = self.team === 'player' ? playerUnits : aiUnits; var availableCoins = []; // First, collect all untargeted coins for (var i = 0; i < targetCoins.length; i++) { var coin = targetCoins[i]; if (!coin.collected) { // Check if another worker is already targeting this coin var isTargeted = false; for (var j = 0; j < teamWorkers.length; j++) { var worker = teamWorkers[j]; if (worker.unitType === 'worker' && worker !== self && worker.target === coin) { isTargeted = true; break; } } if (!isTargeted) { availableCoins.push(coin); } } } // If no available coins, clear target if (availableCoins.length === 0) { self.target = null; return; } // Get worker index to create unique targeting preference var workerIndex = -1; for (var i = 0; i < teamWorkers.length; i++) { if (teamWorkers[i] === self && teamWorkers[i].unitType === 'worker') { workerIndex = i; break; } } // Use worker index to create different targeting preferences var targetCoin = null; if (workerIndex >= 0 && workerIndex < availableCoins.length) { // Each worker gets a different coin based on their index targetCoin = availableCoins[workerIndex]; } else { // If more workers than coins, use modulo to cycle through available coins var coinIndex = workerIndex % availableCoins.length; targetCoin = availableCoins[coinIndex]; } // If targeted approach fails, fall back to nearest coin if (!targetCoin) { var nearestCoin = null; var nearestDistance = Infinity; for (var i = 0; i < availableCoins.length; i++) { var coin = availableCoins[i]; var distance = Math.sqrt(Math.pow(coin.x - self.x, 2) + Math.pow(coin.y - self.y, 2)); if (distance < nearestDistance) { nearestDistance = distance; nearestCoin = coin; } } targetCoin = nearestCoin; } self.target = targetCoin; }; self.moveToTarget = function () { if (!self.target || self.target.collected) { self.target = null; 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 < self.collectRange) { self.collectCoin(); } else { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } }; self.collectCoin = function () { if (self.target && !self.target.collected) { self.target.collected = true; if (self.team === 'player') { playerCoins += self.target.value; } else { aiCoins += self.target.value; } LK.getSound('coinCollect').play(); self.target = null; } }; self.defendSelf = function () { var enemyUnits = self.team === 'player' ? aiUnits : playerUnits; var defenseRange = 50; for (var i = 0; i < enemyUnits.length; i++) { var enemy = enemyUnits[i]; // Workers only defend against other workers if (enemy.unitType === 'worker') { var dx = enemy.x - self.x; var dy = enemy.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance <= defenseRange) { enemy.health -= 5; // Workers do less damage LK.getSound('attack').play(); if (enemy.health <= 0) { enemyUnits.splice(i, 1); enemy.destroy(); } break; } } } }; return self; }); var Zombie = Container.expand(function (waveNumber) { var self = Container.call(this); var graphics = self.attachAsset('zombie', { anchorX: 0.5, anchorY: 0.5 }); // Stats increase with wave number var waveMultiplier = waveNumber || 1; self.speed = 1.5 + (waveMultiplier - 1) * 0.2; // Speed increases slightly each wave self.health = 30 + (waveMultiplier - 1) * 15; // Health increases by 15 each wave self.maxHealth = self.health; self.damage = 10 + (waveMultiplier - 1) * 5; // Damage increases by 5 each wave self.waveNumber = waveNumber; self.target = null; self.attackCooldown = 0; // Create health bar background (black) self.healthBarBg = LK.getAsset('blackBackground', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 0.75 }); self.healthBarBg.x = 0; self.healthBarBg.y = -120; self.healthBarBg.tint = 0x000000; self.addChild(self.healthBarBg); // Create health bar (red for zombies) self.healthBar = LK.getAsset('blackBackground', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 0.75 }); self.healthBar.x = 0; self.healthBar.y = -120; self.healthBar.tint = 0xff0000; self.addChild(self.healthBar); self.healthText = new Text2(self.health.toString(), { size: 50, fill: '#ffffff' }); self.healthText.anchor.set(0.5, 0.5); self.addChild(self.healthText); self.healthText.x = 0; self.healthText.y = -120; self.update = function () { if (self.attackCooldown > 0) { self.attackCooldown--; } if (!self.target) { self.findNearestPlayerTower(); } else { self.moveToTarget(); } // Attack nearby player units self.attackNearbyPlayerUnits(); self.healthText.setText(self.health.toString()); // Update health bar scale based on health percentage var healthPercentage = self.health / self.maxHealth; tween(self.healthBar, { scaleX: 1.5 * healthPercentage }, { duration: 200 }); }; self.findNearestPlayerTower = function () { // Target player tower if (playerTowers.length > 0) { self.target = playerTowers[0]; } }; self.moveToTarget = function () { if (!self.target) { 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 < 60) { self.attackTarget(); } else { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } }; self.attackTarget = function () { if (self.attackCooldown <= 0 && self.target) { self.target.health -= self.damage; self.attackCooldown = 60; LK.getSound('attack').play(); if (self.target.health <= 0) { // Tower destroyed var index = playerTowers.indexOf(self.target); if (index > -1) { playerTowers.splice(index, 1); self.target.destroy(); LK.getSound('towerDestroyed').play(); self.target = null; } } } }; self.attackNearbyPlayerUnits = function () { if (self.attackCooldown <= 0) { var meleeRange = 60; for (var i = 0; i < playerUnits.length; i++) { var unit = playerUnits[i]; var dx = unit.x - self.x; var dy = unit.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance <= meleeRange) { unit.health -= self.damage; self.attackCooldown = 60; LK.getSound('attack').play(); if (unit.health <= 0) { playerUnits.splice(i, 1); unit.destroy(); } break; } } } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x228B22 }); /**** * Game Code ****/ // Game state management var gameState = 'menu'; // 'menu' or 'playing' // Add menu background var menuBackground = LK.getAsset('menuBg', { anchorX: 0, anchorY: 0, x: 0, y: 0 }); game.addChild(menuBackground); // Create menu overlay var menuOverlay = new Container(); game.addChild(menuOverlay); // Add towers asset at the top of the menu var towersAsset = LK.getAsset('Towers', { anchorX: 0.5, anchorY: 0, scaleX: 4.0, scaleY: 4.0 }); towersAsset.x = 1024; towersAsset.y = 50; menuOverlay.addChild(towersAsset); // Add app banner at top of menu var appBanner = LK.getAsset('Appbanner', { anchorX: 0.5, anchorY: 0, x: 1024, y: 20 }); menuOverlay.addChild(appBanner); // Start button background var startButtonBg = LK.getAsset('blackBackground', { anchorX: 0.5, anchorY: 0.5, scaleX: 4.0, scaleY: 1.5 }); startButtonBg.x = 1024; startButtonBg.y = 1000; startButtonBg.tint = 0x228b22; menuOverlay.addChild(startButtonBg); // Start button image var startButton = LK.getAsset('StartGameButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 4.0, scaleY: 2.0 }); startButton.x = 1024; startButton.y = 1000; menuOverlay.addChild(startButton); // How to Play button var howToPlayButton = LK.getAsset('Howtoplay22', { anchorX: 0.5, anchorY: 0.5, scaleX: 4.0, scaleY: 4.0 }); howToPlayButton.x = 1024; howToPlayButton.y = 1615; // 1.3x higher (2100 - 485 = 1615) menuOverlay.addChild(howToPlayButton); // Play menu music when game starts LK.playMusic('Menusong'); // How to Play instructions overlay var howToPlayOverlay = new Container(); howToPlayOverlay.visible = false; game.addChild(howToPlayOverlay); // How to Play background var howToPlayBg = LK.getAsset('blackBackground', { anchorX: 0.5, anchorY: 0.5, scaleX: 18.0, scaleY: 24.0 }); howToPlayBg.x = 1024; howToPlayBg.y = 1366; howToPlayBg.tint = 0x000000; howToPlayBg.alpha = 0.9; howToPlayOverlay.addChild(howToPlayBg); // How to Play title var howToPlayTitle = new Text2('HOW TO PLAY', { size: 100, fill: '#ffffff' }); howToPlayTitle.anchor.set(0.5, 0.5); howToPlayTitle.x = 1024; howToPlayTitle.y = 400; howToPlayOverlay.addChild(howToPlayTitle); // How to Play instructions var instructionsText = new Text2('NORMAL MODE:\n• Collect gold coins with workers\n• Spend gold to recruit units\n• Press Attack to command units to advance\n• Destroy enemy tower to win\n\nUNIT TYPES & STATS:\n• Worker: 5 gold, 10 HP, 5 damage, collects coins\n• Warrior: 10 gold, 20 HP, 10 damage, melee combat\n• Archer: 15 gold, 30 HP, 20 damage, ranged arrows\n• Wizard: 20 gold, 40 HP, 30 damage, magic attacks\n• Dragon: 25 gold, 50 HP, 40 damage, fire breath\n\nTOWERS:\n• Player Tower: 500 HP, 5 damage per second, attacks nearest enemy\n• AI Tower: 500 HP, 5 damage per second, attacks nearest enemy\n• Attack range: 400 pixels\n\nZOMBIE MODE:\n• Survive endless zombie waves\n• Units automatically attack zombies first\n• Zombies spawn 30 seconds after start\n• Wave 1: 5 zombies (30 HP, 10 damage)\n• Each wave: +2 zombies, +15 HP, +5 damage\n• Defend your tower at all costs!', { size: 42, fill: '#ffffff' }); instructionsText.anchor.set(0.5, 0.5); instructionsText.x = 1024; instructionsText.y = 1300; howToPlayOverlay.addChild(instructionsText); // Back button var backButton = new Text2('BACK TO MENU', { size: 80, fill: '#ffff00' }); backButton.anchor.set(0.5, 0.5); backButton.x = 1024; backButton.y = 2100; howToPlayOverlay.addChild(backButton); // Mode selection overlay var modeSelectionOverlay = new Container(); modeSelectionOverlay.visible = false; game.addChild(modeSelectionOverlay); // Mode selection background var modeSelectionBg = LK.getAsset('blackBackground', { anchorX: 0.5, anchorY: 0.5, scaleX: 18.0, scaleY: 24.0 }); modeSelectionBg.x = 1024; modeSelectionBg.y = 1366; modeSelectionBg.tint = 0x000000; modeSelectionBg.alpha = 0.9; modeSelectionOverlay.addChild(modeSelectionBg); // Mode selection title var modeSelectionTitle = new Text2('SELECT MODE', { size: 100, fill: '#ffffff' }); modeSelectionTitle.anchor.set(0.5, 0.5); modeSelectionTitle.x = 1024; modeSelectionTitle.y = 600; modeSelectionOverlay.addChild(modeSelectionTitle); // Normal mode button var normalModeButton = LK.getAsset('Normalmode', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); normalModeButton.x = 1024; normalModeButton.y = 1000; modeSelectionOverlay.addChild(normalModeButton); // Zombie mode button in mode selection var zombieModeSelectButton = LK.getAsset('Zombiemode', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 }); zombieModeSelectButton.x = 1024; zombieModeSelectButton.y = 1400; modeSelectionOverlay.addChild(zombieModeSelectButton); // Back to menu button from mode selection var backToMenuButton = new Text2('BACK TO MENU', { size: 80, fill: '#ffff00' }); backToMenuButton.anchor.set(0.5, 0.5); backToMenuButton.x = 1024; backToMenuButton.y = 2000; modeSelectionOverlay.addChild(backToMenuButton); // Start button event handler - now shows mode selection startButton.down = function () { menuOverlay.visible = false; modeSelectionOverlay.visible = true; }; startButtonBg.down = function () { menuOverlay.visible = false; modeSelectionOverlay.visible = true; }; // Normal mode button event handler normalModeButton.down = function () { zombieMode = false; gameState = 'playing'; modeSelectionOverlay.visible = false; LK.stopMusic(); // Stop menu music when starting game initializeGame(); }; // Zombie mode button event handler in mode selection zombieModeSelectButton.down = function () { zombieMode = true; gameState = 'playing'; modeSelectionOverlay.visible = false; LK.stopMusic(); initializeGame(); }; // Back to menu button event handler backToMenuButton.down = function () { modeSelectionOverlay.visible = false; menuOverlay.visible = true; }; // How to Play button event handler howToPlayButton.down = function () { menuOverlay.visible = false; howToPlayOverlay.visible = true; }; // Back button event handler backButton.down = function () { howToPlayOverlay.visible = false; menuOverlay.visible = true; }; // Add game background (initially hidden) var background = LK.getAsset('background', { anchorX: 0, anchorY: 0, x: 0, y: 0 }); background.visible = false; game.addChild(background); var playerCoins = 0; var aiCoins = 0; var playerTowers = []; var aiTowers = []; var coins = []; var playerCoins_array = []; var aiCoins_array = []; var playerUnits = []; var aiUnits = []; var arrows = []; var magics = []; var fires = []; var coinSpawnTimer = 0; var aiActionTimer = 0; var zombies = []; var zombieSpawnTimer = 0; var zombieMode = false; var zombieWaveNumber = 1; var zombieWaveSpawnTimer = 0; var zombieWaveInProgress = false; var zombiesInCurrentWave = 0; var zombiesToSpawnInWave = 0; // UI Elements var coinDisplay = new Text2('Golds: 0', { size: 80, fill: '#ffff00' }); coinDisplay.anchor.set(0.5, 0.5); coinDisplay.x = 200; coinDisplay.y = -273.75; coinDisplay.visible = false; LK.gui.bottom.addChild(coinDisplay); // Attack button var attackButton = new Text2('Attack', { size: 80, fill: '#ff0000' }); attackButton.anchor.set(0.5, 0.5); attackButton.x = -200; attackButton.y = -273.75; attackButton.visible = false; LK.gui.bottom.addChild(attackButton); var workerButton = new Text2('5', { size: 32, fill: '#ffffff' }); workerButton.anchor.set(0.5, 0.5); workerButton.x = -400; workerButton.y = -45; var warriorButton = new Text2('10', { size: 32, fill: '#ffffff' }); warriorButton.anchor.set(0.5, 0.5); warriorButton.x = -200; warriorButton.y = -45; var wizardButton = new Text2('20', { size: 32, fill: '#ffffff' }); wizardButton.anchor.set(0.5, 0.5); wizardButton.x = 200; wizardButton.y = -45; var archerButton = new Text2('15', { size: 32, fill: '#ffffff' }); archerButton.anchor.set(0.5, 0.5); archerButton.x = 0; archerButton.y = -45; var dragonButton = new Text2('25', { size: 32, fill: '#ffffff' }); dragonButton.anchor.set(0.5, 0.5); dragonButton.x = 400; dragonButton.y = -45; // Add unified black background behind all recruitment buttons and unit images var unifiedBackground = LK.getAsset('blackBackground', { anchorX: 0.5, anchorY: 0.5, scaleX: 22.0, scaleY: 2.8 }); unifiedBackground.x = 0; unifiedBackground.y = -78; unifiedBackground.tint = 0x000000; unifiedBackground.alpha = 0.5; unifiedBackground.visible = false; LK.gui.bottom.addChild(unifiedBackground); // Add unit images above recruitment buttons var workerImage = LK.getAsset('worker', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.0, scaleY: 1.0 }); workerImage.x = -400; workerImage.y = -110; LK.gui.bottom.addChild(workerImage); var warriorImage = LK.getAsset('warrior', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.0, scaleY: 1.0 }); warriorImage.x = -200; warriorImage.y = -110; LK.gui.bottom.addChild(warriorImage); var wizardImage = LK.getAsset('wizard', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.0, scaleY: 1.0 }); wizardImage.x = 200; wizardImage.y = -110; LK.gui.bottom.addChild(wizardImage); var archerImage = LK.getAsset('archer', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.0, scaleY: 1.0 }); archerImage.x = 0; archerImage.y = -110; LK.gui.bottom.addChild(archerImage); var dragonImage = LK.getAsset('dragon', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.0, scaleY: 1.0 }); dragonImage.x = 400; dragonImage.y = -110; LK.gui.bottom.addChild(dragonImage); // Wave display for zombie mode var waveDisplay = new Text2('Wave: 1', { size: 80, fill: '#ff0000' }); waveDisplay.anchor.set(0.5, 0.5); waveDisplay.x = 0; waveDisplay.y = 100; waveDisplay.visible = false; LK.gui.top.addChild(waveDisplay); // Hide all UI elements initially (menu state) workerButton.visible = false; warriorButton.visible = false; wizardButton.visible = false; archerButton.visible = false; dragonButton.visible = false; workerImage.visible = false; warriorImage.visible = false; wizardImage.visible = false; archerImage.visible = false; dragonImage.visible = false; // Add texts after backgrounds so they appear on top LK.gui.bottom.addChild(workerButton); LK.gui.bottom.addChild(warriorButton); LK.gui.bottom.addChild(wizardButton); LK.gui.bottom.addChild(archerButton); LK.gui.bottom.addChild(dragonButton); // Initialize towers function initializeTowers() { // Player tower var playerTower = new Tower('player'); playerTower.x = 1024; playerTower.y = 2300; playerTowers.push(playerTower); game.addChild(playerTower); // AI tower (only in normal mode) if (!zombieMode) { var aiTower = new Tower('ai'); aiTower.x = 1024; aiTower.y = 400; aiTowers.push(aiTower); game.addChild(aiTower); } } ; function spawnCoin() { // Spawn player coin var playerCoin = new Coin(); playerCoin.x = Math.random() * 1800 + 124; playerCoin.y = Math.random() * 1000 + 1200; // Lower half for player playerCoins_array.push(playerCoin); coins.push(playerCoin); game.addChild(playerCoin); // Spawn AI coin var aiCoin = new Coin(); aiCoin.x = Math.random() * 1800 + 124; aiCoin.y = Math.random() * 1000 + 400; // Upper half for AI aiCoins_array.push(aiCoin); coins.push(aiCoin); game.addChild(aiCoin); } function spawnUnit(team, unitType) { var unit; var cost = unitType === 'worker' ? 5 : unitType === 'warrior' ? 10 : unitType === 'wizard' ? 20 : unitType === 'archer' ? 15 : 25; if (team === 'player' && playerCoins >= cost) { playerCoins -= cost; if (unitType === 'worker') { unit = new Worker('player'); } else { unit = new CombatUnit('player', unitType); } if (!zombieMode && unitType !== 'worker') { // Position combat units in front of tower in normal mode with better spacing var unitCount = playerUnits.length; var spreadRadius = 300; var angle = unitCount * 0.5 % (Math.PI * 2); unit.x = playerTowers[0].x + Math.cos(angle) * spreadRadius; unit.y = playerTowers[0].y - 507 + Math.sin(angle) * 100; } else { var unitCount = playerUnits.length; var spreadRadius = 200; var angle = unitCount * 0.8 % (Math.PI * 2); unit.x = playerTowers[0].x + Math.cos(angle) * spreadRadius; unit.y = playerTowers[0].y - 100 + Math.sin(angle) * 50; } playerUnits.push(unit); game.addChild(unit); LK.getSound('unitSpawn').play(); } else if (team === 'ai' && aiCoins >= cost) { aiCoins -= cost; if (unitType === 'worker') { unit = new Worker('ai'); } else { unit = new CombatUnit('ai', unitType); } var unitCount = aiUnits.length; var spreadRadius = 200; var angle = unitCount * 0.8 % (Math.PI * 2); unit.x = aiTowers[0].x + Math.cos(angle) * spreadRadius; unit.y = aiTowers[0].y + 100 + Math.sin(angle) * 50; aiUnits.push(unit); game.addChild(unit); } } function spawnZombie() { var zombie = new Zombie(zombieWaveNumber); zombie.x = Math.random() * 1800 + 124; // Random X position across screen width zombie.y = 50; // Spawn at top of screen zombies.push(zombie); game.addChild(zombie); } function startZombieWave() { zombieWaveInProgress = true; zombiesToSpawnInWave = 3 + zombieWaveNumber * 2; // Wave 1: 5 zombies, Wave 2: 7 zombies, etc. zombiesInCurrentWave = 0; zombieWaveSpawnTimer = 0; // Update wave display if (zombieMode) { waveDisplay.setText('Wave: ' + zombieWaveNumber); } } function checkWaveComplete() { // Check if all zombies in current wave are spawned and destroyed if (zombieWaveInProgress && zombiesInCurrentWave >= zombiesToSpawnInWave && zombies.length === 0) { zombieWaveInProgress = false; zombieWaveNumber++; // Start next wave after 10 seconds (doubled from 5 seconds) zombieWaveSpawnTimer = -600; // 10 seconds delay before next wave } } function aiLogic() { if (aiActionTimer <= 0) { if (aiCoins >= 25 && Math.random() < 0.1) { spawnUnit('ai', 'dragon'); } else if (aiCoins >= 15 && Math.random() < 0.15) { spawnUnit('ai', 'archer'); } else if (aiCoins >= 20 && Math.random() < 0.2) { spawnUnit('ai', 'wizard'); } else if (aiCoins >= 10 && Math.random() < 0.3) { spawnUnit('ai', 'warrior'); } else if (aiCoins >= 5 && Math.random() < 0.4) { spawnUnit('ai', 'worker'); } aiActionTimer = 120; } aiActionTimer--; } function checkGameEnd() { if (playerTowers.length === 0) { LK.showGameOver(); } else if (!zombieMode && aiTowers.length === 0) { LK.showYouWin(); } } function cleanupCollectedCoins() { // Clean up from main coins array for (var i = coins.length - 1; i >= 0; i--) { if (coins[i].collected) { coins[i].destroy(); coins.splice(i, 1); } } // Clean up from player coins array for (var i = playerCoins_array.length - 1; i >= 0; i--) { if (playerCoins_array[i].collected) { playerCoins_array.splice(i, 1); } } // Clean up from AI coins array for (var i = aiCoins_array.length - 1; i >= 0; i--) { if (aiCoins_array[i].collected) { aiCoins_array.splice(i, 1); } } } // Button event handlers workerButton.down = function () { spawnUnit('player', 'worker'); }; warriorButton.down = function () { spawnUnit('player', 'warrior'); }; wizardButton.down = function () { spawnUnit('player', 'wizard'); }; archerButton.down = function () { spawnUnit('player', 'archer'); }; dragonButton.down = function () { spawnUnit('player', 'dragon'); }; // Character image event handlers workerImage.down = function () { spawnUnit('player', 'worker'); }; warriorImage.down = function () { spawnUnit('player', 'warrior'); }; wizardImage.down = function () { spawnUnit('player', 'wizard'); }; archerImage.down = function () { spawnUnit('player', 'archer'); }; dragonImage.down = function () { spawnUnit('player', 'dragon'); }; // Attack button event handler attackButton.down = function () { if (!zombieMode) { // Make all waiting player units start attacking for (var i = 0; i < playerUnits.length; i++) { var unit = playerUnits[i]; if (unit.unitType !== 'worker') { unit.isWaiting = false; } } } }; // Initialize game function function initializeGame() { background.visible = true; // Show UI elements when game starts coinDisplay.visible = true; unifiedBackground.visible = true; workerButton.visible = true; warriorButton.visible = true; wizardButton.visible = true; archerButton.visible = true; dragonButton.visible = true; workerImage.visible = true; warriorImage.visible = true; wizardImage.visible = true; archerImage.visible = true; dragonImage.visible = true; // Show attack button only in normal mode if (!zombieMode) { attackButton.visible = true; } else { // Show wave display in zombie mode waveDisplay.visible = true; waveDisplay.setText('Wave: ' + zombieWaveNumber); } // Reset zombie wave system zombieWaveNumber = 1; zombieWaveSpawnTimer = -1800; // 30 second delay (30 * 60 FPS = 1800 frames) zombieWaveInProgress = false; zombiesInCurrentWave = 0; zombiesToSpawnInWave = 0; // Play game music when match starts LK.playMusic('Song'); initializeTowers(); // Spawn initial workers for both teams var playerWorker = new Worker('player'); playerWorker.x = playerTowers[0].x + 50; playerWorker.y = playerTowers[0].y - 100; playerUnits.push(playerWorker); game.addChild(playerWorker); // AI worker (only in normal mode) if (!zombieMode) { var aiWorker = new Worker('ai'); aiWorker.x = aiTowers[0].x + 50; aiWorker.y = aiTowers[0].y + 100; aiUnits.push(aiWorker); game.addChild(aiWorker); } } // Main game loop game.update = function () { if (gameState === 'playing') { // Update coin display coinDisplay.setText('Golds: ' + playerCoins); // Spawn coins coinSpawnTimer++; if (coinSpawnTimer >= 36) { // 5x more frequent (180/5 = 36) spawnCoin(); coinSpawnTimer = 0; } // AI logic (only in normal mode) if (!zombieMode) { aiLogic(); } // Clean up collected coins cleanupCollectedCoins(); // Zombie mode logic if (zombieMode) { zombieWaveSpawnTimer++; // Start first wave or next wave after delay if (!zombieWaveInProgress && zombieWaveSpawnTimer >= 0) { startZombieWave(); } // Spawn zombies in current wave if (zombieWaveInProgress && zombiesInCurrentWave < zombiesToSpawnInWave) { if (zombieWaveSpawnTimer % 60 === 0) { // Spawn one zombie every second during wave spawnZombie(); zombiesInCurrentWave++; } } // Check if current wave is complete checkWaveComplete(); // Clean up off-screen zombies for (var i = zombies.length - 1; i >= 0; i--) { if (zombies[i].y > 2800) { zombies[i].destroy(); zombies.splice(i, 1); } } } // Check game end conditions checkGameEnd(); } };
===================================================================
--- original.js
+++ change.js
@@ -1108,9 +1108,9 @@
howToPlayTitle.x = 1024;
howToPlayTitle.y = 400;
howToPlayOverlay.addChild(howToPlayTitle);
// How to Play instructions
-var instructionsText = new Text2('NORMAL MODE:\n• Collect gold coins with workers\n• Spend gold to recruit units\n• Press Attack to command units to advance\n• Destroy enemy tower to win\n\nUNIT TYPES & STATS:\n• Worker: 5 gold, 10 HP, 5 damage, collects coins\n• Warrior: 10 gold, 20 HP, 10 damage, melee combat\n• Archer: 15 gold, 30 HP, 20 damage, ranged arrows\n• Wizard: 20 gold, 40 HP, 30 damage, magic attacks\n• Dragon: 25 gold, 50 HP, 40 damage, fire breath\n\nTOWERS:\n• Player Tower: 500 HP, 1 damage per second, attacks nearest enemy\n• AI Tower: 500 HP, 1 damage per second, attacks nearest enemy\n• Attack range: 400 pixels\n\nZOMBIE MODE:\n• Survive endless zombie waves\n• Units automatically attack zombies first\n• Zombies spawn 30 seconds after start\n• Wave 1: 5 zombies (30 HP, 10 damage)\n• Each wave: +2 zombies, +15 HP, +5 damage\n• Defend your tower at all costs!', {
+var instructionsText = new Text2('NORMAL MODE:\n• Collect gold coins with workers\n• Spend gold to recruit units\n• Press Attack to command units to advance\n• Destroy enemy tower to win\n\nUNIT TYPES & STATS:\n• Worker: 5 gold, 10 HP, 5 damage, collects coins\n• Warrior: 10 gold, 20 HP, 10 damage, melee combat\n• Archer: 15 gold, 30 HP, 20 damage, ranged arrows\n• Wizard: 20 gold, 40 HP, 30 damage, magic attacks\n• Dragon: 25 gold, 50 HP, 40 damage, fire breath\n\nTOWERS:\n• Player Tower: 500 HP, 5 damage per second, attacks nearest enemy\n• AI Tower: 500 HP, 5 damage per second, attacks nearest enemy\n• Attack range: 400 pixels\n\nZOMBIE MODE:\n• Survive endless zombie waves\n• Units automatically attack zombies first\n• Zombies spawn 30 seconds after start\n• Wave 1: 5 zombies (30 HP, 10 damage)\n• Each wave: +2 zombies, +15 HP, +5 damage\n• Defend your tower at all costs!', {
size: 42,
fill: '#ffffff'
});
instructionsText.anchor.set(0.5, 0.5);
Worker. In-Game asset. 2d. High contrast. No shadows
Wizard. In-Game asset. 2d. High contrast. No shadows
Dragon. In-Game asset. 2d. High contrast. No shadows
Warrior. In-Game asset. 2d. High contrast. No shadows
etrafı kırmızı işçi. In-Game asset. 2d. High contrast. No shadows
Archer. In-Game asset. 2d. High contrast. No shadows
Magic. In-Game asset. 2d. High contrast. No shadows
Sadece 1 Altın parçacığı. In-Game asset. 2d. High contrast. No shadows
Köşelerdeki taş yerleri kaldır
Çözünürlüğü artır ve kırmızı şeyleri kaldır. In-Game asset. 2d. High contrast. No shadows
Ağzından ateş püskürtsün
Tam yukarıdan bakılan bir kule clash royaledeki gibi. In-Game asset. 2d. High contrast. No shadows
Mavi yerler kırmızı olsun
Sol tarafında kılıçlar olan start buton. In-Game asset. 2d. High contrast. No shadows
How to play button. In-Game asset. 2d. High contrast. No shadows
Tower defence menü background. In-Game asset. 2d. High contrast. No shadows
Towers On Attack yazısı. In-Game asset. 2d. High contrast. No shadows
Zombie. In-Game asset. 2d. High contrast. No shadows
Normal Mode button. In-Game asset. 2d. High contrast. No shadows
Zombie Mode buton. In-Game asset. 2d. High contrast. No shadows