User prompt
Sabit bir yönde ilerlemesin, düşük sayıda olan birimler önlerinde ki diğer birliklerin kenarından geçebilsinler.
User prompt
Hızlı olan birimler, önlerine çıkan birimlerin etrafını dolaşsın ve önüne geçsin.
User prompt
Daha az askerler daha hızlı, daha çok askerler daha yavaş hareket etsin.
User prompt
Birim sayısı, birimlerin üst kısmında ilerlesin. birim sayısı satır satır ilerlemesin.
User prompt
birim sayısı, birimler ile hareket etsin. atlıyor gibi görünmesin. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'length')' in or related to this line: 'currentPath = null;' Line Number: 936
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'length')' in or related to this line: 'for (var i = 0; i < movingUnitGroups.length; i++) {' Line Number: 938
User prompt
Hareket eden birimlerin üst kısmında, kaç adet birim var ise, kule birim sayısının boyutunda yazsın.
User prompt
Birimlerin hareket hızını %50 oranında yavaşlat.
User prompt
Fulloyun arkaplan resmi oluştur.
User prompt
Kulede ki birim sayısı, Kule resminin üst satırına denk gelsin. Ayrıca boyutunu %50 küçült.
User prompt
sorunu düzelt.
User prompt
Her düşmana ve diğer kule birimine özel resim dosyası oluştur.
User prompt
Hiç bir yapay zeka 100 olarak birim olmasın, 100'e yaklaşınca harekete geçsin
User prompt
Reset yapınca baştan başlasın, game over olunca aynı seviyeden başlasın.
User prompt
Please fix the bug: 'Error: Error: Invalid color format. Expected 0xRRGGBB format, received: undefined' in or related to this line: 'tween(towerGraphics, {' Line Number: 140 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please fix the bug: 'Error: Error: Invalid color format. Expected 0xRRGGBB format, received: undefined' in or related to this line: 'tween(towerGraphics, {' Line Number: 138 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'tween(tower.children[i], {' Line Number: 354 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'tween(tower.children[i], {' Line Number: 353 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'tween(tower.children[i], {' Line Number: 353 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Sahip olduğumuz kulenin üzerine tıklayınca; Kule Türleri ve özelleştirme seçebildiğimiz bir açılır pencere ekle. **Özel Kule Tipleri**: - **Savunma Kulesi**: Daha dayanıklı, saldırılara karşı dirençli. - **Hızlı Üretim Kulesi**: Birim üretimi daha hızlı ama savunması zayıf. - **Güçlü Saldırı Kulesi**: Gönderdiği birimler daha güçlü ama üretimi yavaş. - **Ekonomi Kulesi**: Kaynak üretimi yapan, savaşmayan özel kule. Seçilen özel kule tipi, kaybedilene kadar bir daha değiştirilmesin. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Game over olunca, kaldığı seviye yeniden başlasın.
User prompt
panel içinde ki Sıralama; Birim sayısına göre anlık olarak alt alta hizalansın.
User prompt
Panelde, ''Rakip'' yerine, rakibin ismi yazsın. Ayrıca ''0'' olan rakibin üstü çizilsin. ayrıca birim sayısına göre sıralansın.
User prompt
Ekranın sol altına, oyuncu ve rakiplerin toplam birim sayıları yazan bir panel oluştur.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var PathLine = Container.expand(function () { var self = Container.call(this); self.points = []; self.graphics = []; self.setPath = function (points) { // Clear old graphics for (var i = 0; i < self.graphics.length; i++) { self.graphics[i].destroy(); } self.graphics = []; self.points = points; // Draw new path for (var i = 0; i < points.length - 1; i++) { var dist = Math.sqrt(Math.pow(points[i + 1].x - points[i].x, 2) + Math.pow(points[i + 1].y - points[i].y, 2)); var segments = Math.floor(dist / 20); for (var j = 0; j < segments; j++) { var t = j / segments; var dot; if (memoryManager.pathDotPool.length > 0) { dot = memoryManager.pathDotPool.pop(); dot.visible = true; dot.alpha = 0.5; self.addChild(dot); } else { dot = self.attachAsset('path', { anchorX: 0.5, anchorY: 0.5 }); } dot.x = points[i].x + (points[i + 1].x - points[i].x) * t; dot.y = points[i].y + (points[i + 1].y - points[i].y) * t; dot.alpha = 0.5; self.graphics.push(dot); } } }; self.clear = function () { for (var i = 0; i < self.graphics.length; i++) { var dot = self.graphics[i]; if (dot && dot.parent) { dot.parent.removeChild(dot); dot.visible = false; memoryManager.pathDotPool.push(dot); } } self.graphics = []; self.points = []; }; return self; }); var Tower = Container.expand(function () { var self = Container.call(this); self.owner = 0; // 0 = neutral, 1 = player, 2 = enemy self.unitCount = 0; self.maxUnits = 100; self.spawnRate = 30; // ticks between spawns self.lastSpawn = 0; var towerGraphics = self.attachAsset('tower', { anchorX: 0.5, anchorY: 0.5 }); self.countText = new Text2('0', { size: 60, fill: 0xFFFFFF }); self.countText.anchor.set(0.5, 0.5); self.addChild(self.countText); // Enemy name text (positioned below tower) self.nameText = new Text2('', { size: 40, fill: 0xFFFFFF }); self.nameText.anchor.set(0.5, 0); self.nameText.y = 90; // Position below the tower self.addChild(self.nameText); self.setOwner = function (newOwner) { var oldOwner = self.owner; self.owner = newOwner; var targetColor; if (newOwner === 0) { targetColor = 0x888888; // neutral gray } else if (newOwner === 1) { targetColor = 0x4a90e2; // player blue } else if (newOwner === 2) { targetColor = 0xe74c3c; // enemy red } else if (newOwner === 3) { targetColor = 0x9b59b6; // enemy purple } else if (newOwner === 4) { targetColor = 0xf39c12; // enemy orange } else { targetColor = 0xe74c3c; // default enemy red } // Update name display if (newOwner >= 2) { // Enemy tower - show name var enemyName = assignEnemyName(newOwner); self.nameText.setText(enemyName); self.nameText.alpha = 1; } else if (newOwner === 1) { // Player tower - show "Player" self.nameText.setText('Player'); self.nameText.alpha = 1; } else { // Neutral tower - hide name self.nameText.setText(''); self.nameText.alpha = 0; } // Only animate if ownership actually changed if (oldOwner !== newOwner) { // Smooth color transition over 500ms tween(towerGraphics, { tint: targetColor }, { duration: 500, easing: tween.easeInOut }); } else { // Immediate color change if no ownership change towerGraphics.tint = targetColor; } }; self.addUnits = function (count) { self.unitCount = Math.min(self.unitCount + count, self.maxUnits); self.countText.setText(Math.floor(self.unitCount)); }; self.removeUnits = function (count) { self.unitCount = Math.max(0, self.unitCount - count); self.countText.setText(Math.floor(self.unitCount)); return count; }; self.update = function () { if (self.owner > 0) { // Calculate dynamic spawn rate based on unit count // More units = faster production (lower spawn rate number) // Base rate is 30, reduced by unit count factor var dynamicSpawnRate = Math.max(10, self.spawnRate - Math.floor(self.unitCount / 10)); if (LK.ticks - self.lastSpawn > dynamicSpawnRate) { self.addUnits(1); self.lastSpawn = LK.ticks; } } }; return self; }); var Unit = Container.expand(function () { var self = Container.call(this); self.owner = 1; self.speed = 3; self.targetTower = null; self.pathIndex = 0; self.path = []; var unitGraphics = self.attachAsset('unit', { anchorX: 0.5, anchorY: 0.5 }); self.setOwner = function (owner) { self.owner = owner; if (owner === 1) { unitGraphics.tint = 0x4a90e2; // player blue } else if (owner === 2) { unitGraphics.tint = 0xe74c3c; // enemy red } else if (owner === 3) { unitGraphics.tint = 0x9b59b6; // enemy purple } else if (owner === 4) { unitGraphics.tint = 0xf39c12; // enemy orange } else { unitGraphics.tint = 0xe74c3c; // default enemy red } }; self.setPath = function (path, target) { // Add random offset to create scattered movement var scatterRange = 40; // Maximum scatter distance var offsetX = (Math.random() - 0.5) * scatterRange; var offsetY = (Math.random() - 0.5) * scatterRange; // Create scattered path by adding random offsets to each point self.path = []; for (var i = 0; i < path.length; i++) { // Apply consistent offset throughout the path, but reduce it near the end var offsetFactor = Math.max(0.2, 1 - i / path.length * 0.8); self.path.push({ x: path[i].x + offsetX * offsetFactor, y: path[i].y + offsetY * offsetFactor }); } self.targetTower = target; self.pathIndex = 0; if (self.path.length > 0) { self.x = self.path[0].x; self.y = self.path[0].y; } }; self.lastWasIntersecting = false; self.update = function () { if (!self.targetTower || self.pathIndex >= self.path.length) { return; } // Check for combat with enemy units var currentIntersecting = false; for (var i = 0; i < units.length; i++) { var otherUnit = units[i]; if (otherUnit !== self && otherUnit.owner !== self.owner) { // Check if units are close enough to fight (within 30 pixels) var combatDx = self.x - otherUnit.x; var combatDy = self.y - otherUnit.y; var combatDist = Math.sqrt(combatDx * combatDx + combatDy * combatDy); if (combatDist < 30) { currentIntersecting = true; // Combat occurs - both units destroy each other if (!self.lastWasIntersecting) { // Create combat sparkle effects at the battle location var battleX = (self.x + otherUnit.x) / 2; var battleY = (self.y + otherUnit.y) / 2; // Create multiple sparkle particles for (var sparkleIndex = 0; sparkleIndex < 8; sparkleIndex++) { var sparkle = memoryManager.getSparkle(); game.addChild(sparkle); sparkle.x = battleX + (Math.random() - 0.5) * 40; sparkle.y = battleY + (Math.random() - 0.5) * 40; sparkle.alpha = 1; sparkle.scaleX = 0.5 + Math.random() * 0.5; sparkle.scaleY = sparkle.scaleX; sparkle.tint = 0xffff00 + Math.floor(Math.random() * 0x444444); // Animate sparkles flying outward and fading var randomAngle = Math.random() * Math.PI * 2; var flyDistance = 50 + Math.random() * 30; var targetX = sparkle.x + Math.cos(randomAngle) * flyDistance; var targetY = sparkle.y + Math.sin(randomAngle) * flyDistance; tween(sparkle, { x: targetX, y: targetY, alpha: 0, scaleX: 0, scaleY: 0 }, { duration: 300 + Math.random() * 200, easing: tween.easeOut, onFinish: function onFinish() { if (sparkle && sparkle.parent) { memoryManager.recycleSparkle(sparkle); } } }); } // Flash both units red before destroying LK.effects.flashObject(self, 0xff0000, 200); LK.effects.flashObject(otherUnit, 0xff0000, 200); LK.getSound('combat').play(); // Destroy both units after flash LK.setTimeout(function () { if (self && self.parent) { memoryManager.recycleUnit(self); var selfIndex = units.indexOf(self); if (selfIndex !== -1) { units.splice(selfIndex, 1); } } if (otherUnit && otherUnit.parent) { memoryManager.recycleUnit(otherUnit); var otherIndex = units.indexOf(otherUnit); if (otherIndex !== -1) { units.splice(otherIndex, 1); } } }, 200); return; } } } } self.lastWasIntersecting = currentIntersecting; var target = self.path[self.pathIndex]; var dx = target.x - self.x; var dy = target.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < self.speed) { self.pathIndex++; if (self.pathIndex >= self.path.length && self.targetTower) { // Reached target tower if (self.targetTower.owner === self.owner) { self.targetTower.addUnits(1); } else { self.targetTower.unitCount--; if (self.targetTower.unitCount < 0) { self.targetTower.unitCount = 1; self.targetTower.setOwner(self.owner); LK.getSound('capture').play(); } self.targetTower.countText.setText(Math.floor(Math.abs(self.targetTower.unitCount))); } memoryManager.recycleUnit(self); units.splice(units.indexOf(self), 1); } } else { // Add slight random movement variation for scattered appearance var moveX = dx / dist * self.speed; var moveY = dy / dist * self.speed; // Add small random deviation (5% of movement speed) var deviation = self.speed * 0.05; moveX += (Math.random() - 0.5) * deviation; moveY += (Math.random() - 0.5) * deviation; self.x += moveX; self.y += moveY; } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1a1a1a }); /**** * Game Code ****/ var towers = []; var units = []; var currentPath = null; var selectedTower = null; var isDragging = false; var currentLevel = storage.currentLevel || 0; var aiStartTime = null; // Track when AI should start (null = not started yet) // Enemy names for different factions var enemyNames = ["Karabekir", "Enver", "Talat", "Cemal", "İsmet", "Fevzi", "Kazım", "Refet", "Ali Fuat", "Rauf", "Bekir Sami", "Adnan", "Kâzım Özalp", "Salih", "Nureddin"]; var assignedEnemyNames = {}; // Track names assigned to each enemy faction // Level configurations - 10 levels with progressive difficulty (scaled up 100%) var levels = [{ // Level 1 - Tutorial towers: [{ x: 300, y: 1366, owner: 1, units: 30 }, { x: 1024, y: 800, owner: 0, units: 10 }, { x: 1748, y: 1366, owner: 2, units: 20 }, { x: 1748, y: 400, owner: 3, units: 15 }] }, { // Level 2 - Basic Strategy towers: [{ x: 300, y: 400, owner: 1, units: 35 }, { x: 1024, y: 1366, owner: 0, units: 15 }, { x: 1748, y: 400, owner: 2, units: 25 }, { x: 1748, y: 2332, owner: 3, units: 25 }, { x: 300, y: 2332, owner: 4, units: 20 }] }, { // Level 3 - Multi-Front towers: [{ x: 300, y: 1366, owner: 1, units: 45 }, { x: 700, y: 800, owner: 0, units: 15 }, { x: 1348, y: 800, owner: 0, units: 15 }, { x: 700, y: 1932, owner: 0, units: 15 }, { x: 1348, y: 1932, owner: 0, units: 15 }, { x: 1748, y: 400, owner: 2, units: 30 }, { x: 1748, y: 1366, owner: 3, units: 30 }, { x: 1748, y: 2332, owner: 4, units: 30 }] }, { // Level 4 - Defensive Challenge towers: [{ x: 300, y: 1366, owner: 1, units: 50 }, { x: 600, y: 600, owner: 0, units: 20 }, { x: 1024, y: 400, owner: 2, units: 40 }, { x: 1448, y: 600, owner: 0, units: 20 }, { x: 1748, y: 1366, owner: 2, units: 40 }, { x: 1024, y: 2100, owner: 2, units: 40 }] }, { // Level 5 - Resource Management towers: [{ x: 200, y: 800, owner: 1, units: 55 }, { x: 200, y: 1932, owner: 1, units: 55 }, { x: 700, y: 1366, owner: 0, units: 25 }, { x: 1348, y: 1366, owner: 0, units: 25 }, { x: 1748, y: 600, owner: 2, units: 45 }, { x: 1748, y: 1366, owner: 2, units: 45 }, { x: 1748, y: 2132, owner: 2, units: 45 }] }, { // Level 6 - Territory Control towers: [{ x: 300, y: 400, owner: 1, units: 60 }, { x: 300, y: 2332, owner: 1, units: 60 }, { x: 600, y: 800, owner: 0, units: 30 }, { x: 1024, y: 1366, owner: 0, units: 30 }, { x: 1448, y: 1932, owner: 0, units: 30 }, { x: 1748, y: 800, owner: 2, units: 50 }, { x: 1748, y: 1500, owner: 2, units: 50 }, { x: 1748, y: 2200, owner: 2, units: 50 }] }, { // Level 7 - Advanced Tactics towers: [{ x: 200, y: 1366, owner: 1, units: 65 }, { x: 500, y: 600, owner: 0, units: 35 }, { x: 500, y: 1366, owner: 0, units: 35 }, { x: 500, y: 2132, owner: 0, units: 35 }, { x: 1024, y: 400, owner: 0, units: 35 }, { x: 1024, y: 2332, owner: 0, units: 35 }, { x: 1548, y: 600, owner: 0, units: 35 }, { x: 1548, y: 1366, owner: 0, units: 35 }, { x: 1548, y: 2132, owner: 0, units: 35 }, { x: 1848, y: 1366, owner: 2, units: 55 }] }, { // Level 8 - Siege Warfare towers: [{ x: 300, y: 600, owner: 1, units: 70 }, { x: 300, y: 1366, owner: 1, units: 70 }, { x: 300, y: 2132, owner: 1, units: 70 }, { x: 800, y: 800, owner: 0, units: 40 }, { x: 800, y: 1932, owner: 0, units: 40 }, { x: 1248, y: 800, owner: 0, units: 40 }, { x: 1248, y: 1932, owner: 0, units: 40 }, { x: 1650, y: 400, owner: 2, units: 60 }, { x: 1650, y: 1366, owner: 2, units: 60 }, { x: 1650, y: 2332, owner: 2, units: 60 }] }, { // Level 9 - Final Challenge towers: [{ x: 200, y: 800, owner: 1, units: 75 }, { x: 200, y: 1932, owner: 1, units: 75 }, { x: 600, y: 400, owner: 0, units: 45 }, { x: 600, y: 1366, owner: 0, units: 45 }, { x: 600, y: 2332, owner: 0, units: 45 }, { x: 1024, y: 600, owner: 0, units: 45 }, { x: 1024, y: 2132, owner: 0, units: 45 }, { x: 1448, y: 400, owner: 0, units: 45 }, { x: 1448, y: 1366, owner: 0, units: 45 }, { x: 1448, y: 2332, owner: 0, units: 45 }, { x: 1748, y: 600, owner: 2, units: 65 }, { x: 1748, y: 1366, owner: 2, units: 65 }, { x: 1748, y: 2132, owner: 2, units: 65 }] }, { // Level 10 - Master's Trial towers: [{ x: 150, y: 1366, owner: 1, units: 80 }, { x: 400, y: 600, owner: 0, units: 50 }, { x: 400, y: 1100, owner: 0, units: 50 }, { x: 400, y: 1632, owner: 0, units: 50 }, { x: 400, y: 2132, owner: 0, units: 50 }, { x: 800, y: 400, owner: 0, units: 50 }, { x: 800, y: 800, owner: 0, units: 50 }, { x: 800, y: 1932, owner: 0, units: 50 }, { x: 800, y: 2332, owner: 0, units: 50 }, { x: 1248, y: 400, owner: 0, units: 50 }, { x: 1248, y: 800, owner: 0, units: 50 }, { x: 1248, y: 1932, owner: 0, units: 50 }, { x: 1248, y: 2332, owner: 0, units: 50 }, { x: 1648, y: 600, owner: 0, units: 50 }, { x: 1648, y: 1100, owner: 0, units: 50 }, { x: 1648, y: 1632, owner: 0, units: 50 }, { x: 1648, y: 2132, owner: 0, units: 50 }, { x: 1898, y: 1366, owner: 2, units: 70 }] }]; // UI Elements var levelText = new Text2('Level ' + (currentLevel + 1), { size: 80, fill: 0xFFFFFF }); levelText.anchor.set(0.5, 0); LK.gui.top.addChild(levelText); function assignEnemyName(owner) { if (!assignedEnemyNames[owner] && owner >= 2) { // Get available names (not already assigned) var availableNames = enemyNames.filter(function (name) { return !Object.values(assignedEnemyNames).includes(name); }); // If no available names, reuse from the pool if (availableNames.length === 0) { availableNames = enemyNames; } // Assign random name var randomIndex = Math.floor(Math.random() * availableNames.length); assignedEnemyNames[owner] = availableNames[randomIndex]; } return assignedEnemyNames[owner] || ""; } function loadLevel(levelIndex) { // Clear existing game objects for (var i = 0; i < towers.length; i++) { towers[i].destroy(); } for (var i = 0; i < units.length; i++) { units[i].destroy(); } towers = []; units = []; if (currentPath) { currentPath.destroy(); currentPath = null; } // Reset game state variables selectedTower = null; isDragging = false; // Reset enemy name assignments assignedEnemyNames = {}; // Load new level var levelData = levels[levelIndex % levels.length]; for (var i = 0; i < levelData.towers.length; i++) { var towerData = levelData.towers[i]; var tower = new Tower(); tower.x = towerData.x; tower.y = towerData.y; tower.setOwner(towerData.owner); tower.addUnits(towerData.units); towers.push(tower); game.addChild(tower); } levelText.setText('Level ' + (levelIndex + 1)); // Set AI to start after 5 seconds (5000ms) aiStartTime = LK.ticks + 5 * 60; // 5 seconds at 60 FPS } function createPath(start, end) { var points = []; var steps = 20; for (var i = 0; i <= steps; i++) { points.push({ x: start.x + (end.x - start.x) * (i / steps), y: start.y + (end.y - start.y) * (i / steps) }); } return points; } function sendUnits(fromTower, toTower, count) { var path = createPath(fromTower, toTower); var unitsToSend = Math.min(count, fromTower.unitCount); for (var i = 0; i < unitsToSend; i++) { var unit = memoryManager.getUnit(); unit.setOwner(fromTower.owner); unit.setPath(path, toTower); units.push(unit); game.addChild(unit); // Add random spawn delay and position offset for scattered deployment var randomDelay = i * (30 + Math.random() * 40); // Random delay between 30-70ms per unit var spawnOffsetX = (Math.random() - 0.5) * 60; // Random spawn position offset var spawnOffsetY = (Math.random() - 0.5) * 60; // Position unit at spawn location with offset unit.x = fromTower.x + spawnOffsetX; unit.y = fromTower.y + spawnOffsetY; // Stagger unit spawning with random timing tween(unit, { x: path[0].x, y: path[0].y }, { duration: randomDelay, onFinish: function onFinish() { LK.getSound('deploy').play(); } }); } fromTower.removeUnits(unitsToSend); } function checkWinCondition() { var playerTowers = 0; var enemyTowers = 0; for (var i = 0; i < towers.length; i++) { if (towers[i].owner === 1) playerTowers++; if (towers[i].owner >= 2) enemyTowers++; } if (enemyTowers === 0) { // Win condition - player defeated all enemy factions currentLevel++; storage.currentLevel = currentLevel; LK.showYouWin(); } else if (playerTowers === 0) { // Lose condition - reset everything to start from beginning currentLevel = 0; storage.currentLevel = 0; LK.showGameOver(); } } // Multi-faction AI with sophisticated strategies function runAI() { // Don't run AI until 5 seconds have passed if (aiStartTime && LK.ticks < aiStartTime) { return; } // Analyze game state for strategic decisions var gameState = analyzeGameState(); for (var i = 0; i < towers.length; i++) { var tower = towers[i]; if (tower.owner >= 2) { // Get strategic context for this tower var strategy = getOptimalStrategy(tower, gameState); executeStrategy(tower, strategy, gameState); } } } // Analyze current game state for AI decision making function analyzeGameState() { var state = { playerStrength: 0, enemyStrength: 0, neutralTowers: 0, playerTowers: [], enemyTowers: [], neutralTowersByDistance: [], threats: [], opportunities: [] }; // Calculate faction strengths and positions for (var i = 0; i < towers.length; i++) { var tower = towers[i]; if (tower.owner === 1) { state.playerStrength += tower.unitCount; state.playerTowers.push(tower); } else if (tower.owner >= 2) { state.enemyStrength += tower.unitCount; state.enemyTowers.push(tower); } else { state.neutralTowers++; } } // Find strategic opportunities and threats for each enemy tower for (var i = 0; i < state.enemyTowers.length; i++) { var enemyTower = state.enemyTowers[i]; var towerThreats = []; var towerOpportunities = []; // Analyze threats from player and other enemy factions for (var j = 0; j < towers.length; j++) { var otherTower = towers[j]; if (otherTower.owner !== enemyTower.owner) { var distance = getDistance(enemyTower, otherTower); var threatLevel = calculateThreatLevel(enemyTower, otherTower, distance); if (threatLevel > 0) { towerThreats.push({ tower: otherTower, distance: distance, threatLevel: threatLevel }); } // Check for opportunities (weak targets) if (otherTower.unitCount < enemyTower.unitCount * 0.8) { towerOpportunities.push({ tower: otherTower, distance: distance, advantage: enemyTower.unitCount - otherTower.unitCount }); } } } state.threats[enemyTower.owner] = towerThreats.sort(function (a, b) { return b.threatLevel - a.threatLevel; }); state.opportunities[enemyTower.owner] = towerOpportunities.sort(function (a, b) { return b.advantage - a.advantage; }); } return state; } // Calculate threat level between two towers function calculateThreatLevel(myTower, enemyTower, distance) { if (distance > 1000) return 0; // Too far to be immediate threat var unitRatio = enemyTower.unitCount / Math.max(myTower.unitCount, 1); var distanceFactor = Math.max(0, 1 - distance / 1000); return unitRatio * distanceFactor * 100; } // Get distance between two towers function getDistance(tower1, tower2) { var dx = tower1.x - tower2.x; var dy = tower1.y - tower2.y; return Math.sqrt(dx * dx + dy * dy); } // Determine optimal strategy for a tower based on game state function getOptimalStrategy(tower, gameState) { var threats = gameState.threats[tower.owner] || []; var opportunities = gameState.opportunities[tower.owner] || []; var isPlayerWinning = gameState.playerStrength > gameState.enemyStrength * 1.2; var isPlayerLosing = gameState.enemyStrength > gameState.playerStrength * 1.2; // Emergency defense if under immediate threat if (threats.length > 0 && threats[0].threatLevel > 50) { return { type: 'EMERGENCY_DEFENSE', target: threats[0].tower, urgency: threats[0].threatLevel }; } // Different faction personalities with adaptive behavior if (tower.owner === 2) { // Faction 2: Adaptive Aggressor - changes tactics based on game state if (isPlayerLosing) { return { type: 'PRESS_ADVANTAGE', target: findWeakestPlayerTower(gameState.playerTowers, tower), minUnits: 8 }; } else if (opportunities.length > 0 && tower.unitCount > 15) { return { type: 'OPPORTUNISTIC_STRIKE', target: opportunities[0].tower, minUnits: 12 }; } else { return { type: 'AGGRESSIVE_EXPAND', target: findNearestEnemy(tower), minUnits: 10 }; } } else if (tower.owner === 3) { // Faction 3: Strategic Defender - focuses on timing and coordination if (tower.unitCount > 30 && isPlayerWinning) { return { type: 'COORDINATED_COUNTER', target: findStrongestPlayerTower(gameState.playerTowers, tower), minUnits: 25 }; } else if (opportunities.length > 0 && tower.unitCount > opportunities[0].tower.unitCount * 1.5) { return { type: 'CALCULATED_STRIKE', target: opportunities[0].tower, minUnits: 20 }; } else { return { type: 'DEFENSIVE_BUILD', target: null, minUnits: 35 }; } } else if (tower.owner === 4) { // Faction 4: Economic Opportunist - focuses on efficient expansion var nearbyNeutrals = findNearbyNeutralTowers(tower, 600); if (nearbyNeutrals.length > 0 && tower.unitCount > 15) { return { type: 'ECONOMIC_EXPANSION', target: nearbyNeutrals[0], minUnits: 12 }; } else if (opportunities.length > 0 && getDistance(tower, opportunities[0].tower) < 500) { return { type: 'EFFICIENT_CAPTURE', target: opportunities[0].tower, minUnits: opportunities[0].tower.unitCount + 5 }; } else { return { type: 'RESOURCE_BUILD', target: null, minUnits: 25 }; } } else { // Default faction: Balanced approach if (opportunities.length > 0 && tower.unitCount > 18) { return { type: 'BALANCED_ATTACK', target: opportunities[0].tower, minUnits: 15 }; } else { return { type: 'DEFENSIVE_BUILD', target: null, minUnits: 20 }; } } } // Execute the determined strategy function executeStrategy(tower, strategy, gameState) { if (!strategy.target && strategy.type.indexOf('BUILD') === -1) return; if (tower.unitCount < strategy.minUnits) return; var unitsToSend; switch (strategy.type) { case 'EMERGENCY_DEFENSE': unitsToSend = Math.floor(tower.unitCount * 0.8); // Send most units in emergency break; case 'PRESS_ADVANTAGE': unitsToSend = Math.floor(tower.unitCount * 0.7); // Aggressive when winning break; case 'COORDINATED_COUNTER': unitsToSend = Math.floor(tower.unitCount * 0.6); // Calculated counter-attack break; case 'OPPORTUNISTIC_STRIKE': case 'CALCULATED_STRIKE': case 'EFFICIENT_CAPTURE': unitsToSend = Math.min(Math.floor(tower.unitCount * 0.6), strategy.target.unitCount + 10); break; case 'ECONOMIC_EXPANSION': unitsToSend = Math.floor(tower.unitCount * 0.4); // Conservative expansion break; case 'AGGRESSIVE_EXPAND': case 'BALANCED_ATTACK': unitsToSend = Math.floor(tower.unitCount * 0.5); // Standard attack break; default: return; // No action for build strategies } if (strategy.target && unitsToSend > 0) { sendUnits(tower, strategy.target, unitsToSend); } } // Helper functions for target selection function findWeakestPlayerTower(playerTowers, fromTower) { var weakest = null; var minUnits = Infinity; for (var i = 0; i < playerTowers.length; i++) { if (playerTowers[i].unitCount < minUnits) { minUnits = playerTowers[i].unitCount; weakest = playerTowers[i]; } } return weakest; } function findStrongestPlayerTower(playerTowers, fromTower) { var strongest = null; var maxUnits = 0; for (var i = 0; i < playerTowers.length; i++) { if (playerTowers[i].unitCount > maxUnits) { maxUnits = playerTowers[i].unitCount; strongest = playerTowers[i]; } } return strongest; } function findNearestEnemy(fromTower) { var nearest = null; var minDist = Infinity; for (var i = 0; i < towers.length; i++) { if (towers[i].owner !== fromTower.owner) { var dist = getDistance(fromTower, towers[i]); if (dist < minDist) { minDist = dist; nearest = towers[i]; } } } return nearest; } function findNearbyNeutralTowers(fromTower, maxDistance) { var nearby = []; for (var i = 0; i < towers.length; i++) { if (towers[i].owner === 0) { var dist = getDistance(fromTower, towers[i]); if (dist <= maxDistance) { nearby.push(towers[i]); } } } return nearby.sort(function (a, b) { return getDistance(fromTower, a) - getDistance(fromTower, b); }); } game.down = function (x, y, obj) { // Find if we clicked on a player tower (scaled up detection area) for (var i = 0; i < towers.length; i++) { var tower = towers[i]; if (tower.owner === 1 && Math.abs(tower.x - x) < 75 && Math.abs(tower.y - y) < 75) { selectedTower = tower; isDragging = true; if (!currentPath) { currentPath = new PathLine(); game.addChild(currentPath); } currentPath.setPath([{ x: tower.x, y: tower.y }]); break; } } }; game.move = function (x, y, obj) { if (isDragging && selectedTower && currentPath) { currentPath.setPath([{ x: selectedTower.x, y: selectedTower.y }, { x: x, y: y }]); } }; game.up = function (x, y, obj) { if (isDragging && selectedTower) { // Find target tower (scaled up detection area) var targetTower = null; for (var i = 0; i < towers.length; i++) { var tower = towers[i]; if (tower !== selectedTower && Math.abs(tower.x - x) < 75 && Math.abs(tower.y - y) < 75) { targetTower = tower; break; } } if (targetTower && selectedTower.unitCount > 0) { sendUnits(selectedTower, targetTower, Math.floor(selectedTower.unitCount * 0.5)); } if (currentPath) { currentPath.clear(); } } isDragging = false; selectedTower = null; }; game.update = function () { // Update all units for (var i = units.length - 1; i >= 0; i--) { if (!units[i] || !units[i].parent) { units.splice(i, 1); } } // Run AI every 2 seconds if (LK.ticks % 120 === 0) { runAI(); } // Run memory cleanup memoryManager.performCleanup(); // Check win/lose conditions if (LK.ticks % 60 === 0) { checkWinCondition(); } // Update unit count display every 30 ticks (twice per second) if (LK.ticks % 30 === 0) { updateUnitCountDisplay(); } }; // Create Reset button var resetButton = new Text2('Reset', { size: 60, fill: 0xFFFFFF }); resetButton.anchor.set(1, 1); // Anchor to bottom right LK.gui.bottomRight.addChild(resetButton); // Reset button functionality resetButton.down = function (x, y, obj) { // Reset all game state currentLevel = 0; storage.currentLevel = 0; // Clear existing game objects for (var i = 0; i < towers.length; i++) { towers[i].destroy(); } for (var i = 0; i < units.length; i++) { units[i].destroy(); } towers = []; units = []; if (currentPath) { currentPath.destroy(); currentPath = null; } // Reset game state variables selectedTower = null; isDragging = false; aiStartTime = null; // Load first level loadLevel(currentLevel); }; // Initialize first level loadLevel(currentLevel); // Memory Management and Performance Optimization System var memoryManager = { // Object pools for reusing objects instead of creating new ones unitPool: [], sparklePool: [], pathDotPool: [], // Memory cleanup settings cleanupInterval: 300, // Clean up every 5 seconds (300 ticks at 60fps) lastCleanup: 0, // Get unit from pool or create new one getUnit: function getUnit() { if (this.unitPool.length > 0) { var unit = this.unitPool.pop(); // Reset unit properties unit.alpha = 1; unit.visible = true; unit.owner = 1; unit.speed = 3; unit.targetTower = null; unit.pathIndex = 0; unit.path = []; unit.lastWasIntersecting = false; return unit; } return new Unit(); }, // Return unit to pool instead of destroying recycleUnit: function recycleUnit(unit) { if (unit && unit.parent) { unit.parent.removeChild(unit); unit.visible = false; this.unitPool.push(unit); } }, // Get sparkle from pool or create new one getSparkle: function getSparkle() { if (this.sparklePool.length > 0) { var sparkle = this.sparklePool.pop(); sparkle.alpha = 1; sparkle.visible = true; sparkle.scaleX = 0.5 + Math.random() * 0.5; sparkle.scaleY = sparkle.scaleX; return sparkle; } return game.attachAsset('sparkle', { anchorX: 0.5, anchorY: 0.5 }); }, // Return sparkle to pool recycleSparkle: function recycleSparkle(sparkle) { if (sparkle && sparkle.parent) { sparkle.parent.removeChild(sparkle); sparkle.visible = false; this.sparklePool.push(sparkle); } }, // Periodic memory cleanup performCleanup: function performCleanup() { if (LK.ticks - this.lastCleanup < this.cleanupInterval) { return; } this.lastCleanup = LK.ticks; // Clean up destroyed units from arrays for (var i = units.length - 1; i >= 0; i--) { if (!units[i] || !units[i].parent) { units.splice(i, 1); } } // Limit pool sizes to prevent excessive memory usage if (this.unitPool.length > 50) { // Actually destroy excess units var excess = this.unitPool.splice(50); for (var i = 0; i < excess.length; i++) { if (excess[i].destroy) { excess[i].destroy(); } } } if (this.sparklePool.length > 100) { var excess = this.sparklePool.splice(100); for (var i = 0; i < excess.length; i++) { if (excess[i].destroy) { excess[i].destroy(); } } } if (this.pathDotPool.length > 200) { var excess = this.pathDotPool.splice(200); for (var i = 0; i < excess.length; i++) { if (excess[i].destroy) { excess[i].destroy(); } } } // Force garbage collection hint by nullifying references var temp = []; temp = null; } }; // Create unit count panel in bottom left var unitCountPanel = new Container(); LK.gui.bottomLeft.addChild(unitCountPanel); // Panel background (optional visual enhancement) var panelBg = LK.getAsset('tower', { width: 300, height: 200, anchorX: 0, anchorY: 1, alpha: 0.3 }); unitCountPanel.addChild(panelBg); // Player unit count text var playerCountText = new Text2('Oyuncu: 0', { size: 40, fill: 0x4a90e2 // Player blue color }); playerCountText.anchor.set(0, 1); playerCountText.x = 10; playerCountText.y = -10; unitCountPanel.addChild(playerCountText); // Enemy faction count texts var enemyCountTexts = []; var enemyColors = [0xe74c3c, 0x9b59b6, 0xf39c12]; // Red, purple, orange for (var i = 0; i < 3; i++) { var enemyText = new Text2('Rakip ' + (i + 1) + ': 0', { size: 40, fill: enemyColors[i] }); enemyText.anchor.set(0, 1); enemyText.x = 10; enemyText.y = -50 - i * 40; unitCountPanel.addChild(enemyText); enemyCountTexts.push(enemyText); } // Function to update unit count display function updateUnitCountDisplay() { var playerUnits = 0; var enemyUnits = [0, 0, 0]; // For factions 2, 3, 4 // Count units in towers for (var i = 0; i < towers.length; i++) { var tower = towers[i]; if (tower.owner === 1) { playerUnits += tower.unitCount; } else if (tower.owner >= 2 && tower.owner <= 4) { enemyUnits[tower.owner - 2] += tower.unitCount; } } // Count units in transit for (var i = 0; i < units.length; i++) { var unit = units[i]; if (unit.owner === 1) { playerUnits++; } else if (unit.owner >= 2 && unit.owner <= 4) { enemyUnits[unit.owner - 2]++; } } // Update display texts playerCountText.setText('Oyuncu: ' + playerUnits); for (var i = 0; i < enemyCountTexts.length; i++) { enemyCountTexts[i].setText('Rakip ' + (i + 1) + ': ' + enemyUnits[i]); } } // Play background music LK.playMusic('battle'); ;
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var PathLine = Container.expand(function () {
var self = Container.call(this);
self.points = [];
self.graphics = [];
self.setPath = function (points) {
// Clear old graphics
for (var i = 0; i < self.graphics.length; i++) {
self.graphics[i].destroy();
}
self.graphics = [];
self.points = points;
// Draw new path
for (var i = 0; i < points.length - 1; i++) {
var dist = Math.sqrt(Math.pow(points[i + 1].x - points[i].x, 2) + Math.pow(points[i + 1].y - points[i].y, 2));
var segments = Math.floor(dist / 20);
for (var j = 0; j < segments; j++) {
var t = j / segments;
var dot;
if (memoryManager.pathDotPool.length > 0) {
dot = memoryManager.pathDotPool.pop();
dot.visible = true;
dot.alpha = 0.5;
self.addChild(dot);
} else {
dot = self.attachAsset('path', {
anchorX: 0.5,
anchorY: 0.5
});
}
dot.x = points[i].x + (points[i + 1].x - points[i].x) * t;
dot.y = points[i].y + (points[i + 1].y - points[i].y) * t;
dot.alpha = 0.5;
self.graphics.push(dot);
}
}
};
self.clear = function () {
for (var i = 0; i < self.graphics.length; i++) {
var dot = self.graphics[i];
if (dot && dot.parent) {
dot.parent.removeChild(dot);
dot.visible = false;
memoryManager.pathDotPool.push(dot);
}
}
self.graphics = [];
self.points = [];
};
return self;
});
var Tower = Container.expand(function () {
var self = Container.call(this);
self.owner = 0; // 0 = neutral, 1 = player, 2 = enemy
self.unitCount = 0;
self.maxUnits = 100;
self.spawnRate = 30; // ticks between spawns
self.lastSpawn = 0;
var towerGraphics = self.attachAsset('tower', {
anchorX: 0.5,
anchorY: 0.5
});
self.countText = new Text2('0', {
size: 60,
fill: 0xFFFFFF
});
self.countText.anchor.set(0.5, 0.5);
self.addChild(self.countText);
// Enemy name text (positioned below tower)
self.nameText = new Text2('', {
size: 40,
fill: 0xFFFFFF
});
self.nameText.anchor.set(0.5, 0);
self.nameText.y = 90; // Position below the tower
self.addChild(self.nameText);
self.setOwner = function (newOwner) {
var oldOwner = self.owner;
self.owner = newOwner;
var targetColor;
if (newOwner === 0) {
targetColor = 0x888888; // neutral gray
} else if (newOwner === 1) {
targetColor = 0x4a90e2; // player blue
} else if (newOwner === 2) {
targetColor = 0xe74c3c; // enemy red
} else if (newOwner === 3) {
targetColor = 0x9b59b6; // enemy purple
} else if (newOwner === 4) {
targetColor = 0xf39c12; // enemy orange
} else {
targetColor = 0xe74c3c; // default enemy red
}
// Update name display
if (newOwner >= 2) {
// Enemy tower - show name
var enemyName = assignEnemyName(newOwner);
self.nameText.setText(enemyName);
self.nameText.alpha = 1;
} else if (newOwner === 1) {
// Player tower - show "Player"
self.nameText.setText('Player');
self.nameText.alpha = 1;
} else {
// Neutral tower - hide name
self.nameText.setText('');
self.nameText.alpha = 0;
}
// Only animate if ownership actually changed
if (oldOwner !== newOwner) {
// Smooth color transition over 500ms
tween(towerGraphics, {
tint: targetColor
}, {
duration: 500,
easing: tween.easeInOut
});
} else {
// Immediate color change if no ownership change
towerGraphics.tint = targetColor;
}
};
self.addUnits = function (count) {
self.unitCount = Math.min(self.unitCount + count, self.maxUnits);
self.countText.setText(Math.floor(self.unitCount));
};
self.removeUnits = function (count) {
self.unitCount = Math.max(0, self.unitCount - count);
self.countText.setText(Math.floor(self.unitCount));
return count;
};
self.update = function () {
if (self.owner > 0) {
// Calculate dynamic spawn rate based on unit count
// More units = faster production (lower spawn rate number)
// Base rate is 30, reduced by unit count factor
var dynamicSpawnRate = Math.max(10, self.spawnRate - Math.floor(self.unitCount / 10));
if (LK.ticks - self.lastSpawn > dynamicSpawnRate) {
self.addUnits(1);
self.lastSpawn = LK.ticks;
}
}
};
return self;
});
var Unit = Container.expand(function () {
var self = Container.call(this);
self.owner = 1;
self.speed = 3;
self.targetTower = null;
self.pathIndex = 0;
self.path = [];
var unitGraphics = self.attachAsset('unit', {
anchorX: 0.5,
anchorY: 0.5
});
self.setOwner = function (owner) {
self.owner = owner;
if (owner === 1) {
unitGraphics.tint = 0x4a90e2; // player blue
} else if (owner === 2) {
unitGraphics.tint = 0xe74c3c; // enemy red
} else if (owner === 3) {
unitGraphics.tint = 0x9b59b6; // enemy purple
} else if (owner === 4) {
unitGraphics.tint = 0xf39c12; // enemy orange
} else {
unitGraphics.tint = 0xe74c3c; // default enemy red
}
};
self.setPath = function (path, target) {
// Add random offset to create scattered movement
var scatterRange = 40; // Maximum scatter distance
var offsetX = (Math.random() - 0.5) * scatterRange;
var offsetY = (Math.random() - 0.5) * scatterRange;
// Create scattered path by adding random offsets to each point
self.path = [];
for (var i = 0; i < path.length; i++) {
// Apply consistent offset throughout the path, but reduce it near the end
var offsetFactor = Math.max(0.2, 1 - i / path.length * 0.8);
self.path.push({
x: path[i].x + offsetX * offsetFactor,
y: path[i].y + offsetY * offsetFactor
});
}
self.targetTower = target;
self.pathIndex = 0;
if (self.path.length > 0) {
self.x = self.path[0].x;
self.y = self.path[0].y;
}
};
self.lastWasIntersecting = false;
self.update = function () {
if (!self.targetTower || self.pathIndex >= self.path.length) {
return;
}
// Check for combat with enemy units
var currentIntersecting = false;
for (var i = 0; i < units.length; i++) {
var otherUnit = units[i];
if (otherUnit !== self && otherUnit.owner !== self.owner) {
// Check if units are close enough to fight (within 30 pixels)
var combatDx = self.x - otherUnit.x;
var combatDy = self.y - otherUnit.y;
var combatDist = Math.sqrt(combatDx * combatDx + combatDy * combatDy);
if (combatDist < 30) {
currentIntersecting = true;
// Combat occurs - both units destroy each other
if (!self.lastWasIntersecting) {
// Create combat sparkle effects at the battle location
var battleX = (self.x + otherUnit.x) / 2;
var battleY = (self.y + otherUnit.y) / 2;
// Create multiple sparkle particles
for (var sparkleIndex = 0; sparkleIndex < 8; sparkleIndex++) {
var sparkle = memoryManager.getSparkle();
game.addChild(sparkle);
sparkle.x = battleX + (Math.random() - 0.5) * 40;
sparkle.y = battleY + (Math.random() - 0.5) * 40;
sparkle.alpha = 1;
sparkle.scaleX = 0.5 + Math.random() * 0.5;
sparkle.scaleY = sparkle.scaleX;
sparkle.tint = 0xffff00 + Math.floor(Math.random() * 0x444444);
// Animate sparkles flying outward and fading
var randomAngle = Math.random() * Math.PI * 2;
var flyDistance = 50 + Math.random() * 30;
var targetX = sparkle.x + Math.cos(randomAngle) * flyDistance;
var targetY = sparkle.y + Math.sin(randomAngle) * flyDistance;
tween(sparkle, {
x: targetX,
y: targetY,
alpha: 0,
scaleX: 0,
scaleY: 0
}, {
duration: 300 + Math.random() * 200,
easing: tween.easeOut,
onFinish: function onFinish() {
if (sparkle && sparkle.parent) {
memoryManager.recycleSparkle(sparkle);
}
}
});
}
// Flash both units red before destroying
LK.effects.flashObject(self, 0xff0000, 200);
LK.effects.flashObject(otherUnit, 0xff0000, 200);
LK.getSound('combat').play();
// Destroy both units after flash
LK.setTimeout(function () {
if (self && self.parent) {
memoryManager.recycleUnit(self);
var selfIndex = units.indexOf(self);
if (selfIndex !== -1) {
units.splice(selfIndex, 1);
}
}
if (otherUnit && otherUnit.parent) {
memoryManager.recycleUnit(otherUnit);
var otherIndex = units.indexOf(otherUnit);
if (otherIndex !== -1) {
units.splice(otherIndex, 1);
}
}
}, 200);
return;
}
}
}
}
self.lastWasIntersecting = currentIntersecting;
var target = self.path[self.pathIndex];
var dx = target.x - self.x;
var dy = target.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < self.speed) {
self.pathIndex++;
if (self.pathIndex >= self.path.length && self.targetTower) {
// Reached target tower
if (self.targetTower.owner === self.owner) {
self.targetTower.addUnits(1);
} else {
self.targetTower.unitCount--;
if (self.targetTower.unitCount < 0) {
self.targetTower.unitCount = 1;
self.targetTower.setOwner(self.owner);
LK.getSound('capture').play();
}
self.targetTower.countText.setText(Math.floor(Math.abs(self.targetTower.unitCount)));
}
memoryManager.recycleUnit(self);
units.splice(units.indexOf(self), 1);
}
} else {
// Add slight random movement variation for scattered appearance
var moveX = dx / dist * self.speed;
var moveY = dy / dist * self.speed;
// Add small random deviation (5% of movement speed)
var deviation = self.speed * 0.05;
moveX += (Math.random() - 0.5) * deviation;
moveY += (Math.random() - 0.5) * deviation;
self.x += moveX;
self.y += moveY;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a1a
});
/****
* Game Code
****/
var towers = [];
var units = [];
var currentPath = null;
var selectedTower = null;
var isDragging = false;
var currentLevel = storage.currentLevel || 0;
var aiStartTime = null; // Track when AI should start (null = not started yet)
// Enemy names for different factions
var enemyNames = ["Karabekir", "Enver", "Talat", "Cemal", "İsmet", "Fevzi", "Kazım", "Refet", "Ali Fuat", "Rauf", "Bekir Sami", "Adnan", "Kâzım Özalp", "Salih", "Nureddin"];
var assignedEnemyNames = {}; // Track names assigned to each enemy faction
// Level configurations - 10 levels with progressive difficulty (scaled up 100%)
var levels = [{
// Level 1 - Tutorial
towers: [{
x: 300,
y: 1366,
owner: 1,
units: 30
}, {
x: 1024,
y: 800,
owner: 0,
units: 10
}, {
x: 1748,
y: 1366,
owner: 2,
units: 20
}, {
x: 1748,
y: 400,
owner: 3,
units: 15
}]
}, {
// Level 2 - Basic Strategy
towers: [{
x: 300,
y: 400,
owner: 1,
units: 35
}, {
x: 1024,
y: 1366,
owner: 0,
units: 15
}, {
x: 1748,
y: 400,
owner: 2,
units: 25
}, {
x: 1748,
y: 2332,
owner: 3,
units: 25
}, {
x: 300,
y: 2332,
owner: 4,
units: 20
}]
}, {
// Level 3 - Multi-Front
towers: [{
x: 300,
y: 1366,
owner: 1,
units: 45
}, {
x: 700,
y: 800,
owner: 0,
units: 15
}, {
x: 1348,
y: 800,
owner: 0,
units: 15
}, {
x: 700,
y: 1932,
owner: 0,
units: 15
}, {
x: 1348,
y: 1932,
owner: 0,
units: 15
}, {
x: 1748,
y: 400,
owner: 2,
units: 30
}, {
x: 1748,
y: 1366,
owner: 3,
units: 30
}, {
x: 1748,
y: 2332,
owner: 4,
units: 30
}]
}, {
// Level 4 - Defensive Challenge
towers: [{
x: 300,
y: 1366,
owner: 1,
units: 50
}, {
x: 600,
y: 600,
owner: 0,
units: 20
}, {
x: 1024,
y: 400,
owner: 2,
units: 40
}, {
x: 1448,
y: 600,
owner: 0,
units: 20
}, {
x: 1748,
y: 1366,
owner: 2,
units: 40
}, {
x: 1024,
y: 2100,
owner: 2,
units: 40
}]
}, {
// Level 5 - Resource Management
towers: [{
x: 200,
y: 800,
owner: 1,
units: 55
}, {
x: 200,
y: 1932,
owner: 1,
units: 55
}, {
x: 700,
y: 1366,
owner: 0,
units: 25
}, {
x: 1348,
y: 1366,
owner: 0,
units: 25
}, {
x: 1748,
y: 600,
owner: 2,
units: 45
}, {
x: 1748,
y: 1366,
owner: 2,
units: 45
}, {
x: 1748,
y: 2132,
owner: 2,
units: 45
}]
}, {
// Level 6 - Territory Control
towers: [{
x: 300,
y: 400,
owner: 1,
units: 60
}, {
x: 300,
y: 2332,
owner: 1,
units: 60
}, {
x: 600,
y: 800,
owner: 0,
units: 30
}, {
x: 1024,
y: 1366,
owner: 0,
units: 30
}, {
x: 1448,
y: 1932,
owner: 0,
units: 30
}, {
x: 1748,
y: 800,
owner: 2,
units: 50
}, {
x: 1748,
y: 1500,
owner: 2,
units: 50
}, {
x: 1748,
y: 2200,
owner: 2,
units: 50
}]
}, {
// Level 7 - Advanced Tactics
towers: [{
x: 200,
y: 1366,
owner: 1,
units: 65
}, {
x: 500,
y: 600,
owner: 0,
units: 35
}, {
x: 500,
y: 1366,
owner: 0,
units: 35
}, {
x: 500,
y: 2132,
owner: 0,
units: 35
}, {
x: 1024,
y: 400,
owner: 0,
units: 35
}, {
x: 1024,
y: 2332,
owner: 0,
units: 35
}, {
x: 1548,
y: 600,
owner: 0,
units: 35
}, {
x: 1548,
y: 1366,
owner: 0,
units: 35
}, {
x: 1548,
y: 2132,
owner: 0,
units: 35
}, {
x: 1848,
y: 1366,
owner: 2,
units: 55
}]
}, {
// Level 8 - Siege Warfare
towers: [{
x: 300,
y: 600,
owner: 1,
units: 70
}, {
x: 300,
y: 1366,
owner: 1,
units: 70
}, {
x: 300,
y: 2132,
owner: 1,
units: 70
}, {
x: 800,
y: 800,
owner: 0,
units: 40
}, {
x: 800,
y: 1932,
owner: 0,
units: 40
}, {
x: 1248,
y: 800,
owner: 0,
units: 40
}, {
x: 1248,
y: 1932,
owner: 0,
units: 40
}, {
x: 1650,
y: 400,
owner: 2,
units: 60
}, {
x: 1650,
y: 1366,
owner: 2,
units: 60
}, {
x: 1650,
y: 2332,
owner: 2,
units: 60
}]
}, {
// Level 9 - Final Challenge
towers: [{
x: 200,
y: 800,
owner: 1,
units: 75
}, {
x: 200,
y: 1932,
owner: 1,
units: 75
}, {
x: 600,
y: 400,
owner: 0,
units: 45
}, {
x: 600,
y: 1366,
owner: 0,
units: 45
}, {
x: 600,
y: 2332,
owner: 0,
units: 45
}, {
x: 1024,
y: 600,
owner: 0,
units: 45
}, {
x: 1024,
y: 2132,
owner: 0,
units: 45
}, {
x: 1448,
y: 400,
owner: 0,
units: 45
}, {
x: 1448,
y: 1366,
owner: 0,
units: 45
}, {
x: 1448,
y: 2332,
owner: 0,
units: 45
}, {
x: 1748,
y: 600,
owner: 2,
units: 65
}, {
x: 1748,
y: 1366,
owner: 2,
units: 65
}, {
x: 1748,
y: 2132,
owner: 2,
units: 65
}]
}, {
// Level 10 - Master's Trial
towers: [{
x: 150,
y: 1366,
owner: 1,
units: 80
}, {
x: 400,
y: 600,
owner: 0,
units: 50
}, {
x: 400,
y: 1100,
owner: 0,
units: 50
}, {
x: 400,
y: 1632,
owner: 0,
units: 50
}, {
x: 400,
y: 2132,
owner: 0,
units: 50
}, {
x: 800,
y: 400,
owner: 0,
units: 50
}, {
x: 800,
y: 800,
owner: 0,
units: 50
}, {
x: 800,
y: 1932,
owner: 0,
units: 50
}, {
x: 800,
y: 2332,
owner: 0,
units: 50
}, {
x: 1248,
y: 400,
owner: 0,
units: 50
}, {
x: 1248,
y: 800,
owner: 0,
units: 50
}, {
x: 1248,
y: 1932,
owner: 0,
units: 50
}, {
x: 1248,
y: 2332,
owner: 0,
units: 50
}, {
x: 1648,
y: 600,
owner: 0,
units: 50
}, {
x: 1648,
y: 1100,
owner: 0,
units: 50
}, {
x: 1648,
y: 1632,
owner: 0,
units: 50
}, {
x: 1648,
y: 2132,
owner: 0,
units: 50
}, {
x: 1898,
y: 1366,
owner: 2,
units: 70
}]
}];
// UI Elements
var levelText = new Text2('Level ' + (currentLevel + 1), {
size: 80,
fill: 0xFFFFFF
});
levelText.anchor.set(0.5, 0);
LK.gui.top.addChild(levelText);
function assignEnemyName(owner) {
if (!assignedEnemyNames[owner] && owner >= 2) {
// Get available names (not already assigned)
var availableNames = enemyNames.filter(function (name) {
return !Object.values(assignedEnemyNames).includes(name);
});
// If no available names, reuse from the pool
if (availableNames.length === 0) {
availableNames = enemyNames;
}
// Assign random name
var randomIndex = Math.floor(Math.random() * availableNames.length);
assignedEnemyNames[owner] = availableNames[randomIndex];
}
return assignedEnemyNames[owner] || "";
}
function loadLevel(levelIndex) {
// Clear existing game objects
for (var i = 0; i < towers.length; i++) {
towers[i].destroy();
}
for (var i = 0; i < units.length; i++) {
units[i].destroy();
}
towers = [];
units = [];
if (currentPath) {
currentPath.destroy();
currentPath = null;
}
// Reset game state variables
selectedTower = null;
isDragging = false;
// Reset enemy name assignments
assignedEnemyNames = {};
// Load new level
var levelData = levels[levelIndex % levels.length];
for (var i = 0; i < levelData.towers.length; i++) {
var towerData = levelData.towers[i];
var tower = new Tower();
tower.x = towerData.x;
tower.y = towerData.y;
tower.setOwner(towerData.owner);
tower.addUnits(towerData.units);
towers.push(tower);
game.addChild(tower);
}
levelText.setText('Level ' + (levelIndex + 1));
// Set AI to start after 5 seconds (5000ms)
aiStartTime = LK.ticks + 5 * 60; // 5 seconds at 60 FPS
}
function createPath(start, end) {
var points = [];
var steps = 20;
for (var i = 0; i <= steps; i++) {
points.push({
x: start.x + (end.x - start.x) * (i / steps),
y: start.y + (end.y - start.y) * (i / steps)
});
}
return points;
}
function sendUnits(fromTower, toTower, count) {
var path = createPath(fromTower, toTower);
var unitsToSend = Math.min(count, fromTower.unitCount);
for (var i = 0; i < unitsToSend; i++) {
var unit = memoryManager.getUnit();
unit.setOwner(fromTower.owner);
unit.setPath(path, toTower);
units.push(unit);
game.addChild(unit);
// Add random spawn delay and position offset for scattered deployment
var randomDelay = i * (30 + Math.random() * 40); // Random delay between 30-70ms per unit
var spawnOffsetX = (Math.random() - 0.5) * 60; // Random spawn position offset
var spawnOffsetY = (Math.random() - 0.5) * 60;
// Position unit at spawn location with offset
unit.x = fromTower.x + spawnOffsetX;
unit.y = fromTower.y + spawnOffsetY;
// Stagger unit spawning with random timing
tween(unit, {
x: path[0].x,
y: path[0].y
}, {
duration: randomDelay,
onFinish: function onFinish() {
LK.getSound('deploy').play();
}
});
}
fromTower.removeUnits(unitsToSend);
}
function checkWinCondition() {
var playerTowers = 0;
var enemyTowers = 0;
for (var i = 0; i < towers.length; i++) {
if (towers[i].owner === 1) playerTowers++;
if (towers[i].owner >= 2) enemyTowers++;
}
if (enemyTowers === 0) {
// Win condition - player defeated all enemy factions
currentLevel++;
storage.currentLevel = currentLevel;
LK.showYouWin();
} else if (playerTowers === 0) {
// Lose condition - reset everything to start from beginning
currentLevel = 0;
storage.currentLevel = 0;
LK.showGameOver();
}
}
// Multi-faction AI with sophisticated strategies
function runAI() {
// Don't run AI until 5 seconds have passed
if (aiStartTime && LK.ticks < aiStartTime) {
return;
}
// Analyze game state for strategic decisions
var gameState = analyzeGameState();
for (var i = 0; i < towers.length; i++) {
var tower = towers[i];
if (tower.owner >= 2) {
// Get strategic context for this tower
var strategy = getOptimalStrategy(tower, gameState);
executeStrategy(tower, strategy, gameState);
}
}
}
// Analyze current game state for AI decision making
function analyzeGameState() {
var state = {
playerStrength: 0,
enemyStrength: 0,
neutralTowers: 0,
playerTowers: [],
enemyTowers: [],
neutralTowersByDistance: [],
threats: [],
opportunities: []
};
// Calculate faction strengths and positions
for (var i = 0; i < towers.length; i++) {
var tower = towers[i];
if (tower.owner === 1) {
state.playerStrength += tower.unitCount;
state.playerTowers.push(tower);
} else if (tower.owner >= 2) {
state.enemyStrength += tower.unitCount;
state.enemyTowers.push(tower);
} else {
state.neutralTowers++;
}
}
// Find strategic opportunities and threats for each enemy tower
for (var i = 0; i < state.enemyTowers.length; i++) {
var enemyTower = state.enemyTowers[i];
var towerThreats = [];
var towerOpportunities = [];
// Analyze threats from player and other enemy factions
for (var j = 0; j < towers.length; j++) {
var otherTower = towers[j];
if (otherTower.owner !== enemyTower.owner) {
var distance = getDistance(enemyTower, otherTower);
var threatLevel = calculateThreatLevel(enemyTower, otherTower, distance);
if (threatLevel > 0) {
towerThreats.push({
tower: otherTower,
distance: distance,
threatLevel: threatLevel
});
}
// Check for opportunities (weak targets)
if (otherTower.unitCount < enemyTower.unitCount * 0.8) {
towerOpportunities.push({
tower: otherTower,
distance: distance,
advantage: enemyTower.unitCount - otherTower.unitCount
});
}
}
}
state.threats[enemyTower.owner] = towerThreats.sort(function (a, b) {
return b.threatLevel - a.threatLevel;
});
state.opportunities[enemyTower.owner] = towerOpportunities.sort(function (a, b) {
return b.advantage - a.advantage;
});
}
return state;
}
// Calculate threat level between two towers
function calculateThreatLevel(myTower, enemyTower, distance) {
if (distance > 1000) return 0; // Too far to be immediate threat
var unitRatio = enemyTower.unitCount / Math.max(myTower.unitCount, 1);
var distanceFactor = Math.max(0, 1 - distance / 1000);
return unitRatio * distanceFactor * 100;
}
// Get distance between two towers
function getDistance(tower1, tower2) {
var dx = tower1.x - tower2.x;
var dy = tower1.y - tower2.y;
return Math.sqrt(dx * dx + dy * dy);
}
// Determine optimal strategy for a tower based on game state
function getOptimalStrategy(tower, gameState) {
var threats = gameState.threats[tower.owner] || [];
var opportunities = gameState.opportunities[tower.owner] || [];
var isPlayerWinning = gameState.playerStrength > gameState.enemyStrength * 1.2;
var isPlayerLosing = gameState.enemyStrength > gameState.playerStrength * 1.2;
// Emergency defense if under immediate threat
if (threats.length > 0 && threats[0].threatLevel > 50) {
return {
type: 'EMERGENCY_DEFENSE',
target: threats[0].tower,
urgency: threats[0].threatLevel
};
}
// Different faction personalities with adaptive behavior
if (tower.owner === 2) {
// Faction 2: Adaptive Aggressor - changes tactics based on game state
if (isPlayerLosing) {
return {
type: 'PRESS_ADVANTAGE',
target: findWeakestPlayerTower(gameState.playerTowers, tower),
minUnits: 8
};
} else if (opportunities.length > 0 && tower.unitCount > 15) {
return {
type: 'OPPORTUNISTIC_STRIKE',
target: opportunities[0].tower,
minUnits: 12
};
} else {
return {
type: 'AGGRESSIVE_EXPAND',
target: findNearestEnemy(tower),
minUnits: 10
};
}
} else if (tower.owner === 3) {
// Faction 3: Strategic Defender - focuses on timing and coordination
if (tower.unitCount > 30 && isPlayerWinning) {
return {
type: 'COORDINATED_COUNTER',
target: findStrongestPlayerTower(gameState.playerTowers, tower),
minUnits: 25
};
} else if (opportunities.length > 0 && tower.unitCount > opportunities[0].tower.unitCount * 1.5) {
return {
type: 'CALCULATED_STRIKE',
target: opportunities[0].tower,
minUnits: 20
};
} else {
return {
type: 'DEFENSIVE_BUILD',
target: null,
minUnits: 35
};
}
} else if (tower.owner === 4) {
// Faction 4: Economic Opportunist - focuses on efficient expansion
var nearbyNeutrals = findNearbyNeutralTowers(tower, 600);
if (nearbyNeutrals.length > 0 && tower.unitCount > 15) {
return {
type: 'ECONOMIC_EXPANSION',
target: nearbyNeutrals[0],
minUnits: 12
};
} else if (opportunities.length > 0 && getDistance(tower, opportunities[0].tower) < 500) {
return {
type: 'EFFICIENT_CAPTURE',
target: opportunities[0].tower,
minUnits: opportunities[0].tower.unitCount + 5
};
} else {
return {
type: 'RESOURCE_BUILD',
target: null,
minUnits: 25
};
}
} else {
// Default faction: Balanced approach
if (opportunities.length > 0 && tower.unitCount > 18) {
return {
type: 'BALANCED_ATTACK',
target: opportunities[0].tower,
minUnits: 15
};
} else {
return {
type: 'DEFENSIVE_BUILD',
target: null,
minUnits: 20
};
}
}
}
// Execute the determined strategy
function executeStrategy(tower, strategy, gameState) {
if (!strategy.target && strategy.type.indexOf('BUILD') === -1) return;
if (tower.unitCount < strategy.minUnits) return;
var unitsToSend;
switch (strategy.type) {
case 'EMERGENCY_DEFENSE':
unitsToSend = Math.floor(tower.unitCount * 0.8); // Send most units in emergency
break;
case 'PRESS_ADVANTAGE':
unitsToSend = Math.floor(tower.unitCount * 0.7); // Aggressive when winning
break;
case 'COORDINATED_COUNTER':
unitsToSend = Math.floor(tower.unitCount * 0.6); // Calculated counter-attack
break;
case 'OPPORTUNISTIC_STRIKE':
case 'CALCULATED_STRIKE':
case 'EFFICIENT_CAPTURE':
unitsToSend = Math.min(Math.floor(tower.unitCount * 0.6), strategy.target.unitCount + 10);
break;
case 'ECONOMIC_EXPANSION':
unitsToSend = Math.floor(tower.unitCount * 0.4); // Conservative expansion
break;
case 'AGGRESSIVE_EXPAND':
case 'BALANCED_ATTACK':
unitsToSend = Math.floor(tower.unitCount * 0.5); // Standard attack
break;
default:
return;
// No action for build strategies
}
if (strategy.target && unitsToSend > 0) {
sendUnits(tower, strategy.target, unitsToSend);
}
}
// Helper functions for target selection
function findWeakestPlayerTower(playerTowers, fromTower) {
var weakest = null;
var minUnits = Infinity;
for (var i = 0; i < playerTowers.length; i++) {
if (playerTowers[i].unitCount < minUnits) {
minUnits = playerTowers[i].unitCount;
weakest = playerTowers[i];
}
}
return weakest;
}
function findStrongestPlayerTower(playerTowers, fromTower) {
var strongest = null;
var maxUnits = 0;
for (var i = 0; i < playerTowers.length; i++) {
if (playerTowers[i].unitCount > maxUnits) {
maxUnits = playerTowers[i].unitCount;
strongest = playerTowers[i];
}
}
return strongest;
}
function findNearestEnemy(fromTower) {
var nearest = null;
var minDist = Infinity;
for (var i = 0; i < towers.length; i++) {
if (towers[i].owner !== fromTower.owner) {
var dist = getDistance(fromTower, towers[i]);
if (dist < minDist) {
minDist = dist;
nearest = towers[i];
}
}
}
return nearest;
}
function findNearbyNeutralTowers(fromTower, maxDistance) {
var nearby = [];
for (var i = 0; i < towers.length; i++) {
if (towers[i].owner === 0) {
var dist = getDistance(fromTower, towers[i]);
if (dist <= maxDistance) {
nearby.push(towers[i]);
}
}
}
return nearby.sort(function (a, b) {
return getDistance(fromTower, a) - getDistance(fromTower, b);
});
}
game.down = function (x, y, obj) {
// Find if we clicked on a player tower (scaled up detection area)
for (var i = 0; i < towers.length; i++) {
var tower = towers[i];
if (tower.owner === 1 && Math.abs(tower.x - x) < 75 && Math.abs(tower.y - y) < 75) {
selectedTower = tower;
isDragging = true;
if (!currentPath) {
currentPath = new PathLine();
game.addChild(currentPath);
}
currentPath.setPath([{
x: tower.x,
y: tower.y
}]);
break;
}
}
};
game.move = function (x, y, obj) {
if (isDragging && selectedTower && currentPath) {
currentPath.setPath([{
x: selectedTower.x,
y: selectedTower.y
}, {
x: x,
y: y
}]);
}
};
game.up = function (x, y, obj) {
if (isDragging && selectedTower) {
// Find target tower (scaled up detection area)
var targetTower = null;
for (var i = 0; i < towers.length; i++) {
var tower = towers[i];
if (tower !== selectedTower && Math.abs(tower.x - x) < 75 && Math.abs(tower.y - y) < 75) {
targetTower = tower;
break;
}
}
if (targetTower && selectedTower.unitCount > 0) {
sendUnits(selectedTower, targetTower, Math.floor(selectedTower.unitCount * 0.5));
}
if (currentPath) {
currentPath.clear();
}
}
isDragging = false;
selectedTower = null;
};
game.update = function () {
// Update all units
for (var i = units.length - 1; i >= 0; i--) {
if (!units[i] || !units[i].parent) {
units.splice(i, 1);
}
}
// Run AI every 2 seconds
if (LK.ticks % 120 === 0) {
runAI();
}
// Run memory cleanup
memoryManager.performCleanup();
// Check win/lose conditions
if (LK.ticks % 60 === 0) {
checkWinCondition();
}
// Update unit count display every 30 ticks (twice per second)
if (LK.ticks % 30 === 0) {
updateUnitCountDisplay();
}
};
// Create Reset button
var resetButton = new Text2('Reset', {
size: 60,
fill: 0xFFFFFF
});
resetButton.anchor.set(1, 1); // Anchor to bottom right
LK.gui.bottomRight.addChild(resetButton);
// Reset button functionality
resetButton.down = function (x, y, obj) {
// Reset all game state
currentLevel = 0;
storage.currentLevel = 0;
// Clear existing game objects
for (var i = 0; i < towers.length; i++) {
towers[i].destroy();
}
for (var i = 0; i < units.length; i++) {
units[i].destroy();
}
towers = [];
units = [];
if (currentPath) {
currentPath.destroy();
currentPath = null;
}
// Reset game state variables
selectedTower = null;
isDragging = false;
aiStartTime = null;
// Load first level
loadLevel(currentLevel);
};
// Initialize first level
loadLevel(currentLevel);
// Memory Management and Performance Optimization System
var memoryManager = {
// Object pools for reusing objects instead of creating new ones
unitPool: [],
sparklePool: [],
pathDotPool: [],
// Memory cleanup settings
cleanupInterval: 300,
// Clean up every 5 seconds (300 ticks at 60fps)
lastCleanup: 0,
// Get unit from pool or create new one
getUnit: function getUnit() {
if (this.unitPool.length > 0) {
var unit = this.unitPool.pop();
// Reset unit properties
unit.alpha = 1;
unit.visible = true;
unit.owner = 1;
unit.speed = 3;
unit.targetTower = null;
unit.pathIndex = 0;
unit.path = [];
unit.lastWasIntersecting = false;
return unit;
}
return new Unit();
},
// Return unit to pool instead of destroying
recycleUnit: function recycleUnit(unit) {
if (unit && unit.parent) {
unit.parent.removeChild(unit);
unit.visible = false;
this.unitPool.push(unit);
}
},
// Get sparkle from pool or create new one
getSparkle: function getSparkle() {
if (this.sparklePool.length > 0) {
var sparkle = this.sparklePool.pop();
sparkle.alpha = 1;
sparkle.visible = true;
sparkle.scaleX = 0.5 + Math.random() * 0.5;
sparkle.scaleY = sparkle.scaleX;
return sparkle;
}
return game.attachAsset('sparkle', {
anchorX: 0.5,
anchorY: 0.5
});
},
// Return sparkle to pool
recycleSparkle: function recycleSparkle(sparkle) {
if (sparkle && sparkle.parent) {
sparkle.parent.removeChild(sparkle);
sparkle.visible = false;
this.sparklePool.push(sparkle);
}
},
// Periodic memory cleanup
performCleanup: function performCleanup() {
if (LK.ticks - this.lastCleanup < this.cleanupInterval) {
return;
}
this.lastCleanup = LK.ticks;
// Clean up destroyed units from arrays
for (var i = units.length - 1; i >= 0; i--) {
if (!units[i] || !units[i].parent) {
units.splice(i, 1);
}
}
// Limit pool sizes to prevent excessive memory usage
if (this.unitPool.length > 50) {
// Actually destroy excess units
var excess = this.unitPool.splice(50);
for (var i = 0; i < excess.length; i++) {
if (excess[i].destroy) {
excess[i].destroy();
}
}
}
if (this.sparklePool.length > 100) {
var excess = this.sparklePool.splice(100);
for (var i = 0; i < excess.length; i++) {
if (excess[i].destroy) {
excess[i].destroy();
}
}
}
if (this.pathDotPool.length > 200) {
var excess = this.pathDotPool.splice(200);
for (var i = 0; i < excess.length; i++) {
if (excess[i].destroy) {
excess[i].destroy();
}
}
}
// Force garbage collection hint by nullifying references
var temp = [];
temp = null;
}
};
// Create unit count panel in bottom left
var unitCountPanel = new Container();
LK.gui.bottomLeft.addChild(unitCountPanel);
// Panel background (optional visual enhancement)
var panelBg = LK.getAsset('tower', {
width: 300,
height: 200,
anchorX: 0,
anchorY: 1,
alpha: 0.3
});
unitCountPanel.addChild(panelBg);
// Player unit count text
var playerCountText = new Text2('Oyuncu: 0', {
size: 40,
fill: 0x4a90e2 // Player blue color
});
playerCountText.anchor.set(0, 1);
playerCountText.x = 10;
playerCountText.y = -10;
unitCountPanel.addChild(playerCountText);
// Enemy faction count texts
var enemyCountTexts = [];
var enemyColors = [0xe74c3c, 0x9b59b6, 0xf39c12]; // Red, purple, orange
for (var i = 0; i < 3; i++) {
var enemyText = new Text2('Rakip ' + (i + 1) + ': 0', {
size: 40,
fill: enemyColors[i]
});
enemyText.anchor.set(0, 1);
enemyText.x = 10;
enemyText.y = -50 - i * 40;
unitCountPanel.addChild(enemyText);
enemyCountTexts.push(enemyText);
}
// Function to update unit count display
function updateUnitCountDisplay() {
var playerUnits = 0;
var enemyUnits = [0, 0, 0]; // For factions 2, 3, 4
// Count units in towers
for (var i = 0; i < towers.length; i++) {
var tower = towers[i];
if (tower.owner === 1) {
playerUnits += tower.unitCount;
} else if (tower.owner >= 2 && tower.owner <= 4) {
enemyUnits[tower.owner - 2] += tower.unitCount;
}
}
// Count units in transit
for (var i = 0; i < units.length; i++) {
var unit = units[i];
if (unit.owner === 1) {
playerUnits++;
} else if (unit.owner >= 2 && unit.owner <= 4) {
enemyUnits[unit.owner - 2]++;
}
}
// Update display texts
playerCountText.setText('Oyuncu: ' + playerUnits);
for (var i = 0; i < enemyCountTexts.length; i++) {
enemyCountTexts[i].setText('Rakip ' + (i + 1) + ': ' + enemyUnits[i]);
}
}
// Play background music
LK.playMusic('battle');
;
Saldırı kulesi, Gerçekçi, kuş bakışı görünüm, yazısız.. In-Game asset. High contrast. No shadows, 3d olsun.
Saldırı kulesi, Gerçekçi, kuş bakışı görünüm, yazısız.. In-Game asset. High contrast. No shadows, 3d olsun.
Gece çölü arkaplan resmi, Gerçekçi, kuş bakışı görünüm, yazısız. susuz. In-Game asset. High contrast. No shadows, 3d olsun..
Kılıç ve kalkanlı çağı saldırı askeri, Gerçekçi, kuş bakışı görünüm, yazısız.. In-Game asset. High contrast. No shadows, renkli 3d olsun.