User prompt
Nasıl Oynanır butonunu 1 satır aşağı indir. Ayrıca panelin sağ altına paneli kapatmak için Kapat butonu ekle.
User prompt
🔊 Bu iconu ekle.
User prompt
Arkaplan müziği olarak "backgroundmusic" de seçili olan müzik olsun.
User prompt
Oyunu durdur butonunun sağına, arkaplan müzik açma kapatma iconu ekle.
User prompt
Nasıl Oynanır panelinin sağ altına paneli kapatmak için kapat butonu ekle.
User prompt
Şuan k, oyunun arkaplan resminin resim dosyasını oluştur
User prompt
Nasıl Oynanır panel arkasının resim dosyasını oluştur
User prompt
Oyunu Sıfırla yazısının altına Nasıl Oynanır İsimli buton ekle. Bu butonun içerisine açılır panel oluştur ve bu panele de bu en son oluşturduğumuz yazıyı yapıştır.
User prompt
Oyunu sıfırla butonu altına hizalı ve oranlı şekilde Nasıl Oynanır konusunda bilgi yazısı yaz.
User prompt
Düşman gemileri kulelere yaklaşınca kulelere ateş etmeye başlasın.
User prompt
Bu durumu kodları inceleyerek çöz. üşman gemisinin koloniye saldırmamasının nedeni, kodun "aktif kule ve savaşçı yoksa saldır" kontrolünde, arraylerde "ölü" ama silinmemiş objelerin olması veya birimlerin görünürlük/hp bilgilerinin yanlış güncellenmesi olabilir. Ayrıca, state geçişinde bir bug varsa, düşman gemisi "attacking" durumuna geçmeyip bekleyebilir. Böyle bir durum olmasın. Düzelt.
User prompt
Düşman binası yok olunca çıkan sürenin altında kazanmış olduğumuz ödül de yazsın.
User prompt
Hayatta kaldığımız süre boyunca her saniye rastgele 1 maden eklensin.
User prompt
Başlangıç toplam kaynak sayısını 200 yap.
User prompt
Yalnızca koloni seviye yükselt butonunu 0.5 satır aşağı taşı. Diğer herşey yerinde durmaya devam etsin.
User prompt
Yalnızca koloni seviye yazısını 1 satır yukarı taşı. Diğerleri yerinde durmaya devam etsin.
User prompt
Yalnızca koloni seviye yükselt butonunu 2 satır yukarı taşı. Diğer herşey yerinde durmaya devam etsin.
User prompt
Koloni seviye ve yükselt butonlarını 2 satır yukarı taşı.
User prompt
Koloni seviye: yazısına, koloni seviye yükseltme işlemini ekle.
User prompt
Seviye sistemini savunma kulesi seviye yükselt butonunun üst kısmına yerleştir.
User prompt
Koloniye seviye sistemini ekle. Her seviye yükseldikçe maxhp +10 olsun.
User prompt
Görünmesi için ne gerekiyor ise onu yap.
User prompt
Savaşçı satın al paneline eklensin ve panelin 2 satır üst hizasına yerleştirilsin. Görünür hale gelsin.
User prompt
Koloni seviyesi yükseltme butonu görünmüyor. Görünmesini sağla.
User prompt
Sadece Koloni seviye yükseltme butonunu savaşçı satın al panelinin 2 satır yukarısına hizalı şekilde yerleştir. Tamir et ve seviye bilgisi yerinde kalsın.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ // Asteroit Avcısı (Collector) var AsteroidHunter = Container.expand(function () { var self = Container.call(this); var col = self.attachAsset('collector', { anchorX: 0.5, anchorY: 0.5 }); self.target = null; // Avcı hızı, kaynak hızından %25 fazla olacak şekilde ayarlanır self.speed = 1.25 * (0.002 + 0.001) * 0.1 * 2732; // Kaynakların max hızından %25 fazla (normalize için 2732 ile çarpıldı) self.state = 'idle'; // idle, moving, returning self.update = function () { if (self.state === 'moving' && self.target) { var dx = self.target.x - self.x; var dy = self.target.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); // --- Avcı mermi sıksın: 60 tickte bir (1 saniyede bir) --- if (typeof self.lastShot === "undefined") self.lastShot = 0; if (typeof self.shootDelay === "undefined") self.shootDelay = 60; if (LK.ticks - self.lastShot > self.shootDelay && dist > 20) { var b = new Container(); var bulletAsset = b.attachAsset('collector_bullet', { anchorX: 0.5, anchorY: 0.5 }); b.x = self.x; b.y = self.y; // Asteroide doğru yönlendir var tdist = Math.sqrt(dx * dx + dy * dy); b.dirX = tdist > 0 ? dx / tdist : 0; b.dirY = tdist > 0 ? dy / tdist : -1; b.speed = 18 * 0.1 * 1.25 * 1.25; // Başlangıçta %25 daha hızlı (toplamda %56.25 hızlı) b.update = function () { b.x += b.dirX * b.speed; b.y += b.dirY * b.speed; // Asteroide çarptıysa yok et if (self.target && b.intersects(self.target)) { if (typeof self.target.hp === "number" && self.target.hp > 0) { self.target.hp -= 1; } b.destroy(); if (typeof bullets !== "undefined") { var idx = bullets.indexOf(b); if (idx !== -1) bullets.splice(idx, 1); } } // Ekran dışıysa yok et if (b.x < -100 || b.x > 2148 || b.y < -100 || b.y > 2832) { b.destroy(); if (typeof bullets !== "undefined") { var idx = bullets.indexOf(b); if (idx !== -1) bullets.splice(idx, 1); } } }; if (typeof bullets !== "undefined") bullets.push(b); if (typeof game !== "undefined") game.addChild(b); self.lastShot = LK.ticks; } // Asteroit görselinin dışından saldırı: asteroidin görsel yarıçapı + avcı yarıçapı kadar mesafede dur var asteroidRadius = 0; if (self.target && self.target.children && self.target.children.length > 0 && self.target.children[0].width) { asteroidRadius = (self.target.children[0].width * self.target.children[0].scaleX || 1) * 0.5; } else { asteroidRadius = 60; // fallback } var hunterRadius = col && col.width ? col.width * (col.scaleX || 1) * 0.5 : 50; var stopDistance = asteroidRadius + hunterRadius + 8; // 8px tampon if (dist < stopDistance) { // Asteroide yeterince yaklaştı, daha fazla yaklaşma, state'i 'returning' yap self.state = 'returning'; } else { // Asteroide yaklaş, ama içine girme self.x += self.speed * dx / dist; self.y += self.speed * dy / dist; } } else if (self.state === 'returning') { var dx = colony.x - self.x; var dy = colony.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < 10) { self.state = 'idle'; self.target = null; } else { self.x += self.speed * dx / dist; self.y += self.speed * dy / dist; } } }; return self; }); // Asteroid ve kaynak çıkışı için yeni AsteroidNode class'ı var AsteroidNode = Container.expand(function () { var self = Container.call(this); // Kaynak türleri ve asteroid asset id'leri var asteroidTypes = [{ name: "Altın", asset: "asteroid_gold", resourceAsset: "resource_gold" }, { name: "Kobalt", asset: "asteroid_cobalt", resourceAsset: "resource_cobalt" }, { name: "Nikel", asset: "asteroid_nickel", resourceAsset: "resource_nickel" }, { name: "Helyum-3", asset: "asteroid_helium3", resourceAsset: "resource_helium3" }, { name: "Platin", asset: "asteroid_platinum", resourceAsset: "resource_platinum" }, { name: "Demir", asset: "asteroid_iron", resourceAsset: "resource_iron" }, { name: "Manganez", asset: "asteroid_manganese", resourceAsset: "resource_manganese" }]; // Rastgele bir kaynak türü seç var typeIndex = Math.floor(Math.random() * asteroidTypes.length); self.resourceType = asteroidTypes[typeIndex].name; self.asteroidAsset = asteroidTypes[typeIndex].asset; self.resourceAsset = asteroidTypes[typeIndex].resourceAsset; // Asteroid görseli var ast = self.attachAsset(self.asteroidAsset, { anchorX: 0.5, anchorY: 0.5 }); self.hp = 3 + Math.floor(Math.random() * 3); // 3-5 arası can self.collected = false; self.resourceSpawned = false; // Hareket: Rastgele kenardan giriş var edge = Math.floor(Math.random() * 4); var startX, startY, endX, endY; var margin = 120; if (edge === 0) { startX = -margin; startY = 400 + Math.random() * (2732 - 800); endX = 2048 + margin; endY = startY + (Math.random() - 0.5) * 400; } else if (edge === 1) { startX = 2048 + margin; startY = 400 + Math.random() * (2732 - 800); endX = -margin; endY = startY + (Math.random() - 0.5) * 400; } else if (edge === 2) { startX = Math.random() * 2048; startY = -margin; endX = startX + (Math.random() - 0.5) * 400; endY = 2732 + margin; } else { startX = Math.random() * 2048; startY = 2732 + margin; endX = startX + (Math.random() - 0.5) * 400; endY = -margin; } self.x = startX; self.y = startY; self._moveStartX = startX; self._moveStartY = startY; self._moveEndX = endX; self._moveEndY = endY; self._moveProgress = 0; self._moveSpeed = (0.002 + Math.random() * 0.001) * 0.1; self.visible = true; self.resourceNode = null; // Kaynak nesnesi referansı self.update = function () { if (self.collected) return; // Hareket ilerlemesini güncelle self._moveProgress += self._moveSpeed; if (self._moveProgress > 1) { self.collected = true; self.visible = false; return; } // Lineer hareket self.x = self._moveStartX + (self._moveEndX - self._moveStartX) * self._moveProgress; self.y = self._moveStartY + (self._moveEndY - self._moveStartY) * self._moveProgress; // --- Asteroid boyutunu koloniye yaklaştıkça büyüt --- // Koloniye olan mesafeyi hesapla if (typeof colony !== "undefined" && colony && typeof colony.x === "number" && typeof colony.y === "number") { var dxCol = self.x - colony.x; var dyCol = self.y - colony.y; var distCol = Math.sqrt(dxCol * dxCol + dyCol * dyCol); // Maksimum mesafe: ekran köşesinden koloniye (en uzak ~2732) var maxDist = 2732; // Minimum scale: 0.25, Maksimum scale: 1.2 var minScale = 0.25; var maxScale = 1.2; // Koloniye yaklaştıkça scale artar, uzaktayken küçüktür var t = 1 - Math.min(distCol / maxDist, 1); var scale = minScale + (maxScale - minScale) * t; // Asteroit görselini ölçekle if (ast) { ast.scaleX = scale; ast.scaleY = scale; } } // Asteroid yok edildi ve kaynak çıkmadıysa kaynak çıkar if (self.hp <= 0 && !self.resourceSpawned) { self.resourceSpawned = true; // Kaynak node'u oluştur var resNode = new ResourceNode(self.resourceType, self.resourceAsset); resNode.x = self.x; resNode.y = self.y; if (typeof resourceNodes !== "undefined") resourceNodes.push(resNode); if (typeof game !== "undefined") game.addChild(resNode); self.collected = true; self.visible = false; } }; return self; }); // Mermi var Bullet = Container.expand(function () { var self = Container.call(this); var b = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 40 * 0.1; self.dirX = 0; self.dirY = -1; self.from = 'player'; // veya 'enemy' self.targetEnemy = null; // Eğer hedef varsa self.attackPower = 1; // Her merminin saldırı gücü 1 olsun self.update = function () { // Eğer bu oyuncu mermisi ve hedefi varsa, hedefe yönel if (self.from === 'player' && self.targetEnemy && typeof self.targetEnemy.x === "number" && typeof self.targetEnemy.y === "number") { var dx = self.targetEnemy.x - self.x; var dy = self.targetEnemy.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { self.dirX = dx / dist; self.dirY = dy / dist; } } self.x += self.dirX * self.speed; self.y += self.dirY * self.speed; // Savunma kulesi mermisi hedefe ulaşınca veya düşman gemisine değince yok olsun if (self.from === 'player') { // Hedefe çok yaklaştıysa yok et if (self.targetEnemy && typeof self.targetEnemy.x === "number" && typeof self.targetEnemy.y === "number") { var dx = self.targetEnemy.x - self.x; var dy = self.targetEnemy.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < 30) { self.destroy(); if (typeof bullets !== "undefined") { var idx = bullets.indexOf(self); if (idx !== -1) bullets.splice(idx, 1); } return; } } // Düşman gemisine değerse yok et (güvenlik için) if (typeof enemyShips !== "undefined") { for (var i = 0; i < enemyShips.length; i++) { var e = enemyShips[i]; if (e.visible && typeof e.x === "number" && typeof e.y === "number" && self.intersects(e)) { self.destroy(); if (typeof bullets !== "undefined") { var idx = bullets.indexOf(self); if (idx !== -1) bullets.splice(idx, 1); } break; } } } } }; return self; }); // Koloni ana üssü var Colony = Container.expand(function () { var self = Container.call(this); var c = self.attachAsset('colony', { anchorX: 0.5, anchorY: 0.5 }); // Koloni canı self.maxHp = 100; // Maksimum can 100 self.hp = 50; // Başlangıç canı 50 return self; }); // Savunma Kulesi (DefenseTower) var DefenseTower = Container.expand(function () { var self = Container.call(this); // 10 farklı kule görseli var towerImages = ['defense_tower1', 'defense_tower2', 'defense_tower3', 'defense_tower4', 'defense_tower5', 'defense_tower6', 'defense_tower7', 'defense_tower8', 'defense_tower9', 'defense_tower10']; var towerImageIndex = Math.floor(Math.random() * towerImages.length); self.towerImageId = towerImages[towerImageIndex]; var t = self.attachAsset(self.towerImageId, { anchorX: 0.5, anchorY: 0.5 }); // Kule özellikleri self.level = 1; self.maxHp = 20; self.hp = self.maxHp; self.baseAttackPower = 3; self.attackPower = self.baseAttackPower; self.range = 600; // px self.shootDelay = 40; // 0.66s self.lastShot = 0; self.targetEnemy = null; // Kule maxHp ve saldırı gücünü seviyeye göre ayarlayan fonksiyon self.updateStatsByLevel = function () { // Saldırı gücü: her seviye başı %25 artar self.attackPower = Math.round(self.baseAttackPower * Math.pow(1.25, self.level - 1)); // Max HP: her seviye başı +10 ekle self.maxHp = 20 + (self.level - 1) * 10; // Eğer mevcut HP yeni maxHp'den fazlaysa, kırp if (self.hp > self.maxHp) self.hp = self.maxHp; }; self.updateStatsByLevel(); // Kule can barı self.hpBarBg = LK.getAsset('colony_hpbar_bg', { anchorX: 0.5, anchorY: 0.5 }); self.hpBar = LK.getAsset('colony_hpbar_fg', { anchorX: 0.5, anchorY: 0.5 }); self.hpBarBg.x = 0; self.hpBarBg.y = -90; self.hpBar.x = 0; self.hpBar.y = -90; self.addChild(self.hpBarBg); self.addChild(self.hpBar); // Seviye yazısı self.levelTxt = new Text2('Lv.' + self.level, { size: 24, fill: "#fff", dropShadow: true, dropShadowColor: 0x000000, dropShadowDistance: 2, dropShadowAngle: Math.PI / 4, dropShadowBlur: 4, dropShadowAlpha: 0.7 }); self.levelTxt.anchor.set(0.5, 0); self.levelTxt.x = 0; self.levelTxt.y = 60; self.addChild(self.levelTxt); // Kule can yazısı self.hpTxt = new Text2(self.hp + ' / ' + self.maxHp, { size: 22, fill: "#fff", dropShadow: true, dropShadowColor: 0x000000, dropShadowDistance: 2, dropShadowAngle: Math.PI / 4, dropShadowBlur: 4, dropShadowAlpha: 0.7 }); self.hpTxt.anchor.set(0.5, 1); self.hpTxt.x = 0; self.hpTxt.y = -110; self.addChild(self.hpTxt); // Kule update fonksiyonu self.update = function () { // Can barı ve yazılarını güncelle var ratio = self.hp / self.maxHp; if (ratio < 0) ratio = 0; if (ratio > 1) ratio = 1; self.hpBar.width = 86 * ratio; self.hpBar.visible = self.visible; self.hpBarBg.visible = self.visible; self.hpTxt.setText(Math.round(self.hp) + ' / ' + self.maxHp); self.hpTxt.visible = self.visible; self.levelTxt.setText('Lv.' + self.level); self.levelTxt.visible = self.visible; // Kule yoksa update etme if (!self.visible || self.hp <= 0) return; // Saldırı gücü ve maxHp'yi seviyeye göre güncelle self.updateStatsByLevel(); // Hedef düşman bul var nearestEnemy = null; var minDist = 999999; if (typeof enemyShips !== "undefined") { for (var i = 0; i < enemyShips.length; i++) { var e = enemyShips[i]; if (!e.visible || e.hp <= 0) continue; var dx = e.x - self.x; var dy = e.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < self.range && dist < minDist) { minDist = dist; nearestEnemy = e; } } } self.targetEnemy = nearestEnemy; // Ateş et if (self.targetEnemy && LK.ticks - self.lastShot > self.shootDelay) { var b = new Bullet(); b.x = self.x; b.y = self.y - 60; b.targetEnemy = self.targetEnemy; var tx = self.targetEnemy.x - self.x; var ty = self.targetEnemy.y - self.y; var tdist = Math.sqrt(tx * tx + ty * ty); if (tdist > 0) { b.dirX = tx / tdist; b.dirY = ty / tdist; } else { b.dirX = 0; b.dirY = -1; } b.from = 'player'; b.attackPower = self.attackPower; bullets.push(b); if (typeof game !== "undefined") game.addChild(b); self.lastShot = LK.ticks; } }; // Kule seviye atlatma fonksiyonu self.levelUp = function () { self.level++; self.updateStatsByLevel(); self.levelTxt.setText('Lv.' + self.level); self.hpTxt.setText(Math.round(self.hp) + ' / ' + self.maxHp); }; // Kule tamir fonksiyonu self.repair = function (amount) { self.hp += amount; if (self.hp > self.maxHp) self.hp = self.maxHp; }; // Kule yok olunca görünmez yap self.destroyTower = function () { self.visible = false; self.hp = 0; self.x = -9999; self.y = -9999; }; return self; }); // 60 saniye * 60 FPS // Düşman gemisi class'ı (önce base etrafında yavaşça döner, sonra saldırır) var EnemyShip = Container.expand(function () { var self = Container.call(this); // 10 farklı düşman görseli var enemyImages = ['enemy1', 'enemy2', 'enemy3', 'enemy4', 'enemy5', 'enemy6', 'enemy7', 'enemy8', 'enemy9', 'enemy10']; // Rastgele bir düşman görseli seç var enemyImageIndex = Math.floor(Math.random() * enemyImages.length); self.enemyImageId = enemyImages[enemyImageIndex]; var s = self.attachAsset(self.enemyImageId, { anchorX: 0.5, anchorY: 0.5 }); self.x = topAsteroid.x; self.y = topAsteroid.y + 80; // Askerler gibi yavaş hız: ResourceHunter ile aynı hız self.speed = 1.1 * (0.002 + 0.001) * 0.1 * 2732; // 0.0003*0.1*2732 ≈ 0.08*2732 ≈ 218 self.lastShot = 0; self.shootDelay = 60; // 1 saniyede bir ateş etsin // Düşman binası seviyesiyle orantılı olarak can ve saldırı gücü artırılır var baseLevel = typeof enemyBaseLevel !== "undefined" ? enemyBaseLevel : 1; self.hp = Math.floor(3 * Math.pow(1.5, baseLevel - 1)); self.maxHp = self.hp; self.state = 'orbiting'; // 'orbiting' -> 'attacking' self.orbitTime = 0; self.orbitDuration = 180; // 3 saniye boyunca base etrafında dönecek self.orbitRadius = 180 + Math.random() * 60; // 180-240px arası self.orbitAngle = Math.random() * Math.PI * 2; // Düşman gemisinin saldırı gücü, enemyBaseAttackPower ile ve seviye bonusu ile ölçeklenir self.attackPower = (typeof enemyBaseAttackPower !== "undefined" ? enemyBaseAttackPower : 2) * Math.pow(1.5, baseLevel - 1); self.update = function () { // Düşman sağlık barı oluşturulmamışsa ekle if (!self.hpBarBg) { self.hpBarBg = LK.getAsset('ship_hpbar_bg', { anchorX: 0.5, anchorY: 0.5 }); self.hpBar = LK.getAsset('ship_hpbar_fg', { anchorX: 0.5, anchorY: 0.5 }); self.hpBarBg.x = self.x; self.hpBarBg.y = self.y - 50; self.hpBar.x = self.x; self.hpBar.y = self.y - 50; if (typeof game !== "undefined") { game.addChild(self.hpBarBg); game.addChild(self.hpBar); } } // Sağlık barı pozisyon ve genişlik güncelle if (self.hpBar && self.hpBarBg) { self.hpBarBg.x = self.x; // Güvenli şekilde s.height ve s.scaleY kontrolü, yoksa fallback değer kullan var sHeight = s && typeof s.height === "number" ? s.height : 100; var sScaleY = s && typeof s.scaleY === "number" ? s.scaleY : 1; self.hpBarBg.y = self.y - sHeight * sScaleY / 2 - 18; // Düşman görselinin üstüne hizala self.hpBar.x = self.x; self.hpBar.y = self.hpBarBg.y; var maxHp = typeof self.maxHp === "number" ? self.maxHp : 3; var ratio = typeof self.hp === "number" && maxHp > 0 ? self.hp / maxHp : 0; if (ratio < 0) ratio = 0; if (ratio > 1) ratio = 1; self.hpBar.width = 86 * ratio; self.hpBar.visible = self.visible; self.hpBarBg.visible = self.visible; } // Takip mesafesi ve çakışmayı önleme var followDistance = 80; // px, minimum mesafe if (typeof enemyShips !== "undefined" && enemyShips.length > 1) { for (var i = 0; i < enemyShips.length; i++) { var e = enemyShips[i]; if (e === self || !e.visible || typeof e.x !== "number" || typeof e.y !== "number") continue; var dxE = e.x - self.x; var dyE = e.y - self.y; var distE = Math.sqrt(dxE * dxE + dyE * dyE); if (distE < followDistance && distE > 0) { // Düşman gemileri birbirine çok yakınsa, uzaklaş self.x -= (followDistance - distE) * dxE / distE * 0.5; self.y -= (followDistance - distE) * dyE / distE * 0.5; } } } if (self.state === 'orbiting') { // Base etrafında yavaşça daire çiz self.orbitTime++; self.orbitAngle += 0.012; // Yavaşça döner self.x = topAsteroid.x + Math.cos(self.orbitAngle) * self.orbitRadius; self.y = topAsteroid.y + Math.sin(self.orbitAngle) * self.orbitRadius; if (self.orbitTime > self.orbitDuration) { self.state = 'approaching'; // Saldırıya başlarken hedefi koloniye kilitle self.attackTargetX = colony.x; self.attackTargetY = colony.y; } } else if (self.state === 'approaching') { // Koloniye yaklaşana kadar ilerle, ama saldırma var dx = self.attackTargetX - self.x; var dy = self.attackTargetY - self.y; var dist = Math.sqrt(dx * dx + dy * dy); // Koloniye belli bir mesafeye (ör: 350px) kadar yaklaşınca önce kulelere saldır var engageRadius = 350; if (dist > engageRadius) { if (dist > 0) { self.x += self.speed * dx / dist; self.y += self.speed * dy / dist; } } else { // Koloniye yaklaştı, önce kulelere saldır self.state = 'engaging_tower'; } } else if (self.state === 'engaging_tower') { // Önce kulelere saldır, kule kalmayınca savaşçılara geç var nearestTower = null; var minTowerDist = 999999; var activeTowerCount = 0; if (typeof defenseTowers !== "undefined") { for (var i = 0; i < defenseTowers.length; i++) { var t = defenseTowers[i]; if (!t.visible || t.hp <= 0) continue; activeTowerCount++; var dxT = t.x - self.x; var dyT = t.y - self.y; var distT = Math.sqrt(dxT * dxT + dyT * dyT); if (distT < minTowerDist) { minTowerDist = distT; nearestTower = t; } } } if (nearestTower) { // Kuleye yaklaş ve saldır if (minTowerDist > 40) { self.x += self.speed * (nearestTower.x - self.x) / minTowerDist; self.y += self.speed * (nearestTower.y - self.y) / minTowerDist; } // Her 1 saniyede bir kuleye ateş et if (typeof self.lastTowerShot === "undefined") self.lastTowerShot = 0; if (typeof self.towerShootDelay === "undefined") self.towerShootDelay = 60; if (LK.ticks - self.lastTowerShot > self.towerShootDelay) { nearestTower.hp -= Math.max(1, Math.round(self.attackPower)); LK.effects.flashObject(nearestTower, 0xff0000, 400); self.lastTowerShot = LK.ticks; } } else { // Kule kalmadı, savaşçılara saldır self.state = 'engaging'; } } else if (self.state === 'engaging') { // Sadece bizim gemilere saldır, koloniye saldırmaz // En yakın oyuncu savaşçısını bul var nearestShip = null; var minDist = 999999; var activeShipCount = 0; if (ship && ship.visible && typeof ship.x === "number" && typeof ship.y === "number" && ship.hp > 0) { var dxs = ship.x - self.x; var dys = ship.y - self.y; var dists = Math.sqrt(dxs * dxs + dys * dys); if (dists < minDist) { minDist = dists; nearestShip = ship; } activeShipCount++; } // Ekstra savaşçı gemileri de hedef olarak ekle if (typeof extraShips !== "undefined") { for (var i = 0; i < extraShips.length; i++) { var s = extraShips[i]; if (!s.visible || typeof s.x !== "number" || typeof s.y !== "number" || s.hp <= 0) continue; var dxs = s.x - self.x; var dys = s.y - self.y; var dists = Math.sqrt(dxs * dxs + dys * dys); if (dists < minDist) { minDist = dists; nearestShip = s; } activeShipCount++; } } // Eğer yakınsa ona yaklaş ve ateş et if (nearestShip && minDist < 400) { // Yaklaş if (minDist > 40) { self.x += self.speed * (nearestShip.x - self.x) / minDist; self.y += self.speed * (nearestShip.y - self.y) / minDist; } // Ateş etme (her 1 saniyede bir) if (LK.ticks - self.lastShot > self.shootDelay) { var b = new Bullet(); b.x = self.x; b.y = self.y + 40; b.dirX = nearestShip.x - self.x; b.dirY = nearestShip.y - self.y; var bdist = Math.sqrt(b.dirX * b.dirX + b.dirY * b.dirY); if (bdist > 0) { b.dirX /= bdist; b.dirY /= bdist; } else { b.dirX = 0; b.dirY = 1; } b.from = 'enemy'; b.attackPower = self.attackPower; // enemyBaseAttackPower ile ölçekli bullets.push(b); game.addChild(b); self.lastShot = LK.ticks; } // Eğer oyuncu gemisi yok olduysa, tekrar koloniye saldırmaya başla if (nearestShip.hp <= 0 || !nearestShip.visible) { self.state = 'attacking'; } } else { // Oyuncu gemisi yoksa veya çok uzaktaysa, tekrar koloniye saldır // --- DEĞİŞİKLİK: Eğer kule ve savaşçı gemisi yoksa koloniye saldırabilir --- if (activeTowerCount === 0 && activeShipCount === 0) { self.state = 'attacking'; } // Aksi halde, saldıracak hedef yoksa bekle (koloniye saldırma) } } else if (self.state === 'attacking') { // Koloniye doğru düz hareket var dx = self.attackTargetX - self.x; var dy = self.attackTargetY - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { self.x += self.speed * dx / dist; self.y += self.speed * dy / dist; } // Ateş etme (her 1 saniyede bir) if (LK.ticks - self.lastShot > self.shootDelay) { var b = new Bullet(); b.x = self.x; b.y = self.y + 40; b.dirX = colony.x - self.x; b.dirY = colony.y - self.y; var bdist = Math.sqrt(b.dirX * b.dirX + b.dirY * b.dirY); if (bdist > 0) { b.dirX /= bdist; b.dirY /= bdist; } else { b.dirX = 0; b.dirY = 1; } b.from = 'enemy'; b.attackPower = self.attackPower; // enemyBaseAttackPower ile ölçekli bullets.push(b); game.addChild(b); self.lastShot = LK.ticks; } // Koloniye çok yaklaştıysa yok ol if (dist < 40) { self.hp = 0; } } }; // Düşman gemisi can yazısı kaldırıldı return self; }); // Koloni can barı ve can göstergesi // Kaynak Avcısı (ResourceHunter) - sadece haritadaki kaynakları toplar var ResourceHunter = Container.expand(function () { var self = Container.call(this); var hunter = self.attachAsset('resource_hunter', { // Artık kendine özel görsel anchorX: 0.5, anchorY: 0.5 }); self.target = null; self.speed = 1.1 * (0.002 + 0.001) * 0.1 * 2732; // Kaynaklara uygun hız self.state = 'idle'; // idle, moving, returning self.carryType = null; self.carryAmount = 0; self.update = function () { // Eğer kaynak taşıyorsa koloniye dön if (self.state === 'returning' && self.carryType && self.carryAmount > 0) { var dx = colony.x - self.x; var dy = colony.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < 20) { // Kaynağı koloniye bırak if (typeof resourceStocks[self.carryType] === "number") { resourceStocks[self.carryType] += self.carryAmount; } self.carryType = null; self.carryAmount = 0; self.state = 'idle'; self.target = null; } else { self.x += self.speed * dx / dist; self.y += self.speed * dy / dist; } return; } // Eğer hedef kaynak varsa ona git if (self.state === 'moving' && self.target && !self.target.collected && self.target.visible) { var dx = self.target.x - self.x; var dy = self.target.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < 20) { // Kaynağı topla self.carryType = self.target.resourceType; self.carryAmount = self.target.amount; self.target.collected = true; self.target.visible = false; self.state = 'returning'; } else { self.x += self.speed * dx / dist; self.y += self.speed * dy / dist; } return; } // Idle ise yeni hedef ara if (self.state === 'idle') { // En yakın toplanmamış kaynağı bul var minDist = 99999; var targetRes = null; for (var i = 0; i < resourceNodes.length; i++) { var r = resourceNodes[i]; if (!r.collected && r.visible) { var dx = r.x - self.x; var dy = r.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < minDist) { minDist = dist; targetRes = r; } } } if (targetRes) { self.target = targetRes; self.state = 'moving'; } } }; return self; }); // Kaynak noktası (sadece asteroid yok edilince çıkar) var ResourceNode = Container.expand(function (resourceType, resourceAsset) { var self = Container.call(this); // resourceType ve resourceAsset parametre olarak alınır self.resourceType = resourceType || "Altın"; self.resourceAsset = resourceAsset || "resource_gold"; var res = self.attachAsset(self.resourceAsset, { anchorX: 0.5, anchorY: 0.5 }); self.amount = 2 + Math.floor(Math.random() * 9); // 2-10 arası kaynak self.collected = false; self.visible = true; // Sabit durur, hareket etmez self.update = function () {}; return self; }); // Oyuncu gemisi var Ship = Container.expand(function () { var self = Container.call(this); // 10 farklı savaşçı gemisi görseli var shipImages = ['ship1', 'ship2', 'ship3', 'ship4', 'ship5', 'ship6', 'ship7', 'ship8', 'ship9', 'ship10']; // Rastgele bir savaşçı gemisi görseli seç var shipImageIndex = Math.floor(Math.random() * shipImages.length); self.shipImageId = shipImages[shipImageIndex]; var s = self.attachAsset(self.shipImageId, { anchorX: 0.5, anchorY: 0.5 }); // Hız %100 yavaşlatıldı self.speed = 11 * 0.1; self.targetX = self.x; self.targetY = self.y; self.lastShot = 0; self.shootDelay = 30; // 0.5s self.update = function () { // Takip mesafesi ve çakışmayı önleme var followDistance = 80; // px, minimum mesafe // Eğer bir düşman varsa ve ona yaklaşıyorsak, mesafeyi koru if (typeof enemyShips !== "undefined" && enemyShips.length > 0) { for (var i = 0; i < enemyShips.length; i++) { var e = enemyShips[i]; if (!e.visible || typeof e.x !== "number" || typeof e.y !== "number") continue; var dxE = e.x - self.x; var dyE = e.y - self.y; var distE = Math.sqrt(dxE * dxE + dyE * dyE); if (distE < followDistance && distE > 0) { // Gemi ile düşman arasındaki mesafe çok yakınsa, geri çekil self.x -= (followDistance - distE) * dxE / distE * 0.5; self.y -= (followDistance - distE) * dyE / distE * 0.5; } } } // Hareket var dx = self.targetX - self.x; var dy = self.targetY - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > self.speed) { // Hedefe yaklaşırken, diğer gemilerle çakışmayı önle self.x += self.speed * dx / dist; self.y += self.speed * dy / dist; } else { self.x = self.targetX; self.y = self.targetY; } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x0a0a1a }); /**** * Game Code ****/ // Yeni panel resmi asset'i (örnek: 350x250 boyutunda, yeni bir id ile) // Kaynak türleri ve isimleri var resourceTypeList = [{ name: "Altın", asset: "resource_gold" }, { name: "Kobalt", asset: "resource_cobalt" }, { name: "Nikel", asset: "resource_nickel" }, { name: "Helyum-3", asset: "resource_helium3" }, { name: "Platin", asset: "resource_platinum" }, { name: "Demir", asset: "resource_iron" }, { name: "Manganez", asset: "resource_manganese" }]; // --- Şirket Maden İstek Paneli (Seviye yükseltme paneli ile aynı içerik ve konumda, üstte) --- var companyPanelGroup = new Container(); var companyPanelYOffset = 32; var companyPanelHeight = 288; // Seviye paneli ile aynı yükseklik // Panel arka planı (özel şirket paneli arkaplan resmi ile) var companyPanelBg = LK.getAsset('company_panel_bgimg', { anchorX: 0, anchorY: 1 }); companyPanelBg.alpha = 0.92; companyPanelBg.x = 0; companyPanelBg.y = 0; companyPanelGroup.addChild(companyPanelBg); // Panel başlığı (Seviye paneli ile aynı stil) var companyPanelTitle = new Text2('Şirket Maden İsteği', { size: 32, fill: "#fff", dropShadow: true, dropShadowColor: 0x000000, dropShadowDistance: 2, dropShadowAngle: Math.PI / 4, dropShadowBlur: 4, dropShadowAlpha: 0.7 }); companyPanelTitle.anchor.set(0, 1); companyPanelTitle.x = 24; companyPanelTitle.y = -24; companyPanelGroup.addChild(companyPanelTitle); // Açıklama (Seviye paneli ile aynı stil, şirket paneline uygun açıklama) var companyDescTxt = new Text2('Şirketin istediği madenleri teslim et, ödül kazan!', { size: 22, fill: "#fff", dropShadow: true, dropShadowColor: 0x000000, dropShadowDistance: 2, dropShadowAngle: Math.PI / 4, dropShadowBlur: 4, dropShadowAlpha: 0.7 }); companyDescTxt.anchor.set(0, 1); companyDescTxt.x = 32; companyDescTxt.y = -64; companyPanelGroup.addChild(companyDescTxt); // İsteği teslim et butonu (Seviye paneli ile aynı stil) var companyDeliverBtn = new Text2('Teslim Et', { size: 28, fill: "#fff", dropShadow: true, dropShadowColor: 0x000000, dropShadowDistance: 2, dropShadowAngle: Math.PI / 4, dropShadowBlur: 4, dropShadowAlpha: 0.7 }); companyDeliverBtn.anchor.set(0, 1); companyDeliverBtn.x = 32; companyDeliverBtn.y = -112; companyDeliverBtn.interactive = true; companyDeliverBtn.buttonMode = true; companyDeliverBtn.hitArea = { x: -20, y: -10, width: companyDeliverBtn.width + 40, height: companyDeliverBtn.height + 20 }; companyPanelGroup.addChild(companyDeliverBtn); // Şirket isteği verisi var companyRequest = null; var companyRequestTxt = new Text2('', { size: 28, fill: "#fff", dropShadow: true, dropShadowColor: 0x000000, dropShadowDistance: 2, dropShadowAngle: Math.PI / 4, dropShadowBlur: 4, dropShadowAlpha: 0.7 }); companyRequestTxt.anchor.set(0, 1); companyRequestTxt.x = 32; companyRequestTxt.y = -160; companyPanelGroup.addChild(companyRequestTxt); // Şirket isteği oluşturucu function generateCompanyRequest() { // 2-7 farklı maden çeşidi seç var typeCount = 2 + Math.floor(Math.random() * 6); // 2-7 var shuffled = []; for (var i = 0; i < resourceTypeList.length; i++) shuffled.push(resourceTypeList[i].name); // Fisher-Yates shuffle for (var i = shuffled.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); var tmp = shuffled[i]; shuffled[i] = shuffled[j]; shuffled[j] = tmp; } var selectedTypes = shuffled.slice(0, typeCount); // Her biri için 20-200 arası miktar var reqs = []; for (var i = 0; i < selectedTypes.length; i++) { reqs.push({ type: selectedTypes[i], amount: 20 + Math.floor(Math.random() * 181) // 20-200 }); } // Ödül: toplam istenen miktarın %2-%10 fazlası aralığında olacak şekilde ayarla var totalRequested = 0; for (var i = 0; i < reqs.length; i++) totalRequested += reqs[i].amount; // %2-%10 fazlalık aralığı var minReward = Math.ceil(totalRequested * 1.02); var maxReward = Math.ceil(totalRequested * 1.10); var rewardAmount = minReward + Math.floor(Math.random() * (maxReward - minReward + 1)); var rewardType = resourceTypeList[Math.floor(Math.random() * resourceTypeList.length)].name; return { requests: reqs, rewardType: rewardType, rewardAmount: rewardAmount }; } // Şirket isteğini güncelle ve göster function updateCompanyRequestPanel() { if (!companyRequest) companyRequest = generateCompanyRequest(); // Panel metni var txt = ''; for (var i = 0; i < companyRequest.requests.length; i++) { var req = companyRequest.requests[i]; txt += req.type + ': ' + req.amount + '\n'; } // Yüzde kaç fazla olduğunu hesapla var totalRequested = 0; for (var i = 0; i < companyRequest.requests.length; i++) { totalRequested += companyRequest.requests[i].amount; } var rewardPercent = 0; if (totalRequested > 0) { rewardPercent = Math.round((companyRequest.rewardAmount / totalRequested - 1) * 100); } txt += 'Ödül: ' + companyRequest.rewardAmount + ' ' + companyRequest.rewardType; if (rewardPercent > 0) { txt += ' (+' + rewardPercent + '%)'; } companyRequestTxt.setText(txt); } updateCompanyRequestPanel(); // Teslim et butonu fonksiyonu companyDeliverBtn.down = function (x, y, obj) { if (!companyRequest) return; // Yeterli kaynak var mı kontrol et var canDeliver = true; for (var i = 0; i < companyRequest.requests.length; i++) { var req = companyRequest.requests[i]; if (resourceStocks[req.type] < req.amount) { canDeliver = false; break; } } if (!canDeliver) { LK.effects.flashObject(companyPanelBg, 0xff0000, 600); return; } // Kaynakları düş for (var i = 0; i < companyRequest.requests.length; i++) { var req = companyRequest.requests[i]; resourceStocks[req.type] -= req.amount; } // Ödülü ekle resourceStocks[companyRequest.rewardType] += companyRequest.rewardAmount; LK.effects.flashObject(companyPanelBg, 0x4adf4a, 800); // Yeni istek oluştur companyRequest = generateCompanyRequest(); updateCompanyRequestPanel(); }; // --- Sol alt: Seviye Yükseltme Paneli --- // Sağ alt gemi paneli için özel arka plan görseli (daha belirgin, köşeleri yuvarlatılmış, koyu mavi) // 7 farklı asteroid görseli (her kaynak için bir tane) // Koloni, kaynak, gemi ve düşman için temel şekiller // Global değişkenler // Collector'ın sıktığı mermi için özel asset // Colony HP bar custom images // Ship HP bar custom images function _typeof3(o) { "@babel/helpers - typeof"; return _typeof3 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof3(o); } function _typeof2(o) { "@babel/helpers - typeof"; return _typeof2 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof2(o); } function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } var colony; var ship; var collectors = []; var resourceHunters = []; var autoResourceHunters = 1; var resourceNodes = []; var bullets = []; var resources = 0; var autoCollectors = 1; var spawnEnemyTimer = 0; var dragNode = null; var lastTouch = { x: 0, y: 0 }; // Koloni kur colony = new Colony(); colony.x = 2048 / 2; colony.y = 2732 - 400; // Koloni seviye ve maxHp ayarı colony.maxHp = 100 + (colonyLevel - 1) * 10; // Maksimum can 100, seviye başı +10 colony.hp = 50; // Başlangıçta 50 can ile başlasın game.addChild(colony); // --- Düşman Binası (Base) --- // Düşman binası için sağlık, seviye ve saldırı butonu ekle var enemyBaseLevel = 1; var enemyBaseHp = Math.floor(30 * 0.3); var enemyBaseMaxHp = Math.floor(30 * 0.3); var enemyBaseAttackPower = 2 * 0.3; var enemyBaseGroup = new Container(); // Düşman binası için 10 farklı görsel id'si var enemyBaseImageIds = ['enemy_base1', 'enemy_base2', 'enemy_base3', 'enemy_base4', 'enemy_base5', 'enemy_base6', 'enemy_base7', 'enemy_base8', 'enemy_base9', 'enemy_base10']; // İlk başta rastgele bir görsel seç var currentEnemyBaseImageId = enemyBaseImageIds[Math.floor(Math.random() * enemyBaseImageIds.length)]; var enemyBaseSprite = LK.getAsset(currentEnemyBaseImageId, { anchorX: 0.5, anchorY: 0.5 }); enemyBaseSprite.x = 0; enemyBaseSprite.y = 0; enemyBaseGroup.addChild(enemyBaseSprite); // Sağlık barı var enemyBaseHpBarBg = LK.getAsset('colony_hpbar_bg', { anchorX: 0.5, anchorY: 0.5 }); enemyBaseHpBarBg.x = 0; enemyBaseHpBarBg.y = -120; enemyBaseGroup.addChild(enemyBaseHpBarBg); var enemyBaseHpBar = LK.getAsset('colony_hpbar_fg', { anchorX: 0.5, anchorY: 0.5 }); enemyBaseHpBar.x = 0; enemyBaseHpBar.y = -120; enemyBaseGroup.addChild(enemyBaseHpBar); // Sağlık yazısı var enemyBaseHpTxt = new Text2('', { size: 32, fill: "#fff", dropShadow: true, dropShadowColor: 0x000000, dropShadowDistance: 2, dropShadowAngle: Math.PI / 4, dropShadowBlur: 4, dropShadowAlpha: 0.7 }); enemyBaseHpTxt.anchor.set(0.5, 1); enemyBaseHpTxt.x = 0; enemyBaseHpTxt.y = -150; enemyBaseGroup.addChild(enemyBaseHpTxt); // Seviye yazısı var enemyBaseLevelTxt = new Text2('Seviye: 1', { size: 28, fill: "#fff", dropShadow: true, dropShadowColor: 0x000000, dropShadowDistance: 2, dropShadowAngle: Math.PI / 4, dropShadowBlur: 4, dropShadowAlpha: 0.7 }); enemyBaseLevelTxt.anchor.set(0.5, 0); enemyBaseLevelTxt.x = 0; enemyBaseLevelTxt.y = 100; enemyBaseGroup.addChild(enemyBaseLevelTxt); // Saldırı butonu var enemyBaseAttackBtn = new Text2('SALDIR', { size: 36, fill: "#fff", dropShadow: true, dropShadowColor: 0x000000, dropShadowDistance: 2, dropShadowAngle: Math.PI / 4, dropShadowBlur: 4, dropShadowAlpha: 0.7 }); enemyBaseAttackBtn.anchor.set(0.5, 0); enemyBaseAttackBtn.x = 0; enemyBaseAttackBtn.y = 160; enemyBaseAttackBtn.interactive = true; enemyBaseAttackBtn.buttonMode = true; enemyBaseAttackBtn.hitArea = { x: -enemyBaseAttackBtn.width / 2 - 20, y: -10, width: enemyBaseAttackBtn.width + 40, height: enemyBaseAttackBtn.height + 20 }; enemyBaseGroup.addChild(enemyBaseAttackBtn); // Düşman binasını üstte ortala enemyBaseGroup.x = 2048 / 2; enemyBaseGroup.y = 120; game.addChild(enemyBaseGroup); // Düşman binası referansı (eski kod uyumluluğu için) var topAsteroid = enemyBaseGroup; // Düşman binasının en son gönderdiği geminin saldırı gücü var lastEnemyShipAttackPower = 2; // Saldırı butonu fonksiyonu enemyBaseAttackBtn.down = function (x, y, obj) { // Saldırıya katılacak askerler: aktif olan tüm savaşçılar var attackingShips = []; if (ship && ship.visible && ship.hp > 0) attackingShips.push(ship); for (var i = 0; i < extraShips.length; i++) { var s = extraShips[i]; if (s.visible && s.hp > 0) attackingShips.push(s); } if (attackingShips.length === 0) { LK.effects.flashObject(enemyBaseAttackBtn, 0xff0000, 600); return; } // Düşman binası savunma gücü: en son gönderdiği düşman geminin saldırı gücü (yoksa default) var defensePower = lastEnemyShipAttackPower || enemyBaseAttackPower; // --- Animasyonlu saldırı: Gemiler hareket ederek saldıracak ve mermiyle savaşacak --- // Saldırı sırasında butonu pasifleştir enemyBaseAttackBtn.alpha = 0.5; enemyBaseAttackBtn.interactive = false; // Saldırıya katılan gemilerin orijinal pozisyonlarını kaydet var originalPositions = []; for (var i = 0; i < attackingShips.length; i++) { originalPositions.push({ x: attackingShips[i].x, y: attackingShips[i].y }); } // Saldırı hedef noktası: düşman binasının hemen altı var targetX = enemyBaseGroup.x; var targetY = enemyBaseGroup.y + 220; // Saldırı animasyonu ve savaş simülasyonu var attackStep = 0; var baseHp = enemyBaseHp; var shipIdx = 0; var shipLost = false; var battleEnded = false; // Saldırı sırasında mermiler ve animasyonlar için referanslar var attackBullets = []; var attackTweenIds = []; // Saldırı animasyonunu başlat function startNextAttack() { if (battleEnded) return; if (baseHp <= 0 || shipIdx >= attackingShips.length) { finishBattle(); return; } // --- DEĞİŞİKLİK: Tüm gemiler aynı anda hareket etsin --- // Sadece ilk çağrıda tüm gemileri başlat if (attackStep === 0) { for (var i = 0; i < attackingShips.length; i++) { var s = attackingShips[i]; if (!s.visible || s.hp <= 0) continue; var destX = targetX + (i - (attackingShips.length - 1) / 2) * 80; var destY = targetY + Math.random() * 40 - 20; s._attackMoveTargetX = destX; s._attackMoveTargetY = destY; s._attackMoveInProgress = true; s._attackMoveStep = 0; s._attackMoveMaxStep = 180 * 3; // 540 frame = %300 daha yavaş (3 kat daha yavaş) s._attackMoveStartX = s.x; s._attackMoveStartY = s.y; s._attackMoveDeltaX = destX - s.x; s._attackMoveDeltaY = destY - s.y; s._attackMoveOrigUpdate = s.update; (function (shipRef, idx) { shipRef.update = function () { if (shipRef._attackMoveInProgress) { shipRef._attackMoveStep++; var t = shipRef._attackMoveStep / shipRef._attackMoveMaxStep; if (t > 1) t = 1; shipRef.x = shipRef._attackMoveStartX + shipRef._attackMoveDeltaX * t; shipRef.y = shipRef._attackMoveStartY + shipRef._attackMoveDeltaY * t; if (shipRef._attackMoveStep >= shipRef._attackMoveMaxStep) { shipRef._attackMoveInProgress = false; // Mermi animasyonu: gemiden düşman binasına doğru var b = new Bullet(); b.x = shipRef.x; b.y = shipRef.y - 30; b.dirX = enemyBaseGroup.x - b.x; b.dirY = enemyBaseGroup.y - 80 - b.y; var bdist = Math.sqrt(b.dirX * b.dirX + b.dirY * b.dirY); if (bdist > 0) { b.dirX /= bdist; b.dirY /= bdist; } else { b.dirX = 0; b.dirY = -1; } b.from = 'player'; b.attackPower = 1; b.update = function () { b.x += b.dirX * 32; b.y += b.dirY * 32; // Düşman binasına çarptıysa var bx = b.x - enemyBaseGroup.x; var by = b.y - (enemyBaseGroup.y - 80); if (bx * bx + by * by < 60 * 60) { // Hasar uygula baseHp -= 1; LK.effects.flashObject(enemyBaseSprite, 0xffe000, 400); b.destroy(); var idx2 = attackBullets.indexOf(b); if (idx2 !== -1) attackBullets.splice(idx2, 1); // Bina savunur (her savunma defensePower hasar) shipRef.hp -= defensePower; if (shipRef.hp <= 0) { shipRef.hp = 0; shipRef.visible = false; shipRef.x = -9999; shipRef.y = -9999; shipLost = true; } // Her gemi mermisi sonrası battle bitti mi kontrol et var allDone = true; for (var si = 0; si < attackingShips.length; si++) { var ss = attackingShips[si]; if (ss._attackMoveInProgress) { allDone = false; break; } } if (allDone) { // Tüm gemiler bitirdi, battle'ı bitir LK.setTimeout(finishBattle, 350); } } // Ekran dışıysa yok et if (b.x < -100 || b.x > 2148 || b.y < -100 || b.y > 2832) { b.destroy(); var idx2 = attackBullets.indexOf(b); if (idx2 !== -1) attackBullets.splice(idx2, 1); } }; attackBullets.push(b); game.addChild(b); // Saldırı hareketi bitti, eski update fonksiyonunu geri yükle if (typeof shipRef._attackMoveOrigUpdate === "function") { shipRef.update = shipRef._attackMoveOrigUpdate; } } } else if (typeof shipRef._attackMoveOrigUpdate === "function") { shipRef._attackMoveOrigUpdate(); } }; })(s, i); } attackStep = 1; } // Artık her gemi kendi update fonksiyonunda hareket ediyor, battle'ın bitişi mermi çarpışmalarında kontrol ediliyor } // Saldırı bitince gemileri eski pozisyonuna döndür ve sonucu uygula function finishBattle() { battleEnded = true; // Gemileri eski pozisyonuna döndür for (var i = 0; i < attackingShips.length; i++) { var s = attackingShips[i]; if (s.visible && originalPositions[i]) { tween(s, { x: originalPositions[i].x, y: originalPositions[i].y }, { duration: 400 * 3, // %300 daha yavaş (3 kat daha yavaş) easing: tween.quadInOut }); } } // Saldırı mermilerini temizle for (var i = 0; i < attackBullets.length; i++) { if (attackBullets[i] && typeof attackBullets[i].destroy === "function") attackBullets[i].destroy(); } attackBullets = []; // Saldırı tweenlerini temizle for (var i = 0; i < attackTweenIds.length; i++) { tween.cancel(attackTweenIds[i]); } attackTweenIds = []; // Sonuç: Kazanırsak ödül, kaybedersek askerler eski görevine döner if (baseHp <= 0) { // Kazandık: ödül ver, bina yok et, yeni bina oluştur var reward = Math.floor(200 * enemyBaseLevel); var types = []; for (var t = 0; t < resourceTypeList.length; t++) types.push(resourceTypeList[t].name); var remaining = reward; while (remaining > 0) { var idx = Math.floor(Math.random() * types.length); resourceStocks[types[idx]] += 1; remaining--; } LK.effects.flashObject(enemyBaseSprite, 0x4adf4a, 1000); LK.effects.flashObject(enemyBaseHpBar, 0x4adf4a, 1000); // Yeni bina oluştur: seviye +1, hp +%20, saldırı gücü +%10, yeni gemiler %10 daha güçlü enemyBaseMaxHp = Math.floor(enemyBaseMaxHp * 1.2); enemyBaseHp = enemyBaseMaxHp; enemyBaseAttackPower = Math.ceil(enemyBaseAttackPower * 1.1); lastEnemyShipAttackPower = enemyBaseAttackPower; enemyBaseLevelTxt.setText('Seviye: ' + enemyBaseLevel); } else { // Kaybettik: askerler eski görevine döner LK.effects.flashObject(enemyBaseAttackBtn, 0xff0000, 800); } // Bina hp güncelle enemyBaseHp = Math.max(0, baseHp); // Saldırı bitince butonu tekrar aktif et LK.setTimeout(function () { enemyBaseAttackBtn.alpha = 1; enemyBaseAttackBtn.interactive = true; }, 600); } // Saldırı döngüsünü başlat startNextAttack(); // Saldırı sırasında mermileri güncellemek için game.update'e ekle if (!game._attackBattleUpdate) { game._attackBattleUpdate = function () { if (attackBullets && attackBullets.length > 0) { for (var i = attackBullets.length - 1; i >= 0; i--) { if (attackBullets[i] && typeof attackBullets[i].update === "function") attackBullets[i].update(); } } }; var oldUpdate = game.update; game.update = function () { if (typeof oldUpdate === "function") oldUpdate.apply(this, arguments); if (typeof game._attackBattleUpdate === "function") game._attackBattleUpdate(); }; } }; // --- Düşman binası GUI güncellemesi game.update'e eklenecek --- // Düşman gemisi için array ve timer var enemyShips = []; var enemySpawnTimer = 0; var ENEMY_SPAWN_INTERVAL = 60 * 60; // Düşman dalga sayacı ve gönderilecek gemi sayısı var enemyWaveCount = 0; var enemyShipsPerWave = 1; // Koloni seviye değişkenleri var colonyLevel = 1; var colonyLevelBasePrice = 100; var colonyLevelPrice = colonyLevelBasePrice; // Koloni sağlık sistemi: Bar, seviye, tamir ve yükseltme tek noktadan yönetimi var colonyHealthSystem = { barBg: LK.getAsset('colony_hpbar_bg', { anchorX: 0.5, anchorY: 0.5 }), bar: LK.getAsset('colony_hpbar_fg', { anchorX: 0.5, anchorY: 0.5 }), levelTxt: new Text2('Seviye: ' + colonyLevel, { size: 28, fill: "#fff", dropShadow: true, dropShadowColor: 0x000000, dropShadowDistance: 2, dropShadowAngle: Math.PI / 4, dropShadowBlur: 4, dropShadowAlpha: 0.7 }), upBtn: new Text2('Koloni Seviye Yükselt (' + colonyLevelPrice + ' Kaynak)', { size: 28, fill: "#fff", dropShadow: true, dropShadowColor: 0x000000, dropShadowDistance: 2, dropShadowAngle: Math.PI / 4, dropShadowBlur: 4, dropShadowAlpha: 0.7 }), repairBtn: new Text2('Tamir Et', { size: 28, fill: "#fff", dropShadow: true, dropShadowColor: 0x000000, dropShadowDistance: 2, dropShadowAngle: Math.PI / 4, dropShadowBlur: 4, dropShadowAlpha: 0.7 }), repairCost: 20, repairCostIncrease: 1.1 }; // Bar ve yazı konumları colonyHealthSystem.barBg.y = colony.y - 160; colonyHealthSystem.barBg.x = colony.x; colonyHealthSystem.bar.y = colony.y - 160; colonyHealthSystem.bar.x = colony.x; game.addChild(colonyHealthSystem.barBg); game.addChild(colonyHealthSystem.bar); // Seviye yazısı colonyHealthSystem.levelTxt.anchor.set(0.5, 0); colonyHealthSystem.levelTxt.x = colony.x; colonyHealthSystem.levelTxt.y = colony.y - 200 - 40; game.addChild(colonyHealthSystem.levelTxt); // Seviye yükseltme butonu colonyHealthSystem.upBtn.anchor.set(1, 1); // 2 satır yukarı: her satır yaklaşık 60px (buton yüksekliği + boşluk), toplamda 120px yukarı colonyHealthSystem.upBtn.x = -32; colonyHealthSystem.upBtn.y = -140; // shipBuyBtn.y = -80, collectorBuyBtn.y = -140, 2 satır yukarı = -200, ama -140 hizalı (üstten 2. satır) colonyHealthSystem.upBtn.interactive = true; colonyHealthSystem.upBtn.buttonMode = true; colonyHealthSystem.upBtn.hitArea = { x: -colonyHealthSystem.upBtn.width - 20, y: -10, width: colonyHealthSystem.upBtn.width + 40, height: colonyHealthSystem.upBtn.height + 20 }; // shipBuyPanelGroup'un en üstüne ekle if (typeof shipBuyPanelGroup !== "undefined" && shipBuyPanelGroup && typeof shipBuyPanelGroup.addChildAt === "function") { shipBuyPanelGroup.addChildAt(colonyHealthSystem.upBtn, 0); } // Tamir butonu colonyHealthSystem.repairBtn.anchor.set(0.5, 1); colonyHealthSystem.repairBtn.x = colony.x; colonyHealthSystem.repairBtn.y = colony.y - 200 - colonyHealthSystem.repairBtn.height - 20 + (colonyHealthSystem.repairBtn.height + 20) * 0.25; colonyHealthSystem.repairBtn.interactive = true; colonyHealthSystem.repairBtn.buttonMode = true; colonyHealthSystem.repairBtn.hitArea = { x: -colonyHealthSystem.repairBtn.width / 2 - 20, y: -colonyHealthSystem.repairBtn.height - 10, width: colonyHealthSystem.repairBtn.width + 40, height: colonyHealthSystem.repairBtn.height + 20 }; game.addChild(colonyHealthSystem.repairBtn); // Seviye yükseltme fonksiyonu colonyHealthSystem.upBtn.down = function (x, y, obj) { var totalResourceStock = 0; for (var i = 0; i < resourceTypeList.length; i++) { totalResourceStock += resourceStocks[resourceTypeList[i].name]; } if (totalResourceStock < colonyLevelPrice) { LK.effects.flashObject(colonyHealthSystem.upBtn, 0xff0000, 600); return; } // Kaynakları harca (her kaynaktan orantılı olarak düş) var remaining = colonyLevelPrice; for (var i = 0; i < resourceTypeList.length; i++) { var typeName = resourceTypeList[i].name; var take = Math.min(resourceStocks[typeName], remaining); resourceStocks[typeName] -= take; remaining -= take; if (remaining <= 0) break; } // Seviye artır, maxHp +10, canı yeni maxHp'nin yarısına çek colonyLevel++; colony.maxHp = 100 + (colonyLevel - 1) * 10; colony.hp = Math.floor(colony.maxHp / 2); colonyHealthSystem.levelTxt.setText('Seviye: ' + colonyLevel); // Fiyatı 100 ve katları olarak artır colonyLevelPrice += colonyLevelBasePrice; colonyHealthSystem.upBtn.setText('Koloni Seviye Yükselt (' + colonyLevelPrice + ' Kaynak)'); LK.effects.flashObject(colony, 0x4adf4a, 600); }; // Tamir fonksiyonu colonyHealthSystem.repairBtn.down = function (x, y, obj) { var totalResourceStock = 0; for (var i = 0; i < resourceTypeList.length; i++) { totalResourceStock += resourceStocks[resourceTypeList[i].name]; } if (colony.hp >= colony.maxHp) { LK.effects.flashObject(colonyHealthSystem.barBg, 0x4adf4a, 400); return; } if (totalResourceStock < colonyHealthSystem.repairCost) { LK.effects.flashObject(colonyHealthSystem.barBg, 0xff0000, 600); return; } // Kaynakları harca (her kaynaktan orantılı olarak düş) var remaining = colonyHealthSystem.repairCost; for (var i = 0; i < resourceTypeList.length; i++) { var typeName = resourceTypeList[i].name; var take = Math.min(resourceStocks[typeName], remaining); resourceStocks[typeName] -= take; remaining -= take; if (remaining <= 0) break; } // 3-10 arası rastgele can ekle, maxHp'yi geçemez var heal = 3 + Math.floor(Math.random() * 8); colony.hp += heal; if (colony.hp > colony.maxHp) colony.hp = colony.maxHp; LK.effects.flashObject(colonyHealthSystem.bar, 0x4adf4a, 600); // Maliyeti %10 artır colonyHealthSystem.repairCost = Math.ceil(colonyHealthSystem.repairCost * colonyHealthSystem.repairCostIncrease); colonyHealthSystem.repairBtn.setText('Tamir Et (' + colonyHealthSystem.repairCost + ' Kaynak)'); }; // Sol alt köşeye hizalı GUI grubu oluştur var guiLeftBottomGroup = new Container(); LK.gui.bottomLeft.addChild(guiLeftBottomGroup); // Koloni can yazısı (sol alt) var colonyHpTxt = new Text2('50 / 50', { size: 36, fill: "#fff", dropShadow: true, dropShadowColor: 0x000000, dropShadowDistance: 2, dropShadowAngle: Math.PI / 4, dropShadowBlur: 4, dropShadowAlpha: 0.7 }); colonyHpTxt.anchor.set(0, 1); // Sol alt köşe colonyHpTxt.x = 0; colonyHpTxt.y = 0; guiLeftBottomGroup.addChild(colonyHpTxt); // Kaynak göstergesi (sol alt) var resourceTxt = new Text2('Toplam Kaynak: 0', { size: 36, fill: "#fff", dropShadow: true, dropShadowColor: 0x000000, dropShadowDistance: 2, dropShadowAngle: Math.PI / 4, dropShadowBlur: 4, dropShadowAlpha: 0.7 }); resourceTxt.anchor.set(0, 1); resourceTxt.x = 0; resourceTxt.y = colonyHpTxt.y - colonyHpTxt.height - 8; guiLeftBottomGroup.addChild(resourceTxt); // collectorTxt: Sadece yükseklik için dummy olarak tanımlanır (sol panelde gösterilmiyor) var collectorTxt = new Text2('Asteroit Avcısı: 1', { size: 36, fill: "#fff", dropShadow: true, dropShadowColor: 0x000000, dropShadowDistance: 2, dropShadowAngle: Math.PI / 4, dropShadowBlur: 4, dropShadowAlpha: 0.7 }); collectorTxt.anchor.set(0, 1); collectorTxt.x = 0; collectorTxt.y = resourceTxt.y - resourceTxt.height - 8; // Gemi sayısı göstergesi -- KALDIRILDI var guiRightBottomGroup = new Container(); LK.gui.bottomRight.addChild(guiRightBottomGroup); // Koloni Sağlığı başlığı (sağ alt) var colonyHpLabelRight = new Text2('Koloni Sağlığı', { size: 28, fill: "#fff", dropShadow: true, dropShadowColor: 0x000000, dropShadowDistance: 2, dropShadowAngle: Math.PI / 4, dropShadowBlur: 4, dropShadowAlpha: 0.7 }); colonyHpLabelRight.anchor.set(1, 1); colonyHpLabelRight.x = 0; colonyHpLabelRight.y = 0; guiRightBottomGroup.addChild(colonyHpLabelRight); // Koloni can yazısı (sağ alt) var colonyHpTxtRight = new Text2('50 / 50', { size: 36, fill: "#fff", dropShadow: true, dropShadowColor: 0x000000, dropShadowDistance: 2, dropShadowAngle: Math.PI / 4, dropShadowBlur: 4, dropShadowAlpha: 0.7 }); colonyHpTxtRight.anchor.set(1, 1); // Sağ alt köşe colonyHpTxtRight.x = 0; colonyHpTxtRight.y = -colonyHpLabelRight.height - 8; guiRightBottomGroup.addChild(colonyHpTxtRight); // Otomasyon göstergesi (sağ alt) var collectorTxtRight = new Text2('Asteroit Avcısı: 1', { size: 36, fill: "#fff", dropShadow: true, dropShadowColor: 0x000000, dropShadowDistance: 2, dropShadowAngle: Math.PI / 4, dropShadowBlur: 4, dropShadowAlpha: 0.7 }); collectorTxtRight.anchor.set(1, 1); collectorTxtRight.x = 0; collectorTxtRight.y = -colonyHpLabelRight.height - colonyHpTxtRight.height - 16; guiRightBottomGroup.addChild(collectorTxtRight); // Gemi sayısı göstergesi (sağ alt) var shipCountTxtRight = new Text2('Savaşçı: 1', { size: 36, fill: "#fff", dropShadow: true, dropShadowColor: 0x000000, dropShadowDistance: 2, dropShadowAngle: Math.PI / 4, dropShadowBlur: 4, dropShadowAlpha: 0.7 }); shipCountTxtRight.anchor.set(1, 1); shipCountTxtRight.x = 0; shipCountTxtRight.y = -colonyHpLabelRight.height - colonyHpTxtRight.height - collectorTxtRight.height - 24; guiRightBottomGroup.addChild(shipCountTxtRight); // Gemi canı göstergesi (sağ alt) -- KALDIRILDI // --- Sağ alt panel: Gemi satın alma paneli (yeni) --- var shipBuyPanelGroup = new Container(); shipBuyPanelGroup.x = 0; shipBuyPanelGroup.y = -colonyHpLabelRight.height - colonyHpTxtRight.height - collectorTxtRight.height - shipCountTxtRight.height - 48 - 260; // 260px üstte, panel yüksekliği kadar yukarıda guiRightBottomGroup.addChild(shipBuyPanelGroup); // Panel arka planı (özel görsel, hafif şeffaf) var shipBuyPanelBg = LK.getAsset('ship_buy_panel_bg', { anchorX: 1, anchorY: 1 }); shipBuyPanelBg.alpha = 0.92; shipBuyPanelBg.x = 0; shipBuyPanelBg.y = 0; shipBuyPanelGroup.addChild(shipBuyPanelBg); // Panel başlığı var shipBuyPanelTitle = new Text2('Savaşçı Satın Al', { size: 32, fill: "#fff", dropShadow: true, dropShadowColor: 0x000000, dropShadowDistance: 2, dropShadowAngle: Math.PI / 4, dropShadowBlur: 4, dropShadowAlpha: 0.7 }); shipBuyPanelTitle.anchor.set(1, 1); shipBuyPanelTitle.x = -24; shipBuyPanelTitle.y = -24; shipBuyPanelGroup.addChild(shipBuyPanelTitle); // Satın alma butonu var shipBuyBtn = new Text2('Yeni Savaşçı (200 Kaynak)', { size: 28, fill: "#fff", dropShadow: true, dropShadowColor: 0x000000, dropShadowDistance: 2, dropShadowAngle: Math.PI / 4, dropShadowBlur: 4, dropShadowAlpha: 0.7 }); shipBuyBtn.anchor.set(1, 1); shipBuyBtn.x = -32; shipBuyBtn.y = -80; shipBuyBtn.interactive = true; shipBuyBtn.buttonMode = true; shipBuyBtn.hitArea = { x: -shipBuyBtn.width - 20, y: -10, width: shipBuyBtn.width + 40, height: shipBuyBtn.height + 20 }; shipBuyPanelGroup.addChild(shipBuyBtn); // Asteroit Avcısı satın alma butonu var collectorBuyBtn = new Text2('Asteroit Avcısı (100 Kaynak)', { size: 28, fill: "#fff", dropShadow: true, dropShadowColor: 0x000000, dropShadowDistance: 2, dropShadowAngle: Math.PI / 4, dropShadowBlur: 4, dropShadowAlpha: 0.7 }); collectorBuyBtn.anchor.set(1, 1); collectorBuyBtn.x = -32; collectorBuyBtn.y = -140; collectorBuyBtn.interactive = true; collectorBuyBtn.buttonMode = true; collectorBuyBtn.hitArea = { x: -collectorBuyBtn.width - 20, y: -10, width: collectorBuyBtn.width + 40, height: collectorBuyBtn.height + 20 }; shipBuyPanelGroup.addChild(collectorBuyBtn); // --- Satın alma fiyatları ve artış oranı --- // Kaynak Avcısı ve Asteroid Avcısı: 100 kaynak, Savaşçı: 200 kaynak, her satın alımda %50 artış var shipBuyPrice = 200; var collectorBuyPrice = 100; var resourceHunterBuyPrice = 100; var shipBuyPriceIncrease = 1.5; var collectorBuyPriceIncrease = 1.5; var resourceHunterBuyPriceIncrease = 1.5; // Savunma Kulesi için değişkenler var defenseTowers = []; var defenseTowerBuyPrice = 100; var defenseTowerBuyPriceIncrease = 1.5; var defenseTowerMaxCount = 4; // En fazla 4 kule alınabilir // Savunma Kulesi Seviye Yükselt butonu (yeni) -- Savunma Kulesi satın alma butonunun üst satırında // Savunma Kulesi Seviye Yükseltme maliyeti ve artış oranı var defenseTowerLevelUpBasePrice = 100; var defenseTowerLevelUpPrice = defenseTowerLevelUpBasePrice; // --- Savunma Kulesi Tamir Et Butonu ve Fonksiyonu --- function createDefenseTowerRepairBtn(targetTower, yOffset) { var btn = new Text2('Tamir Et (' + targetTower.repairCost + ' Kaynak)', { size: 24, fill: "#fff", dropShadow: true, dropShadowColor: 0x000000, dropShadowDistance: 2, dropShadowAngle: Math.PI / 4, dropShadowBlur: 4, dropShadowAlpha: 0.7 }); btn.anchor.set(0.5, 1); btn.x = targetTower.x; btn.y = targetTower.y - yOffset; btn.interactive = true; btn.buttonMode = true; btn.hitArea = { x: -btn.width / 2 - 20, y: -btn.height - 10, width: btn.width + 40, height: btn.height + 20 }; btn.visible = targetTower.visible; btn.down = function (x, y, obj) { // Toplam kaynak stoğu ile kontrol var totalResourceStock = 0; for (var i = 0; i < resourceTypeList.length; i++) { totalResourceStock += resourceStocks[resourceTypeList[i].name]; } if (targetTower.hp >= targetTower.maxHp) { LK.effects.flashObject(btn, 0x4adf4a, 400); return; } if (totalResourceStock < targetTower.repairCost) { LK.effects.flashObject(btn, 0xff0000, 600); return; } // Kaynakları harca (her kaynaktan orantılı olarak düş) var remaining = targetTower.repairCost; for (var i = 0; i < resourceTypeList.length; i++) { var typeName = resourceTypeList[i].name; var take = Math.min(resourceStocks[typeName], remaining); resourceStocks[typeName] -= take; remaining -= take; if (remaining <= 0) break; } // HP'yi 3 artır, maxHp'yi geçemez targetTower.hp += 3; if (targetTower.hp > targetTower.maxHp) targetTower.hp = targetTower.maxHp; LK.effects.flashObject(targetTower, 0x4adf4a, 600); // Maliyeti %10 artır targetTower.repairCost = Math.ceil(targetTower.repairCost * targetTower.repairCostIncrease); btn.setText('Tamir Et (' + targetTower.repairCost + ' Kaynak)'); }; game.addChild(btn); // Butonun pozisyonunu ve görünürlüğünü update fonksiyonunda güncellemek için tower objesine referans ekle targetTower.repairBtn = btn; } // Savunma Kulesi Seviye Yükselt butonu (Savunma Kulesi satın alma butonunun üstünde) var defenseTowerLevelUpBtn = new Text2('Savunma Kulesi Seviye Yükselt (' + defenseTowerLevelUpPrice + ' Kaynak)', { size: 28, fill: "#fff", dropShadow: true, dropShadowColor: 0x000000, dropShadowDistance: 2, dropShadowAngle: Math.PI / 4, dropShadowBlur: 4, dropShadowAlpha: 0.7 }); defenseTowerLevelUpBtn.anchor.set(1, 1); defenseTowerLevelUpBtn.x = -32; // 3 satır yukarı taşı: her satır yaklaşık 60px (buton yüksekliği + boşluk), toplamda 180px yukarı // 2 satır yukarı taşı: her satır yaklaşık 60px (buton yüksekliği + boşluk), toplamda 120px yukarı defenseTowerLevelUpBtn.y = -260 - (defenseTowerLevelUpBtn.height + 20) * 1; // hizalamayı Savunma Kulesi satın alma butonunun üstüne ve sağa göre yap defenseTowerLevelUpBtn.interactive = true; defenseTowerLevelUpBtn.buttonMode = true; defenseTowerLevelUpBtn.hitArea = { x: -defenseTowerLevelUpBtn.width - 20, y: -10, width: defenseTowerLevelUpBtn.width + 40, height: defenseTowerLevelUpBtn.height + 20 }; shipBuyPanelGroup.addChild(defenseTowerLevelUpBtn); // Savunma Kulesi satın alma butonu (sağ alt panelde, gemi satın alma panelinin altına) var defenseTowerBuyBtn = new Text2('Savunma Kulesi (100 Kaynak)', { size: 28, fill: "#fff", dropShadow: true, dropShadowColor: 0x000000, dropShadowDistance: 2, dropShadowAngle: Math.PI / 4, dropShadowBlur: 4, dropShadowAlpha: 0.7 }); defenseTowerBuyBtn.anchor.set(1, 1); defenseTowerBuyBtn.x = -32; defenseTowerBuyBtn.y = -260; defenseTowerBuyBtn.interactive = true; defenseTowerBuyBtn.buttonMode = true; defenseTowerBuyBtn.hitArea = { x: -defenseTowerBuyBtn.width - 20, y: -10, width: defenseTowerBuyBtn.width + 40, height: defenseTowerBuyBtn.height + 20 }; shipBuyPanelGroup.addChild(defenseTowerBuyBtn); // Savunma Kulesi satın alma işlemi defenseTowerBuyBtn.down = function (x, y, obj) { // Sadece 1 kule varsa tekrar alınamaz, kule yok olunca tekrar alınabilir var activeTowers = 0; for (var i = 0; i < defenseTowers.length; i++) { if (defenseTowers[i].visible && defenseTowers[i].hp > 0) activeTowers++; } if (activeTowers >= defenseTowerMaxCount) { LK.effects.flashObject(defenseTowerBuyBtn, 0xff0000, 600); return; } // Toplam kaynak stoğu ile kontrol var totalResourceStock = 0; for (var i = 0; i < resourceTypeList.length; i++) { totalResourceStock += resourceStocks[resourceTypeList[i].name]; } if (totalResourceStock < defenseTowerBuyPrice) { LK.effects.flashObject(defenseTowerBuyBtn, 0xff0000, 600); return; } // Kaynakları harca (her kaynaktan orantılı olarak düş) var remaining = defenseTowerBuyPrice; for (var i = 0; i < resourceTypeList.length; i++) { var typeName = resourceTypeList[i].name; var take = Math.min(resourceStocks[typeName], remaining); resourceStocks[typeName] -= take; remaining -= take; if (remaining <= 0) break; } // Kuleyi oluştur ve ekle var tower = new DefenseTower(); // Savunma kulesi tamir maliyeti ve artış oranı tower.repairCost = 20; tower.repairCostIncrease = 1.1; // Kuleleri yan yana ve 1'er satır boşlukla sıralayalım // Her kule için x: colony.x + (i - (defenseTowerMaxCount-1)/2) * kuleArasıMesafe // y: colony.y - 320 - 88 (sabit) var towerIndex = 0; for (var i = 0; i < defenseTowerMaxCount; i++) { if (defenseTowers[i] && defenseTowers[i].visible && defenseTowers[i].hp > 0) { towerIndex++; } } towerIndex = defenseTowers.length; var towerSpacingX = 220; // Yan yana aralık (1 satır daha büyük) tower.x = colony.x + (towerIndex - (defenseTowerMaxCount - 1) / 2) * towerSpacingX; tower.y = colony.y - 320 - 88; defenseTowers.push(tower); game.addChild(tower); // Savunma kulesi için tamir et butonu ekle (yOffset: 170) -- 1 satır yukarı taşındı createDefenseTowerRepairBtn(tower, 170); LK.effects.flashObject(tower, 0x4adf4a, 800); // Fiyatı %50 artır defenseTowerBuyPrice = Math.ceil(defenseTowerBuyPrice * defenseTowerBuyPriceIncrease); defenseTowerBuyBtn.setText('Savunma Kulesi (' + defenseTowerBuyPrice + ' Kaynak)'); // Kulelerin pozisyonunu güncelle (her zaman yan yana ve boşluklu) for (var i = 0; i < defenseTowers.length; i++) { defenseTowers[i].x = colony.x + (i - (defenseTowerMaxCount - 1) / 2) * towerSpacingX; defenseTowers[i].y = colony.y - 320 - 88; // Seviye atlatma butonu varsa onun da pozisyonunu güncelle if (defenseTowers[i].levelUpBtn) { defenseTowers[i].levelUpBtn.x = defenseTowers[i].x; defenseTowers[i].levelUpBtn.y = defenseTowers[i].y + 80; } } }; // Savunma Kulesi seviye atlatma fonksiyonu (örnek: kuleye tıklayınca seviye atlat) // (İsteğe bağlı: Kuleye tıklayınca seviye atlatmak için) for (var i = 0; i < defenseTowers.length; i++) { var tower = defenseTowers[i]; if (!tower.levelUpBtn) { var btn = new Text2('Seviye Atla', { size: 20, fill: "#fff", dropShadow: true, dropShadowColor: 0x000000, dropShadowDistance: 2, dropShadowAngle: Math.PI / 4, dropShadowBlur: 4, dropShadowAlpha: 0.7 }); btn.anchor.set(0.5, 0); btn.x = tower.x; btn.y = tower.y + 80; btn.interactive = true; btn.buttonMode = true; btn.hitArea = { x: -btn.width / 2 - 10, y: -10, width: btn.width + 20, height: btn.height + 20 }; btn.down = function (tw) { return function () { // Seviye atlatmak için 100 kaynak harca var totalResourceStock = 0; for (var i = 0; i < resourceTypeList.length; i++) { totalResourceStock += resourceStocks[resourceTypeList[i].name]; } if (totalResourceStock < 100) { LK.effects.flashObject(btn, 0xff0000, 600); return; } // Kaynakları harca var remaining = 100; for (var i = 0; i < resourceTypeList.length; i++) { var typeName = resourceTypeList[i].name; var take = Math.min(resourceStocks[typeName], remaining); resourceStocks[typeName] -= take; remaining -= take; if (remaining <= 0) break; } tw.levelUp(); LK.effects.flashObject(tw, 0x4adf4a, 600); }; }(tower); game.addChild(btn); tower.levelUpBtn = btn; } // Butonun pozisyonunu güncelle if (tower.levelUpBtn) { tower.levelUpBtn.x = tower.x; tower.levelUpBtn.y = tower.y + 80; tower.levelUpBtn.visible = tower.visible && tower.hp > 0; } } // Savunma Kulesi Seviye Yükselt butonu işlevi defenseTowerLevelUpBtn.down = function (x, y, obj) { // Sadece aktif bir kule varsa seviye atlat var activeTowers = []; for (var i = 0; i < defenseTowers.length; i++) { if (defenseTowers[i].visible && defenseTowers[i].hp > 0) activeTowers.push(defenseTowers[i]); } if (activeTowers.length === 0) { LK.effects.flashObject(defenseTowerLevelUpBtn, 0xff0000, 600); return; } // Toplam kaynak stoğu ile kontrol var totalResourceStock = 0; for (var i = 0; i < resourceTypeList.length; i++) { totalResourceStock += resourceStocks[resourceTypeList[i].name]; } if (totalResourceStock < defenseTowerLevelUpPrice) { LK.effects.flashObject(defenseTowerLevelUpBtn, 0xff0000, 600); return; } // Kaynakları harca (her kaynaktan orantılı olarak düş) var remaining = defenseTowerLevelUpPrice; for (var i = 0; i < resourceTypeList.length; i++) { var typeName = resourceTypeList[i].name; var take = Math.min(resourceStocks[typeName], remaining); resourceStocks[typeName] -= take; remaining -= take; if (remaining <= 0) break; } // En düşük seviye olan kuleyi bul ve sadece onu seviye atlat var minLevel = 9999; var minLevelTowers = []; for (var i = 0; i < activeTowers.length; i++) { if (activeTowers[i].level < minLevel) { minLevel = activeTowers[i].level; minLevelTowers = [activeTowers[i]]; } else if (activeTowers[i].level === minLevel) { minLevelTowers.push(activeTowers[i]); } } if (minLevelTowers.length > 0) { // Birden fazla aynı seviyede kule varsa, ilkini yükselt minLevelTowers[0].levelUp(); LK.effects.flashObject(minLevelTowers[0], 0x4adf4a, 600); } // Fiyatı 100 ve katları olarak artır defenseTowerLevelUpPrice += defenseTowerLevelUpBasePrice; defenseTowerLevelUpBtn.setText('Savunma Kulesi Seviye Yükselt (' + defenseTowerLevelUpPrice + ' Kaynak)'); }; // Gemi satın alma işlemi shipBuyBtn.down = function (x, y, obj) { // Toplam kaynak stoğu ile kontrol (artık resourceStocks kullanılacak) var totalResourceStock = 0; for (var i = 0; i < resourceTypeList.length; i++) { totalResourceStock += resourceStocks[resourceTypeList[i].name]; } if (totalResourceStock >= shipBuyPrice) { // Kaynakları harca (her kaynaktan orantılı olarak düş) var remaining = shipBuyPrice; for (var i = 0; i < resourceTypeList.length; i++) { var typeName = resourceTypeList[i].name; var take = Math.min(resourceStocks[typeName], remaining); resourceStocks[typeName] -= take; remaining -= take; if (remaining <= 0) break; } // Ana geminin canı ve maxHp'si değişmesin, sadece yeni savaşçı ekle ship.visible = true; ship.x = 2048 / 2; ship.y = 2732 - 700; LK.effects.flashObject(ship, 0x4adf4a, 800); shipBuyPrice = Math.ceil(shipBuyPrice * shipBuyPriceIncrease); shipBuyBtn.setText('Yeni Savaşçı (' + shipBuyPrice + ' Kaynak)'); // Yeni savaşçı gemisi oluştur ve diziye ekle var newShip = new Ship(); // Her spawn'da farklı bir savaşçı gemisi görseli kullan var shipImages = ['ship1', 'ship2', 'ship3', 'ship4', 'ship5', 'ship6', 'ship7', 'ship8', 'ship9', 'ship10']; var shipImageIndex = Math.floor(Math.random() * shipImages.length); newShip.shipImageId = shipImages[shipImageIndex]; // Eski asset'i kaldırıp yeni asset'i ekle if (newShip.children && newShip.children.length > 0) { var oldAsset = newShip.children[0]; if (typeof oldAsset.destroy === "function") oldAsset.destroy(); newShip.removeChild(oldAsset); } var s = newShip.attachAsset(newShip.shipImageId, { anchorX: 0.5, anchorY: 0.5 }); newShip.x = 2048 / 2 + (Math.random() * 200 - 100); newShip.y = 2732 - 700 + (Math.random() * 100 - 50); // Yeni alınan savaşçı 5/5 can ile başlasın newShip.maxHp = 5; newShip.hp = 5; // Diğer ayarlar da aynı şekilde uygulansın newShip.repairCost = 20; newShip.repairCostIncrease = 1.1; newShip.visible = true; newShip.isExtra = true; // AI kontrollü olduğunu belirtmek için game.addChild(newShip); extraShips.push(newShip); // Her yeni gemi için can yazısı ekle var hpTxt = new Text2('', { size: 32, fill: "#fff", dropShadow: true, dropShadowColor: 0x000000, dropShadowDistance: 2, dropShadowAngle: Math.PI / 4, dropShadowBlur: 4, dropShadowAlpha: 0.7 }); hpTxt.anchor.set(0.5, 1); hpTxt.x = newShip.x; hpTxt.y = newShip.y - 70; game.addChild(hpTxt); extraShipHpTxts.push({ ship: newShip, txt: hpTxt }); // Her yeni gemi için Tamir Et butonu ekle (yOffset: 110) createShipRepairBtn(newShip, 110); } }; // Asteroit Avcısı satın alma işlemi collectorBuyBtn.down = function (x, y, obj) { // Toplam kaynak stoğu ile kontrol var totalResourceStock = 0; for (var i = 0; i < resourceTypeList.length; i++) { totalResourceStock += resourceStocks[resourceTypeList[i].name]; } if (totalResourceStock >= collectorBuyPrice) { // Kaynakları harca (her kaynaktan orantılı olarak düş) var remaining = collectorBuyPrice; for (var i = 0; i < resourceTypeList.length; i++) { var typeName = resourceTypeList[i].name; var take = Math.min(resourceStocks[typeName], remaining); resourceStocks[typeName] -= take; remaining -= take; if (remaining <= 0) break; } autoCollectors++; createCollectors(autoCollectors); LK.effects.flashObject(collectors[collectors.length - 1], 0x4adf4a, 800); collectorBuyPrice = Math.ceil(collectorBuyPrice * collectorBuyPriceIncrease); collectorBuyBtn.setText('Asteroit Avcısı (' + collectorBuyPrice + ' Kaynak)'); } }; // Kaynak Avcısı satın alma butonu var resourceHunterBuyBtn = new Text2('Kaynak Avcısı (100 Kaynak)', { size: 28, fill: "#fff", dropShadow: true, dropShadowColor: 0x000000, dropShadowDistance: 2, dropShadowAngle: Math.PI / 4, dropShadowBlur: 4, dropShadowAlpha: 0.7 }); resourceHunterBuyBtn.anchor.set(1, 1); resourceHunterBuyBtn.x = -32; resourceHunterBuyBtn.y = -200; resourceHunterBuyBtn.interactive = true; resourceHunterBuyBtn.buttonMode = true; resourceHunterBuyBtn.hitArea = { x: -resourceHunterBuyBtn.width - 20, y: -10, width: resourceHunterBuyBtn.width + 40, height: resourceHunterBuyBtn.height + 20 }; shipBuyPanelGroup.addChild(resourceHunterBuyBtn); // Kaynak Avcısı satın alma işlemi resourceHunterBuyBtn.down = function (x, y, obj) { // Toplam kaynak stoğu ile kontrol var totalResourceStock = 0; for (var i = 0; i < resourceTypeList.length; i++) { totalResourceStock += resourceStocks[resourceTypeList[i].name]; } if (totalResourceStock >= resourceHunterBuyPrice) { // Kaynakları harca (her kaynaktan orantılı olarak düş) var remaining = resourceHunterBuyPrice; for (var i = 0; i < resourceTypeList.length; i++) { var typeName = resourceTypeList[i].name; var take = Math.min(resourceStocks[typeName], remaining); resourceStocks[typeName] -= take; remaining -= take; if (remaining <= 0) break; } autoResourceHunters++; createResourceHunters(autoResourceHunters); LK.effects.flashObject(resourceHunters[resourceHunters.length - 1], 0x4adf4a, 800); resourceHunterBuyPrice = Math.ceil(resourceHunterBuyPrice * resourceHunterBuyPriceIncrease); resourceHunterBuyBtn.setText('Kaynak Avcısı (' + resourceHunterBuyPrice + ' Kaynak)'); } }; // --- Sağ alt panel: Gemi öğeleri satın alma paneli --- var shipPanelGroup = new Container(); shipPanelGroup.x = 0; shipPanelGroup.y = -colonyHpLabelRight.height - colonyHpTxtRight.height - collectorTxtRight.height - shipCountTxtRight.height - 48; guiRightBottomGroup.addChild(shipPanelGroup); // Panel arka planı (özel görsel, hafif şeffaf) var shipPanelBg = LK.getAsset('ship_panel_bg', { anchorX: 1, anchorY: 1 }); shipPanelBg.alpha = 0.92; shipPanelBg.x = 0; shipPanelBg.y = 0; shipPanelGroup.addChild(shipPanelBg); // Panel başlığı var shipPanelTitle = new Text2('Savaşçı Yükseltmeleri', { size: 32, fill: "#fff", dropShadow: true, dropShadowColor: 0x000000, dropShadowDistance: 2, dropShadowAngle: Math.PI / 4, dropShadowBlur: 4, dropShadowAlpha: 0.7 }); shipPanelTitle.anchor.set(1, 1); shipPanelTitle.x = -24; shipPanelTitle.y = -24; shipPanelGroup.addChild(shipPanelTitle); // --- Sol alt: Seviye Yükseltme Paneli --- // Paneli sol alt kaynak panelinin üstünden iki satır daha yukarı taşı var upgradePanelGroup = new Container(); // Sol alt panelin yüksekliğini hesapla (kaynak yazılarının en üstünden iki satır daha yukarı hizalanacak) var upgradePanelYOffset = 32; // Kaynak paneli ile aradaki boşluk var upgradePanelRowHeight = 0; if (typeof resourceStockTxts !== "undefined" && resourceStockTxts.length > 0) { // resourceStockTxts[resourceStockTxts.length-1] en üstteki (yukarıdan aşağıya ekleniyor) var topResourceTxt = resourceStockTxts[resourceStockTxts.length - 1]; upgradePanelRowHeight = topResourceTxt.height; } var upgradePanelTopY = 0; if (typeof resourceStockTxts !== "undefined" && resourceStockTxts.length > 0) { // İki satır daha yukarı taşı: iki kaynak satırı yüksekliği kadar yukarı var topResourceTxt = resourceStockTxts[resourceStockTxts.length - 1]; upgradePanelTopY = topResourceTxt.y - 2 * topResourceTxt.height - upgradePanelYOffset - upgradePanelRowHeight; } else { upgradePanelTopY = -400 - 36 - 36; // fallback, iki satır daha yukarı } upgradePanelGroup.x = 0; upgradePanelGroup.y = upgradePanelTopY; guiLeftBottomGroup.addChild(upgradePanelGroup); // Şirket panelini upgradePanelGroup'un hemen üstüne ve aynı konumda hizala (seviye paneli ile aynı genişlik ve hizalama) companyPanelGroup.x = upgradePanelGroup.x; companyPanelGroup.y = upgradePanelGroup.y - companyPanelHeight - companyPanelYOffset; guiLeftBottomGroup.addChild(companyPanelGroup); // Panelin yeni görünümünün özel resim dosyasını oluştur (örnek: panelin ekran görüntüsünü kaydet) if (typeof LK.screenshot === "function") { LK.screenshot(companyPanelGroup, "sirket.png", { replace: true }); } // Panel arka planı var upgradePanelBg = LK.getAsset('upgrade_panel_bg', { anchorX: 0, // sol hizalı anchorY: 1 // üst hizalı }); upgradePanelBg.alpha = 0.92; upgradePanelBg.x = 0; upgradePanelBg.y = 0; upgradePanelGroup.addChild(upgradePanelBg); // Panel başlığı var upgradePanelTitle = new Text2('Seviye Yükseltme', { size: 32, fill: "#fff", dropShadow: true, dropShadowColor: 0x000000, dropShadowDistance: 2, dropShadowAngle: Math.PI / 4, dropShadowBlur: 4, dropShadowAlpha: 0.7 }); upgradePanelTitle.anchor.set(0, 1); upgradePanelTitle.x = 24; upgradePanelTitle.y = -24; upgradePanelGroup.addChild(upgradePanelTitle); // Seviye göstergesi var upgradeLevel = 0; var upgradeLevelTxt = new Text2('Seviye: 0', { size: 28, fill: "#fff", dropShadow: true, dropShadowColor: 0x000000, dropShadowDistance: 2, dropShadowAngle: Math.PI / 4, dropShadowBlur: 4, dropShadowAlpha: 0.7 }); upgradeLevelTxt.anchor.set(0, 1); upgradeLevelTxt.x = 32; upgradeLevelTxt.y = -80; upgradePanelGroup.addChild(upgradeLevelTxt); // Yükseltme butonu var upgradeBasePrice = 100; var upgradePrice = upgradeBasePrice; var upgradeBtn = new Text2('Yükselt (' + upgradePrice + ' Kaynak)', { size: 28, fill: "#fff", dropShadow: true, dropShadowColor: 0x000000, dropShadowDistance: 2, dropShadowAngle: Math.PI / 4, dropShadowBlur: 4, dropShadowAlpha: 0.7 }); upgradeBtn.anchor.set(0, 1); upgradeBtn.x = 32; upgradeBtn.y = -140; upgradeBtn.interactive = true; upgradeBtn.buttonMode = true; upgradeBtn.hitArea = { x: -20, y: -10, width: upgradeBtn.width + 40, height: upgradeBtn.height + 20 }; upgradePanelGroup.addChild(upgradeBtn); // Açıklama var upgradeDescTxt = new Text2('Her seviye:\n- Mermi hızı %20 artar\n- Gemi hızı %10 artar\n- Maden kaynağı %10 artar', { size: 22, fill: "#fff", dropShadow: true, dropShadowColor: 0x000000, dropShadowDistance: 2, dropShadowAngle: Math.PI / 4, dropShadowBlur: 4, dropShadowAlpha: 0.7 }); upgradeDescTxt.anchor.set(0, 1); upgradeDescTxt.x = 32; upgradeDescTxt.y = -200; upgradePanelGroup.addChild(upgradeDescTxt); // Yükseltme butonu fonksiyonu upgradeBtn.down = function (x, y, obj) { // Toplam kaynak ile kontrol var totalResourceStock = 0; for (var i = 0; i < resourceTypeList.length; i++) { totalResourceStock += resourceStocks[resourceTypeList[i].name]; } if (totalResourceStock >= upgradePrice) { // Kaynakları harca (her kaynaktan orantılı olarak düş) var remaining = upgradePrice; for (var i = 0; i < resourceTypeList.length; i++) { var typeName = resourceTypeList[i].name; var take = Math.min(resourceStocks[typeName], remaining); resourceStocks[typeName] -= take; remaining -= take; if (remaining <= 0) break; } upgradeLevel++; upgradeLevelTxt.setText('Seviye: ' + upgradeLevel); // Fiyatı %25 artır upgradePrice = Math.ceil(upgradeBasePrice * Math.pow(1.25, upgradeLevel)); upgradeBtn.setText('Yükselt (' + upgradePrice + ' Kaynak)'); LK.effects.flashObject(upgradePanelBg, 0x4adf4a, 600); } }; // Satın alınabilir öğeler: örnek olarak "Savaşçı Canı +1" ve "Savaşçı Yenile" var shipUpgradeBtn = new Text2('Can +1 (30 Kaynak)', { size: 28, fill: "#fff", dropShadow: true, dropShadowColor: 0x000000, dropShadowDistance: 2, dropShadowAngle: Math.PI / 4, dropShadowBlur: 4, dropShadowAlpha: 0.7 }); shipUpgradeBtn.anchor.set(1, 1); shipUpgradeBtn.x = -32; shipUpgradeBtn.y = -80; shipUpgradeBtn.interactive = true; shipUpgradeBtn.buttonMode = true; shipUpgradeBtn.hitArea = { x: -shipUpgradeBtn.width - 20, y: -10, width: shipUpgradeBtn.width + 40, height: shipUpgradeBtn.height + 20 }; shipPanelGroup.addChild(shipUpgradeBtn); shipUpgradeBtn.down = function (x, y, obj) { // 30 toplam kaynak ile savaşçı canı artır var totalResourceStock = 0; for (var i = 0; i < resourceTypeList.length; i++) { totalResourceStock += resourceStocks[resourceTypeList[i].name]; } // Aktif savaşçı gemilerinin listesini oluştur var shipsToUpgrade = []; if (typeof ship.maxHp === "number" && ship.visible && ship.maxHp < 10) { shipsToUpgrade.push(ship); } for (var i = 0; i < extraShips.length; i++) { var s = extraShips[i]; if (typeof s.maxHp === "number" && s.visible && s.maxHp < 10) { shipsToUpgrade.push(s); } } if (totalResourceStock >= 30 && shipsToUpgrade.length > 0) { // Kaynakları harca (her kaynaktan orantılı olarak düş) var remaining = 30; for (var i = 0; i < resourceTypeList.length; i++) { var typeName = resourceTypeList[i].name; var take = Math.min(resourceStocks[typeName], remaining); resourceStocks[typeName] -= take; remaining -= take; if (remaining <= 0) break; } // Her aktif savaşçı gemisinin maxHp'sini 1 artır (10'a kadar), hp aynı kalsın for (var i = 0; i < shipsToUpgrade.length; i++) { if (shipsToUpgrade[i].maxHp < 10) { shipsToUpgrade[i].maxHp += 1; if (shipsToUpgrade[i].maxHp > 10) shipsToUpgrade[i].maxHp = 10; // shipsToUpgrade[i].hp = shipsToUpgrade[i].maxHp; // hp artık değişmiyor LK.effects.flashObject(shipsToUpgrade[i], 0x4adf4a, 600); } } } }; var shipRespawnBtn = new Text2('Savaşçı Yenile (100 Kaynak)', { size: 28, fill: "#fff", dropShadow: true, dropShadowColor: 0x000000, dropShadowDistance: 2, dropShadowAngle: Math.PI / 4, dropShadowBlur: 4, dropShadowAlpha: 0.7 }); shipRespawnBtn.anchor.set(1, 1); shipRespawnBtn.x = -32; shipRespawnBtn.y = -140; shipRespawnBtn.interactive = true; shipRespawnBtn.buttonMode = true; shipRespawnBtn.hitArea = { x: -shipRespawnBtn.width - 20, y: -10, width: shipRespawnBtn.width + 40, height: shipRespawnBtn.height + 20 }; shipPanelGroup.addChild(shipRespawnBtn); shipRespawnBtn.down = function (x, y, obj) { // Savaşçı Yenile: Her yenilenecek savaşçı için 100 Toplam Kaynak maliyeti // Yenilenecek savaşçıları bul var shipsToRespawn = []; if (!ship.visible || ship.hp <= 0) { shipsToRespawn.push(ship); } for (var i = 0; i < extraShips.length; i++) { var s = extraShips[i]; if (!s.visible || s.hp <= 0) { shipsToRespawn.push(s); } } var respawnCost = shipsToRespawn.length * 100; // Toplam kaynak stoğu ile kontrol var totalResourceStock = 0; for (var i = 0; i < resourceTypeList.length; i++) { totalResourceStock += resourceStocks[resourceTypeList[i].name]; } if (shipsToRespawn.length === 0) { LK.effects.flashObject(shipRespawnBtn, 0x4adf4a, 400); return; } if (totalResourceStock < respawnCost) { LK.effects.flashObject(shipRespawnBtn, 0xff0000, 600); return; } // Kaynakları harca (her kaynaktan orantılı olarak düş) var remaining = respawnCost; for (var i = 0; i < resourceTypeList.length; i++) { var typeName = resourceTypeList[i].name; var take = Math.min(resourceStocks[typeName], remaining); resourceStocks[typeName] -= take; remaining -= take; if (remaining <= 0) break; } // Her savaşçıyı tekrar aktif et for (var i = 0; i < shipsToRespawn.length; i++) { var s = shipsToRespawn[i]; if (typeof s.maxHp !== "number" || s.maxHp < 1) s.maxHp = 6; if (s.maxHp > 10) s.maxHp = 10; s.hp = s.maxHp; s.visible = true; s.x = 2048 / 2 + (s === ship ? 0 : Math.random() * 200 - 100); s.y = 2732 - 700 + (s === ship ? 0 : Math.random() * 100 - 50); // Her yenilemede farklı bir savaşçı gemisi görseli kullan var shipImages = ['ship1', 'ship2', 'ship3', 'ship4', 'ship5', 'ship6', 'ship7', 'ship8', 'ship9', 'ship10']; var shipImageIndex = Math.floor(Math.random() * shipImages.length); s.shipImageId = shipImages[shipImageIndex]; // Eski asset'i kaldırıp yeni asset'i ekle if (s.children && s.children.length > 0) { var oldAsset = s.children[0]; if (typeof oldAsset.destroy === "function") oldAsset.destroy(); s.removeChild(oldAsset); } var newAsset = s.attachAsset(s.shipImageId, { anchorX: 0.5, anchorY: 0.5 }); LK.effects.flashObject(s, 0x4adf4a, 800); } }; // Paneli sağ alt köşede, diğer yazıların üstünde tutmak için z-index ayarı if (typeof shipPanelGroup.setChildIndex === "function") { shipPanelGroup.setChildIndex(shipPanelBg, 0); } // Sağ üst köşeye "Oyunu Sıfırla" butonu ekle var resetBtn = new Text2('Oyunu Sıfırla', { size: 44, fill: "#fff", font: "bold", dropShadow: true, dropShadowColor: 0x000000, dropShadowDistance: 2, dropShadowAngle: Math.PI / 4, dropShadowBlur: 4, dropShadowAlpha: 0.7 }); resetBtn.anchor.set(1, 0); // sağ üst köşe resetBtn.x = 0; resetBtn.y = 0; resetBtn.interactive = true; resetBtn.buttonMode = true; resetBtn.hitArea = { x: -20, y: -10, width: resetBtn.width + 40, height: resetBtn.height + 20 }; resetBtn.down = function (x, y, obj) { // Oyun ilerlemesini sıfırla if (typeof storage !== "undefined" && storage.clear) { storage.clear(); } LK.showGameOver(); // Oyun sıfırlama için game over popup tetikle }; LK.gui.topRight.addChild(resetBtn); // Kaynak türleri ve isimleri var resourceTypeList = [{ name: "Altın", asset: "resource_gold" }, { name: "Kobalt", asset: "resource_cobalt" }, { name: "Nikel", asset: "resource_nickel" }, { name: "Helyum-3", asset: "resource_helium3" }, { name: "Platin", asset: "resource_platinum" }, { name: "Demir", asset: "resource_iron" }, { name: "Manganez", asset: "resource_manganese" }]; // Her kaynak için stok tut var resourceStocks = {}; // Başlangıç toplam kaynağı 5000 olacak şekilde eşit dağıt var initialTotalResource = 5000; var perResource = Math.floor(initialTotalResource / resourceTypeList.length); var remaining = initialTotalResource; for (var i = 0; i < resourceTypeList.length; i++) { // Son kaynağa kalanı ekle ki toplam tam 5000 olsun if (i === resourceTypeList.length - 1) { resourceStocks[resourceTypeList[i].name] = remaining; } else { resourceStocks[resourceTypeList[i].name] = perResource; remaining -= perResource; } } // Oyun başında storage'dan yükleme yapılmaz, her zaman sıfırdan başlar // Her kaynak için ayrı Text2 oluştur, alt alta hizala var resourceStockTxts = []; var lastY = collectorTxt.y - collectorTxt.height - 16; for (var i = 0; i < resourceTypeList.length; i++) { // Kaynak rengi: asset id'sinden shape tanımını bul var assetId = resourceTypeList[i].asset; var assetColor = 0xffffff; // Asset tanımlarını yukarıda sabit olarak bildiğimiz için, elle eşleştiriyoruz if (assetId === "resource_gold") assetColor = 0x5b6733;else if (assetId === "resource_cobalt") assetColor = 0x52459a;else if (assetId === "resource_nickel") assetColor = 0x825648;else if (assetId === "resource_helium3") assetColor = 0xf59af1;else if (assetId === "resource_platinum") assetColor = 0x63dbd1;else if (assetId === "resource_iron") assetColor = 0xe5bf1c;else if (assetId === "resource_manganese") assetColor = 0xbc3379; var txt = new Text2(resourceTypeList[i].name + ": 0", { size: 36, fill: assetColor, dropShadow: true, dropShadowColor: 0x000000, dropShadowDistance: 2, dropShadowAngle: Math.PI / 4, dropShadowBlur: 4, dropShadowAlpha: 0.7 }); txt.anchor.set(0, 1); txt.x = 0; txt.y = lastY; guiLeftBottomGroup.addChild(txt); resourceStockTxts.push(txt); lastY = txt.y - txt.height; // Satır arası boşluğu kaldırıldı } // Gemi sayısı göstergesi (sol alt) -- KALDIRILDI, sadece yükseklik için dummy olarak tanımlanır var shipCountTxt = new Text2('Savaşçı: 1', { size: 36, fill: "#fff", dropShadow: true, dropShadowColor: 0x000000, dropShadowDistance: 2, dropShadowAngle: Math.PI / 4, dropShadowBlur: 4, dropShadowAlpha: 0.7 }); shipCountTxt.anchor.set(0, 1); shipCountTxt.x = 0; shipCountTxt.y = -colonyHpTxt.height - resourceTxt.height - collectorTxt.height - 24; // Eğer başka yazı veya butonlar eklenirse, aynı şekilde guiLeftBottomGroup'a eklenmeli ve // y koordinatları bir önceki elemanın yüksekliği ve aradaki boşluk ile ayarlanmalı. // Tüm yazılar ve butonlar bu grupta, sol alt köşeye hizalı ve font boyutu 36 olacak şekilde ayarlanmıştır. // Gemi kur ship = new Ship(); ship.x = 2048 / 2; ship.y = 2732 - 700; ship.maxHp = 5; ship.hp = 5; ship.repairCost = 20; ship.repairCostIncrease = 1.1; game.addChild(ship); // Ek savaşçı gemiler için dizi var extraShips = []; // Her ekstra gemi için can yazısı tutulacak dizi var extraShipHpTxts = []; // Gemi can barı: geminin üstünde gösterilecek (özel resim ile) var shipHpBarBg = LK.getAsset('ship_hpbar_bg', { anchorX: 0.5, anchorY: 0.5 }); var shipHpBar = LK.getAsset('ship_hpbar_fg', { anchorX: 0.5, anchorY: 0.5 }); shipHpBarBg.y = ship.y - 50; shipHpBarBg.x = ship.x; shipHpBar.y = ship.y - 50; shipHpBar.x = ship.x; game.addChild(shipHpBarBg); game.addChild(shipHpBar); // Gemi üzerinde kalan can miktarı sayı olarak gösterilsin var shipHpTxt = new Text2('', { size: 32, fill: "#fff", dropShadow: true, dropShadowColor: 0x000000, dropShadowDistance: 2, dropShadowAngle: Math.PI / 4, dropShadowBlur: 4, dropShadowAlpha: 0.7 }); shipHpTxt.anchor.set(0.5, 1); shipHpTxt.x = ship.x; shipHpTxt.y = ship.y - 70; game.addChild(shipHpTxt); // --- Her gemi için Tamir Et butonu ve maliyetini ekle --- function createShipRepairBtn(targetShip, yOffset) { var btn = new Text2('Tamir Et (' + targetShip.repairCost + ' Kaynak)', { size: 24, fill: "#fff", dropShadow: true, dropShadowColor: 0x000000, dropShadowDistance: 2, dropShadowAngle: Math.PI / 4, dropShadowBlur: 4, dropShadowAlpha: 0.7 }); btn.anchor.set(0.5, 1); btn.x = targetShip.x; btn.y = targetShip.y - yOffset; btn.interactive = true; btn.buttonMode = true; btn.hitArea = { x: -btn.width / 2 - 20, y: -btn.height - 10, width: btn.width + 40, height: btn.height + 20 }; btn.visible = targetShip.visible; btn.down = function (x, y, obj) { // Toplam kaynak stoğu ile kontrol var totalResourceStock = 0; for (var i = 0; i < resourceTypeList.length; i++) { totalResourceStock += resourceStocks[resourceTypeList[i].name]; } if (targetShip.hp >= targetShip.maxHp) { LK.effects.flashObject(btn, 0x4adf4a, 400); return; } if (totalResourceStock < targetShip.repairCost) { LK.effects.flashObject(btn, 0xff0000, 600); return; } // Kaynakları harca (her kaynaktan orantılı olarak düş) var remaining = targetShip.repairCost; for (var i = 0; i < resourceTypeList.length; i++) { var typeName = resourceTypeList[i].name; var take = Math.min(resourceStocks[typeName], remaining); resourceStocks[typeName] -= take; remaining -= take; if (remaining <= 0) break; } // HP'yi 1 artır, maxHp'yi geçemez targetShip.hp += 1; if (targetShip.hp > targetShip.maxHp) targetShip.hp = targetShip.maxHp; LK.effects.flashObject(targetShip, 0x4adf4a, 600); // Maliyeti %10 artır targetShip.repairCost = Math.ceil(targetShip.repairCost * targetShip.repairCostIncrease); btn.setText('Tamir Et (' + targetShip.repairCost + ' Kaynak)'); }; game.addChild(btn); // Butonun pozisyonunu ve görünürlüğünü update fonksiyonunda güncellemek için ship objesine referans ekle targetShip.repairBtn = btn; } // Ana gemi için buton ekle createShipRepairBtn(ship, 110); // Ekstra gemiler için butonlar spawn edildiğinde eklenecek (aşağıda shipBuyBtn.down fonksiyonunda) // Asteroit Avcısı'nın aktif olacağı oran (ör: 0.5 = alt %50'lik kısımda avlanır, ileride artırılabilir) var hunterActiveRatio = 0.5; // Alt %50'lik kısımda aktif // Asteroit Avcılarını oluştur function createCollectors(n) { for (var i = collectors.length; i < n; i++) { var c = new AsteroidHunter(); c.x = colony.x + 100 * (i - n / 2); c.y = colony.y + 100; collectors.push(c); game.addChild(c); } } createCollectors(autoCollectors); // Kaynak Avcılarını oluştur function createResourceHunters(n) { for (var i = resourceHunters.length; i < n; i++) { var h = new ResourceHunter(); h.x = colony.x + 100 * (i - n / 2); h.y = colony.y + 200; resourceHunters.push(h); game.addChild(h); // Yeni kaynaklar için baseAmount ayarla for (var j = 0; j < resourceNodes.length; j++) { if (typeof resourceNodes[j].baseAmount === "undefined") { resourceNodes[j].baseAmount = resourceNodes[j].amount; } } } } createResourceHunters(autoResourceHunters); // Asteroidleri oluştur (kaynaklar asteroid yok edilince çıkacak) // Artık asteroidler haritaya yavaşça girip rastgele ilerleyecek, sayıları 2-6 arası olacak var asteroidNodes = []; function spawnAsteroids() { // Haritada 2-6 asteroid olacak şekilde ayarla var minAsteroids = 2; var maxAsteroids = 6; // Mevcut asteroid sayısını kontrol et var currentAsteroids = 0; for (var i = 0; i < asteroidNodes.length; i++) { if (!asteroidNodes[i].collected) currentAsteroids++; } var toSpawn = Math.max(minAsteroids - currentAsteroids, 0); toSpawn = Math.min(maxAsteroids - currentAsteroids, toSpawn + Math.floor(Math.random() * (maxAsteroids - minAsteroids + 1))); for (var i = 0; i < toSpawn; i++) { var a = new AsteroidNode(); asteroidNodes.push(a); game.addChild(a); // Yeni kaynaklar için baseAmount ayarla for (var j = 0; j < resourceNodes.length; j++) { if (typeof resourceNodes[j].baseAmount === "undefined") { resourceNodes[j].baseAmount = resourceNodes[j].amount; } } } } // Başlangıçta asteroidleri oluştur spawnAsteroids(); // Gemiye dokunma ve sürükleme game.down = function (x, y, obj) { // Gemiye dokunulduysa sürükle var local = game.toLocal({ x: x, y: y }); var dx = local.x - ship.x; var dy = local.y - ship.y; if (dx * dx + dy * dy < 120 * 120) { dragNode = ship; lastTouch.x = local.x; lastTouch.y = local.y; } else { // Hedefe git ship.targetX = local.x; ship.targetY = local.y; } }; game.move = function (x, y, obj) { if (dragNode === ship) { var local = game.toLocal({ x: x, y: y }); ship.targetX = local.x; ship.targetY = local.y; lastTouch.x = local.x; lastTouch.y = local.y; } }; game.up = function (x, y, obj) { dragNode = null; }; // Kaynak toplama otomasyonu function assignCollectors() { for (var i = 0; i < collectors.length; i++) { var c = collectors[i]; // Eğer collector bir asteroidi takip ediyorsa ve asteroid haritadan çıkmadıysa veya yok olmadıysa veya kaynak almadıysa, takip etmeye devam etsin if (c.state === 'moving' && c.target && typeof c.target.hp === "number" && !c.target.collected && c.target.visible && // Asteroid Avcısı sadece ilgili alan (hunterActiveY) içindeki asteroidi yok edene kadar peşini bırakmasın c.target.y >= 2732 * hunterActiveRatio && (!c.target.resourceSpawned || _typeof3(c.target.resourceNode) === "object" && c.target.resourceNode && !c.target.resourceNode.collected)) { // Asteroid yok edilmedi ve kaynak alınmadı, takip etmeye devam et continue; } // Sadece idle veya returning durumundakiler için yeni hedef ata if (c.state === 'idle' || c.state === 'returning' || !c.target || c.target && (c.target.collected || !c.target.visible)) { // --- Tüm haritadaki asteroidlere saldır, öncelik koloniye en yakın olan --- // Asteroit Avcısı haritanın üst yarısına müdahale etmesin (oran ile) var hunterActiveY = 2732 * hunterActiveRatio; var minDistAst = 99999; var targetAst = null; for (var j = 0; j < asteroidNodes.length; j++) { var a = asteroidNodes[j]; if (!a.collected && a.visible && typeof a.x === "number" && typeof a.y === "number") { // Asteroit Avcısı sadece hunterActiveY'den aşağıdaki asteroidlere saldırır if (a.y < hunterActiveY) continue; // Koloniye olan mesafeyi hesapla var dxCol = a.x - colony.x; var dyCol = a.y - colony.y; var distCol = Math.sqrt(dxCol * dxCol + dyCol * dyCol); // Her durumda, en yakın asteroidi bul var dx = a.x - c.x; var dy = a.y - c.y; var dist = dx * dx + dy * dy; // Öncelik: koloniye en yakın asteroid if (distCol < minDistAst) { minDistAst = distCol; targetAst = a; } } } if (targetAst) { c.target = targetAst; c.state = 'moving'; continue; } // Eğer hedef yoksa, haritada rastgele bir noktaya doğru dolaşmaya başlasın if (!c.target || c.state === 'idle') { // Rastgele bir hedef belirle (harita içinde) var randX = 200 + Math.random() * (2048 - 400); var randY = 400 + Math.random() * (2732 - 800); // Sahte bir hedef objesi oluştur (sadece pozisyon için) c.target = { x: randX, y: randY, hp: 9999, collected: false, visible: true }; c.state = 'moving'; continue; } } // Asteroit Avcıları kaynak toplamaz, sadece asteroit yok ederler } } // Gemi ateş etme function shipShoot() { if (LK.ticks - ship.lastShot > ship.shootDelay) { var b = new Bullet(); b.x = ship.x; b.y = ship.y - 60; // En yakın düşmanı bul var nearestEnemy = null; var minDist = 999999; for (var i = 0; i < enemies.length; i++) { var dx = enemies[i].x - ship.x; var dy = enemies[i].y - ship.y; var dist = dx * dx + dy * dy; if (dist < minDist) { minDist = dist; nearestEnemy = enemies[i]; } } if (nearestEnemy) { // Merminin hedefini kaydet b.targetEnemy = nearestEnemy; var tx = nearestEnemy.x - ship.x; var ty = nearestEnemy.y - ship.y; var tdist = Math.sqrt(tx * tx + ty * ty); if (tdist > 0) { b.dirX = tx / tdist; b.dirY = ty / tdist; } else { b.dirX = 0; b.dirY = -1; } } else { b.dirX = 0; b.dirY = -1; } b.from = 'player'; bullets.push(b); game.addChild(b); ship.lastShot = LK.ticks; } } // Oyun güncelleme döngüsü game.update = function () { // Kaynak göstergesini güncelle var totalResourceStock = 0; for (var i = 0; i < resourceTypeList.length; i++) { totalResourceStock += resourceStocks[resourceTypeList[i].name]; } resources = totalResourceStock; // resources birimini Toplam Kaynak ile eşdeğer yap resourceTxt.setText('Toplam Kaynak: ' + totalResourceStock); collectorTxt.setText('Asteroit Avcısı: ' + autoCollectors); // Her kaynak türünden stokta olan miktarı göster for (var i = 0; i < resourceTypeList.length; i++) { var typeName = resourceTypeList[i].name; // resourceStocks[typeName] zaten Collector tarafından güncelleniyor, burada tekrar sıfırlama veya toplama yapma! // Sadece GUI güncellemesi için değerler kullanılacak. } // Her kaynak için GUI yazısını güncelle for (var i = 0; i < resourceTypeList.length; i++) { var typeName = resourceTypeList[i].name; resourceStockTxts[i].setText(typeName + ": " + resourceStocks[typeName]); } // Gemi sayısı güncelle (gemi yoksa 0, varsa 1) var activeShipCount = ship && ship.visible && ship.hp > 0 ? 1 : 0; for (var i = 0; i < extraShips.length; i++) { if (extraShips[i].visible && extraShips[i].hp > 0) activeShipCount++; } shipCountTxt.setText('Savaşçı: ' + activeShipCount); shipCountTxtRight.setText('Savaşçı: ' + activeShipCount); // Gemi canı güncelle -- KALDIRILDI // --- Sağ alt panel butonlarının aktif/pasif durumunu güncelle --- // Gemi satın alma paneli butonu if (typeof shipBuyBtn !== "undefined") { var totalResourceStock = 0; for (var i = 0; i < resourceTypeList.length; i++) { totalResourceStock += resourceStocks[resourceTypeList[i].name]; } if (totalResourceStock >= shipBuyPrice) { shipBuyBtn.alpha = 1; } else { shipBuyBtn.alpha = 0.5; } } // Asteroit Avcısı satın alma butonu if (typeof collectorBuyBtn !== "undefined") { if (resources >= collectorBuyPrice) { collectorBuyBtn.alpha = 1; } else { collectorBuyBtn.alpha = 0.5; } } // Savunma Kulesi satın alma butonu aktiflik if (typeof defenseTowerBuyBtn !== "undefined") { var activeTowers = 0; for (var i = 0; i < defenseTowers.length; i++) { if (defenseTowers[i].visible && defenseTowers[i].hp > 0) activeTowers++; } if (resources >= defenseTowerBuyPrice && activeTowers < defenseTowerMaxCount) { defenseTowerBuyBtn.alpha = 1; } else { defenseTowerBuyBtn.alpha = 0.5; } } // Savunma Kulesi Seviye Yükselt butonu aktif/pasif güncelle if (typeof defenseTowerLevelUpBtn !== "undefined") { var activeTowers = 0; for (var i = 0; i < defenseTowers.length; i++) { if (defenseTowers[i].visible && defenseTowers[i].hp > 0) activeTowers++; } if (resources >= defenseTowerLevelUpPrice && activeTowers > 0) { defenseTowerLevelUpBtn.alpha = 1; } else { defenseTowerLevelUpBtn.alpha = 0.5; } } // Kaynak Avcısı satın alma butonu aktiflik if (typeof resourceHunterBuyBtn !== "undefined") { if (resources >= resourceHunterBuyPrice) { resourceHunterBuyBtn.alpha = 1; } else { resourceHunterBuyBtn.alpha = 0.5; } } if (typeof shipUpgradeBtn !== "undefined") { var totalResourceStock = 0; for (var i = 0; i < resourceTypeList.length; i++) { totalResourceStock += resourceStocks[resourceTypeList[i].name]; } // Herhangi bir savaşçı gemisinin maxHp'si 10'dan küçükse buton aktif, hepsi 10 ise pasif var anyShipMaxBelow10 = false; if (typeof ship.maxHp === "number" && ship.visible && ship.maxHp < 10) { anyShipMaxBelow10 = true; } for (var i = 0; i < extraShips.length; i++) { var s = extraShips[i]; if (typeof s.maxHp === "number" && s.visible && s.maxHp < 10) { anyShipMaxBelow10 = true; break; } } if (anyShipMaxBelow10 && totalResourceStock >= 30) { shipUpgradeBtn.alpha = 1; } else { shipUpgradeBtn.alpha = 0.5; } } if (typeof shipRespawnBtn !== "undefined") { // Yenilenecek savaşçı sayısını bul var shipsToRespawn = 0; if (!ship.visible || ship.hp <= 0) shipsToRespawn++; for (var i = 0; i < extraShips.length; i++) { var s = extraShips[i]; if (!s.visible || s.hp <= 0) shipsToRespawn++; } var respawnCost = shipsToRespawn * 100; if (shipsToRespawn > 0) { shipRespawnBtn.setText('Savaşçı Yenile (' + respawnCost + ' Kaynak)'); } else { shipRespawnBtn.setText('Savaşçı Yenile (0 Kaynak)'); } if (resources >= respawnCost && shipsToRespawn > 0) { shipRespawnBtn.alpha = 1; } else { shipRespawnBtn.alpha = 0.5; } } // Seviye yükseltme butonu aktiflik if (typeof upgradeBtn !== "undefined") { var totalResourceStock = 0; for (var i = 0; i < resourceTypeList.length; i++) { totalResourceStock += resourceStocks[resourceTypeList[i].name]; } if (totalResourceStock >= upgradePrice) { upgradeBtn.alpha = 1; } else { upgradeBtn.alpha = 0.5; } } // Koloni sağlık sistemi güncellemesi if (colony.hp < 0) colony.hp = 0; if (colony.hp > colony.maxHp) colony.hp = colony.maxHp; var ratio = colony.maxHp > 0 ? colony.hp / colony.maxHp : 0; if (ratio < 0) ratio = 0; if (ratio > 1) ratio = 1; colonyHealthSystem.bar.width = 216 * ratio; colonyHealthSystem.bar.x = colony.x; colonyHealthSystem.bar.y = colony.y - 160; colonyHealthSystem.barBg.x = colony.x; colonyHealthSystem.barBg.y = colony.y - 160; colonyHealthSystem.levelTxt.x = colony.x; colonyHealthSystem.levelTxt.y = colony.y - 200 - 40; colonyHealthSystem.levelTxt.setText('Seviye: ' + colonyLevel); colonyHealthSystem.upBtn.x = -32; colonyHealthSystem.upBtn.y = -140; // shipBuyBtn.y = -80, collectorBuyBtn.y = -140, 2 satır yukarı = -200, ama -140 hizalı (üstten 2. satır) colonyHealthSystem.upBtn.setText('Koloni Seviye Yükselt (' + colonyLevelPrice + ' Kaynak)'); colonyHealthSystem.repairBtn.x = colony.x; colonyHealthSystem.repairBtn.y = colony.y - 200 - colonyHealthSystem.repairBtn.height - 20 + (colonyHealthSystem.repairBtn.height + 20) * 0.25; colonyHealthSystem.repairBtn.setText('Tamir Et (' + colonyHealthSystem.repairCost + ' Kaynak)'); // Sol alt ve sağ alt koloni canı yazılarını güncelle colonyHpTxt.setText(Math.round(colony.hp) + ' / ' + colony.maxHp); colonyHpTxt.x = colony.x; colonyHpTxt.y = colony.y - 160; var rightHp = 0; var rightMaxHp = 100; if (typeof colony !== "undefined" && colony) { if (typeof colony.hp === "number" && !isNaN(colony.hp)) { rightHp = Math.max(0, Math.round(colony.hp)); } if (typeof colony.maxHp === "number" && !isNaN(colony.maxHp) && colony.maxHp > 0) { rightMaxHp = colony.maxHp; } } colonyHpTxtRight.setText(rightHp + " / " + rightMaxHp); // Koloni seviye yazısı ve butonunu güncelle if (typeof colonyLevelTxt !== "undefined") { colonyLevelTxt.x = colony.x; colonyLevelTxt.y = colony.y - 200 - 40; colonyLevelTxt.setText('Seviye: ' + colonyLevel); } if (typeof colonyLevelUpBtn !== "undefined") { colonyLevelUpBtn.x = colony.x; colonyLevelUpBtn.y = colony.y - 200 - 80; // Buton aktiflik: kaynak yetersizse veya canı doluysa pasif var totalResourceStock = 0; for (var i = 0; i < resourceTypeList.length; i++) { totalResourceStock += resourceStocks[resourceTypeList[i].name]; } if (totalResourceStock < colonyLevelPrice) { colonyLevelUpBtn.alpha = 0.5; } else { colonyLevelUpBtn.alpha = 1; } } // Koloni Tamir Et butonu aktif/pasif güncelle if (typeof colonyRepairBtn !== "undefined") { var totalResourceStock = 0; for (var i = 0; i < resourceTypeList.length; i++) { totalResourceStock += resourceStocks[resourceTypeList[i].name]; } if (colony.hp >= colony.maxHp || totalResourceStock < colonyRepairCost) { colonyRepairBtn.alpha = 0.5; } else { colonyRepairBtn.alpha = 1; } } // Sağ alt collector güncelle collectorTxtRight.setText('Asteroit Avcısı: ' + autoCollectors); // Sağ alt Kaynak Avcısı güncelle if (typeof resourceHunterBuyBtn !== "undefined") { if (!game.resourceHunterTxtRight) { var txt = new Text2('Kaynak Avcısı: ' + autoResourceHunters, { size: 36, fill: "#fff", dropShadow: true, dropShadowColor: 0x000000, dropShadowDistance: 2, dropShadowAngle: Math.PI / 4, dropShadowBlur: 4, dropShadowAlpha: 0.7 }); txt.anchor.set(1, 1); txt.x = 0; txt.y = -colonyHpLabelRight.height - colonyHpTxtRight.height - collectorTxtRight.height - shipCountTxtRight.height - 24; guiRightBottomGroup.addChild(txt); game.resourceHunterTxtRight = txt; } game.resourceHunterTxtRight.setText('Kaynak Avcısı: ' + autoResourceHunters); } // Asteroidleri güncelle ve haritada minimum 2, maksimum 6 asteroid olmasını sağla for (var i = asteroidNodes.length - 1; i >= 0; i--) { var a = asteroidNodes[i]; if (typeof a.update === "function") a.update(); // Haritadan çıkan veya yok edilen asteroidleri temizle if (a.collected || !a.visible) { a.destroy(); asteroidNodes.splice(i, 1); } } // Asteroid sayısı azaldıysa yeni asteroid ekle spawnAsteroids(); // Kaynakları güncelle (hareket ettir) for (var i = 0; i < resourceNodes.length; i++) { if (typeof resourceNodes[i].update === "function") resourceNodes[i].update(); } // Toplayıcıları görevlendir assignCollectors(); // Collector güncelle ve AI ile otomatik görev yapmalarını sağla for (var i = 0; i < collectors.length; i++) { var c = collectors[i]; // Eğer collector yok olduysa veya görünmüyorsa, atla if (!c.visible) continue; // --- AI: En yakın uygun asteroide saldır --- if ((c.state === 'idle' || c.state === 'returning' || !c.target || c.target && (c.target.collected || !c.target.visible)) && asteroidNodes.length > 0) { // Asteroit Avcısı haritanın alt yarısında çalışır var hunterActiveY = 2732 * hunterActiveRatio; var minDistAst = 99999; var targetAst = null; for (var j = 0; j < asteroidNodes.length; j++) { var a = asteroidNodes[j]; if (!a.collected && a.visible && typeof a.x === "number" && typeof a.y === "number") { if (a.y < hunterActiveY) continue; var dxCol = a.x - colony.x; var dyCol = a.y - colony.y; var distCol = Math.sqrt(dxCol * dxCol + dyCol * dyCol); if (distCol < minDistAst) { minDistAst = distCol; targetAst = a; } } } if (targetAst) { c.target = targetAst; c.state = 'moving'; } else { // Hedef yoksa rastgele bir noktaya git var randX = 200 + Math.random() * (2048 - 400); var randY = 400 + Math.random() * (2732 - 800); c.target = { x: randX, y: randY, hp: 9999, collected: false, visible: true }; c.state = 'moving'; } } c.update(); } // Kaynak Avcısı güncelle ve AI ile otomatik görev yapmalarını sağla for (var i = 0; i < resourceHunters.length; i++) { var h = resourceHunters[i]; if (!h.visible) continue; // Eğer kaynak taşıyorsa koloniye dön if (h.state === 'returning' && h.carryType && h.carryAmount > 0) { // update fonksiyonu zaten taşıma işlemini yapıyor h.update(); continue; } // Eğer hedef kaynak yoksa veya hedefi toplandıysa yeni hedef ata if ((h.state === 'idle' || !h.target || h.target && (h.target.collected || !h.target.visible)) && resourceNodes.length > 0) { var minDist = 99999; var targetRes = null; for (var j = 0; j < resourceNodes.length; j++) { var r = resourceNodes[j]; if (!r.collected && r.visible) { var dx = r.x - h.x; var dy = r.y - h.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < minDist) { minDist = dist; targetRes = r; } } } if (targetRes) { h.target = targetRes; h.state = 'moving'; } } h.update(); } // --- Seviye yükseltme bonuslarını uygula --- if (typeof upgradeLevel !== "undefined" && upgradeLevel > 0) { // Gemi hızı ship.speed = 11 * 0.1 * Math.pow(1.1, upgradeLevel); // Asteroid Avcısı ve Kaynak Avcısı hızları for (var i = 0; i < collectors.length; i++) { collectors[i].speed = 1.25 * (0.002 + 0.001) * 0.1 * 2732 * Math.pow(1.1, upgradeLevel); } for (var i = 0; i < resourceHunters.length; i++) { resourceHunters[i].speed = 1.1 * (0.002 + 0.001) * 0.1 * 2732 * Math.pow(1.1, upgradeLevel); } // Mermi hızı for (var i = 0; i < bullets.length; i++) { if (typeof bullets[i].speed === "number") { // Sadece oyuncu ve collector mermileri için uygula if (bullets[i].from === 'player' || typeof bullets[i].from === "undefined") { bullets[i].speed = 40 * 0.1 * Math.pow(1.2, upgradeLevel); } else if (bullets[i].from === 'enemy') { // Düşman mermisi sabit kalsın } } } // Maden kaynağı artırımı (yeni kaynaklar için) for (var i = 0; i < resourceNodes.length; i++) { if (typeof resourceNodes[i].baseAmount === "undefined") { resourceNodes[i].baseAmount = resourceNodes[i].amount; } resourceNodes[i].amount = Math.floor(resourceNodes[i].baseAmount * Math.pow(1.1, upgradeLevel)); } } // Gemi güncelle ship.update(); // Ekstra savaşçı gemileri güncelle ve AI ile kontrol et for (var i = 0; i < extraShips.length; i++) { var s = extraShips[i]; // Eğer gemi yok olduysa veya görünmüyorsa, atla if (!s.visible || s.hp <= 0) continue; // --- AI: En yakın düşmana saldır --- var nearestEnemy = null; var minEnemyDist = 999999; for (var j = 0; j < enemyShips.length; j++) { var e = enemyShips[j]; if (e.state === 'approaching' || e.state === 'engaging' || e.state === 'attacking') { var dx = e.x - s.x; var dy = e.y - s.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < minEnemyDist) { minEnemyDist = dist; nearestEnemy = e; } } } // Eğer bir düşman koloniye 600px mesafedeyse, gemi ona saldırı pozisyonuna geçsin if (nearestEnemy && minEnemyDist < 600) { // Saldırı pozisyonu: düşmana yaklaş ve ateş et var dx = nearestEnemy.x - s.x; var dy = nearestEnemy.y - s.y; var dist = Math.sqrt(dx * dx + dy * dy); // Eğer çok uzaktaysa yaklaş if (dist > 200) { s.targetX = nearestEnemy.x + Math.random() * 40 - 20; s.targetY = nearestEnemy.y + Math.random() * 40 - 20; } else { // Yakındaysa ateş et if (typeof s.lastShot === "undefined") s.lastShot = 0; if (typeof s.shootDelay === "undefined") s.shootDelay = 30; if (LK.ticks - s.lastShot > s.shootDelay) { var b = new Bullet(); b.x = s.x; b.y = s.y - 60; b.targetEnemy = nearestEnemy; var tx = nearestEnemy.x - s.x; var ty = nearestEnemy.y - s.y; var tdist = Math.sqrt(tx * tx + ty * ty); if (tdist > 0) { b.dirX = tx / tdist; b.dirY = ty / tdist; } else { b.dirX = 0; b.dirY = -1; } b.from = 'player'; bullets.push(b); game.addChild(b); s.lastShot = LK.ticks; } } s.isAttacking = true; s.randomMoveTimer = 0; } else { // Gemi rastgele hareket etsin, düşman yok if (!s.randomMoveTimer) s.randomMoveTimer = 0; s.randomMoveTimer++; if (s.randomMoveTimer > 60) { // Her 1 saniyede bir yeni hedef belirle var angle = Math.random() * Math.PI * 2; var dist = 300 + Math.random() * 350; s.targetX = colony.x + Math.cos(angle) * dist; s.targetY = colony.y + Math.sin(angle) * dist; s.isAttacking = false; s.randomMoveTimer = 0; } } s.update(); } // Gemi can barı pozisyon ve genişlik güncelle if (typeof shipHpBar !== "undefined" && typeof shipHpBarBg !== "undefined") { shipHpBarBg.x = ship.x; shipHpBarBg.y = ship.y - 50; shipHpBar.x = ship.x; shipHpBar.y = ship.y - 50; var ratio = typeof ship.hp === "number" && typeof ship.maxHp === "number" && ship.maxHp > 0 ? ship.hp / ship.maxHp : 1; if (ratio < 0) ratio = 0; if (ratio > 1) ratio = 1; shipHpBar.width = 86 * ratio; shipHpBar.visible = ship.visible; shipHpBarBg.visible = ship.visible; } // Gemi üzerindeki can miktarı yazısını güncelle if (typeof shipHpTxt !== "undefined") { shipHpTxt.setText((typeof ship.hp === "number" ? Math.max(0, Math.round(ship.hp)) : 0) + " / " + (typeof ship.maxHp === "number" ? ship.maxHp : 0)); shipHpTxt.x = ship.x; shipHpTxt.y = ship.y - 70; shipHpTxt.visible = ship.visible; } // Ekstra savaşçı gemilerinin can yazılarını güncelle if (typeof extraShipHpTxts !== "undefined") { for (var i = 0; i < extraShipHpTxts.length; i++) { var s = extraShipHpTxts[i].ship; var t = extraShipHpTxts[i].txt; if (!s || !t) continue; t.setText((typeof s.hp === "number" ? Math.max(0, Math.round(s.hp)) : 0) + " / " + (typeof s.maxHp === "number" ? s.maxHp : 0)); t.x = s.x; t.y = s.y - 70; t.visible = s.visible; } } // --- Her gemi için Tamir Et butonunun pozisyonu, görünürlüğü ve aktifliği güncellensin --- if (ship.repairBtn) { ship.repairBtn.x = ship.x; ship.repairBtn.y = ship.y - 110; ship.repairBtn.visible = ship.visible; // Buton aktiflik: canı doluysa veya kaynak yoksa pasif var totalResourceStock = 0; for (var i = 0; i < resourceTypeList.length; i++) { totalResourceStock += resourceStocks[resourceTypeList[i].name]; } if (ship.hp >= ship.maxHp || totalResourceStock < ship.repairCost) { ship.repairBtn.alpha = 0.5; } else { ship.repairBtn.alpha = 1; } } // Ekstra gemiler için de aynı şekilde güncelle for (var i = 0; i < extraShips.length; i++) { var s = extraShips[i]; if (s.repairBtn) { s.repairBtn.x = s.x; s.repairBtn.y = s.y - 110; s.repairBtn.visible = s.visible; var totalResourceStock = 0; for (var j = 0; j < resourceTypeList.length; j++) { totalResourceStock += resourceStocks[resourceTypeList[j].name]; } if (s.hp >= s.maxHp || totalResourceStock < s.repairCost) { s.repairBtn.alpha = 0.5; } else { s.repairBtn.alpha = 1; } } } // --- Bizim askerler, düşman birliği koloniye yaklaşırken savunma saldırısı yapsın --- // En yakın düşman gemisini bul ve eğer koloniye yaklaşıyorsa saldır var nearestEnemy = null; var minEnemyDist = 999999; for (var i = 0; i < enemyShips.length; i++) { var e = enemyShips[i]; // Sadece koloniye yaklaşan veya saldıran düşmanları dikkate al if (e.state === 'approaching' || e.state === 'engaging' || e.state === 'attacking') { var dx = e.x - colony.x; var dy = e.y - colony.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < minEnemyDist) { minEnemyDist = dist; nearestEnemy = e; } } } // Eğer bir düşman koloniye 600px mesafedeyse, gemi ona saldırı pozisyonuna geçsin if (nearestEnemy && minEnemyDist < 600 && ship.visible && ship.hp > 0) { // Saldırı pozisyonu: düşmana yaklaş ve ateş et var dx = nearestEnemy.x - ship.x; var dy = nearestEnemy.y - ship.y; var dist = Math.sqrt(dx * dx + dy * dy); // Eğer çok uzaktaysa yaklaş if (dist > 200) { ship.targetX = nearestEnemy.x + Math.random() * 40 - 20; ship.targetY = nearestEnemy.y + Math.random() * 40 - 20; } else { // Yakındaysa ateş et if (LK.ticks - ship.lastShot > ship.shootDelay) { var b = new Bullet(); b.x = ship.x; b.y = ship.y - 60; b.targetEnemy = nearestEnemy; var tx = nearestEnemy.x - ship.x; var ty = nearestEnemy.y - ship.y; var tdist = Math.sqrt(tx * tx + ty * ty); if (tdist > 0) { b.dirX = tx / tdist; b.dirY = ty / tdist; } else { b.dirX = 0; b.dirY = -1; } b.from = 'player'; bullets.push(b); game.addChild(b); ship.lastShot = LK.ticks; } } ship.isAttacking = true; ship.randomMoveTimer = 0; } else { // Gemi rastgele hareket etsin, düşman yok if (!ship.randomMoveTimer) ship.randomMoveTimer = 0; ship.randomMoveTimer++; if (ship.randomMoveTimer > 60) { // Her 1 saniyede bir yeni hedef belirle var angle = Math.random() * Math.PI * 2; var dist = 300 + Math.random() * 350; ship.targetX = colony.x + Math.cos(angle) * dist; ship.targetY = colony.y + Math.sin(angle) * dist; ship.isAttacking = false; ship.randomMoveTimer = 0; } } // --- Düşman gemisi üretimi ve güncellemesi --- enemySpawnTimer++; if (enemySpawnTimer >= ENEMY_SPAWN_INTERVAL) { // Düşman dalga sayısını artır enemyWaveCount++; // Her dalgada gönderilecek gemi sayısı: 1 * 1.25^enemyWaveCount, en az 1, tam sayı enemyShipsPerWave = Math.max(1, Math.floor(1 * Math.pow(1.25, enemyWaveCount))); for (var i = 0; i < enemyShipsPerWave; i++) { var newEnemy = new EnemyShip(); // Dalga içindeki gemileri biraz farklı açılarda gönder if (typeof topAsteroid !== "undefined" && typeof topAsteroid.x === "number" && typeof topAsteroid.y === "number") { var angle = Math.PI / 2 + (i - (enemyShipsPerWave - 1) / 2) * (Math.PI / 16); var radius = 80 + i * 20; newEnemy.x = topAsteroid.x + Math.cos(angle) * radius; newEnemy.y = topAsteroid.y + Math.sin(angle) * radius; } enemyShips.push(newEnemy); game.addChild(newEnemy); } enemySpawnTimer = 0; } // Düşman gemilerini güncelle for (var i = enemyShips.length - 1; i >= 0; i--) { var e = enemyShips[i]; if (typeof e.update === "function") e.update(); // Eğer yok olduysa sil if (e.hp <= 0 || e.x < -200 || e.x > 2248 || e.y < -200 || e.y > 2932) { // Düşman sağlık barı varsa yok et if (e.hpBar) { e.hpBar.destroy(); } if (e.hpBarBg) { e.hpBarBg.destroy(); } // Eğer düşman öldüyse (haritadan çıkmadıysa), kaynak ekle if (e.hp <= 0) { // 30 kaynağı rastgele kaynak türlerine dağıt var remaining = 30; var types = []; for (var t = 0; t < resourceTypeList.length; t++) { types.push(resourceTypeList[t].name); } while (remaining > 0) { var idx = Math.floor(Math.random() * types.length); resourceStocks[types[idx]] += 1; remaining--; } // resources değişkenini de güncelle (Toplam Kaynak ile eşdeğer) var totalResourceStock = 0; for (var t = 0; t < resourceTypeList.length; t++) { totalResourceStock += resourceStocks[types[t].name]; } resources = totalResourceStock; } // Düşman binasının en son gönderdiği geminin saldırı gücünü güncelle if (typeof e.attackPower === "number") { lastEnemyShipAttackPower = e.attackPower; } e.destroy(); enemyShips.splice(i, 1); } } // --- Düşman binası GUI ve mekanik güncellemesi --- // HP barı ve yazılarını güncelle if (typeof enemyBaseHpBar !== "undefined" && typeof enemyBaseHpBarBg !== "undefined") { enemyBaseHpBarBg.x = 0; enemyBaseHpBarBg.y = -120; enemyBaseHpBar.x = 0; enemyBaseHpBar.y = -120; var ratio = enemyBaseHp / enemyBaseMaxHp; if (ratio < 0) ratio = 0; if (ratio > 1) ratio = 1; enemyBaseHpBar.width = 216 * ratio; enemyBaseHpBar.visible = true; enemyBaseHpBarBg.visible = true; } if (typeof enemyBaseHpTxt !== "undefined") { enemyBaseHpTxt.setText(Math.round(enemyBaseHp) + ' / ' + enemyBaseMaxHp); enemyBaseHpTxt.x = 0; enemyBaseHpTxt.y = -150; enemyBaseHpTxt.visible = true; } if (typeof enemyBaseLevelTxt !== "undefined") { enemyBaseLevelTxt.setText('Seviye: ' + enemyBaseLevel); enemyBaseLevelTxt.x = 0; enemyBaseLevelTxt.y = 100; enemyBaseLevelTxt.visible = true; } if (typeof enemyBaseAttackBtn !== "undefined") { // Buton aktifliği: bina yoksa pasif if (enemyBaseHp <= 0) { enemyBaseAttackBtn.alpha = 0.5; } else { enemyBaseAttackBtn.alpha = 1; } enemyBaseAttackBtn.x = 0; enemyBaseAttackBtn.y = 160; enemyBaseAttackBtn.visible = true; } // Düşman binası yoksa, yeni bina oluştur (otomatik) if (enemyBaseHp <= 0) { // Respawn kalan süre göstergesi için static değişkenler if (typeof enemyBaseRespawnTxt === "undefined") { enemyBaseRespawnTxt = new Text2('', { size: 40, fill: "#fff", dropShadow: true, dropShadowColor: 0x000000, dropShadowDistance: 2, dropShadowAngle: Math.PI / 4, dropShadowBlur: 4, dropShadowAlpha: 0.7 }); enemyBaseRespawnTxt.anchor.set(0.5, 0.5); enemyBaseRespawnTxt.x = enemyBaseGroup.x; enemyBaseRespawnTxt.y = enemyBaseGroup.y + 40; game.addChild(enemyBaseRespawnTxt); enemyBaseRespawnTxt.visible = false; } // Eğer yok olma süresi başlamadıysa başlat if (typeof enemyBaseRespawnTimer === "undefined" || enemyBaseRespawnTimer === null) { // Bina ve GUI'yi görünmez yap enemyBaseGroup.visible = false; enemyBaseSprite.visible = false; if (enemyBaseHpBar) enemyBaseHpBar.visible = false; if (enemyBaseHpBarBg) enemyBaseHpBarBg.visible = false; if (enemyBaseHpTxt) enemyBaseHpTxt.visible = false; if (enemyBaseLevelTxt) enemyBaseLevelTxt.visible = false; if (enemyBaseAttackBtn) enemyBaseAttackBtn.visible = false; // --- Düşman gemilerinin sağlık yazılarını da gizle --- for (var i = 0; i < enemyShips.length; i++) { if (enemyShips[i] && enemyShips[i].hpTxt) { enemyShips[i].hpTxt.visible = false; } } // Respawn kalan süreyi başlat enemyBaseRespawnTxt.visible = true; enemyBaseRespawnTxt.x = enemyBaseGroup.x; enemyBaseRespawnTxt.y = enemyBaseGroup.y + 40; enemyBaseRespawnTxt.setText("Yeni bina için: 10 sn"); // Respawn kalan süreyi güncellemek için tick sayacı enemyBaseRespawnStartTick = LK.ticks; enemyBaseRespawnDuration = 600; // 10 saniye * 60 FPS // 10 saniye sonra yeni bina spawn et enemyBaseRespawnTimer = LK.setTimeout(function () { // Seviye +1, hp +%20, saldırı gücü +%10, yeni gemiler %10 daha güçlü enemyBaseLevel++; enemyBaseMaxHp = Math.floor(enemyBaseMaxHp * 1.2); enemyBaseMaxHp = Math.floor(enemyBaseMaxHp * 0.3); // %70 azaltılmış şekilde başlat enemyBaseHp = enemyBaseMaxHp; enemyBaseAttackPower = Math.ceil(enemyBaseAttackPower * 1.1); enemyBaseAttackPower = enemyBaseAttackPower * 0.3; // %70 azaltılmış şekilde başlat lastEnemyShipAttackPower = enemyBaseAttackPower; if (enemyBaseLevelTxt) enemyBaseLevelTxt.setText('Seviye: ' + enemyBaseLevel); // Sağlık yazısını yeni seviyeye göre güncelle if (enemyBaseHpTxt) enemyBaseHpTxt.setText(Math.round(enemyBaseHp) + ' / ' + enemyBaseMaxHp); // --- Düşman binası görselini rastgele değiştir --- if (enemyBaseSprite && typeof enemyBaseGroup.removeChild === "function") { enemyBaseGroup.removeChild(enemyBaseSprite); if (typeof enemyBaseSprite.destroy === "function") enemyBaseSprite.destroy(); } currentEnemyBaseImageId = enemyBaseImageIds[Math.floor(Math.random() * enemyBaseImageIds.length)]; enemyBaseSprite = LK.getAsset(currentEnemyBaseImageId, { anchorX: 0.5, anchorY: 0.5 }); enemyBaseSprite.x = 0; enemyBaseSprite.y = 0; enemyBaseGroup.addChildAt(enemyBaseSprite, 0); // En alta ekle // Bina ve GUI'yi tekrar görünür yap enemyBaseGroup.visible = true; enemyBaseSprite.visible = true; if (enemyBaseHpBar) enemyBaseHpBar.visible = true; if (enemyBaseHpBarBg) enemyBaseHpBarBg.visible = true; if (enemyBaseHpTxt) enemyBaseHpTxt.visible = true; if (enemyBaseLevelTxt) enemyBaseLevelTxt.visible = true; if (enemyBaseAttackBtn) enemyBaseAttackBtn.visible = true; // Respawn kalan süre yazısını gizle if (enemyBaseRespawnTxt) enemyBaseRespawnTxt.visible = false; enemyBaseRespawnTimer = null; }, 10000); } // Her frame'de kalan süreyi güncelle if (enemyBaseRespawnTxt && enemyBaseRespawnTxt.visible && typeof enemyBaseRespawnStartTick !== "undefined" && typeof enemyBaseRespawnDuration !== "undefined") { var elapsed = LK.ticks - enemyBaseRespawnStartTick; var remain = Math.ceil((enemyBaseRespawnDuration - elapsed) / 60); if (remain < 0) remain = 0; enemyBaseRespawnTxt.setText("Yeni bina için: " + remain + " sn"); } } else { // Bina hayattaysa timer'ı sıfırla if (typeof enemyBaseRespawnTimer !== "undefined" && enemyBaseRespawnTimer !== null) { LK.clearTimeout(enemyBaseRespawnTimer); enemyBaseRespawnTimer = null; } } // Savunma kulelerini güncelle for (var i = 0; i < defenseTowers.length; i++) { var tower = defenseTowers[i]; if (typeof tower.update === "function") tower.update(); // Kule yok olduysa görünmez yap if (tower.hp <= 0 && tower.visible) { tower.destroyTower(); } // --- Savunma kulesi tamir et butonu pozisyon, görünürlük ve aktiflik güncelle --- if (tower.repairBtn) { tower.repairBtn.x = tower.x; tower.repairBtn.y = tower.y - 170; // 1 satır yukarı taşındı tower.repairBtn.visible = tower.visible && tower.hp > 0; // Buton aktiflik: canı doluysa veya kaynak yoksa pasif var totalResourceStock = 0; for (var j = 0; j < resourceTypeList.length; j++) { totalResourceStock += resourceStocks[resourceTypeList[j].name]; } if (tower.hp >= tower.maxHp || totalResourceStock < tower.repairCost) { tower.repairBtn.alpha = 0.5; } else { tower.repairBtn.alpha = 1; } } } // Düşman gemileri kuleye saldırabiliyor mu? // Her düşman gemisi, kule menziline girerse kuleye saldırır for (var i = 0; i < enemyShips.length; i++) { var e = enemyShips[i]; if (!e.visible || e.hp <= 0) continue; for (var j = 0; j < defenseTowers.length; j++) { var tower = defenseTowers[j]; if (!tower.visible || tower.hp <= 0) continue; var dx = tower.x - e.x; var dy = tower.y - e.y; var dist = Math.sqrt(dx * dx + dy * dy); // Düşman gemisi kuleye 120px yaklaştıysa saldırı başlat if (dist < 120) { // Her 1 saniyede bir kuleye saldırı if (typeof e.lastTowerAttack === "undefined") e.lastTowerAttack = 0; if (typeof e.towerAttackDelay === "undefined") e.towerAttackDelay = 60; if (LK.ticks - e.lastTowerAttack > e.towerAttackDelay) { tower.hp -= Math.max(1, Math.round(e.attackPower)); LK.effects.flashObject(tower, 0xff0000, 400); e.lastTowerAttack = LK.ticks; } } } } // Mermileri güncelle for (var i = bullets.length - 1; i >= 0; i--) { var b = bullets[i]; b.update(); // Ekran dışıysa sil if (b.x < -100 || b.x > 2148 || b.y < -100 || b.y > 2832) { b.destroy(); bullets.splice(i, 1); continue; } // Çarpışmalar // Oyuncu mermisi düşmana çarptıysa if (b.from === 'player') { for (var j = enemyShips.length - 1; j >= 0; j--) { var e = enemyShips[j]; if (e.visible && typeof e.x === "number" && typeof e.y === "number" && b.intersects(e)) { // Düşman canını azalt if (typeof e.hp === "number") e.hp -= typeof b.attackPower === "number" ? b.attackPower : 1; LK.effects.flashObject(e, 0xff0000, 400); b.destroy(); bullets.splice(i, 1); break; } } if (i >= bullets.length) continue; // mermi silindiyse diğer kontrolleri atla } // Sadece koloni ve gemi ile çarpışma kontrolü (düşman yok) if (b.from === 'enemy') { // Koloniye çarpma if (b.intersects(colony)) { if (typeof colony.hp !== "number") colony.hp = colony.maxHp || 50; colony.hp -= typeof b.attackPower === "number" ? b.attackPower : 1; LK.effects.flashObject(colony, 0xff0000, 400); b.destroy(); bullets.splice(i, 1); if (colony.hp <= 0) { LK.effects.flashScreen(0xff0000, 800); LK.showGameOver(); return; } continue; } // Gemiye çarpma if (b.intersects(ship)) { LK.effects.flashObject(ship, 0xff0000, 500); b.destroy(); bullets.splice(i, 1); if (typeof ship.hp !== "number") ship.hp = ship.maxHp || 6; ship.hp -= typeof b.attackPower === "number" ? b.attackPower : 1; if (ship.hp <= 0) { ship.hp = 0; LK.effects.flashObject(ship, 0xff0000, 800); ship.visible = false; ship.x = -9999; ship.y = -9999; // Sağ alttaki birim sayı listesini güncelle if (typeof shipCountTxtRight !== "undefined") { shipCountTxtRight.setText('Savaşçı: 0'); } if (typeof shipCountTxt !== "undefined") { shipCountTxt.setText('Savaşçı: 0'); } } } // Ekstra savaşçı gemilerine çarpma for (var si = 0; si < extraShips.length; si++) { var s = extraShips[si]; if (s.visible && s.hp > 0 && b.intersects(s)) { LK.effects.flashObject(s, 0xff0000, 500); b.destroy(); bullets.splice(i, 1); if (typeof s.hp !== "number") s.hp = s.maxHp || 6; s.hp -= typeof b.attackPower === "number" ? b.attackPower : 1; if (s.hp <= 0) { s.hp = 0; LK.effects.flashObject(s, 0xff0000, 800); s.visible = false; s.x = -9999; s.y = -9999; } break; } } } } // Otomasyon yükseltme: 50 kaynak ile yeni toplayıcı // (Otomatik satın alma kaldırıldı) // Kazanma koşulu kaldırıldı: Artık oyun sonsuz, kaynak limiti yok };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
// Asteroit Avcısı (Collector)
var AsteroidHunter = Container.expand(function () {
var self = Container.call(this);
var col = self.attachAsset('collector', {
anchorX: 0.5,
anchorY: 0.5
});
self.target = null;
// Avcı hızı, kaynak hızından %25 fazla olacak şekilde ayarlanır
self.speed = 1.25 * (0.002 + 0.001) * 0.1 * 2732; // Kaynakların max hızından %25 fazla (normalize için 2732 ile çarpıldı)
self.state = 'idle'; // idle, moving, returning
self.update = function () {
if (self.state === 'moving' && self.target) {
var dx = self.target.x - self.x;
var dy = self.target.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
// --- Avcı mermi sıksın: 60 tickte bir (1 saniyede bir) ---
if (typeof self.lastShot === "undefined") self.lastShot = 0;
if (typeof self.shootDelay === "undefined") self.shootDelay = 60;
if (LK.ticks - self.lastShot > self.shootDelay && dist > 20) {
var b = new Container();
var bulletAsset = b.attachAsset('collector_bullet', {
anchorX: 0.5,
anchorY: 0.5
});
b.x = self.x;
b.y = self.y;
// Asteroide doğru yönlendir
var tdist = Math.sqrt(dx * dx + dy * dy);
b.dirX = tdist > 0 ? dx / tdist : 0;
b.dirY = tdist > 0 ? dy / tdist : -1;
b.speed = 18 * 0.1 * 1.25 * 1.25; // Başlangıçta %25 daha hızlı (toplamda %56.25 hızlı)
b.update = function () {
b.x += b.dirX * b.speed;
b.y += b.dirY * b.speed;
// Asteroide çarptıysa yok et
if (self.target && b.intersects(self.target)) {
if (typeof self.target.hp === "number" && self.target.hp > 0) {
self.target.hp -= 1;
}
b.destroy();
if (typeof bullets !== "undefined") {
var idx = bullets.indexOf(b);
if (idx !== -1) bullets.splice(idx, 1);
}
}
// Ekran dışıysa yok et
if (b.x < -100 || b.x > 2148 || b.y < -100 || b.y > 2832) {
b.destroy();
if (typeof bullets !== "undefined") {
var idx = bullets.indexOf(b);
if (idx !== -1) bullets.splice(idx, 1);
}
}
};
if (typeof bullets !== "undefined") bullets.push(b);
if (typeof game !== "undefined") game.addChild(b);
self.lastShot = LK.ticks;
}
// Asteroit görselinin dışından saldırı: asteroidin görsel yarıçapı + avcı yarıçapı kadar mesafede dur
var asteroidRadius = 0;
if (self.target && self.target.children && self.target.children.length > 0 && self.target.children[0].width) {
asteroidRadius = (self.target.children[0].width * self.target.children[0].scaleX || 1) * 0.5;
} else {
asteroidRadius = 60; // fallback
}
var hunterRadius = col && col.width ? col.width * (col.scaleX || 1) * 0.5 : 50;
var stopDistance = asteroidRadius + hunterRadius + 8; // 8px tampon
if (dist < stopDistance) {
// Asteroide yeterince yaklaştı, daha fazla yaklaşma, state'i 'returning' yap
self.state = 'returning';
} else {
// Asteroide yaklaş, ama içine girme
self.x += self.speed * dx / dist;
self.y += self.speed * dy / dist;
}
} else if (self.state === 'returning') {
var dx = colony.x - self.x;
var dy = colony.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < 10) {
self.state = 'idle';
self.target = null;
} else {
self.x += self.speed * dx / dist;
self.y += self.speed * dy / dist;
}
}
};
return self;
});
// Asteroid ve kaynak çıkışı için yeni AsteroidNode class'ı
var AsteroidNode = Container.expand(function () {
var self = Container.call(this);
// Kaynak türleri ve asteroid asset id'leri
var asteroidTypes = [{
name: "Altın",
asset: "asteroid_gold",
resourceAsset: "resource_gold"
}, {
name: "Kobalt",
asset: "asteroid_cobalt",
resourceAsset: "resource_cobalt"
}, {
name: "Nikel",
asset: "asteroid_nickel",
resourceAsset: "resource_nickel"
}, {
name: "Helyum-3",
asset: "asteroid_helium3",
resourceAsset: "resource_helium3"
}, {
name: "Platin",
asset: "asteroid_platinum",
resourceAsset: "resource_platinum"
}, {
name: "Demir",
asset: "asteroid_iron",
resourceAsset: "resource_iron"
}, {
name: "Manganez",
asset: "asteroid_manganese",
resourceAsset: "resource_manganese"
}];
// Rastgele bir kaynak türü seç
var typeIndex = Math.floor(Math.random() * asteroidTypes.length);
self.resourceType = asteroidTypes[typeIndex].name;
self.asteroidAsset = asteroidTypes[typeIndex].asset;
self.resourceAsset = asteroidTypes[typeIndex].resourceAsset;
// Asteroid görseli
var ast = self.attachAsset(self.asteroidAsset, {
anchorX: 0.5,
anchorY: 0.5
});
self.hp = 3 + Math.floor(Math.random() * 3); // 3-5 arası can
self.collected = false;
self.resourceSpawned = false;
// Hareket: Rastgele kenardan giriş
var edge = Math.floor(Math.random() * 4);
var startX, startY, endX, endY;
var margin = 120;
if (edge === 0) {
startX = -margin;
startY = 400 + Math.random() * (2732 - 800);
endX = 2048 + margin;
endY = startY + (Math.random() - 0.5) * 400;
} else if (edge === 1) {
startX = 2048 + margin;
startY = 400 + Math.random() * (2732 - 800);
endX = -margin;
endY = startY + (Math.random() - 0.5) * 400;
} else if (edge === 2) {
startX = Math.random() * 2048;
startY = -margin;
endX = startX + (Math.random() - 0.5) * 400;
endY = 2732 + margin;
} else {
startX = Math.random() * 2048;
startY = 2732 + margin;
endX = startX + (Math.random() - 0.5) * 400;
endY = -margin;
}
self.x = startX;
self.y = startY;
self._moveStartX = startX;
self._moveStartY = startY;
self._moveEndX = endX;
self._moveEndY = endY;
self._moveProgress = 0;
self._moveSpeed = (0.002 + Math.random() * 0.001) * 0.1;
self.visible = true;
self.resourceNode = null; // Kaynak nesnesi referansı
self.update = function () {
if (self.collected) return;
// Hareket ilerlemesini güncelle
self._moveProgress += self._moveSpeed;
if (self._moveProgress > 1) {
self.collected = true;
self.visible = false;
return;
}
// Lineer hareket
self.x = self._moveStartX + (self._moveEndX - self._moveStartX) * self._moveProgress;
self.y = self._moveStartY + (self._moveEndY - self._moveStartY) * self._moveProgress;
// --- Asteroid boyutunu koloniye yaklaştıkça büyüt ---
// Koloniye olan mesafeyi hesapla
if (typeof colony !== "undefined" && colony && typeof colony.x === "number" && typeof colony.y === "number") {
var dxCol = self.x - colony.x;
var dyCol = self.y - colony.y;
var distCol = Math.sqrt(dxCol * dxCol + dyCol * dyCol);
// Maksimum mesafe: ekran köşesinden koloniye (en uzak ~2732)
var maxDist = 2732;
// Minimum scale: 0.25, Maksimum scale: 1.2
var minScale = 0.25;
var maxScale = 1.2;
// Koloniye yaklaştıkça scale artar, uzaktayken küçüktür
var t = 1 - Math.min(distCol / maxDist, 1);
var scale = minScale + (maxScale - minScale) * t;
// Asteroit görselini ölçekle
if (ast) {
ast.scaleX = scale;
ast.scaleY = scale;
}
}
// Asteroid yok edildi ve kaynak çıkmadıysa kaynak çıkar
if (self.hp <= 0 && !self.resourceSpawned) {
self.resourceSpawned = true;
// Kaynak node'u oluştur
var resNode = new ResourceNode(self.resourceType, self.resourceAsset);
resNode.x = self.x;
resNode.y = self.y;
if (typeof resourceNodes !== "undefined") resourceNodes.push(resNode);
if (typeof game !== "undefined") game.addChild(resNode);
self.collected = true;
self.visible = false;
}
};
return self;
});
// Mermi
var Bullet = Container.expand(function () {
var self = Container.call(this);
var b = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 40 * 0.1;
self.dirX = 0;
self.dirY = -1;
self.from = 'player'; // veya 'enemy'
self.targetEnemy = null; // Eğer hedef varsa
self.attackPower = 1; // Her merminin saldırı gücü 1 olsun
self.update = function () {
// Eğer bu oyuncu mermisi ve hedefi varsa, hedefe yönel
if (self.from === 'player' && self.targetEnemy && typeof self.targetEnemy.x === "number" && typeof self.targetEnemy.y === "number") {
var dx = self.targetEnemy.x - self.x;
var dy = self.targetEnemy.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 0) {
self.dirX = dx / dist;
self.dirY = dy / dist;
}
}
self.x += self.dirX * self.speed;
self.y += self.dirY * self.speed;
// Savunma kulesi mermisi hedefe ulaşınca veya düşman gemisine değince yok olsun
if (self.from === 'player') {
// Hedefe çok yaklaştıysa yok et
if (self.targetEnemy && typeof self.targetEnemy.x === "number" && typeof self.targetEnemy.y === "number") {
var dx = self.targetEnemy.x - self.x;
var dy = self.targetEnemy.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < 30) {
self.destroy();
if (typeof bullets !== "undefined") {
var idx = bullets.indexOf(self);
if (idx !== -1) bullets.splice(idx, 1);
}
return;
}
}
// Düşman gemisine değerse yok et (güvenlik için)
if (typeof enemyShips !== "undefined") {
for (var i = 0; i < enemyShips.length; i++) {
var e = enemyShips[i];
if (e.visible && typeof e.x === "number" && typeof e.y === "number" && self.intersects(e)) {
self.destroy();
if (typeof bullets !== "undefined") {
var idx = bullets.indexOf(self);
if (idx !== -1) bullets.splice(idx, 1);
}
break;
}
}
}
}
};
return self;
});
// Koloni ana üssü
var Colony = Container.expand(function () {
var self = Container.call(this);
var c = self.attachAsset('colony', {
anchorX: 0.5,
anchorY: 0.5
});
// Koloni canı
self.maxHp = 100; // Maksimum can 100
self.hp = 50; // Başlangıç canı 50
return self;
});
// Savunma Kulesi (DefenseTower)
var DefenseTower = Container.expand(function () {
var self = Container.call(this);
// 10 farklı kule görseli
var towerImages = ['defense_tower1', 'defense_tower2', 'defense_tower3', 'defense_tower4', 'defense_tower5', 'defense_tower6', 'defense_tower7', 'defense_tower8', 'defense_tower9', 'defense_tower10'];
var towerImageIndex = Math.floor(Math.random() * towerImages.length);
self.towerImageId = towerImages[towerImageIndex];
var t = self.attachAsset(self.towerImageId, {
anchorX: 0.5,
anchorY: 0.5
});
// Kule özellikleri
self.level = 1;
self.maxHp = 20;
self.hp = self.maxHp;
self.baseAttackPower = 3;
self.attackPower = self.baseAttackPower;
self.range = 600; // px
self.shootDelay = 40; // 0.66s
self.lastShot = 0;
self.targetEnemy = null;
// Kule maxHp ve saldırı gücünü seviyeye göre ayarlayan fonksiyon
self.updateStatsByLevel = function () {
// Saldırı gücü: her seviye başı %25 artar
self.attackPower = Math.round(self.baseAttackPower * Math.pow(1.25, self.level - 1));
// Max HP: her seviye başı +10 ekle
self.maxHp = 20 + (self.level - 1) * 10;
// Eğer mevcut HP yeni maxHp'den fazlaysa, kırp
if (self.hp > self.maxHp) self.hp = self.maxHp;
};
self.updateStatsByLevel();
// Kule can barı
self.hpBarBg = LK.getAsset('colony_hpbar_bg', {
anchorX: 0.5,
anchorY: 0.5
});
self.hpBar = LK.getAsset('colony_hpbar_fg', {
anchorX: 0.5,
anchorY: 0.5
});
self.hpBarBg.x = 0;
self.hpBarBg.y = -90;
self.hpBar.x = 0;
self.hpBar.y = -90;
self.addChild(self.hpBarBg);
self.addChild(self.hpBar);
// Seviye yazısı
self.levelTxt = new Text2('Lv.' + self.level, {
size: 24,
fill: "#fff",
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 2,
dropShadowAngle: Math.PI / 4,
dropShadowBlur: 4,
dropShadowAlpha: 0.7
});
self.levelTxt.anchor.set(0.5, 0);
self.levelTxt.x = 0;
self.levelTxt.y = 60;
self.addChild(self.levelTxt);
// Kule can yazısı
self.hpTxt = new Text2(self.hp + ' / ' + self.maxHp, {
size: 22,
fill: "#fff",
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 2,
dropShadowAngle: Math.PI / 4,
dropShadowBlur: 4,
dropShadowAlpha: 0.7
});
self.hpTxt.anchor.set(0.5, 1);
self.hpTxt.x = 0;
self.hpTxt.y = -110;
self.addChild(self.hpTxt);
// Kule update fonksiyonu
self.update = function () {
// Can barı ve yazılarını güncelle
var ratio = self.hp / self.maxHp;
if (ratio < 0) ratio = 0;
if (ratio > 1) ratio = 1;
self.hpBar.width = 86 * ratio;
self.hpBar.visible = self.visible;
self.hpBarBg.visible = self.visible;
self.hpTxt.setText(Math.round(self.hp) + ' / ' + self.maxHp);
self.hpTxt.visible = self.visible;
self.levelTxt.setText('Lv.' + self.level);
self.levelTxt.visible = self.visible;
// Kule yoksa update etme
if (!self.visible || self.hp <= 0) return;
// Saldırı gücü ve maxHp'yi seviyeye göre güncelle
self.updateStatsByLevel();
// Hedef düşman bul
var nearestEnemy = null;
var minDist = 999999;
if (typeof enemyShips !== "undefined") {
for (var i = 0; i < enemyShips.length; i++) {
var e = enemyShips[i];
if (!e.visible || e.hp <= 0) continue;
var dx = e.x - self.x;
var dy = e.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < self.range && dist < minDist) {
minDist = dist;
nearestEnemy = e;
}
}
}
self.targetEnemy = nearestEnemy;
// Ateş et
if (self.targetEnemy && LK.ticks - self.lastShot > self.shootDelay) {
var b = new Bullet();
b.x = self.x;
b.y = self.y - 60;
b.targetEnemy = self.targetEnemy;
var tx = self.targetEnemy.x - self.x;
var ty = self.targetEnemy.y - self.y;
var tdist = Math.sqrt(tx * tx + ty * ty);
if (tdist > 0) {
b.dirX = tx / tdist;
b.dirY = ty / tdist;
} else {
b.dirX = 0;
b.dirY = -1;
}
b.from = 'player';
b.attackPower = self.attackPower;
bullets.push(b);
if (typeof game !== "undefined") game.addChild(b);
self.lastShot = LK.ticks;
}
};
// Kule seviye atlatma fonksiyonu
self.levelUp = function () {
self.level++;
self.updateStatsByLevel();
self.levelTxt.setText('Lv.' + self.level);
self.hpTxt.setText(Math.round(self.hp) + ' / ' + self.maxHp);
};
// Kule tamir fonksiyonu
self.repair = function (amount) {
self.hp += amount;
if (self.hp > self.maxHp) self.hp = self.maxHp;
};
// Kule yok olunca görünmez yap
self.destroyTower = function () {
self.visible = false;
self.hp = 0;
self.x = -9999;
self.y = -9999;
};
return self;
});
// 60 saniye * 60 FPS
// Düşman gemisi class'ı (önce base etrafında yavaşça döner, sonra saldırır)
var EnemyShip = Container.expand(function () {
var self = Container.call(this);
// 10 farklı düşman görseli
var enemyImages = ['enemy1', 'enemy2', 'enemy3', 'enemy4', 'enemy5', 'enemy6', 'enemy7', 'enemy8', 'enemy9', 'enemy10'];
// Rastgele bir düşman görseli seç
var enemyImageIndex = Math.floor(Math.random() * enemyImages.length);
self.enemyImageId = enemyImages[enemyImageIndex];
var s = self.attachAsset(self.enemyImageId, {
anchorX: 0.5,
anchorY: 0.5
});
self.x = topAsteroid.x;
self.y = topAsteroid.y + 80;
// Askerler gibi yavaş hız: ResourceHunter ile aynı hız
self.speed = 1.1 * (0.002 + 0.001) * 0.1 * 2732; // 0.0003*0.1*2732 ≈ 0.08*2732 ≈ 218
self.lastShot = 0;
self.shootDelay = 60; // 1 saniyede bir ateş etsin
// Düşman binası seviyesiyle orantılı olarak can ve saldırı gücü artırılır
var baseLevel = typeof enemyBaseLevel !== "undefined" ? enemyBaseLevel : 1;
self.hp = Math.floor(3 * Math.pow(1.5, baseLevel - 1));
self.maxHp = self.hp;
self.state = 'orbiting'; // 'orbiting' -> 'attacking'
self.orbitTime = 0;
self.orbitDuration = 180; // 3 saniye boyunca base etrafında dönecek
self.orbitRadius = 180 + Math.random() * 60; // 180-240px arası
self.orbitAngle = Math.random() * Math.PI * 2;
// Düşman gemisinin saldırı gücü, enemyBaseAttackPower ile ve seviye bonusu ile ölçeklenir
self.attackPower = (typeof enemyBaseAttackPower !== "undefined" ? enemyBaseAttackPower : 2) * Math.pow(1.5, baseLevel - 1);
self.update = function () {
// Düşman sağlık barı oluşturulmamışsa ekle
if (!self.hpBarBg) {
self.hpBarBg = LK.getAsset('ship_hpbar_bg', {
anchorX: 0.5,
anchorY: 0.5
});
self.hpBar = LK.getAsset('ship_hpbar_fg', {
anchorX: 0.5,
anchorY: 0.5
});
self.hpBarBg.x = self.x;
self.hpBarBg.y = self.y - 50;
self.hpBar.x = self.x;
self.hpBar.y = self.y - 50;
if (typeof game !== "undefined") {
game.addChild(self.hpBarBg);
game.addChild(self.hpBar);
}
}
// Sağlık barı pozisyon ve genişlik güncelle
if (self.hpBar && self.hpBarBg) {
self.hpBarBg.x = self.x;
// Güvenli şekilde s.height ve s.scaleY kontrolü, yoksa fallback değer kullan
var sHeight = s && typeof s.height === "number" ? s.height : 100;
var sScaleY = s && typeof s.scaleY === "number" ? s.scaleY : 1;
self.hpBarBg.y = self.y - sHeight * sScaleY / 2 - 18; // Düşman görselinin üstüne hizala
self.hpBar.x = self.x;
self.hpBar.y = self.hpBarBg.y;
var maxHp = typeof self.maxHp === "number" ? self.maxHp : 3;
var ratio = typeof self.hp === "number" && maxHp > 0 ? self.hp / maxHp : 0;
if (ratio < 0) ratio = 0;
if (ratio > 1) ratio = 1;
self.hpBar.width = 86 * ratio;
self.hpBar.visible = self.visible;
self.hpBarBg.visible = self.visible;
}
// Takip mesafesi ve çakışmayı önleme
var followDistance = 80; // px, minimum mesafe
if (typeof enemyShips !== "undefined" && enemyShips.length > 1) {
for (var i = 0; i < enemyShips.length; i++) {
var e = enemyShips[i];
if (e === self || !e.visible || typeof e.x !== "number" || typeof e.y !== "number") continue;
var dxE = e.x - self.x;
var dyE = e.y - self.y;
var distE = Math.sqrt(dxE * dxE + dyE * dyE);
if (distE < followDistance && distE > 0) {
// Düşman gemileri birbirine çok yakınsa, uzaklaş
self.x -= (followDistance - distE) * dxE / distE * 0.5;
self.y -= (followDistance - distE) * dyE / distE * 0.5;
}
}
}
if (self.state === 'orbiting') {
// Base etrafında yavaşça daire çiz
self.orbitTime++;
self.orbitAngle += 0.012; // Yavaşça döner
self.x = topAsteroid.x + Math.cos(self.orbitAngle) * self.orbitRadius;
self.y = topAsteroid.y + Math.sin(self.orbitAngle) * self.orbitRadius;
if (self.orbitTime > self.orbitDuration) {
self.state = 'approaching';
// Saldırıya başlarken hedefi koloniye kilitle
self.attackTargetX = colony.x;
self.attackTargetY = colony.y;
}
} else if (self.state === 'approaching') {
// Koloniye yaklaşana kadar ilerle, ama saldırma
var dx = self.attackTargetX - self.x;
var dy = self.attackTargetY - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
// Koloniye belli bir mesafeye (ör: 350px) kadar yaklaşınca önce kulelere saldır
var engageRadius = 350;
if (dist > engageRadius) {
if (dist > 0) {
self.x += self.speed * dx / dist;
self.y += self.speed * dy / dist;
}
} else {
// Koloniye yaklaştı, önce kulelere saldır
self.state = 'engaging_tower';
}
} else if (self.state === 'engaging_tower') {
// Önce kulelere saldır, kule kalmayınca savaşçılara geç
var nearestTower = null;
var minTowerDist = 999999;
var activeTowerCount = 0;
if (typeof defenseTowers !== "undefined") {
for (var i = 0; i < defenseTowers.length; i++) {
var t = defenseTowers[i];
if (!t.visible || t.hp <= 0) continue;
activeTowerCount++;
var dxT = t.x - self.x;
var dyT = t.y - self.y;
var distT = Math.sqrt(dxT * dxT + dyT * dyT);
if (distT < minTowerDist) {
minTowerDist = distT;
nearestTower = t;
}
}
}
if (nearestTower) {
// Kuleye yaklaş ve saldır
if (minTowerDist > 40) {
self.x += self.speed * (nearestTower.x - self.x) / minTowerDist;
self.y += self.speed * (nearestTower.y - self.y) / minTowerDist;
}
// Her 1 saniyede bir kuleye ateş et
if (typeof self.lastTowerShot === "undefined") self.lastTowerShot = 0;
if (typeof self.towerShootDelay === "undefined") self.towerShootDelay = 60;
if (LK.ticks - self.lastTowerShot > self.towerShootDelay) {
nearestTower.hp -= Math.max(1, Math.round(self.attackPower));
LK.effects.flashObject(nearestTower, 0xff0000, 400);
self.lastTowerShot = LK.ticks;
}
} else {
// Kule kalmadı, savaşçılara saldır
self.state = 'engaging';
}
} else if (self.state === 'engaging') {
// Sadece bizim gemilere saldır, koloniye saldırmaz
// En yakın oyuncu savaşçısını bul
var nearestShip = null;
var minDist = 999999;
var activeShipCount = 0;
if (ship && ship.visible && typeof ship.x === "number" && typeof ship.y === "number" && ship.hp > 0) {
var dxs = ship.x - self.x;
var dys = ship.y - self.y;
var dists = Math.sqrt(dxs * dxs + dys * dys);
if (dists < minDist) {
minDist = dists;
nearestShip = ship;
}
activeShipCount++;
}
// Ekstra savaşçı gemileri de hedef olarak ekle
if (typeof extraShips !== "undefined") {
for (var i = 0; i < extraShips.length; i++) {
var s = extraShips[i];
if (!s.visible || typeof s.x !== "number" || typeof s.y !== "number" || s.hp <= 0) continue;
var dxs = s.x - self.x;
var dys = s.y - self.y;
var dists = Math.sqrt(dxs * dxs + dys * dys);
if (dists < minDist) {
minDist = dists;
nearestShip = s;
}
activeShipCount++;
}
}
// Eğer yakınsa ona yaklaş ve ateş et
if (nearestShip && minDist < 400) {
// Yaklaş
if (minDist > 40) {
self.x += self.speed * (nearestShip.x - self.x) / minDist;
self.y += self.speed * (nearestShip.y - self.y) / minDist;
}
// Ateş etme (her 1 saniyede bir)
if (LK.ticks - self.lastShot > self.shootDelay) {
var b = new Bullet();
b.x = self.x;
b.y = self.y + 40;
b.dirX = nearestShip.x - self.x;
b.dirY = nearestShip.y - self.y;
var bdist = Math.sqrt(b.dirX * b.dirX + b.dirY * b.dirY);
if (bdist > 0) {
b.dirX /= bdist;
b.dirY /= bdist;
} else {
b.dirX = 0;
b.dirY = 1;
}
b.from = 'enemy';
b.attackPower = self.attackPower; // enemyBaseAttackPower ile ölçekli
bullets.push(b);
game.addChild(b);
self.lastShot = LK.ticks;
}
// Eğer oyuncu gemisi yok olduysa, tekrar koloniye saldırmaya başla
if (nearestShip.hp <= 0 || !nearestShip.visible) {
self.state = 'attacking';
}
} else {
// Oyuncu gemisi yoksa veya çok uzaktaysa, tekrar koloniye saldır
// --- DEĞİŞİKLİK: Eğer kule ve savaşçı gemisi yoksa koloniye saldırabilir ---
if (activeTowerCount === 0 && activeShipCount === 0) {
self.state = 'attacking';
}
// Aksi halde, saldıracak hedef yoksa bekle (koloniye saldırma)
}
} else if (self.state === 'attacking') {
// Koloniye doğru düz hareket
var dx = self.attackTargetX - self.x;
var dy = self.attackTargetY - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 0) {
self.x += self.speed * dx / dist;
self.y += self.speed * dy / dist;
}
// Ateş etme (her 1 saniyede bir)
if (LK.ticks - self.lastShot > self.shootDelay) {
var b = new Bullet();
b.x = self.x;
b.y = self.y + 40;
b.dirX = colony.x - self.x;
b.dirY = colony.y - self.y;
var bdist = Math.sqrt(b.dirX * b.dirX + b.dirY * b.dirY);
if (bdist > 0) {
b.dirX /= bdist;
b.dirY /= bdist;
} else {
b.dirX = 0;
b.dirY = 1;
}
b.from = 'enemy';
b.attackPower = self.attackPower; // enemyBaseAttackPower ile ölçekli
bullets.push(b);
game.addChild(b);
self.lastShot = LK.ticks;
}
// Koloniye çok yaklaştıysa yok ol
if (dist < 40) {
self.hp = 0;
}
}
};
// Düşman gemisi can yazısı kaldırıldı
return self;
});
// Koloni can barı ve can göstergesi
// Kaynak Avcısı (ResourceHunter) - sadece haritadaki kaynakları toplar
var ResourceHunter = Container.expand(function () {
var self = Container.call(this);
var hunter = self.attachAsset('resource_hunter', {
// Artık kendine özel görsel
anchorX: 0.5,
anchorY: 0.5
});
self.target = null;
self.speed = 1.1 * (0.002 + 0.001) * 0.1 * 2732; // Kaynaklara uygun hız
self.state = 'idle'; // idle, moving, returning
self.carryType = null;
self.carryAmount = 0;
self.update = function () {
// Eğer kaynak taşıyorsa koloniye dön
if (self.state === 'returning' && self.carryType && self.carryAmount > 0) {
var dx = colony.x - self.x;
var dy = colony.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < 20) {
// Kaynağı koloniye bırak
if (typeof resourceStocks[self.carryType] === "number") {
resourceStocks[self.carryType] += self.carryAmount;
}
self.carryType = null;
self.carryAmount = 0;
self.state = 'idle';
self.target = null;
} else {
self.x += self.speed * dx / dist;
self.y += self.speed * dy / dist;
}
return;
}
// Eğer hedef kaynak varsa ona git
if (self.state === 'moving' && self.target && !self.target.collected && self.target.visible) {
var dx = self.target.x - self.x;
var dy = self.target.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < 20) {
// Kaynağı topla
self.carryType = self.target.resourceType;
self.carryAmount = self.target.amount;
self.target.collected = true;
self.target.visible = false;
self.state = 'returning';
} else {
self.x += self.speed * dx / dist;
self.y += self.speed * dy / dist;
}
return;
}
// Idle ise yeni hedef ara
if (self.state === 'idle') {
// En yakın toplanmamış kaynağı bul
var minDist = 99999;
var targetRes = null;
for (var i = 0; i < resourceNodes.length; i++) {
var r = resourceNodes[i];
if (!r.collected && r.visible) {
var dx = r.x - self.x;
var dy = r.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < minDist) {
minDist = dist;
targetRes = r;
}
}
}
if (targetRes) {
self.target = targetRes;
self.state = 'moving';
}
}
};
return self;
});
// Kaynak noktası (sadece asteroid yok edilince çıkar)
var ResourceNode = Container.expand(function (resourceType, resourceAsset) {
var self = Container.call(this);
// resourceType ve resourceAsset parametre olarak alınır
self.resourceType = resourceType || "Altın";
self.resourceAsset = resourceAsset || "resource_gold";
var res = self.attachAsset(self.resourceAsset, {
anchorX: 0.5,
anchorY: 0.5
});
self.amount = 2 + Math.floor(Math.random() * 9); // 2-10 arası kaynak
self.collected = false;
self.visible = true;
// Sabit durur, hareket etmez
self.update = function () {};
return self;
});
// Oyuncu gemisi
var Ship = Container.expand(function () {
var self = Container.call(this);
// 10 farklı savaşçı gemisi görseli
var shipImages = ['ship1', 'ship2', 'ship3', 'ship4', 'ship5', 'ship6', 'ship7', 'ship8', 'ship9', 'ship10'];
// Rastgele bir savaşçı gemisi görseli seç
var shipImageIndex = Math.floor(Math.random() * shipImages.length);
self.shipImageId = shipImages[shipImageIndex];
var s = self.attachAsset(self.shipImageId, {
anchorX: 0.5,
anchorY: 0.5
});
// Hız %100 yavaşlatıldı
self.speed = 11 * 0.1;
self.targetX = self.x;
self.targetY = self.y;
self.lastShot = 0;
self.shootDelay = 30; // 0.5s
self.update = function () {
// Takip mesafesi ve çakışmayı önleme
var followDistance = 80; // px, minimum mesafe
// Eğer bir düşman varsa ve ona yaklaşıyorsak, mesafeyi koru
if (typeof enemyShips !== "undefined" && enemyShips.length > 0) {
for (var i = 0; i < enemyShips.length; i++) {
var e = enemyShips[i];
if (!e.visible || typeof e.x !== "number" || typeof e.y !== "number") continue;
var dxE = e.x - self.x;
var dyE = e.y - self.y;
var distE = Math.sqrt(dxE * dxE + dyE * dyE);
if (distE < followDistance && distE > 0) {
// Gemi ile düşman arasındaki mesafe çok yakınsa, geri çekil
self.x -= (followDistance - distE) * dxE / distE * 0.5;
self.y -= (followDistance - distE) * dyE / distE * 0.5;
}
}
}
// Hareket
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > self.speed) {
// Hedefe yaklaşırken, diğer gemilerle çakışmayı önle
self.x += self.speed * dx / dist;
self.y += self.speed * dy / dist;
} else {
self.x = self.targetX;
self.y = self.targetY;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x0a0a1a
});
/****
* Game Code
****/
// Yeni panel resmi asset'i (örnek: 350x250 boyutunda, yeni bir id ile)
// Kaynak türleri ve isimleri
var resourceTypeList = [{
name: "Altın",
asset: "resource_gold"
}, {
name: "Kobalt",
asset: "resource_cobalt"
}, {
name: "Nikel",
asset: "resource_nickel"
}, {
name: "Helyum-3",
asset: "resource_helium3"
}, {
name: "Platin",
asset: "resource_platinum"
}, {
name: "Demir",
asset: "resource_iron"
}, {
name: "Manganez",
asset: "resource_manganese"
}];
// --- Şirket Maden İstek Paneli (Seviye yükseltme paneli ile aynı içerik ve konumda, üstte) ---
var companyPanelGroup = new Container();
var companyPanelYOffset = 32;
var companyPanelHeight = 288; // Seviye paneli ile aynı yükseklik
// Panel arka planı (özel şirket paneli arkaplan resmi ile)
var companyPanelBg = LK.getAsset('company_panel_bgimg', {
anchorX: 0,
anchorY: 1
});
companyPanelBg.alpha = 0.92;
companyPanelBg.x = 0;
companyPanelBg.y = 0;
companyPanelGroup.addChild(companyPanelBg);
// Panel başlığı (Seviye paneli ile aynı stil)
var companyPanelTitle = new Text2('Şirket Maden İsteği', {
size: 32,
fill: "#fff",
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 2,
dropShadowAngle: Math.PI / 4,
dropShadowBlur: 4,
dropShadowAlpha: 0.7
});
companyPanelTitle.anchor.set(0, 1);
companyPanelTitle.x = 24;
companyPanelTitle.y = -24;
companyPanelGroup.addChild(companyPanelTitle);
// Açıklama (Seviye paneli ile aynı stil, şirket paneline uygun açıklama)
var companyDescTxt = new Text2('Şirketin istediği madenleri teslim et, ödül kazan!', {
size: 22,
fill: "#fff",
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 2,
dropShadowAngle: Math.PI / 4,
dropShadowBlur: 4,
dropShadowAlpha: 0.7
});
companyDescTxt.anchor.set(0, 1);
companyDescTxt.x = 32;
companyDescTxt.y = -64;
companyPanelGroup.addChild(companyDescTxt);
// İsteği teslim et butonu (Seviye paneli ile aynı stil)
var companyDeliverBtn = new Text2('Teslim Et', {
size: 28,
fill: "#fff",
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 2,
dropShadowAngle: Math.PI / 4,
dropShadowBlur: 4,
dropShadowAlpha: 0.7
});
companyDeliverBtn.anchor.set(0, 1);
companyDeliverBtn.x = 32;
companyDeliverBtn.y = -112;
companyDeliverBtn.interactive = true;
companyDeliverBtn.buttonMode = true;
companyDeliverBtn.hitArea = {
x: -20,
y: -10,
width: companyDeliverBtn.width + 40,
height: companyDeliverBtn.height + 20
};
companyPanelGroup.addChild(companyDeliverBtn);
// Şirket isteği verisi
var companyRequest = null;
var companyRequestTxt = new Text2('', {
size: 28,
fill: "#fff",
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 2,
dropShadowAngle: Math.PI / 4,
dropShadowBlur: 4,
dropShadowAlpha: 0.7
});
companyRequestTxt.anchor.set(0, 1);
companyRequestTxt.x = 32;
companyRequestTxt.y = -160;
companyPanelGroup.addChild(companyRequestTxt);
// Şirket isteği oluşturucu
function generateCompanyRequest() {
// 2-7 farklı maden çeşidi seç
var typeCount = 2 + Math.floor(Math.random() * 6); // 2-7
var shuffled = [];
for (var i = 0; i < resourceTypeList.length; i++) shuffled.push(resourceTypeList[i].name);
// Fisher-Yates shuffle
for (var i = shuffled.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var tmp = shuffled[i];
shuffled[i] = shuffled[j];
shuffled[j] = tmp;
}
var selectedTypes = shuffled.slice(0, typeCount);
// Her biri için 20-200 arası miktar
var reqs = [];
for (var i = 0; i < selectedTypes.length; i++) {
reqs.push({
type: selectedTypes[i],
amount: 20 + Math.floor(Math.random() * 181) // 20-200
});
}
// Ödül: toplam istenen miktarın %2-%10 fazlası aralığında olacak şekilde ayarla
var totalRequested = 0;
for (var i = 0; i < reqs.length; i++) totalRequested += reqs[i].amount;
// %2-%10 fazlalık aralığı
var minReward = Math.ceil(totalRequested * 1.02);
var maxReward = Math.ceil(totalRequested * 1.10);
var rewardAmount = minReward + Math.floor(Math.random() * (maxReward - minReward + 1));
var rewardType = resourceTypeList[Math.floor(Math.random() * resourceTypeList.length)].name;
return {
requests: reqs,
rewardType: rewardType,
rewardAmount: rewardAmount
};
}
// Şirket isteğini güncelle ve göster
function updateCompanyRequestPanel() {
if (!companyRequest) companyRequest = generateCompanyRequest();
// Panel metni
var txt = '';
for (var i = 0; i < companyRequest.requests.length; i++) {
var req = companyRequest.requests[i];
txt += req.type + ': ' + req.amount + '\n';
}
// Yüzde kaç fazla olduğunu hesapla
var totalRequested = 0;
for (var i = 0; i < companyRequest.requests.length; i++) {
totalRequested += companyRequest.requests[i].amount;
}
var rewardPercent = 0;
if (totalRequested > 0) {
rewardPercent = Math.round((companyRequest.rewardAmount / totalRequested - 1) * 100);
}
txt += 'Ödül: ' + companyRequest.rewardAmount + ' ' + companyRequest.rewardType;
if (rewardPercent > 0) {
txt += ' (+' + rewardPercent + '%)';
}
companyRequestTxt.setText(txt);
}
updateCompanyRequestPanel();
// Teslim et butonu fonksiyonu
companyDeliverBtn.down = function (x, y, obj) {
if (!companyRequest) return;
// Yeterli kaynak var mı kontrol et
var canDeliver = true;
for (var i = 0; i < companyRequest.requests.length; i++) {
var req = companyRequest.requests[i];
if (resourceStocks[req.type] < req.amount) {
canDeliver = false;
break;
}
}
if (!canDeliver) {
LK.effects.flashObject(companyPanelBg, 0xff0000, 600);
return;
}
// Kaynakları düş
for (var i = 0; i < companyRequest.requests.length; i++) {
var req = companyRequest.requests[i];
resourceStocks[req.type] -= req.amount;
}
// Ödülü ekle
resourceStocks[companyRequest.rewardType] += companyRequest.rewardAmount;
LK.effects.flashObject(companyPanelBg, 0x4adf4a, 800);
// Yeni istek oluştur
companyRequest = generateCompanyRequest();
updateCompanyRequestPanel();
};
// --- Sol alt: Seviye Yükseltme Paneli ---
// Sağ alt gemi paneli için özel arka plan görseli (daha belirgin, köşeleri yuvarlatılmış, koyu mavi)
// 7 farklı asteroid görseli (her kaynak için bir tane)
// Koloni, kaynak, gemi ve düşman için temel şekiller
// Global değişkenler
// Collector'ın sıktığı mermi için özel asset
// Colony HP bar custom images
// Ship HP bar custom images
function _typeof3(o) {
"@babel/helpers - typeof";
return _typeof3 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
return typeof o;
} : function (o) {
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
}, _typeof3(o);
}
function _typeof2(o) {
"@babel/helpers - typeof";
return _typeof2 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
return typeof o;
} : function (o) {
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
}, _typeof2(o);
}
function _typeof(o) {
"@babel/helpers - typeof";
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
return typeof o;
} : function (o) {
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
}, _typeof(o);
}
var colony;
var ship;
var collectors = [];
var resourceHunters = [];
var autoResourceHunters = 1;
var resourceNodes = [];
var bullets = [];
var resources = 0;
var autoCollectors = 1;
var spawnEnemyTimer = 0;
var dragNode = null;
var lastTouch = {
x: 0,
y: 0
};
// Koloni kur
colony = new Colony();
colony.x = 2048 / 2;
colony.y = 2732 - 400;
// Koloni seviye ve maxHp ayarı
colony.maxHp = 100 + (colonyLevel - 1) * 10; // Maksimum can 100, seviye başı +10
colony.hp = 50; // Başlangıçta 50 can ile başlasın
game.addChild(colony);
// --- Düşman Binası (Base) ---
// Düşman binası için sağlık, seviye ve saldırı butonu ekle
var enemyBaseLevel = 1;
var enemyBaseHp = Math.floor(30 * 0.3);
var enemyBaseMaxHp = Math.floor(30 * 0.3);
var enemyBaseAttackPower = 2 * 0.3;
var enemyBaseGroup = new Container();
// Düşman binası için 10 farklı görsel id'si
var enemyBaseImageIds = ['enemy_base1', 'enemy_base2', 'enemy_base3', 'enemy_base4', 'enemy_base5', 'enemy_base6', 'enemy_base7', 'enemy_base8', 'enemy_base9', 'enemy_base10'];
// İlk başta rastgele bir görsel seç
var currentEnemyBaseImageId = enemyBaseImageIds[Math.floor(Math.random() * enemyBaseImageIds.length)];
var enemyBaseSprite = LK.getAsset(currentEnemyBaseImageId, {
anchorX: 0.5,
anchorY: 0.5
});
enemyBaseSprite.x = 0;
enemyBaseSprite.y = 0;
enemyBaseGroup.addChild(enemyBaseSprite);
// Sağlık barı
var enemyBaseHpBarBg = LK.getAsset('colony_hpbar_bg', {
anchorX: 0.5,
anchorY: 0.5
});
enemyBaseHpBarBg.x = 0;
enemyBaseHpBarBg.y = -120;
enemyBaseGroup.addChild(enemyBaseHpBarBg);
var enemyBaseHpBar = LK.getAsset('colony_hpbar_fg', {
anchorX: 0.5,
anchorY: 0.5
});
enemyBaseHpBar.x = 0;
enemyBaseHpBar.y = -120;
enemyBaseGroup.addChild(enemyBaseHpBar);
// Sağlık yazısı
var enemyBaseHpTxt = new Text2('', {
size: 32,
fill: "#fff",
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 2,
dropShadowAngle: Math.PI / 4,
dropShadowBlur: 4,
dropShadowAlpha: 0.7
});
enemyBaseHpTxt.anchor.set(0.5, 1);
enemyBaseHpTxt.x = 0;
enemyBaseHpTxt.y = -150;
enemyBaseGroup.addChild(enemyBaseHpTxt);
// Seviye yazısı
var enemyBaseLevelTxt = new Text2('Seviye: 1', {
size: 28,
fill: "#fff",
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 2,
dropShadowAngle: Math.PI / 4,
dropShadowBlur: 4,
dropShadowAlpha: 0.7
});
enemyBaseLevelTxt.anchor.set(0.5, 0);
enemyBaseLevelTxt.x = 0;
enemyBaseLevelTxt.y = 100;
enemyBaseGroup.addChild(enemyBaseLevelTxt);
// Saldırı butonu
var enemyBaseAttackBtn = new Text2('SALDIR', {
size: 36,
fill: "#fff",
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 2,
dropShadowAngle: Math.PI / 4,
dropShadowBlur: 4,
dropShadowAlpha: 0.7
});
enemyBaseAttackBtn.anchor.set(0.5, 0);
enemyBaseAttackBtn.x = 0;
enemyBaseAttackBtn.y = 160;
enemyBaseAttackBtn.interactive = true;
enemyBaseAttackBtn.buttonMode = true;
enemyBaseAttackBtn.hitArea = {
x: -enemyBaseAttackBtn.width / 2 - 20,
y: -10,
width: enemyBaseAttackBtn.width + 40,
height: enemyBaseAttackBtn.height + 20
};
enemyBaseGroup.addChild(enemyBaseAttackBtn);
// Düşman binasını üstte ortala
enemyBaseGroup.x = 2048 / 2;
enemyBaseGroup.y = 120;
game.addChild(enemyBaseGroup);
// Düşman binası referansı (eski kod uyumluluğu için)
var topAsteroid = enemyBaseGroup;
// Düşman binasının en son gönderdiği geminin saldırı gücü
var lastEnemyShipAttackPower = 2;
// Saldırı butonu fonksiyonu
enemyBaseAttackBtn.down = function (x, y, obj) {
// Saldırıya katılacak askerler: aktif olan tüm savaşçılar
var attackingShips = [];
if (ship && ship.visible && ship.hp > 0) attackingShips.push(ship);
for (var i = 0; i < extraShips.length; i++) {
var s = extraShips[i];
if (s.visible && s.hp > 0) attackingShips.push(s);
}
if (attackingShips.length === 0) {
LK.effects.flashObject(enemyBaseAttackBtn, 0xff0000, 600);
return;
}
// Düşman binası savunma gücü: en son gönderdiği düşman geminin saldırı gücü (yoksa default)
var defensePower = lastEnemyShipAttackPower || enemyBaseAttackPower;
// --- Animasyonlu saldırı: Gemiler hareket ederek saldıracak ve mermiyle savaşacak ---
// Saldırı sırasında butonu pasifleştir
enemyBaseAttackBtn.alpha = 0.5;
enemyBaseAttackBtn.interactive = false;
// Saldırıya katılan gemilerin orijinal pozisyonlarını kaydet
var originalPositions = [];
for (var i = 0; i < attackingShips.length; i++) {
originalPositions.push({
x: attackingShips[i].x,
y: attackingShips[i].y
});
}
// Saldırı hedef noktası: düşman binasının hemen altı
var targetX = enemyBaseGroup.x;
var targetY = enemyBaseGroup.y + 220;
// Saldırı animasyonu ve savaş simülasyonu
var attackStep = 0;
var baseHp = enemyBaseHp;
var shipIdx = 0;
var shipLost = false;
var battleEnded = false;
// Saldırı sırasında mermiler ve animasyonlar için referanslar
var attackBullets = [];
var attackTweenIds = [];
// Saldırı animasyonunu başlat
function startNextAttack() {
if (battleEnded) return;
if (baseHp <= 0 || shipIdx >= attackingShips.length) {
finishBattle();
return;
}
// --- DEĞİŞİKLİK: Tüm gemiler aynı anda hareket etsin ---
// Sadece ilk çağrıda tüm gemileri başlat
if (attackStep === 0) {
for (var i = 0; i < attackingShips.length; i++) {
var s = attackingShips[i];
if (!s.visible || s.hp <= 0) continue;
var destX = targetX + (i - (attackingShips.length - 1) / 2) * 80;
var destY = targetY + Math.random() * 40 - 20;
s._attackMoveTargetX = destX;
s._attackMoveTargetY = destY;
s._attackMoveInProgress = true;
s._attackMoveStep = 0;
s._attackMoveMaxStep = 180 * 3; // 540 frame = %300 daha yavaş (3 kat daha yavaş)
s._attackMoveStartX = s.x;
s._attackMoveStartY = s.y;
s._attackMoveDeltaX = destX - s.x;
s._attackMoveDeltaY = destY - s.y;
s._attackMoveOrigUpdate = s.update;
(function (shipRef, idx) {
shipRef.update = function () {
if (shipRef._attackMoveInProgress) {
shipRef._attackMoveStep++;
var t = shipRef._attackMoveStep / shipRef._attackMoveMaxStep;
if (t > 1) t = 1;
shipRef.x = shipRef._attackMoveStartX + shipRef._attackMoveDeltaX * t;
shipRef.y = shipRef._attackMoveStartY + shipRef._attackMoveDeltaY * t;
if (shipRef._attackMoveStep >= shipRef._attackMoveMaxStep) {
shipRef._attackMoveInProgress = false;
// Mermi animasyonu: gemiden düşman binasına doğru
var b = new Bullet();
b.x = shipRef.x;
b.y = shipRef.y - 30;
b.dirX = enemyBaseGroup.x - b.x;
b.dirY = enemyBaseGroup.y - 80 - b.y;
var bdist = Math.sqrt(b.dirX * b.dirX + b.dirY * b.dirY);
if (bdist > 0) {
b.dirX /= bdist;
b.dirY /= bdist;
} else {
b.dirX = 0;
b.dirY = -1;
}
b.from = 'player';
b.attackPower = 1;
b.update = function () {
b.x += b.dirX * 32;
b.y += b.dirY * 32;
// Düşman binasına çarptıysa
var bx = b.x - enemyBaseGroup.x;
var by = b.y - (enemyBaseGroup.y - 80);
if (bx * bx + by * by < 60 * 60) {
// Hasar uygula
baseHp -= 1;
LK.effects.flashObject(enemyBaseSprite, 0xffe000, 400);
b.destroy();
var idx2 = attackBullets.indexOf(b);
if (idx2 !== -1) attackBullets.splice(idx2, 1);
// Bina savunur (her savunma defensePower hasar)
shipRef.hp -= defensePower;
if (shipRef.hp <= 0) {
shipRef.hp = 0;
shipRef.visible = false;
shipRef.x = -9999;
shipRef.y = -9999;
shipLost = true;
}
// Her gemi mermisi sonrası battle bitti mi kontrol et
var allDone = true;
for (var si = 0; si < attackingShips.length; si++) {
var ss = attackingShips[si];
if (ss._attackMoveInProgress) {
allDone = false;
break;
}
}
if (allDone) {
// Tüm gemiler bitirdi, battle'ı bitir
LK.setTimeout(finishBattle, 350);
}
}
// Ekran dışıysa yok et
if (b.x < -100 || b.x > 2148 || b.y < -100 || b.y > 2832) {
b.destroy();
var idx2 = attackBullets.indexOf(b);
if (idx2 !== -1) attackBullets.splice(idx2, 1);
}
};
attackBullets.push(b);
game.addChild(b);
// Saldırı hareketi bitti, eski update fonksiyonunu geri yükle
if (typeof shipRef._attackMoveOrigUpdate === "function") {
shipRef.update = shipRef._attackMoveOrigUpdate;
}
}
} else if (typeof shipRef._attackMoveOrigUpdate === "function") {
shipRef._attackMoveOrigUpdate();
}
};
})(s, i);
}
attackStep = 1;
}
// Artık her gemi kendi update fonksiyonunda hareket ediyor, battle'ın bitişi mermi çarpışmalarında kontrol ediliyor
}
// Saldırı bitince gemileri eski pozisyonuna döndür ve sonucu uygula
function finishBattle() {
battleEnded = true;
// Gemileri eski pozisyonuna döndür
for (var i = 0; i < attackingShips.length; i++) {
var s = attackingShips[i];
if (s.visible && originalPositions[i]) {
tween(s, {
x: originalPositions[i].x,
y: originalPositions[i].y
}, {
duration: 400 * 3,
// %300 daha yavaş (3 kat daha yavaş)
easing: tween.quadInOut
});
}
}
// Saldırı mermilerini temizle
for (var i = 0; i < attackBullets.length; i++) {
if (attackBullets[i] && typeof attackBullets[i].destroy === "function") attackBullets[i].destroy();
}
attackBullets = [];
// Saldırı tweenlerini temizle
for (var i = 0; i < attackTweenIds.length; i++) {
tween.cancel(attackTweenIds[i]);
}
attackTweenIds = [];
// Sonuç: Kazanırsak ödül, kaybedersek askerler eski görevine döner
if (baseHp <= 0) {
// Kazandık: ödül ver, bina yok et, yeni bina oluştur
var reward = Math.floor(200 * enemyBaseLevel);
var types = [];
for (var t = 0; t < resourceTypeList.length; t++) types.push(resourceTypeList[t].name);
var remaining = reward;
while (remaining > 0) {
var idx = Math.floor(Math.random() * types.length);
resourceStocks[types[idx]] += 1;
remaining--;
}
LK.effects.flashObject(enemyBaseSprite, 0x4adf4a, 1000);
LK.effects.flashObject(enemyBaseHpBar, 0x4adf4a, 1000);
// Yeni bina oluştur: seviye +1, hp +%20, saldırı gücü +%10, yeni gemiler %10 daha güçlü
enemyBaseMaxHp = Math.floor(enemyBaseMaxHp * 1.2);
enemyBaseHp = enemyBaseMaxHp;
enemyBaseAttackPower = Math.ceil(enemyBaseAttackPower * 1.1);
lastEnemyShipAttackPower = enemyBaseAttackPower;
enemyBaseLevelTxt.setText('Seviye: ' + enemyBaseLevel);
} else {
// Kaybettik: askerler eski görevine döner
LK.effects.flashObject(enemyBaseAttackBtn, 0xff0000, 800);
}
// Bina hp güncelle
enemyBaseHp = Math.max(0, baseHp);
// Saldırı bitince butonu tekrar aktif et
LK.setTimeout(function () {
enemyBaseAttackBtn.alpha = 1;
enemyBaseAttackBtn.interactive = true;
}, 600);
}
// Saldırı döngüsünü başlat
startNextAttack();
// Saldırı sırasında mermileri güncellemek için game.update'e ekle
if (!game._attackBattleUpdate) {
game._attackBattleUpdate = function () {
if (attackBullets && attackBullets.length > 0) {
for (var i = attackBullets.length - 1; i >= 0; i--) {
if (attackBullets[i] && typeof attackBullets[i].update === "function") attackBullets[i].update();
}
}
};
var oldUpdate = game.update;
game.update = function () {
if (typeof oldUpdate === "function") oldUpdate.apply(this, arguments);
if (typeof game._attackBattleUpdate === "function") game._attackBattleUpdate();
};
}
};
// --- Düşman binası GUI güncellemesi game.update'e eklenecek ---
// Düşman gemisi için array ve timer
var enemyShips = [];
var enemySpawnTimer = 0;
var ENEMY_SPAWN_INTERVAL = 60 * 60;
// Düşman dalga sayacı ve gönderilecek gemi sayısı
var enemyWaveCount = 0;
var enemyShipsPerWave = 1;
// Koloni seviye değişkenleri
var colonyLevel = 1;
var colonyLevelBasePrice = 100;
var colonyLevelPrice = colonyLevelBasePrice;
// Koloni sağlık sistemi: Bar, seviye, tamir ve yükseltme tek noktadan yönetimi
var colonyHealthSystem = {
barBg: LK.getAsset('colony_hpbar_bg', {
anchorX: 0.5,
anchorY: 0.5
}),
bar: LK.getAsset('colony_hpbar_fg', {
anchorX: 0.5,
anchorY: 0.5
}),
levelTxt: new Text2('Seviye: ' + colonyLevel, {
size: 28,
fill: "#fff",
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 2,
dropShadowAngle: Math.PI / 4,
dropShadowBlur: 4,
dropShadowAlpha: 0.7
}),
upBtn: new Text2('Koloni Seviye Yükselt (' + colonyLevelPrice + ' Kaynak)', {
size: 28,
fill: "#fff",
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 2,
dropShadowAngle: Math.PI / 4,
dropShadowBlur: 4,
dropShadowAlpha: 0.7
}),
repairBtn: new Text2('Tamir Et', {
size: 28,
fill: "#fff",
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 2,
dropShadowAngle: Math.PI / 4,
dropShadowBlur: 4,
dropShadowAlpha: 0.7
}),
repairCost: 20,
repairCostIncrease: 1.1
};
// Bar ve yazı konumları
colonyHealthSystem.barBg.y = colony.y - 160;
colonyHealthSystem.barBg.x = colony.x;
colonyHealthSystem.bar.y = colony.y - 160;
colonyHealthSystem.bar.x = colony.x;
game.addChild(colonyHealthSystem.barBg);
game.addChild(colonyHealthSystem.bar);
// Seviye yazısı
colonyHealthSystem.levelTxt.anchor.set(0.5, 0);
colonyHealthSystem.levelTxt.x = colony.x;
colonyHealthSystem.levelTxt.y = colony.y - 200 - 40;
game.addChild(colonyHealthSystem.levelTxt);
// Seviye yükseltme butonu
colonyHealthSystem.upBtn.anchor.set(1, 1);
// 2 satır yukarı: her satır yaklaşık 60px (buton yüksekliği + boşluk), toplamda 120px yukarı
colonyHealthSystem.upBtn.x = -32;
colonyHealthSystem.upBtn.y = -140; // shipBuyBtn.y = -80, collectorBuyBtn.y = -140, 2 satır yukarı = -200, ama -140 hizalı (üstten 2. satır)
colonyHealthSystem.upBtn.interactive = true;
colonyHealthSystem.upBtn.buttonMode = true;
colonyHealthSystem.upBtn.hitArea = {
x: -colonyHealthSystem.upBtn.width - 20,
y: -10,
width: colonyHealthSystem.upBtn.width + 40,
height: colonyHealthSystem.upBtn.height + 20
};
// shipBuyPanelGroup'un en üstüne ekle
if (typeof shipBuyPanelGroup !== "undefined" && shipBuyPanelGroup && typeof shipBuyPanelGroup.addChildAt === "function") {
shipBuyPanelGroup.addChildAt(colonyHealthSystem.upBtn, 0);
}
// Tamir butonu
colonyHealthSystem.repairBtn.anchor.set(0.5, 1);
colonyHealthSystem.repairBtn.x = colony.x;
colonyHealthSystem.repairBtn.y = colony.y - 200 - colonyHealthSystem.repairBtn.height - 20 + (colonyHealthSystem.repairBtn.height + 20) * 0.25;
colonyHealthSystem.repairBtn.interactive = true;
colonyHealthSystem.repairBtn.buttonMode = true;
colonyHealthSystem.repairBtn.hitArea = {
x: -colonyHealthSystem.repairBtn.width / 2 - 20,
y: -colonyHealthSystem.repairBtn.height - 10,
width: colonyHealthSystem.repairBtn.width + 40,
height: colonyHealthSystem.repairBtn.height + 20
};
game.addChild(colonyHealthSystem.repairBtn);
// Seviye yükseltme fonksiyonu
colonyHealthSystem.upBtn.down = function (x, y, obj) {
var totalResourceStock = 0;
for (var i = 0; i < resourceTypeList.length; i++) {
totalResourceStock += resourceStocks[resourceTypeList[i].name];
}
if (totalResourceStock < colonyLevelPrice) {
LK.effects.flashObject(colonyHealthSystem.upBtn, 0xff0000, 600);
return;
}
// Kaynakları harca (her kaynaktan orantılı olarak düş)
var remaining = colonyLevelPrice;
for (var i = 0; i < resourceTypeList.length; i++) {
var typeName = resourceTypeList[i].name;
var take = Math.min(resourceStocks[typeName], remaining);
resourceStocks[typeName] -= take;
remaining -= take;
if (remaining <= 0) break;
}
// Seviye artır, maxHp +10, canı yeni maxHp'nin yarısına çek
colonyLevel++;
colony.maxHp = 100 + (colonyLevel - 1) * 10;
colony.hp = Math.floor(colony.maxHp / 2);
colonyHealthSystem.levelTxt.setText('Seviye: ' + colonyLevel);
// Fiyatı 100 ve katları olarak artır
colonyLevelPrice += colonyLevelBasePrice;
colonyHealthSystem.upBtn.setText('Koloni Seviye Yükselt (' + colonyLevelPrice + ' Kaynak)');
LK.effects.flashObject(colony, 0x4adf4a, 600);
};
// Tamir fonksiyonu
colonyHealthSystem.repairBtn.down = function (x, y, obj) {
var totalResourceStock = 0;
for (var i = 0; i < resourceTypeList.length; i++) {
totalResourceStock += resourceStocks[resourceTypeList[i].name];
}
if (colony.hp >= colony.maxHp) {
LK.effects.flashObject(colonyHealthSystem.barBg, 0x4adf4a, 400);
return;
}
if (totalResourceStock < colonyHealthSystem.repairCost) {
LK.effects.flashObject(colonyHealthSystem.barBg, 0xff0000, 600);
return;
}
// Kaynakları harca (her kaynaktan orantılı olarak düş)
var remaining = colonyHealthSystem.repairCost;
for (var i = 0; i < resourceTypeList.length; i++) {
var typeName = resourceTypeList[i].name;
var take = Math.min(resourceStocks[typeName], remaining);
resourceStocks[typeName] -= take;
remaining -= take;
if (remaining <= 0) break;
}
// 3-10 arası rastgele can ekle, maxHp'yi geçemez
var heal = 3 + Math.floor(Math.random() * 8);
colony.hp += heal;
if (colony.hp > colony.maxHp) colony.hp = colony.maxHp;
LK.effects.flashObject(colonyHealthSystem.bar, 0x4adf4a, 600);
// Maliyeti %10 artır
colonyHealthSystem.repairCost = Math.ceil(colonyHealthSystem.repairCost * colonyHealthSystem.repairCostIncrease);
colonyHealthSystem.repairBtn.setText('Tamir Et (' + colonyHealthSystem.repairCost + ' Kaynak)');
};
// Sol alt köşeye hizalı GUI grubu oluştur
var guiLeftBottomGroup = new Container();
LK.gui.bottomLeft.addChild(guiLeftBottomGroup);
// Koloni can yazısı (sol alt)
var colonyHpTxt = new Text2('50 / 50', {
size: 36,
fill: "#fff",
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 2,
dropShadowAngle: Math.PI / 4,
dropShadowBlur: 4,
dropShadowAlpha: 0.7
});
colonyHpTxt.anchor.set(0, 1); // Sol alt köşe
colonyHpTxt.x = 0;
colonyHpTxt.y = 0;
guiLeftBottomGroup.addChild(colonyHpTxt);
// Kaynak göstergesi (sol alt)
var resourceTxt = new Text2('Toplam Kaynak: 0', {
size: 36,
fill: "#fff",
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 2,
dropShadowAngle: Math.PI / 4,
dropShadowBlur: 4,
dropShadowAlpha: 0.7
});
resourceTxt.anchor.set(0, 1);
resourceTxt.x = 0;
resourceTxt.y = colonyHpTxt.y - colonyHpTxt.height - 8;
guiLeftBottomGroup.addChild(resourceTxt);
// collectorTxt: Sadece yükseklik için dummy olarak tanımlanır (sol panelde gösterilmiyor)
var collectorTxt = new Text2('Asteroit Avcısı: 1', {
size: 36,
fill: "#fff",
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 2,
dropShadowAngle: Math.PI / 4,
dropShadowBlur: 4,
dropShadowAlpha: 0.7
});
collectorTxt.anchor.set(0, 1);
collectorTxt.x = 0;
collectorTxt.y = resourceTxt.y - resourceTxt.height - 8;
// Gemi sayısı göstergesi -- KALDIRILDI
var guiRightBottomGroup = new Container();
LK.gui.bottomRight.addChild(guiRightBottomGroup);
// Koloni Sağlığı başlığı (sağ alt)
var colonyHpLabelRight = new Text2('Koloni Sağlığı', {
size: 28,
fill: "#fff",
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 2,
dropShadowAngle: Math.PI / 4,
dropShadowBlur: 4,
dropShadowAlpha: 0.7
});
colonyHpLabelRight.anchor.set(1, 1);
colonyHpLabelRight.x = 0;
colonyHpLabelRight.y = 0;
guiRightBottomGroup.addChild(colonyHpLabelRight);
// Koloni can yazısı (sağ alt)
var colonyHpTxtRight = new Text2('50 / 50', {
size: 36,
fill: "#fff",
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 2,
dropShadowAngle: Math.PI / 4,
dropShadowBlur: 4,
dropShadowAlpha: 0.7
});
colonyHpTxtRight.anchor.set(1, 1); // Sağ alt köşe
colonyHpTxtRight.x = 0;
colonyHpTxtRight.y = -colonyHpLabelRight.height - 8;
guiRightBottomGroup.addChild(colonyHpTxtRight);
// Otomasyon göstergesi (sağ alt)
var collectorTxtRight = new Text2('Asteroit Avcısı: 1', {
size: 36,
fill: "#fff",
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 2,
dropShadowAngle: Math.PI / 4,
dropShadowBlur: 4,
dropShadowAlpha: 0.7
});
collectorTxtRight.anchor.set(1, 1);
collectorTxtRight.x = 0;
collectorTxtRight.y = -colonyHpLabelRight.height - colonyHpTxtRight.height - 16;
guiRightBottomGroup.addChild(collectorTxtRight);
// Gemi sayısı göstergesi (sağ alt)
var shipCountTxtRight = new Text2('Savaşçı: 1', {
size: 36,
fill: "#fff",
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 2,
dropShadowAngle: Math.PI / 4,
dropShadowBlur: 4,
dropShadowAlpha: 0.7
});
shipCountTxtRight.anchor.set(1, 1);
shipCountTxtRight.x = 0;
shipCountTxtRight.y = -colonyHpLabelRight.height - colonyHpTxtRight.height - collectorTxtRight.height - 24;
guiRightBottomGroup.addChild(shipCountTxtRight);
// Gemi canı göstergesi (sağ alt) -- KALDIRILDI
// --- Sağ alt panel: Gemi satın alma paneli (yeni) ---
var shipBuyPanelGroup = new Container();
shipBuyPanelGroup.x = 0;
shipBuyPanelGroup.y = -colonyHpLabelRight.height - colonyHpTxtRight.height - collectorTxtRight.height - shipCountTxtRight.height - 48 - 260; // 260px üstte, panel yüksekliği kadar yukarıda
guiRightBottomGroup.addChild(shipBuyPanelGroup);
// Panel arka planı (özel görsel, hafif şeffaf)
var shipBuyPanelBg = LK.getAsset('ship_buy_panel_bg', {
anchorX: 1,
anchorY: 1
});
shipBuyPanelBg.alpha = 0.92;
shipBuyPanelBg.x = 0;
shipBuyPanelBg.y = 0;
shipBuyPanelGroup.addChild(shipBuyPanelBg);
// Panel başlığı
var shipBuyPanelTitle = new Text2('Savaşçı Satın Al', {
size: 32,
fill: "#fff",
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 2,
dropShadowAngle: Math.PI / 4,
dropShadowBlur: 4,
dropShadowAlpha: 0.7
});
shipBuyPanelTitle.anchor.set(1, 1);
shipBuyPanelTitle.x = -24;
shipBuyPanelTitle.y = -24;
shipBuyPanelGroup.addChild(shipBuyPanelTitle);
// Satın alma butonu
var shipBuyBtn = new Text2('Yeni Savaşçı (200 Kaynak)', {
size: 28,
fill: "#fff",
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 2,
dropShadowAngle: Math.PI / 4,
dropShadowBlur: 4,
dropShadowAlpha: 0.7
});
shipBuyBtn.anchor.set(1, 1);
shipBuyBtn.x = -32;
shipBuyBtn.y = -80;
shipBuyBtn.interactive = true;
shipBuyBtn.buttonMode = true;
shipBuyBtn.hitArea = {
x: -shipBuyBtn.width - 20,
y: -10,
width: shipBuyBtn.width + 40,
height: shipBuyBtn.height + 20
};
shipBuyPanelGroup.addChild(shipBuyBtn);
// Asteroit Avcısı satın alma butonu
var collectorBuyBtn = new Text2('Asteroit Avcısı (100 Kaynak)', {
size: 28,
fill: "#fff",
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 2,
dropShadowAngle: Math.PI / 4,
dropShadowBlur: 4,
dropShadowAlpha: 0.7
});
collectorBuyBtn.anchor.set(1, 1);
collectorBuyBtn.x = -32;
collectorBuyBtn.y = -140;
collectorBuyBtn.interactive = true;
collectorBuyBtn.buttonMode = true;
collectorBuyBtn.hitArea = {
x: -collectorBuyBtn.width - 20,
y: -10,
width: collectorBuyBtn.width + 40,
height: collectorBuyBtn.height + 20
};
shipBuyPanelGroup.addChild(collectorBuyBtn);
// --- Satın alma fiyatları ve artış oranı ---
// Kaynak Avcısı ve Asteroid Avcısı: 100 kaynak, Savaşçı: 200 kaynak, her satın alımda %50 artış
var shipBuyPrice = 200;
var collectorBuyPrice = 100;
var resourceHunterBuyPrice = 100;
var shipBuyPriceIncrease = 1.5;
var collectorBuyPriceIncrease = 1.5;
var resourceHunterBuyPriceIncrease = 1.5;
// Savunma Kulesi için değişkenler
var defenseTowers = [];
var defenseTowerBuyPrice = 100;
var defenseTowerBuyPriceIncrease = 1.5;
var defenseTowerMaxCount = 4; // En fazla 4 kule alınabilir
// Savunma Kulesi Seviye Yükselt butonu (yeni) -- Savunma Kulesi satın alma butonunun üst satırında
// Savunma Kulesi Seviye Yükseltme maliyeti ve artış oranı
var defenseTowerLevelUpBasePrice = 100;
var defenseTowerLevelUpPrice = defenseTowerLevelUpBasePrice;
// --- Savunma Kulesi Tamir Et Butonu ve Fonksiyonu ---
function createDefenseTowerRepairBtn(targetTower, yOffset) {
var btn = new Text2('Tamir Et (' + targetTower.repairCost + ' Kaynak)', {
size: 24,
fill: "#fff",
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 2,
dropShadowAngle: Math.PI / 4,
dropShadowBlur: 4,
dropShadowAlpha: 0.7
});
btn.anchor.set(0.5, 1);
btn.x = targetTower.x;
btn.y = targetTower.y - yOffset;
btn.interactive = true;
btn.buttonMode = true;
btn.hitArea = {
x: -btn.width / 2 - 20,
y: -btn.height - 10,
width: btn.width + 40,
height: btn.height + 20
};
btn.visible = targetTower.visible;
btn.down = function (x, y, obj) {
// Toplam kaynak stoğu ile kontrol
var totalResourceStock = 0;
for (var i = 0; i < resourceTypeList.length; i++) {
totalResourceStock += resourceStocks[resourceTypeList[i].name];
}
if (targetTower.hp >= targetTower.maxHp) {
LK.effects.flashObject(btn, 0x4adf4a, 400);
return;
}
if (totalResourceStock < targetTower.repairCost) {
LK.effects.flashObject(btn, 0xff0000, 600);
return;
}
// Kaynakları harca (her kaynaktan orantılı olarak düş)
var remaining = targetTower.repairCost;
for (var i = 0; i < resourceTypeList.length; i++) {
var typeName = resourceTypeList[i].name;
var take = Math.min(resourceStocks[typeName], remaining);
resourceStocks[typeName] -= take;
remaining -= take;
if (remaining <= 0) break;
}
// HP'yi 3 artır, maxHp'yi geçemez
targetTower.hp += 3;
if (targetTower.hp > targetTower.maxHp) targetTower.hp = targetTower.maxHp;
LK.effects.flashObject(targetTower, 0x4adf4a, 600);
// Maliyeti %10 artır
targetTower.repairCost = Math.ceil(targetTower.repairCost * targetTower.repairCostIncrease);
btn.setText('Tamir Et (' + targetTower.repairCost + ' Kaynak)');
};
game.addChild(btn);
// Butonun pozisyonunu ve görünürlüğünü update fonksiyonunda güncellemek için tower objesine referans ekle
targetTower.repairBtn = btn;
}
// Savunma Kulesi Seviye Yükselt butonu (Savunma Kulesi satın alma butonunun üstünde)
var defenseTowerLevelUpBtn = new Text2('Savunma Kulesi Seviye Yükselt (' + defenseTowerLevelUpPrice + ' Kaynak)', {
size: 28,
fill: "#fff",
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 2,
dropShadowAngle: Math.PI / 4,
dropShadowBlur: 4,
dropShadowAlpha: 0.7
});
defenseTowerLevelUpBtn.anchor.set(1, 1);
defenseTowerLevelUpBtn.x = -32;
// 3 satır yukarı taşı: her satır yaklaşık 60px (buton yüksekliği + boşluk), toplamda 180px yukarı
// 2 satır yukarı taşı: her satır yaklaşık 60px (buton yüksekliği + boşluk), toplamda 120px yukarı
defenseTowerLevelUpBtn.y = -260 - (defenseTowerLevelUpBtn.height + 20) * 1;
// hizalamayı Savunma Kulesi satın alma butonunun üstüne ve sağa göre yap
defenseTowerLevelUpBtn.interactive = true;
defenseTowerLevelUpBtn.buttonMode = true;
defenseTowerLevelUpBtn.hitArea = {
x: -defenseTowerLevelUpBtn.width - 20,
y: -10,
width: defenseTowerLevelUpBtn.width + 40,
height: defenseTowerLevelUpBtn.height + 20
};
shipBuyPanelGroup.addChild(defenseTowerLevelUpBtn);
// Savunma Kulesi satın alma butonu (sağ alt panelde, gemi satın alma panelinin altına)
var defenseTowerBuyBtn = new Text2('Savunma Kulesi (100 Kaynak)', {
size: 28,
fill: "#fff",
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 2,
dropShadowAngle: Math.PI / 4,
dropShadowBlur: 4,
dropShadowAlpha: 0.7
});
defenseTowerBuyBtn.anchor.set(1, 1);
defenseTowerBuyBtn.x = -32;
defenseTowerBuyBtn.y = -260;
defenseTowerBuyBtn.interactive = true;
defenseTowerBuyBtn.buttonMode = true;
defenseTowerBuyBtn.hitArea = {
x: -defenseTowerBuyBtn.width - 20,
y: -10,
width: defenseTowerBuyBtn.width + 40,
height: defenseTowerBuyBtn.height + 20
};
shipBuyPanelGroup.addChild(defenseTowerBuyBtn);
// Savunma Kulesi satın alma işlemi
defenseTowerBuyBtn.down = function (x, y, obj) {
// Sadece 1 kule varsa tekrar alınamaz, kule yok olunca tekrar alınabilir
var activeTowers = 0;
for (var i = 0; i < defenseTowers.length; i++) {
if (defenseTowers[i].visible && defenseTowers[i].hp > 0) activeTowers++;
}
if (activeTowers >= defenseTowerMaxCount) {
LK.effects.flashObject(defenseTowerBuyBtn, 0xff0000, 600);
return;
}
// Toplam kaynak stoğu ile kontrol
var totalResourceStock = 0;
for (var i = 0; i < resourceTypeList.length; i++) {
totalResourceStock += resourceStocks[resourceTypeList[i].name];
}
if (totalResourceStock < defenseTowerBuyPrice) {
LK.effects.flashObject(defenseTowerBuyBtn, 0xff0000, 600);
return;
}
// Kaynakları harca (her kaynaktan orantılı olarak düş)
var remaining = defenseTowerBuyPrice;
for (var i = 0; i < resourceTypeList.length; i++) {
var typeName = resourceTypeList[i].name;
var take = Math.min(resourceStocks[typeName], remaining);
resourceStocks[typeName] -= take;
remaining -= take;
if (remaining <= 0) break;
}
// Kuleyi oluştur ve ekle
var tower = new DefenseTower();
// Savunma kulesi tamir maliyeti ve artış oranı
tower.repairCost = 20;
tower.repairCostIncrease = 1.1;
// Kuleleri yan yana ve 1'er satır boşlukla sıralayalım
// Her kule için x: colony.x + (i - (defenseTowerMaxCount-1)/2) * kuleArasıMesafe
// y: colony.y - 320 - 88 (sabit)
var towerIndex = 0;
for (var i = 0; i < defenseTowerMaxCount; i++) {
if (defenseTowers[i] && defenseTowers[i].visible && defenseTowers[i].hp > 0) {
towerIndex++;
}
}
towerIndex = defenseTowers.length;
var towerSpacingX = 220; // Yan yana aralık (1 satır daha büyük)
tower.x = colony.x + (towerIndex - (defenseTowerMaxCount - 1) / 2) * towerSpacingX;
tower.y = colony.y - 320 - 88;
defenseTowers.push(tower);
game.addChild(tower);
// Savunma kulesi için tamir et butonu ekle (yOffset: 170) -- 1 satır yukarı taşındı
createDefenseTowerRepairBtn(tower, 170);
LK.effects.flashObject(tower, 0x4adf4a, 800);
// Fiyatı %50 artır
defenseTowerBuyPrice = Math.ceil(defenseTowerBuyPrice * defenseTowerBuyPriceIncrease);
defenseTowerBuyBtn.setText('Savunma Kulesi (' + defenseTowerBuyPrice + ' Kaynak)');
// Kulelerin pozisyonunu güncelle (her zaman yan yana ve boşluklu)
for (var i = 0; i < defenseTowers.length; i++) {
defenseTowers[i].x = colony.x + (i - (defenseTowerMaxCount - 1) / 2) * towerSpacingX;
defenseTowers[i].y = colony.y - 320 - 88;
// Seviye atlatma butonu varsa onun da pozisyonunu güncelle
if (defenseTowers[i].levelUpBtn) {
defenseTowers[i].levelUpBtn.x = defenseTowers[i].x;
defenseTowers[i].levelUpBtn.y = defenseTowers[i].y + 80;
}
}
};
// Savunma Kulesi seviye atlatma fonksiyonu (örnek: kuleye tıklayınca seviye atlat)
// (İsteğe bağlı: Kuleye tıklayınca seviye atlatmak için)
for (var i = 0; i < defenseTowers.length; i++) {
var tower = defenseTowers[i];
if (!tower.levelUpBtn) {
var btn = new Text2('Seviye Atla', {
size: 20,
fill: "#fff",
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 2,
dropShadowAngle: Math.PI / 4,
dropShadowBlur: 4,
dropShadowAlpha: 0.7
});
btn.anchor.set(0.5, 0);
btn.x = tower.x;
btn.y = tower.y + 80;
btn.interactive = true;
btn.buttonMode = true;
btn.hitArea = {
x: -btn.width / 2 - 10,
y: -10,
width: btn.width + 20,
height: btn.height + 20
};
btn.down = function (tw) {
return function () {
// Seviye atlatmak için 100 kaynak harca
var totalResourceStock = 0;
for (var i = 0; i < resourceTypeList.length; i++) {
totalResourceStock += resourceStocks[resourceTypeList[i].name];
}
if (totalResourceStock < 100) {
LK.effects.flashObject(btn, 0xff0000, 600);
return;
}
// Kaynakları harca
var remaining = 100;
for (var i = 0; i < resourceTypeList.length; i++) {
var typeName = resourceTypeList[i].name;
var take = Math.min(resourceStocks[typeName], remaining);
resourceStocks[typeName] -= take;
remaining -= take;
if (remaining <= 0) break;
}
tw.levelUp();
LK.effects.flashObject(tw, 0x4adf4a, 600);
};
}(tower);
game.addChild(btn);
tower.levelUpBtn = btn;
}
// Butonun pozisyonunu güncelle
if (tower.levelUpBtn) {
tower.levelUpBtn.x = tower.x;
tower.levelUpBtn.y = tower.y + 80;
tower.levelUpBtn.visible = tower.visible && tower.hp > 0;
}
}
// Savunma Kulesi Seviye Yükselt butonu işlevi
defenseTowerLevelUpBtn.down = function (x, y, obj) {
// Sadece aktif bir kule varsa seviye atlat
var activeTowers = [];
for (var i = 0; i < defenseTowers.length; i++) {
if (defenseTowers[i].visible && defenseTowers[i].hp > 0) activeTowers.push(defenseTowers[i]);
}
if (activeTowers.length === 0) {
LK.effects.flashObject(defenseTowerLevelUpBtn, 0xff0000, 600);
return;
}
// Toplam kaynak stoğu ile kontrol
var totalResourceStock = 0;
for (var i = 0; i < resourceTypeList.length; i++) {
totalResourceStock += resourceStocks[resourceTypeList[i].name];
}
if (totalResourceStock < defenseTowerLevelUpPrice) {
LK.effects.flashObject(defenseTowerLevelUpBtn, 0xff0000, 600);
return;
}
// Kaynakları harca (her kaynaktan orantılı olarak düş)
var remaining = defenseTowerLevelUpPrice;
for (var i = 0; i < resourceTypeList.length; i++) {
var typeName = resourceTypeList[i].name;
var take = Math.min(resourceStocks[typeName], remaining);
resourceStocks[typeName] -= take;
remaining -= take;
if (remaining <= 0) break;
}
// En düşük seviye olan kuleyi bul ve sadece onu seviye atlat
var minLevel = 9999;
var minLevelTowers = [];
for (var i = 0; i < activeTowers.length; i++) {
if (activeTowers[i].level < minLevel) {
minLevel = activeTowers[i].level;
minLevelTowers = [activeTowers[i]];
} else if (activeTowers[i].level === minLevel) {
minLevelTowers.push(activeTowers[i]);
}
}
if (minLevelTowers.length > 0) {
// Birden fazla aynı seviyede kule varsa, ilkini yükselt
minLevelTowers[0].levelUp();
LK.effects.flashObject(minLevelTowers[0], 0x4adf4a, 600);
}
// Fiyatı 100 ve katları olarak artır
defenseTowerLevelUpPrice += defenseTowerLevelUpBasePrice;
defenseTowerLevelUpBtn.setText('Savunma Kulesi Seviye Yükselt (' + defenseTowerLevelUpPrice + ' Kaynak)');
};
// Gemi satın alma işlemi
shipBuyBtn.down = function (x, y, obj) {
// Toplam kaynak stoğu ile kontrol (artık resourceStocks kullanılacak)
var totalResourceStock = 0;
for (var i = 0; i < resourceTypeList.length; i++) {
totalResourceStock += resourceStocks[resourceTypeList[i].name];
}
if (totalResourceStock >= shipBuyPrice) {
// Kaynakları harca (her kaynaktan orantılı olarak düş)
var remaining = shipBuyPrice;
for (var i = 0; i < resourceTypeList.length; i++) {
var typeName = resourceTypeList[i].name;
var take = Math.min(resourceStocks[typeName], remaining);
resourceStocks[typeName] -= take;
remaining -= take;
if (remaining <= 0) break;
}
// Ana geminin canı ve maxHp'si değişmesin, sadece yeni savaşçı ekle
ship.visible = true;
ship.x = 2048 / 2;
ship.y = 2732 - 700;
LK.effects.flashObject(ship, 0x4adf4a, 800);
shipBuyPrice = Math.ceil(shipBuyPrice * shipBuyPriceIncrease);
shipBuyBtn.setText('Yeni Savaşçı (' + shipBuyPrice + ' Kaynak)');
// Yeni savaşçı gemisi oluştur ve diziye ekle
var newShip = new Ship();
// Her spawn'da farklı bir savaşçı gemisi görseli kullan
var shipImages = ['ship1', 'ship2', 'ship3', 'ship4', 'ship5', 'ship6', 'ship7', 'ship8', 'ship9', 'ship10'];
var shipImageIndex = Math.floor(Math.random() * shipImages.length);
newShip.shipImageId = shipImages[shipImageIndex];
// Eski asset'i kaldırıp yeni asset'i ekle
if (newShip.children && newShip.children.length > 0) {
var oldAsset = newShip.children[0];
if (typeof oldAsset.destroy === "function") oldAsset.destroy();
newShip.removeChild(oldAsset);
}
var s = newShip.attachAsset(newShip.shipImageId, {
anchorX: 0.5,
anchorY: 0.5
});
newShip.x = 2048 / 2 + (Math.random() * 200 - 100);
newShip.y = 2732 - 700 + (Math.random() * 100 - 50);
// Yeni alınan savaşçı 5/5 can ile başlasın
newShip.maxHp = 5;
newShip.hp = 5;
// Diğer ayarlar da aynı şekilde uygulansın
newShip.repairCost = 20;
newShip.repairCostIncrease = 1.1;
newShip.visible = true;
newShip.isExtra = true; // AI kontrollü olduğunu belirtmek için
game.addChild(newShip);
extraShips.push(newShip);
// Her yeni gemi için can yazısı ekle
var hpTxt = new Text2('', {
size: 32,
fill: "#fff",
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 2,
dropShadowAngle: Math.PI / 4,
dropShadowBlur: 4,
dropShadowAlpha: 0.7
});
hpTxt.anchor.set(0.5, 1);
hpTxt.x = newShip.x;
hpTxt.y = newShip.y - 70;
game.addChild(hpTxt);
extraShipHpTxts.push({
ship: newShip,
txt: hpTxt
});
// Her yeni gemi için Tamir Et butonu ekle (yOffset: 110)
createShipRepairBtn(newShip, 110);
}
};
// Asteroit Avcısı satın alma işlemi
collectorBuyBtn.down = function (x, y, obj) {
// Toplam kaynak stoğu ile kontrol
var totalResourceStock = 0;
for (var i = 0; i < resourceTypeList.length; i++) {
totalResourceStock += resourceStocks[resourceTypeList[i].name];
}
if (totalResourceStock >= collectorBuyPrice) {
// Kaynakları harca (her kaynaktan orantılı olarak düş)
var remaining = collectorBuyPrice;
for (var i = 0; i < resourceTypeList.length; i++) {
var typeName = resourceTypeList[i].name;
var take = Math.min(resourceStocks[typeName], remaining);
resourceStocks[typeName] -= take;
remaining -= take;
if (remaining <= 0) break;
}
autoCollectors++;
createCollectors(autoCollectors);
LK.effects.flashObject(collectors[collectors.length - 1], 0x4adf4a, 800);
collectorBuyPrice = Math.ceil(collectorBuyPrice * collectorBuyPriceIncrease);
collectorBuyBtn.setText('Asteroit Avcısı (' + collectorBuyPrice + ' Kaynak)');
}
};
// Kaynak Avcısı satın alma butonu
var resourceHunterBuyBtn = new Text2('Kaynak Avcısı (100 Kaynak)', {
size: 28,
fill: "#fff",
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 2,
dropShadowAngle: Math.PI / 4,
dropShadowBlur: 4,
dropShadowAlpha: 0.7
});
resourceHunterBuyBtn.anchor.set(1, 1);
resourceHunterBuyBtn.x = -32;
resourceHunterBuyBtn.y = -200;
resourceHunterBuyBtn.interactive = true;
resourceHunterBuyBtn.buttonMode = true;
resourceHunterBuyBtn.hitArea = {
x: -resourceHunterBuyBtn.width - 20,
y: -10,
width: resourceHunterBuyBtn.width + 40,
height: resourceHunterBuyBtn.height + 20
};
shipBuyPanelGroup.addChild(resourceHunterBuyBtn);
// Kaynak Avcısı satın alma işlemi
resourceHunterBuyBtn.down = function (x, y, obj) {
// Toplam kaynak stoğu ile kontrol
var totalResourceStock = 0;
for (var i = 0; i < resourceTypeList.length; i++) {
totalResourceStock += resourceStocks[resourceTypeList[i].name];
}
if (totalResourceStock >= resourceHunterBuyPrice) {
// Kaynakları harca (her kaynaktan orantılı olarak düş)
var remaining = resourceHunterBuyPrice;
for (var i = 0; i < resourceTypeList.length; i++) {
var typeName = resourceTypeList[i].name;
var take = Math.min(resourceStocks[typeName], remaining);
resourceStocks[typeName] -= take;
remaining -= take;
if (remaining <= 0) break;
}
autoResourceHunters++;
createResourceHunters(autoResourceHunters);
LK.effects.flashObject(resourceHunters[resourceHunters.length - 1], 0x4adf4a, 800);
resourceHunterBuyPrice = Math.ceil(resourceHunterBuyPrice * resourceHunterBuyPriceIncrease);
resourceHunterBuyBtn.setText('Kaynak Avcısı (' + resourceHunterBuyPrice + ' Kaynak)');
}
};
// --- Sağ alt panel: Gemi öğeleri satın alma paneli ---
var shipPanelGroup = new Container();
shipPanelGroup.x = 0;
shipPanelGroup.y = -colonyHpLabelRight.height - colonyHpTxtRight.height - collectorTxtRight.height - shipCountTxtRight.height - 48;
guiRightBottomGroup.addChild(shipPanelGroup);
// Panel arka planı (özel görsel, hafif şeffaf)
var shipPanelBg = LK.getAsset('ship_panel_bg', {
anchorX: 1,
anchorY: 1
});
shipPanelBg.alpha = 0.92;
shipPanelBg.x = 0;
shipPanelBg.y = 0;
shipPanelGroup.addChild(shipPanelBg);
// Panel başlığı
var shipPanelTitle = new Text2('Savaşçı Yükseltmeleri', {
size: 32,
fill: "#fff",
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 2,
dropShadowAngle: Math.PI / 4,
dropShadowBlur: 4,
dropShadowAlpha: 0.7
});
shipPanelTitle.anchor.set(1, 1);
shipPanelTitle.x = -24;
shipPanelTitle.y = -24;
shipPanelGroup.addChild(shipPanelTitle);
// --- Sol alt: Seviye Yükseltme Paneli ---
// Paneli sol alt kaynak panelinin üstünden iki satır daha yukarı taşı
var upgradePanelGroup = new Container();
// Sol alt panelin yüksekliğini hesapla (kaynak yazılarının en üstünden iki satır daha yukarı hizalanacak)
var upgradePanelYOffset = 32; // Kaynak paneli ile aradaki boşluk
var upgradePanelRowHeight = 0;
if (typeof resourceStockTxts !== "undefined" && resourceStockTxts.length > 0) {
// resourceStockTxts[resourceStockTxts.length-1] en üstteki (yukarıdan aşağıya ekleniyor)
var topResourceTxt = resourceStockTxts[resourceStockTxts.length - 1];
upgradePanelRowHeight = topResourceTxt.height;
}
var upgradePanelTopY = 0;
if (typeof resourceStockTxts !== "undefined" && resourceStockTxts.length > 0) {
// İki satır daha yukarı taşı: iki kaynak satırı yüksekliği kadar yukarı
var topResourceTxt = resourceStockTxts[resourceStockTxts.length - 1];
upgradePanelTopY = topResourceTxt.y - 2 * topResourceTxt.height - upgradePanelYOffset - upgradePanelRowHeight;
} else {
upgradePanelTopY = -400 - 36 - 36; // fallback, iki satır daha yukarı
}
upgradePanelGroup.x = 0;
upgradePanelGroup.y = upgradePanelTopY;
guiLeftBottomGroup.addChild(upgradePanelGroup);
// Şirket panelini upgradePanelGroup'un hemen üstüne ve aynı konumda hizala (seviye paneli ile aynı genişlik ve hizalama)
companyPanelGroup.x = upgradePanelGroup.x;
companyPanelGroup.y = upgradePanelGroup.y - companyPanelHeight - companyPanelYOffset;
guiLeftBottomGroup.addChild(companyPanelGroup);
// Panelin yeni görünümünün özel resim dosyasını oluştur (örnek: panelin ekran görüntüsünü kaydet)
if (typeof LK.screenshot === "function") {
LK.screenshot(companyPanelGroup, "sirket.png", {
replace: true
});
}
// Panel arka planı
var upgradePanelBg = LK.getAsset('upgrade_panel_bg', {
anchorX: 0,
// sol hizalı
anchorY: 1 // üst hizalı
});
upgradePanelBg.alpha = 0.92;
upgradePanelBg.x = 0;
upgradePanelBg.y = 0;
upgradePanelGroup.addChild(upgradePanelBg);
// Panel başlığı
var upgradePanelTitle = new Text2('Seviye Yükseltme', {
size: 32,
fill: "#fff",
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 2,
dropShadowAngle: Math.PI / 4,
dropShadowBlur: 4,
dropShadowAlpha: 0.7
});
upgradePanelTitle.anchor.set(0, 1);
upgradePanelTitle.x = 24;
upgradePanelTitle.y = -24;
upgradePanelGroup.addChild(upgradePanelTitle);
// Seviye göstergesi
var upgradeLevel = 0;
var upgradeLevelTxt = new Text2('Seviye: 0', {
size: 28,
fill: "#fff",
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 2,
dropShadowAngle: Math.PI / 4,
dropShadowBlur: 4,
dropShadowAlpha: 0.7
});
upgradeLevelTxt.anchor.set(0, 1);
upgradeLevelTxt.x = 32;
upgradeLevelTxt.y = -80;
upgradePanelGroup.addChild(upgradeLevelTxt);
// Yükseltme butonu
var upgradeBasePrice = 100;
var upgradePrice = upgradeBasePrice;
var upgradeBtn = new Text2('Yükselt (' + upgradePrice + ' Kaynak)', {
size: 28,
fill: "#fff",
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 2,
dropShadowAngle: Math.PI / 4,
dropShadowBlur: 4,
dropShadowAlpha: 0.7
});
upgradeBtn.anchor.set(0, 1);
upgradeBtn.x = 32;
upgradeBtn.y = -140;
upgradeBtn.interactive = true;
upgradeBtn.buttonMode = true;
upgradeBtn.hitArea = {
x: -20,
y: -10,
width: upgradeBtn.width + 40,
height: upgradeBtn.height + 20
};
upgradePanelGroup.addChild(upgradeBtn);
// Açıklama
var upgradeDescTxt = new Text2('Her seviye:\n- Mermi hızı %20 artar\n- Gemi hızı %10 artar\n- Maden kaynağı %10 artar', {
size: 22,
fill: "#fff",
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 2,
dropShadowAngle: Math.PI / 4,
dropShadowBlur: 4,
dropShadowAlpha: 0.7
});
upgradeDescTxt.anchor.set(0, 1);
upgradeDescTxt.x = 32;
upgradeDescTxt.y = -200;
upgradePanelGroup.addChild(upgradeDescTxt);
// Yükseltme butonu fonksiyonu
upgradeBtn.down = function (x, y, obj) {
// Toplam kaynak ile kontrol
var totalResourceStock = 0;
for (var i = 0; i < resourceTypeList.length; i++) {
totalResourceStock += resourceStocks[resourceTypeList[i].name];
}
if (totalResourceStock >= upgradePrice) {
// Kaynakları harca (her kaynaktan orantılı olarak düş)
var remaining = upgradePrice;
for (var i = 0; i < resourceTypeList.length; i++) {
var typeName = resourceTypeList[i].name;
var take = Math.min(resourceStocks[typeName], remaining);
resourceStocks[typeName] -= take;
remaining -= take;
if (remaining <= 0) break;
}
upgradeLevel++;
upgradeLevelTxt.setText('Seviye: ' + upgradeLevel);
// Fiyatı %25 artır
upgradePrice = Math.ceil(upgradeBasePrice * Math.pow(1.25, upgradeLevel));
upgradeBtn.setText('Yükselt (' + upgradePrice + ' Kaynak)');
LK.effects.flashObject(upgradePanelBg, 0x4adf4a, 600);
}
};
// Satın alınabilir öğeler: örnek olarak "Savaşçı Canı +1" ve "Savaşçı Yenile"
var shipUpgradeBtn = new Text2('Can +1 (30 Kaynak)', {
size: 28,
fill: "#fff",
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 2,
dropShadowAngle: Math.PI / 4,
dropShadowBlur: 4,
dropShadowAlpha: 0.7
});
shipUpgradeBtn.anchor.set(1, 1);
shipUpgradeBtn.x = -32;
shipUpgradeBtn.y = -80;
shipUpgradeBtn.interactive = true;
shipUpgradeBtn.buttonMode = true;
shipUpgradeBtn.hitArea = {
x: -shipUpgradeBtn.width - 20,
y: -10,
width: shipUpgradeBtn.width + 40,
height: shipUpgradeBtn.height + 20
};
shipPanelGroup.addChild(shipUpgradeBtn);
shipUpgradeBtn.down = function (x, y, obj) {
// 30 toplam kaynak ile savaşçı canı artır
var totalResourceStock = 0;
for (var i = 0; i < resourceTypeList.length; i++) {
totalResourceStock += resourceStocks[resourceTypeList[i].name];
}
// Aktif savaşçı gemilerinin listesini oluştur
var shipsToUpgrade = [];
if (typeof ship.maxHp === "number" && ship.visible && ship.maxHp < 10) {
shipsToUpgrade.push(ship);
}
for (var i = 0; i < extraShips.length; i++) {
var s = extraShips[i];
if (typeof s.maxHp === "number" && s.visible && s.maxHp < 10) {
shipsToUpgrade.push(s);
}
}
if (totalResourceStock >= 30 && shipsToUpgrade.length > 0) {
// Kaynakları harca (her kaynaktan orantılı olarak düş)
var remaining = 30;
for (var i = 0; i < resourceTypeList.length; i++) {
var typeName = resourceTypeList[i].name;
var take = Math.min(resourceStocks[typeName], remaining);
resourceStocks[typeName] -= take;
remaining -= take;
if (remaining <= 0) break;
}
// Her aktif savaşçı gemisinin maxHp'sini 1 artır (10'a kadar), hp aynı kalsın
for (var i = 0; i < shipsToUpgrade.length; i++) {
if (shipsToUpgrade[i].maxHp < 10) {
shipsToUpgrade[i].maxHp += 1;
if (shipsToUpgrade[i].maxHp > 10) shipsToUpgrade[i].maxHp = 10;
// shipsToUpgrade[i].hp = shipsToUpgrade[i].maxHp; // hp artık değişmiyor
LK.effects.flashObject(shipsToUpgrade[i], 0x4adf4a, 600);
}
}
}
};
var shipRespawnBtn = new Text2('Savaşçı Yenile (100 Kaynak)', {
size: 28,
fill: "#fff",
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 2,
dropShadowAngle: Math.PI / 4,
dropShadowBlur: 4,
dropShadowAlpha: 0.7
});
shipRespawnBtn.anchor.set(1, 1);
shipRespawnBtn.x = -32;
shipRespawnBtn.y = -140;
shipRespawnBtn.interactive = true;
shipRespawnBtn.buttonMode = true;
shipRespawnBtn.hitArea = {
x: -shipRespawnBtn.width - 20,
y: -10,
width: shipRespawnBtn.width + 40,
height: shipRespawnBtn.height + 20
};
shipPanelGroup.addChild(shipRespawnBtn);
shipRespawnBtn.down = function (x, y, obj) {
// Savaşçı Yenile: Her yenilenecek savaşçı için 100 Toplam Kaynak maliyeti
// Yenilenecek savaşçıları bul
var shipsToRespawn = [];
if (!ship.visible || ship.hp <= 0) {
shipsToRespawn.push(ship);
}
for (var i = 0; i < extraShips.length; i++) {
var s = extraShips[i];
if (!s.visible || s.hp <= 0) {
shipsToRespawn.push(s);
}
}
var respawnCost = shipsToRespawn.length * 100;
// Toplam kaynak stoğu ile kontrol
var totalResourceStock = 0;
for (var i = 0; i < resourceTypeList.length; i++) {
totalResourceStock += resourceStocks[resourceTypeList[i].name];
}
if (shipsToRespawn.length === 0) {
LK.effects.flashObject(shipRespawnBtn, 0x4adf4a, 400);
return;
}
if (totalResourceStock < respawnCost) {
LK.effects.flashObject(shipRespawnBtn, 0xff0000, 600);
return;
}
// Kaynakları harca (her kaynaktan orantılı olarak düş)
var remaining = respawnCost;
for (var i = 0; i < resourceTypeList.length; i++) {
var typeName = resourceTypeList[i].name;
var take = Math.min(resourceStocks[typeName], remaining);
resourceStocks[typeName] -= take;
remaining -= take;
if (remaining <= 0) break;
}
// Her savaşçıyı tekrar aktif et
for (var i = 0; i < shipsToRespawn.length; i++) {
var s = shipsToRespawn[i];
if (typeof s.maxHp !== "number" || s.maxHp < 1) s.maxHp = 6;
if (s.maxHp > 10) s.maxHp = 10;
s.hp = s.maxHp;
s.visible = true;
s.x = 2048 / 2 + (s === ship ? 0 : Math.random() * 200 - 100);
s.y = 2732 - 700 + (s === ship ? 0 : Math.random() * 100 - 50);
// Her yenilemede farklı bir savaşçı gemisi görseli kullan
var shipImages = ['ship1', 'ship2', 'ship3', 'ship4', 'ship5', 'ship6', 'ship7', 'ship8', 'ship9', 'ship10'];
var shipImageIndex = Math.floor(Math.random() * shipImages.length);
s.shipImageId = shipImages[shipImageIndex];
// Eski asset'i kaldırıp yeni asset'i ekle
if (s.children && s.children.length > 0) {
var oldAsset = s.children[0];
if (typeof oldAsset.destroy === "function") oldAsset.destroy();
s.removeChild(oldAsset);
}
var newAsset = s.attachAsset(s.shipImageId, {
anchorX: 0.5,
anchorY: 0.5
});
LK.effects.flashObject(s, 0x4adf4a, 800);
}
};
// Paneli sağ alt köşede, diğer yazıların üstünde tutmak için z-index ayarı
if (typeof shipPanelGroup.setChildIndex === "function") {
shipPanelGroup.setChildIndex(shipPanelBg, 0);
}
// Sağ üst köşeye "Oyunu Sıfırla" butonu ekle
var resetBtn = new Text2('Oyunu Sıfırla', {
size: 44,
fill: "#fff",
font: "bold",
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 2,
dropShadowAngle: Math.PI / 4,
dropShadowBlur: 4,
dropShadowAlpha: 0.7
});
resetBtn.anchor.set(1, 0); // sağ üst köşe
resetBtn.x = 0;
resetBtn.y = 0;
resetBtn.interactive = true;
resetBtn.buttonMode = true;
resetBtn.hitArea = {
x: -20,
y: -10,
width: resetBtn.width + 40,
height: resetBtn.height + 20
};
resetBtn.down = function (x, y, obj) {
// Oyun ilerlemesini sıfırla
if (typeof storage !== "undefined" && storage.clear) {
storage.clear();
}
LK.showGameOver(); // Oyun sıfırlama için game over popup tetikle
};
LK.gui.topRight.addChild(resetBtn);
// Kaynak türleri ve isimleri
var resourceTypeList = [{
name: "Altın",
asset: "resource_gold"
}, {
name: "Kobalt",
asset: "resource_cobalt"
}, {
name: "Nikel",
asset: "resource_nickel"
}, {
name: "Helyum-3",
asset: "resource_helium3"
}, {
name: "Platin",
asset: "resource_platinum"
}, {
name: "Demir",
asset: "resource_iron"
}, {
name: "Manganez",
asset: "resource_manganese"
}];
// Her kaynak için stok tut
var resourceStocks = {};
// Başlangıç toplam kaynağı 5000 olacak şekilde eşit dağıt
var initialTotalResource = 5000;
var perResource = Math.floor(initialTotalResource / resourceTypeList.length);
var remaining = initialTotalResource;
for (var i = 0; i < resourceTypeList.length; i++) {
// Son kaynağa kalanı ekle ki toplam tam 5000 olsun
if (i === resourceTypeList.length - 1) {
resourceStocks[resourceTypeList[i].name] = remaining;
} else {
resourceStocks[resourceTypeList[i].name] = perResource;
remaining -= perResource;
}
}
// Oyun başında storage'dan yükleme yapılmaz, her zaman sıfırdan başlar
// Her kaynak için ayrı Text2 oluştur, alt alta hizala
var resourceStockTxts = [];
var lastY = collectorTxt.y - collectorTxt.height - 16;
for (var i = 0; i < resourceTypeList.length; i++) {
// Kaynak rengi: asset id'sinden shape tanımını bul
var assetId = resourceTypeList[i].asset;
var assetColor = 0xffffff;
// Asset tanımlarını yukarıda sabit olarak bildiğimiz için, elle eşleştiriyoruz
if (assetId === "resource_gold") assetColor = 0x5b6733;else if (assetId === "resource_cobalt") assetColor = 0x52459a;else if (assetId === "resource_nickel") assetColor = 0x825648;else if (assetId === "resource_helium3") assetColor = 0xf59af1;else if (assetId === "resource_platinum") assetColor = 0x63dbd1;else if (assetId === "resource_iron") assetColor = 0xe5bf1c;else if (assetId === "resource_manganese") assetColor = 0xbc3379;
var txt = new Text2(resourceTypeList[i].name + ": 0", {
size: 36,
fill: assetColor,
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 2,
dropShadowAngle: Math.PI / 4,
dropShadowBlur: 4,
dropShadowAlpha: 0.7
});
txt.anchor.set(0, 1);
txt.x = 0;
txt.y = lastY;
guiLeftBottomGroup.addChild(txt);
resourceStockTxts.push(txt);
lastY = txt.y - txt.height; // Satır arası boşluğu kaldırıldı
}
// Gemi sayısı göstergesi (sol alt) -- KALDIRILDI, sadece yükseklik için dummy olarak tanımlanır
var shipCountTxt = new Text2('Savaşçı: 1', {
size: 36,
fill: "#fff",
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 2,
dropShadowAngle: Math.PI / 4,
dropShadowBlur: 4,
dropShadowAlpha: 0.7
});
shipCountTxt.anchor.set(0, 1);
shipCountTxt.x = 0;
shipCountTxt.y = -colonyHpTxt.height - resourceTxt.height - collectorTxt.height - 24;
// Eğer başka yazı veya butonlar eklenirse, aynı şekilde guiLeftBottomGroup'a eklenmeli ve
// y koordinatları bir önceki elemanın yüksekliği ve aradaki boşluk ile ayarlanmalı.
// Tüm yazılar ve butonlar bu grupta, sol alt köşeye hizalı ve font boyutu 36 olacak şekilde ayarlanmıştır.
// Gemi kur
ship = new Ship();
ship.x = 2048 / 2;
ship.y = 2732 - 700;
ship.maxHp = 5;
ship.hp = 5;
ship.repairCost = 20;
ship.repairCostIncrease = 1.1;
game.addChild(ship);
// Ek savaşçı gemiler için dizi
var extraShips = [];
// Her ekstra gemi için can yazısı tutulacak dizi
var extraShipHpTxts = [];
// Gemi can barı: geminin üstünde gösterilecek (özel resim ile)
var shipHpBarBg = LK.getAsset('ship_hpbar_bg', {
anchorX: 0.5,
anchorY: 0.5
});
var shipHpBar = LK.getAsset('ship_hpbar_fg', {
anchorX: 0.5,
anchorY: 0.5
});
shipHpBarBg.y = ship.y - 50;
shipHpBarBg.x = ship.x;
shipHpBar.y = ship.y - 50;
shipHpBar.x = ship.x;
game.addChild(shipHpBarBg);
game.addChild(shipHpBar);
// Gemi üzerinde kalan can miktarı sayı olarak gösterilsin
var shipHpTxt = new Text2('', {
size: 32,
fill: "#fff",
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 2,
dropShadowAngle: Math.PI / 4,
dropShadowBlur: 4,
dropShadowAlpha: 0.7
});
shipHpTxt.anchor.set(0.5, 1);
shipHpTxt.x = ship.x;
shipHpTxt.y = ship.y - 70;
game.addChild(shipHpTxt);
// --- Her gemi için Tamir Et butonu ve maliyetini ekle ---
function createShipRepairBtn(targetShip, yOffset) {
var btn = new Text2('Tamir Et (' + targetShip.repairCost + ' Kaynak)', {
size: 24,
fill: "#fff",
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 2,
dropShadowAngle: Math.PI / 4,
dropShadowBlur: 4,
dropShadowAlpha: 0.7
});
btn.anchor.set(0.5, 1);
btn.x = targetShip.x;
btn.y = targetShip.y - yOffset;
btn.interactive = true;
btn.buttonMode = true;
btn.hitArea = {
x: -btn.width / 2 - 20,
y: -btn.height - 10,
width: btn.width + 40,
height: btn.height + 20
};
btn.visible = targetShip.visible;
btn.down = function (x, y, obj) {
// Toplam kaynak stoğu ile kontrol
var totalResourceStock = 0;
for (var i = 0; i < resourceTypeList.length; i++) {
totalResourceStock += resourceStocks[resourceTypeList[i].name];
}
if (targetShip.hp >= targetShip.maxHp) {
LK.effects.flashObject(btn, 0x4adf4a, 400);
return;
}
if (totalResourceStock < targetShip.repairCost) {
LK.effects.flashObject(btn, 0xff0000, 600);
return;
}
// Kaynakları harca (her kaynaktan orantılı olarak düş)
var remaining = targetShip.repairCost;
for (var i = 0; i < resourceTypeList.length; i++) {
var typeName = resourceTypeList[i].name;
var take = Math.min(resourceStocks[typeName], remaining);
resourceStocks[typeName] -= take;
remaining -= take;
if (remaining <= 0) break;
}
// HP'yi 1 artır, maxHp'yi geçemez
targetShip.hp += 1;
if (targetShip.hp > targetShip.maxHp) targetShip.hp = targetShip.maxHp;
LK.effects.flashObject(targetShip, 0x4adf4a, 600);
// Maliyeti %10 artır
targetShip.repairCost = Math.ceil(targetShip.repairCost * targetShip.repairCostIncrease);
btn.setText('Tamir Et (' + targetShip.repairCost + ' Kaynak)');
};
game.addChild(btn);
// Butonun pozisyonunu ve görünürlüğünü update fonksiyonunda güncellemek için ship objesine referans ekle
targetShip.repairBtn = btn;
}
// Ana gemi için buton ekle
createShipRepairBtn(ship, 110);
// Ekstra gemiler için butonlar spawn edildiğinde eklenecek (aşağıda shipBuyBtn.down fonksiyonunda)
// Asteroit Avcısı'nın aktif olacağı oran (ör: 0.5 = alt %50'lik kısımda avlanır, ileride artırılabilir)
var hunterActiveRatio = 0.5; // Alt %50'lik kısımda aktif
// Asteroit Avcılarını oluştur
function createCollectors(n) {
for (var i = collectors.length; i < n; i++) {
var c = new AsteroidHunter();
c.x = colony.x + 100 * (i - n / 2);
c.y = colony.y + 100;
collectors.push(c);
game.addChild(c);
}
}
createCollectors(autoCollectors);
// Kaynak Avcılarını oluştur
function createResourceHunters(n) {
for (var i = resourceHunters.length; i < n; i++) {
var h = new ResourceHunter();
h.x = colony.x + 100 * (i - n / 2);
h.y = colony.y + 200;
resourceHunters.push(h);
game.addChild(h);
// Yeni kaynaklar için baseAmount ayarla
for (var j = 0; j < resourceNodes.length; j++) {
if (typeof resourceNodes[j].baseAmount === "undefined") {
resourceNodes[j].baseAmount = resourceNodes[j].amount;
}
}
}
}
createResourceHunters(autoResourceHunters);
// Asteroidleri oluştur (kaynaklar asteroid yok edilince çıkacak)
// Artık asteroidler haritaya yavaşça girip rastgele ilerleyecek, sayıları 2-6 arası olacak
var asteroidNodes = [];
function spawnAsteroids() {
// Haritada 2-6 asteroid olacak şekilde ayarla
var minAsteroids = 2;
var maxAsteroids = 6;
// Mevcut asteroid sayısını kontrol et
var currentAsteroids = 0;
for (var i = 0; i < asteroidNodes.length; i++) {
if (!asteroidNodes[i].collected) currentAsteroids++;
}
var toSpawn = Math.max(minAsteroids - currentAsteroids, 0);
toSpawn = Math.min(maxAsteroids - currentAsteroids, toSpawn + Math.floor(Math.random() * (maxAsteroids - minAsteroids + 1)));
for (var i = 0; i < toSpawn; i++) {
var a = new AsteroidNode();
asteroidNodes.push(a);
game.addChild(a);
// Yeni kaynaklar için baseAmount ayarla
for (var j = 0; j < resourceNodes.length; j++) {
if (typeof resourceNodes[j].baseAmount === "undefined") {
resourceNodes[j].baseAmount = resourceNodes[j].amount;
}
}
}
}
// Başlangıçta asteroidleri oluştur
spawnAsteroids();
// Gemiye dokunma ve sürükleme
game.down = function (x, y, obj) {
// Gemiye dokunulduysa sürükle
var local = game.toLocal({
x: x,
y: y
});
var dx = local.x - ship.x;
var dy = local.y - ship.y;
if (dx * dx + dy * dy < 120 * 120) {
dragNode = ship;
lastTouch.x = local.x;
lastTouch.y = local.y;
} else {
// Hedefe git
ship.targetX = local.x;
ship.targetY = local.y;
}
};
game.move = function (x, y, obj) {
if (dragNode === ship) {
var local = game.toLocal({
x: x,
y: y
});
ship.targetX = local.x;
ship.targetY = local.y;
lastTouch.x = local.x;
lastTouch.y = local.y;
}
};
game.up = function (x, y, obj) {
dragNode = null;
};
// Kaynak toplama otomasyonu
function assignCollectors() {
for (var i = 0; i < collectors.length; i++) {
var c = collectors[i];
// Eğer collector bir asteroidi takip ediyorsa ve asteroid haritadan çıkmadıysa veya yok olmadıysa veya kaynak almadıysa, takip etmeye devam etsin
if (c.state === 'moving' && c.target && typeof c.target.hp === "number" && !c.target.collected && c.target.visible &&
// Asteroid Avcısı sadece ilgili alan (hunterActiveY) içindeki asteroidi yok edene kadar peşini bırakmasın
c.target.y >= 2732 * hunterActiveRatio && (!c.target.resourceSpawned || _typeof3(c.target.resourceNode) === "object" && c.target.resourceNode && !c.target.resourceNode.collected)) {
// Asteroid yok edilmedi ve kaynak alınmadı, takip etmeye devam et
continue;
}
// Sadece idle veya returning durumundakiler için yeni hedef ata
if (c.state === 'idle' || c.state === 'returning' || !c.target || c.target && (c.target.collected || !c.target.visible)) {
// --- Tüm haritadaki asteroidlere saldır, öncelik koloniye en yakın olan ---
// Asteroit Avcısı haritanın üst yarısına müdahale etmesin (oran ile)
var hunterActiveY = 2732 * hunterActiveRatio;
var minDistAst = 99999;
var targetAst = null;
for (var j = 0; j < asteroidNodes.length; j++) {
var a = asteroidNodes[j];
if (!a.collected && a.visible && typeof a.x === "number" && typeof a.y === "number") {
// Asteroit Avcısı sadece hunterActiveY'den aşağıdaki asteroidlere saldırır
if (a.y < hunterActiveY) continue;
// Koloniye olan mesafeyi hesapla
var dxCol = a.x - colony.x;
var dyCol = a.y - colony.y;
var distCol = Math.sqrt(dxCol * dxCol + dyCol * dyCol);
// Her durumda, en yakın asteroidi bul
var dx = a.x - c.x;
var dy = a.y - c.y;
var dist = dx * dx + dy * dy;
// Öncelik: koloniye en yakın asteroid
if (distCol < minDistAst) {
minDistAst = distCol;
targetAst = a;
}
}
}
if (targetAst) {
c.target = targetAst;
c.state = 'moving';
continue;
}
// Eğer hedef yoksa, haritada rastgele bir noktaya doğru dolaşmaya başlasın
if (!c.target || c.state === 'idle') {
// Rastgele bir hedef belirle (harita içinde)
var randX = 200 + Math.random() * (2048 - 400);
var randY = 400 + Math.random() * (2732 - 800);
// Sahte bir hedef objesi oluştur (sadece pozisyon için)
c.target = {
x: randX,
y: randY,
hp: 9999,
collected: false,
visible: true
};
c.state = 'moving';
continue;
}
}
// Asteroit Avcıları kaynak toplamaz, sadece asteroit yok ederler
}
}
// Gemi ateş etme
function shipShoot() {
if (LK.ticks - ship.lastShot > ship.shootDelay) {
var b = new Bullet();
b.x = ship.x;
b.y = ship.y - 60;
// En yakın düşmanı bul
var nearestEnemy = null;
var minDist = 999999;
for (var i = 0; i < enemies.length; i++) {
var dx = enemies[i].x - ship.x;
var dy = enemies[i].y - ship.y;
var dist = dx * dx + dy * dy;
if (dist < minDist) {
minDist = dist;
nearestEnemy = enemies[i];
}
}
if (nearestEnemy) {
// Merminin hedefini kaydet
b.targetEnemy = nearestEnemy;
var tx = nearestEnemy.x - ship.x;
var ty = nearestEnemy.y - ship.y;
var tdist = Math.sqrt(tx * tx + ty * ty);
if (tdist > 0) {
b.dirX = tx / tdist;
b.dirY = ty / tdist;
} else {
b.dirX = 0;
b.dirY = -1;
}
} else {
b.dirX = 0;
b.dirY = -1;
}
b.from = 'player';
bullets.push(b);
game.addChild(b);
ship.lastShot = LK.ticks;
}
}
// Oyun güncelleme döngüsü
game.update = function () {
// Kaynak göstergesini güncelle
var totalResourceStock = 0;
for (var i = 0; i < resourceTypeList.length; i++) {
totalResourceStock += resourceStocks[resourceTypeList[i].name];
}
resources = totalResourceStock; // resources birimini Toplam Kaynak ile eşdeğer yap
resourceTxt.setText('Toplam Kaynak: ' + totalResourceStock);
collectorTxt.setText('Asteroit Avcısı: ' + autoCollectors);
// Her kaynak türünden stokta olan miktarı göster
for (var i = 0; i < resourceTypeList.length; i++) {
var typeName = resourceTypeList[i].name;
// resourceStocks[typeName] zaten Collector tarafından güncelleniyor, burada tekrar sıfırlama veya toplama yapma!
// Sadece GUI güncellemesi için değerler kullanılacak.
}
// Her kaynak için GUI yazısını güncelle
for (var i = 0; i < resourceTypeList.length; i++) {
var typeName = resourceTypeList[i].name;
resourceStockTxts[i].setText(typeName + ": " + resourceStocks[typeName]);
}
// Gemi sayısı güncelle (gemi yoksa 0, varsa 1)
var activeShipCount = ship && ship.visible && ship.hp > 0 ? 1 : 0;
for (var i = 0; i < extraShips.length; i++) {
if (extraShips[i].visible && extraShips[i].hp > 0) activeShipCount++;
}
shipCountTxt.setText('Savaşçı: ' + activeShipCount);
shipCountTxtRight.setText('Savaşçı: ' + activeShipCount);
// Gemi canı güncelle -- KALDIRILDI
// --- Sağ alt panel butonlarının aktif/pasif durumunu güncelle ---
// Gemi satın alma paneli butonu
if (typeof shipBuyBtn !== "undefined") {
var totalResourceStock = 0;
for (var i = 0; i < resourceTypeList.length; i++) {
totalResourceStock += resourceStocks[resourceTypeList[i].name];
}
if (totalResourceStock >= shipBuyPrice) {
shipBuyBtn.alpha = 1;
} else {
shipBuyBtn.alpha = 0.5;
}
}
// Asteroit Avcısı satın alma butonu
if (typeof collectorBuyBtn !== "undefined") {
if (resources >= collectorBuyPrice) {
collectorBuyBtn.alpha = 1;
} else {
collectorBuyBtn.alpha = 0.5;
}
}
// Savunma Kulesi satın alma butonu aktiflik
if (typeof defenseTowerBuyBtn !== "undefined") {
var activeTowers = 0;
for (var i = 0; i < defenseTowers.length; i++) {
if (defenseTowers[i].visible && defenseTowers[i].hp > 0) activeTowers++;
}
if (resources >= defenseTowerBuyPrice && activeTowers < defenseTowerMaxCount) {
defenseTowerBuyBtn.alpha = 1;
} else {
defenseTowerBuyBtn.alpha = 0.5;
}
}
// Savunma Kulesi Seviye Yükselt butonu aktif/pasif güncelle
if (typeof defenseTowerLevelUpBtn !== "undefined") {
var activeTowers = 0;
for (var i = 0; i < defenseTowers.length; i++) {
if (defenseTowers[i].visible && defenseTowers[i].hp > 0) activeTowers++;
}
if (resources >= defenseTowerLevelUpPrice && activeTowers > 0) {
defenseTowerLevelUpBtn.alpha = 1;
} else {
defenseTowerLevelUpBtn.alpha = 0.5;
}
}
// Kaynak Avcısı satın alma butonu aktiflik
if (typeof resourceHunterBuyBtn !== "undefined") {
if (resources >= resourceHunterBuyPrice) {
resourceHunterBuyBtn.alpha = 1;
} else {
resourceHunterBuyBtn.alpha = 0.5;
}
}
if (typeof shipUpgradeBtn !== "undefined") {
var totalResourceStock = 0;
for (var i = 0; i < resourceTypeList.length; i++) {
totalResourceStock += resourceStocks[resourceTypeList[i].name];
}
// Herhangi bir savaşçı gemisinin maxHp'si 10'dan küçükse buton aktif, hepsi 10 ise pasif
var anyShipMaxBelow10 = false;
if (typeof ship.maxHp === "number" && ship.visible && ship.maxHp < 10) {
anyShipMaxBelow10 = true;
}
for (var i = 0; i < extraShips.length; i++) {
var s = extraShips[i];
if (typeof s.maxHp === "number" && s.visible && s.maxHp < 10) {
anyShipMaxBelow10 = true;
break;
}
}
if (anyShipMaxBelow10 && totalResourceStock >= 30) {
shipUpgradeBtn.alpha = 1;
} else {
shipUpgradeBtn.alpha = 0.5;
}
}
if (typeof shipRespawnBtn !== "undefined") {
// Yenilenecek savaşçı sayısını bul
var shipsToRespawn = 0;
if (!ship.visible || ship.hp <= 0) shipsToRespawn++;
for (var i = 0; i < extraShips.length; i++) {
var s = extraShips[i];
if (!s.visible || s.hp <= 0) shipsToRespawn++;
}
var respawnCost = shipsToRespawn * 100;
if (shipsToRespawn > 0) {
shipRespawnBtn.setText('Savaşçı Yenile (' + respawnCost + ' Kaynak)');
} else {
shipRespawnBtn.setText('Savaşçı Yenile (0 Kaynak)');
}
if (resources >= respawnCost && shipsToRespawn > 0) {
shipRespawnBtn.alpha = 1;
} else {
shipRespawnBtn.alpha = 0.5;
}
}
// Seviye yükseltme butonu aktiflik
if (typeof upgradeBtn !== "undefined") {
var totalResourceStock = 0;
for (var i = 0; i < resourceTypeList.length; i++) {
totalResourceStock += resourceStocks[resourceTypeList[i].name];
}
if (totalResourceStock >= upgradePrice) {
upgradeBtn.alpha = 1;
} else {
upgradeBtn.alpha = 0.5;
}
}
// Koloni sağlık sistemi güncellemesi
if (colony.hp < 0) colony.hp = 0;
if (colony.hp > colony.maxHp) colony.hp = colony.maxHp;
var ratio = colony.maxHp > 0 ? colony.hp / colony.maxHp : 0;
if (ratio < 0) ratio = 0;
if (ratio > 1) ratio = 1;
colonyHealthSystem.bar.width = 216 * ratio;
colonyHealthSystem.bar.x = colony.x;
colonyHealthSystem.bar.y = colony.y - 160;
colonyHealthSystem.barBg.x = colony.x;
colonyHealthSystem.barBg.y = colony.y - 160;
colonyHealthSystem.levelTxt.x = colony.x;
colonyHealthSystem.levelTxt.y = colony.y - 200 - 40;
colonyHealthSystem.levelTxt.setText('Seviye: ' + colonyLevel);
colonyHealthSystem.upBtn.x = -32;
colonyHealthSystem.upBtn.y = -140; // shipBuyBtn.y = -80, collectorBuyBtn.y = -140, 2 satır yukarı = -200, ama -140 hizalı (üstten 2. satır)
colonyHealthSystem.upBtn.setText('Koloni Seviye Yükselt (' + colonyLevelPrice + ' Kaynak)');
colonyHealthSystem.repairBtn.x = colony.x;
colonyHealthSystem.repairBtn.y = colony.y - 200 - colonyHealthSystem.repairBtn.height - 20 + (colonyHealthSystem.repairBtn.height + 20) * 0.25;
colonyHealthSystem.repairBtn.setText('Tamir Et (' + colonyHealthSystem.repairCost + ' Kaynak)');
// Sol alt ve sağ alt koloni canı yazılarını güncelle
colonyHpTxt.setText(Math.round(colony.hp) + ' / ' + colony.maxHp);
colonyHpTxt.x = colony.x;
colonyHpTxt.y = colony.y - 160;
var rightHp = 0;
var rightMaxHp = 100;
if (typeof colony !== "undefined" && colony) {
if (typeof colony.hp === "number" && !isNaN(colony.hp)) {
rightHp = Math.max(0, Math.round(colony.hp));
}
if (typeof colony.maxHp === "number" && !isNaN(colony.maxHp) && colony.maxHp > 0) {
rightMaxHp = colony.maxHp;
}
}
colonyHpTxtRight.setText(rightHp + " / " + rightMaxHp);
// Koloni seviye yazısı ve butonunu güncelle
if (typeof colonyLevelTxt !== "undefined") {
colonyLevelTxt.x = colony.x;
colonyLevelTxt.y = colony.y - 200 - 40;
colonyLevelTxt.setText('Seviye: ' + colonyLevel);
}
if (typeof colonyLevelUpBtn !== "undefined") {
colonyLevelUpBtn.x = colony.x;
colonyLevelUpBtn.y = colony.y - 200 - 80;
// Buton aktiflik: kaynak yetersizse veya canı doluysa pasif
var totalResourceStock = 0;
for (var i = 0; i < resourceTypeList.length; i++) {
totalResourceStock += resourceStocks[resourceTypeList[i].name];
}
if (totalResourceStock < colonyLevelPrice) {
colonyLevelUpBtn.alpha = 0.5;
} else {
colonyLevelUpBtn.alpha = 1;
}
}
// Koloni Tamir Et butonu aktif/pasif güncelle
if (typeof colonyRepairBtn !== "undefined") {
var totalResourceStock = 0;
for (var i = 0; i < resourceTypeList.length; i++) {
totalResourceStock += resourceStocks[resourceTypeList[i].name];
}
if (colony.hp >= colony.maxHp || totalResourceStock < colonyRepairCost) {
colonyRepairBtn.alpha = 0.5;
} else {
colonyRepairBtn.alpha = 1;
}
}
// Sağ alt collector güncelle
collectorTxtRight.setText('Asteroit Avcısı: ' + autoCollectors);
// Sağ alt Kaynak Avcısı güncelle
if (typeof resourceHunterBuyBtn !== "undefined") {
if (!game.resourceHunterTxtRight) {
var txt = new Text2('Kaynak Avcısı: ' + autoResourceHunters, {
size: 36,
fill: "#fff",
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 2,
dropShadowAngle: Math.PI / 4,
dropShadowBlur: 4,
dropShadowAlpha: 0.7
});
txt.anchor.set(1, 1);
txt.x = 0;
txt.y = -colonyHpLabelRight.height - colonyHpTxtRight.height - collectorTxtRight.height - shipCountTxtRight.height - 24;
guiRightBottomGroup.addChild(txt);
game.resourceHunterTxtRight = txt;
}
game.resourceHunterTxtRight.setText('Kaynak Avcısı: ' + autoResourceHunters);
}
// Asteroidleri güncelle ve haritada minimum 2, maksimum 6 asteroid olmasını sağla
for (var i = asteroidNodes.length - 1; i >= 0; i--) {
var a = asteroidNodes[i];
if (typeof a.update === "function") a.update();
// Haritadan çıkan veya yok edilen asteroidleri temizle
if (a.collected || !a.visible) {
a.destroy();
asteroidNodes.splice(i, 1);
}
}
// Asteroid sayısı azaldıysa yeni asteroid ekle
spawnAsteroids();
// Kaynakları güncelle (hareket ettir)
for (var i = 0; i < resourceNodes.length; i++) {
if (typeof resourceNodes[i].update === "function") resourceNodes[i].update();
}
// Toplayıcıları görevlendir
assignCollectors();
// Collector güncelle ve AI ile otomatik görev yapmalarını sağla
for (var i = 0; i < collectors.length; i++) {
var c = collectors[i];
// Eğer collector yok olduysa veya görünmüyorsa, atla
if (!c.visible) continue;
// --- AI: En yakın uygun asteroide saldır ---
if ((c.state === 'idle' || c.state === 'returning' || !c.target || c.target && (c.target.collected || !c.target.visible)) && asteroidNodes.length > 0) {
// Asteroit Avcısı haritanın alt yarısında çalışır
var hunterActiveY = 2732 * hunterActiveRatio;
var minDistAst = 99999;
var targetAst = null;
for (var j = 0; j < asteroidNodes.length; j++) {
var a = asteroidNodes[j];
if (!a.collected && a.visible && typeof a.x === "number" && typeof a.y === "number") {
if (a.y < hunterActiveY) continue;
var dxCol = a.x - colony.x;
var dyCol = a.y - colony.y;
var distCol = Math.sqrt(dxCol * dxCol + dyCol * dyCol);
if (distCol < minDistAst) {
minDistAst = distCol;
targetAst = a;
}
}
}
if (targetAst) {
c.target = targetAst;
c.state = 'moving';
} else {
// Hedef yoksa rastgele bir noktaya git
var randX = 200 + Math.random() * (2048 - 400);
var randY = 400 + Math.random() * (2732 - 800);
c.target = {
x: randX,
y: randY,
hp: 9999,
collected: false,
visible: true
};
c.state = 'moving';
}
}
c.update();
}
// Kaynak Avcısı güncelle ve AI ile otomatik görev yapmalarını sağla
for (var i = 0; i < resourceHunters.length; i++) {
var h = resourceHunters[i];
if (!h.visible) continue;
// Eğer kaynak taşıyorsa koloniye dön
if (h.state === 'returning' && h.carryType && h.carryAmount > 0) {
// update fonksiyonu zaten taşıma işlemini yapıyor
h.update();
continue;
}
// Eğer hedef kaynak yoksa veya hedefi toplandıysa yeni hedef ata
if ((h.state === 'idle' || !h.target || h.target && (h.target.collected || !h.target.visible)) && resourceNodes.length > 0) {
var minDist = 99999;
var targetRes = null;
for (var j = 0; j < resourceNodes.length; j++) {
var r = resourceNodes[j];
if (!r.collected && r.visible) {
var dx = r.x - h.x;
var dy = r.y - h.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < minDist) {
minDist = dist;
targetRes = r;
}
}
}
if (targetRes) {
h.target = targetRes;
h.state = 'moving';
}
}
h.update();
}
// --- Seviye yükseltme bonuslarını uygula ---
if (typeof upgradeLevel !== "undefined" && upgradeLevel > 0) {
// Gemi hızı
ship.speed = 11 * 0.1 * Math.pow(1.1, upgradeLevel);
// Asteroid Avcısı ve Kaynak Avcısı hızları
for (var i = 0; i < collectors.length; i++) {
collectors[i].speed = 1.25 * (0.002 + 0.001) * 0.1 * 2732 * Math.pow(1.1, upgradeLevel);
}
for (var i = 0; i < resourceHunters.length; i++) {
resourceHunters[i].speed = 1.1 * (0.002 + 0.001) * 0.1 * 2732 * Math.pow(1.1, upgradeLevel);
}
// Mermi hızı
for (var i = 0; i < bullets.length; i++) {
if (typeof bullets[i].speed === "number") {
// Sadece oyuncu ve collector mermileri için uygula
if (bullets[i].from === 'player' || typeof bullets[i].from === "undefined") {
bullets[i].speed = 40 * 0.1 * Math.pow(1.2, upgradeLevel);
} else if (bullets[i].from === 'enemy') {
// Düşman mermisi sabit kalsın
}
}
}
// Maden kaynağı artırımı (yeni kaynaklar için)
for (var i = 0; i < resourceNodes.length; i++) {
if (typeof resourceNodes[i].baseAmount === "undefined") {
resourceNodes[i].baseAmount = resourceNodes[i].amount;
}
resourceNodes[i].amount = Math.floor(resourceNodes[i].baseAmount * Math.pow(1.1, upgradeLevel));
}
}
// Gemi güncelle
ship.update();
// Ekstra savaşçı gemileri güncelle ve AI ile kontrol et
for (var i = 0; i < extraShips.length; i++) {
var s = extraShips[i];
// Eğer gemi yok olduysa veya görünmüyorsa, atla
if (!s.visible || s.hp <= 0) continue;
// --- AI: En yakın düşmana saldır ---
var nearestEnemy = null;
var minEnemyDist = 999999;
for (var j = 0; j < enemyShips.length; j++) {
var e = enemyShips[j];
if (e.state === 'approaching' || e.state === 'engaging' || e.state === 'attacking') {
var dx = e.x - s.x;
var dy = e.y - s.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < minEnemyDist) {
minEnemyDist = dist;
nearestEnemy = e;
}
}
}
// Eğer bir düşman koloniye 600px mesafedeyse, gemi ona saldırı pozisyonuna geçsin
if (nearestEnemy && minEnemyDist < 600) {
// Saldırı pozisyonu: düşmana yaklaş ve ateş et
var dx = nearestEnemy.x - s.x;
var dy = nearestEnemy.y - s.y;
var dist = Math.sqrt(dx * dx + dy * dy);
// Eğer çok uzaktaysa yaklaş
if (dist > 200) {
s.targetX = nearestEnemy.x + Math.random() * 40 - 20;
s.targetY = nearestEnemy.y + Math.random() * 40 - 20;
} else {
// Yakındaysa ateş et
if (typeof s.lastShot === "undefined") s.lastShot = 0;
if (typeof s.shootDelay === "undefined") s.shootDelay = 30;
if (LK.ticks - s.lastShot > s.shootDelay) {
var b = new Bullet();
b.x = s.x;
b.y = s.y - 60;
b.targetEnemy = nearestEnemy;
var tx = nearestEnemy.x - s.x;
var ty = nearestEnemy.y - s.y;
var tdist = Math.sqrt(tx * tx + ty * ty);
if (tdist > 0) {
b.dirX = tx / tdist;
b.dirY = ty / tdist;
} else {
b.dirX = 0;
b.dirY = -1;
}
b.from = 'player';
bullets.push(b);
game.addChild(b);
s.lastShot = LK.ticks;
}
}
s.isAttacking = true;
s.randomMoveTimer = 0;
} else {
// Gemi rastgele hareket etsin, düşman yok
if (!s.randomMoveTimer) s.randomMoveTimer = 0;
s.randomMoveTimer++;
if (s.randomMoveTimer > 60) {
// Her 1 saniyede bir yeni hedef belirle
var angle = Math.random() * Math.PI * 2;
var dist = 300 + Math.random() * 350;
s.targetX = colony.x + Math.cos(angle) * dist;
s.targetY = colony.y + Math.sin(angle) * dist;
s.isAttacking = false;
s.randomMoveTimer = 0;
}
}
s.update();
}
// Gemi can barı pozisyon ve genişlik güncelle
if (typeof shipHpBar !== "undefined" && typeof shipHpBarBg !== "undefined") {
shipHpBarBg.x = ship.x;
shipHpBarBg.y = ship.y - 50;
shipHpBar.x = ship.x;
shipHpBar.y = ship.y - 50;
var ratio = typeof ship.hp === "number" && typeof ship.maxHp === "number" && ship.maxHp > 0 ? ship.hp / ship.maxHp : 1;
if (ratio < 0) ratio = 0;
if (ratio > 1) ratio = 1;
shipHpBar.width = 86 * ratio;
shipHpBar.visible = ship.visible;
shipHpBarBg.visible = ship.visible;
}
// Gemi üzerindeki can miktarı yazısını güncelle
if (typeof shipHpTxt !== "undefined") {
shipHpTxt.setText((typeof ship.hp === "number" ? Math.max(0, Math.round(ship.hp)) : 0) + " / " + (typeof ship.maxHp === "number" ? ship.maxHp : 0));
shipHpTxt.x = ship.x;
shipHpTxt.y = ship.y - 70;
shipHpTxt.visible = ship.visible;
}
// Ekstra savaşçı gemilerinin can yazılarını güncelle
if (typeof extraShipHpTxts !== "undefined") {
for (var i = 0; i < extraShipHpTxts.length; i++) {
var s = extraShipHpTxts[i].ship;
var t = extraShipHpTxts[i].txt;
if (!s || !t) continue;
t.setText((typeof s.hp === "number" ? Math.max(0, Math.round(s.hp)) : 0) + " / " + (typeof s.maxHp === "number" ? s.maxHp : 0));
t.x = s.x;
t.y = s.y - 70;
t.visible = s.visible;
}
}
// --- Her gemi için Tamir Et butonunun pozisyonu, görünürlüğü ve aktifliği güncellensin ---
if (ship.repairBtn) {
ship.repairBtn.x = ship.x;
ship.repairBtn.y = ship.y - 110;
ship.repairBtn.visible = ship.visible;
// Buton aktiflik: canı doluysa veya kaynak yoksa pasif
var totalResourceStock = 0;
for (var i = 0; i < resourceTypeList.length; i++) {
totalResourceStock += resourceStocks[resourceTypeList[i].name];
}
if (ship.hp >= ship.maxHp || totalResourceStock < ship.repairCost) {
ship.repairBtn.alpha = 0.5;
} else {
ship.repairBtn.alpha = 1;
}
}
// Ekstra gemiler için de aynı şekilde güncelle
for (var i = 0; i < extraShips.length; i++) {
var s = extraShips[i];
if (s.repairBtn) {
s.repairBtn.x = s.x;
s.repairBtn.y = s.y - 110;
s.repairBtn.visible = s.visible;
var totalResourceStock = 0;
for (var j = 0; j < resourceTypeList.length; j++) {
totalResourceStock += resourceStocks[resourceTypeList[j].name];
}
if (s.hp >= s.maxHp || totalResourceStock < s.repairCost) {
s.repairBtn.alpha = 0.5;
} else {
s.repairBtn.alpha = 1;
}
}
}
// --- Bizim askerler, düşman birliği koloniye yaklaşırken savunma saldırısı yapsın ---
// En yakın düşman gemisini bul ve eğer koloniye yaklaşıyorsa saldır
var nearestEnemy = null;
var minEnemyDist = 999999;
for (var i = 0; i < enemyShips.length; i++) {
var e = enemyShips[i];
// Sadece koloniye yaklaşan veya saldıran düşmanları dikkate al
if (e.state === 'approaching' || e.state === 'engaging' || e.state === 'attacking') {
var dx = e.x - colony.x;
var dy = e.y - colony.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < minEnemyDist) {
minEnemyDist = dist;
nearestEnemy = e;
}
}
}
// Eğer bir düşman koloniye 600px mesafedeyse, gemi ona saldırı pozisyonuna geçsin
if (nearestEnemy && minEnemyDist < 600 && ship.visible && ship.hp > 0) {
// Saldırı pozisyonu: düşmana yaklaş ve ateş et
var dx = nearestEnemy.x - ship.x;
var dy = nearestEnemy.y - ship.y;
var dist = Math.sqrt(dx * dx + dy * dy);
// Eğer çok uzaktaysa yaklaş
if (dist > 200) {
ship.targetX = nearestEnemy.x + Math.random() * 40 - 20;
ship.targetY = nearestEnemy.y + Math.random() * 40 - 20;
} else {
// Yakındaysa ateş et
if (LK.ticks - ship.lastShot > ship.shootDelay) {
var b = new Bullet();
b.x = ship.x;
b.y = ship.y - 60;
b.targetEnemy = nearestEnemy;
var tx = nearestEnemy.x - ship.x;
var ty = nearestEnemy.y - ship.y;
var tdist = Math.sqrt(tx * tx + ty * ty);
if (tdist > 0) {
b.dirX = tx / tdist;
b.dirY = ty / tdist;
} else {
b.dirX = 0;
b.dirY = -1;
}
b.from = 'player';
bullets.push(b);
game.addChild(b);
ship.lastShot = LK.ticks;
}
}
ship.isAttacking = true;
ship.randomMoveTimer = 0;
} else {
// Gemi rastgele hareket etsin, düşman yok
if (!ship.randomMoveTimer) ship.randomMoveTimer = 0;
ship.randomMoveTimer++;
if (ship.randomMoveTimer > 60) {
// Her 1 saniyede bir yeni hedef belirle
var angle = Math.random() * Math.PI * 2;
var dist = 300 + Math.random() * 350;
ship.targetX = colony.x + Math.cos(angle) * dist;
ship.targetY = colony.y + Math.sin(angle) * dist;
ship.isAttacking = false;
ship.randomMoveTimer = 0;
}
}
// --- Düşman gemisi üretimi ve güncellemesi ---
enemySpawnTimer++;
if (enemySpawnTimer >= ENEMY_SPAWN_INTERVAL) {
// Düşman dalga sayısını artır
enemyWaveCount++;
// Her dalgada gönderilecek gemi sayısı: 1 * 1.25^enemyWaveCount, en az 1, tam sayı
enemyShipsPerWave = Math.max(1, Math.floor(1 * Math.pow(1.25, enemyWaveCount)));
for (var i = 0; i < enemyShipsPerWave; i++) {
var newEnemy = new EnemyShip();
// Dalga içindeki gemileri biraz farklı açılarda gönder
if (typeof topAsteroid !== "undefined" && typeof topAsteroid.x === "number" && typeof topAsteroid.y === "number") {
var angle = Math.PI / 2 + (i - (enemyShipsPerWave - 1) / 2) * (Math.PI / 16);
var radius = 80 + i * 20;
newEnemy.x = topAsteroid.x + Math.cos(angle) * radius;
newEnemy.y = topAsteroid.y + Math.sin(angle) * radius;
}
enemyShips.push(newEnemy);
game.addChild(newEnemy);
}
enemySpawnTimer = 0;
}
// Düşman gemilerini güncelle
for (var i = enemyShips.length - 1; i >= 0; i--) {
var e = enemyShips[i];
if (typeof e.update === "function") e.update();
// Eğer yok olduysa sil
if (e.hp <= 0 || e.x < -200 || e.x > 2248 || e.y < -200 || e.y > 2932) {
// Düşman sağlık barı varsa yok et
if (e.hpBar) {
e.hpBar.destroy();
}
if (e.hpBarBg) {
e.hpBarBg.destroy();
}
// Eğer düşman öldüyse (haritadan çıkmadıysa), kaynak ekle
if (e.hp <= 0) {
// 30 kaynağı rastgele kaynak türlerine dağıt
var remaining = 30;
var types = [];
for (var t = 0; t < resourceTypeList.length; t++) {
types.push(resourceTypeList[t].name);
}
while (remaining > 0) {
var idx = Math.floor(Math.random() * types.length);
resourceStocks[types[idx]] += 1;
remaining--;
}
// resources değişkenini de güncelle (Toplam Kaynak ile eşdeğer)
var totalResourceStock = 0;
for (var t = 0; t < resourceTypeList.length; t++) {
totalResourceStock += resourceStocks[types[t].name];
}
resources = totalResourceStock;
}
// Düşman binasının en son gönderdiği geminin saldırı gücünü güncelle
if (typeof e.attackPower === "number") {
lastEnemyShipAttackPower = e.attackPower;
}
e.destroy();
enemyShips.splice(i, 1);
}
}
// --- Düşman binası GUI ve mekanik güncellemesi ---
// HP barı ve yazılarını güncelle
if (typeof enemyBaseHpBar !== "undefined" && typeof enemyBaseHpBarBg !== "undefined") {
enemyBaseHpBarBg.x = 0;
enemyBaseHpBarBg.y = -120;
enemyBaseHpBar.x = 0;
enemyBaseHpBar.y = -120;
var ratio = enemyBaseHp / enemyBaseMaxHp;
if (ratio < 0) ratio = 0;
if (ratio > 1) ratio = 1;
enemyBaseHpBar.width = 216 * ratio;
enemyBaseHpBar.visible = true;
enemyBaseHpBarBg.visible = true;
}
if (typeof enemyBaseHpTxt !== "undefined") {
enemyBaseHpTxt.setText(Math.round(enemyBaseHp) + ' / ' + enemyBaseMaxHp);
enemyBaseHpTxt.x = 0;
enemyBaseHpTxt.y = -150;
enemyBaseHpTxt.visible = true;
}
if (typeof enemyBaseLevelTxt !== "undefined") {
enemyBaseLevelTxt.setText('Seviye: ' + enemyBaseLevel);
enemyBaseLevelTxt.x = 0;
enemyBaseLevelTxt.y = 100;
enemyBaseLevelTxt.visible = true;
}
if (typeof enemyBaseAttackBtn !== "undefined") {
// Buton aktifliği: bina yoksa pasif
if (enemyBaseHp <= 0) {
enemyBaseAttackBtn.alpha = 0.5;
} else {
enemyBaseAttackBtn.alpha = 1;
}
enemyBaseAttackBtn.x = 0;
enemyBaseAttackBtn.y = 160;
enemyBaseAttackBtn.visible = true;
}
// Düşman binası yoksa, yeni bina oluştur (otomatik)
if (enemyBaseHp <= 0) {
// Respawn kalan süre göstergesi için static değişkenler
if (typeof enemyBaseRespawnTxt === "undefined") {
enemyBaseRespawnTxt = new Text2('', {
size: 40,
fill: "#fff",
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 2,
dropShadowAngle: Math.PI / 4,
dropShadowBlur: 4,
dropShadowAlpha: 0.7
});
enemyBaseRespawnTxt.anchor.set(0.5, 0.5);
enemyBaseRespawnTxt.x = enemyBaseGroup.x;
enemyBaseRespawnTxt.y = enemyBaseGroup.y + 40;
game.addChild(enemyBaseRespawnTxt);
enemyBaseRespawnTxt.visible = false;
}
// Eğer yok olma süresi başlamadıysa başlat
if (typeof enemyBaseRespawnTimer === "undefined" || enemyBaseRespawnTimer === null) {
// Bina ve GUI'yi görünmez yap
enemyBaseGroup.visible = false;
enemyBaseSprite.visible = false;
if (enemyBaseHpBar) enemyBaseHpBar.visible = false;
if (enemyBaseHpBarBg) enemyBaseHpBarBg.visible = false;
if (enemyBaseHpTxt) enemyBaseHpTxt.visible = false;
if (enemyBaseLevelTxt) enemyBaseLevelTxt.visible = false;
if (enemyBaseAttackBtn) enemyBaseAttackBtn.visible = false;
// --- Düşman gemilerinin sağlık yazılarını da gizle ---
for (var i = 0; i < enemyShips.length; i++) {
if (enemyShips[i] && enemyShips[i].hpTxt) {
enemyShips[i].hpTxt.visible = false;
}
}
// Respawn kalan süreyi başlat
enemyBaseRespawnTxt.visible = true;
enemyBaseRespawnTxt.x = enemyBaseGroup.x;
enemyBaseRespawnTxt.y = enemyBaseGroup.y + 40;
enemyBaseRespawnTxt.setText("Yeni bina için: 10 sn");
// Respawn kalan süreyi güncellemek için tick sayacı
enemyBaseRespawnStartTick = LK.ticks;
enemyBaseRespawnDuration = 600; // 10 saniye * 60 FPS
// 10 saniye sonra yeni bina spawn et
enemyBaseRespawnTimer = LK.setTimeout(function () {
// Seviye +1, hp +%20, saldırı gücü +%10, yeni gemiler %10 daha güçlü
enemyBaseLevel++;
enemyBaseMaxHp = Math.floor(enemyBaseMaxHp * 1.2);
enemyBaseMaxHp = Math.floor(enemyBaseMaxHp * 0.3); // %70 azaltılmış şekilde başlat
enemyBaseHp = enemyBaseMaxHp;
enemyBaseAttackPower = Math.ceil(enemyBaseAttackPower * 1.1);
enemyBaseAttackPower = enemyBaseAttackPower * 0.3; // %70 azaltılmış şekilde başlat
lastEnemyShipAttackPower = enemyBaseAttackPower;
if (enemyBaseLevelTxt) enemyBaseLevelTxt.setText('Seviye: ' + enemyBaseLevel);
// Sağlık yazısını yeni seviyeye göre güncelle
if (enemyBaseHpTxt) enemyBaseHpTxt.setText(Math.round(enemyBaseHp) + ' / ' + enemyBaseMaxHp);
// --- Düşman binası görselini rastgele değiştir ---
if (enemyBaseSprite && typeof enemyBaseGroup.removeChild === "function") {
enemyBaseGroup.removeChild(enemyBaseSprite);
if (typeof enemyBaseSprite.destroy === "function") enemyBaseSprite.destroy();
}
currentEnemyBaseImageId = enemyBaseImageIds[Math.floor(Math.random() * enemyBaseImageIds.length)];
enemyBaseSprite = LK.getAsset(currentEnemyBaseImageId, {
anchorX: 0.5,
anchorY: 0.5
});
enemyBaseSprite.x = 0;
enemyBaseSprite.y = 0;
enemyBaseGroup.addChildAt(enemyBaseSprite, 0); // En alta ekle
// Bina ve GUI'yi tekrar görünür yap
enemyBaseGroup.visible = true;
enemyBaseSprite.visible = true;
if (enemyBaseHpBar) enemyBaseHpBar.visible = true;
if (enemyBaseHpBarBg) enemyBaseHpBarBg.visible = true;
if (enemyBaseHpTxt) enemyBaseHpTxt.visible = true;
if (enemyBaseLevelTxt) enemyBaseLevelTxt.visible = true;
if (enemyBaseAttackBtn) enemyBaseAttackBtn.visible = true;
// Respawn kalan süre yazısını gizle
if (enemyBaseRespawnTxt) enemyBaseRespawnTxt.visible = false;
enemyBaseRespawnTimer = null;
}, 10000);
}
// Her frame'de kalan süreyi güncelle
if (enemyBaseRespawnTxt && enemyBaseRespawnTxt.visible && typeof enemyBaseRespawnStartTick !== "undefined" && typeof enemyBaseRespawnDuration !== "undefined") {
var elapsed = LK.ticks - enemyBaseRespawnStartTick;
var remain = Math.ceil((enemyBaseRespawnDuration - elapsed) / 60);
if (remain < 0) remain = 0;
enemyBaseRespawnTxt.setText("Yeni bina için: " + remain + " sn");
}
} else {
// Bina hayattaysa timer'ı sıfırla
if (typeof enemyBaseRespawnTimer !== "undefined" && enemyBaseRespawnTimer !== null) {
LK.clearTimeout(enemyBaseRespawnTimer);
enemyBaseRespawnTimer = null;
}
}
// Savunma kulelerini güncelle
for (var i = 0; i < defenseTowers.length; i++) {
var tower = defenseTowers[i];
if (typeof tower.update === "function") tower.update();
// Kule yok olduysa görünmez yap
if (tower.hp <= 0 && tower.visible) {
tower.destroyTower();
}
// --- Savunma kulesi tamir et butonu pozisyon, görünürlük ve aktiflik güncelle ---
if (tower.repairBtn) {
tower.repairBtn.x = tower.x;
tower.repairBtn.y = tower.y - 170; // 1 satır yukarı taşındı
tower.repairBtn.visible = tower.visible && tower.hp > 0;
// Buton aktiflik: canı doluysa veya kaynak yoksa pasif
var totalResourceStock = 0;
for (var j = 0; j < resourceTypeList.length; j++) {
totalResourceStock += resourceStocks[resourceTypeList[j].name];
}
if (tower.hp >= tower.maxHp || totalResourceStock < tower.repairCost) {
tower.repairBtn.alpha = 0.5;
} else {
tower.repairBtn.alpha = 1;
}
}
}
// Düşman gemileri kuleye saldırabiliyor mu?
// Her düşman gemisi, kule menziline girerse kuleye saldırır
for (var i = 0; i < enemyShips.length; i++) {
var e = enemyShips[i];
if (!e.visible || e.hp <= 0) continue;
for (var j = 0; j < defenseTowers.length; j++) {
var tower = defenseTowers[j];
if (!tower.visible || tower.hp <= 0) continue;
var dx = tower.x - e.x;
var dy = tower.y - e.y;
var dist = Math.sqrt(dx * dx + dy * dy);
// Düşman gemisi kuleye 120px yaklaştıysa saldırı başlat
if (dist < 120) {
// Her 1 saniyede bir kuleye saldırı
if (typeof e.lastTowerAttack === "undefined") e.lastTowerAttack = 0;
if (typeof e.towerAttackDelay === "undefined") e.towerAttackDelay = 60;
if (LK.ticks - e.lastTowerAttack > e.towerAttackDelay) {
tower.hp -= Math.max(1, Math.round(e.attackPower));
LK.effects.flashObject(tower, 0xff0000, 400);
e.lastTowerAttack = LK.ticks;
}
}
}
}
// Mermileri güncelle
for (var i = bullets.length - 1; i >= 0; i--) {
var b = bullets[i];
b.update();
// Ekran dışıysa sil
if (b.x < -100 || b.x > 2148 || b.y < -100 || b.y > 2832) {
b.destroy();
bullets.splice(i, 1);
continue;
}
// Çarpışmalar
// Oyuncu mermisi düşmana çarptıysa
if (b.from === 'player') {
for (var j = enemyShips.length - 1; j >= 0; j--) {
var e = enemyShips[j];
if (e.visible && typeof e.x === "number" && typeof e.y === "number" && b.intersects(e)) {
// Düşman canını azalt
if (typeof e.hp === "number") e.hp -= typeof b.attackPower === "number" ? b.attackPower : 1;
LK.effects.flashObject(e, 0xff0000, 400);
b.destroy();
bullets.splice(i, 1);
break;
}
}
if (i >= bullets.length) continue; // mermi silindiyse diğer kontrolleri atla
}
// Sadece koloni ve gemi ile çarpışma kontrolü (düşman yok)
if (b.from === 'enemy') {
// Koloniye çarpma
if (b.intersects(colony)) {
if (typeof colony.hp !== "number") colony.hp = colony.maxHp || 50;
colony.hp -= typeof b.attackPower === "number" ? b.attackPower : 1;
LK.effects.flashObject(colony, 0xff0000, 400);
b.destroy();
bullets.splice(i, 1);
if (colony.hp <= 0) {
LK.effects.flashScreen(0xff0000, 800);
LK.showGameOver();
return;
}
continue;
}
// Gemiye çarpma
if (b.intersects(ship)) {
LK.effects.flashObject(ship, 0xff0000, 500);
b.destroy();
bullets.splice(i, 1);
if (typeof ship.hp !== "number") ship.hp = ship.maxHp || 6;
ship.hp -= typeof b.attackPower === "number" ? b.attackPower : 1;
if (ship.hp <= 0) {
ship.hp = 0;
LK.effects.flashObject(ship, 0xff0000, 800);
ship.visible = false;
ship.x = -9999;
ship.y = -9999;
// Sağ alttaki birim sayı listesini güncelle
if (typeof shipCountTxtRight !== "undefined") {
shipCountTxtRight.setText('Savaşçı: 0');
}
if (typeof shipCountTxt !== "undefined") {
shipCountTxt.setText('Savaşçı: 0');
}
}
}
// Ekstra savaşçı gemilerine çarpma
for (var si = 0; si < extraShips.length; si++) {
var s = extraShips[si];
if (s.visible && s.hp > 0 && b.intersects(s)) {
LK.effects.flashObject(s, 0xff0000, 500);
b.destroy();
bullets.splice(i, 1);
if (typeof s.hp !== "number") s.hp = s.maxHp || 6;
s.hp -= typeof b.attackPower === "number" ? b.attackPower : 1;
if (s.hp <= 0) {
s.hp = 0;
LK.effects.flashObject(s, 0xff0000, 800);
s.visible = false;
s.x = -9999;
s.y = -9999;
}
break;
}
}
}
}
// Otomasyon yükseltme: 50 kaynak ile yeni toplayıcı
// (Otomatik satın alma kaldırıldı)
// Kazanma koşulu kaldırıldı: Artık oyun sonsuz, kaynak limiti yok
};
Fullscreen modern App Store landscape banner, 16:9, high definition, for a game titled "Galactic Colony Command" and with the description "Kendi uzay kolonini kur, kaynakları topla, otomasyon sistemleri geliştir ve diğer kolonilerle stratejik savaşlara girerek galaksinin hakimi ol!". No text on banner!
Fullscreen modern App Store landscape banner, 16:9, high definition, for a game titled "Uzay İstasyonu" and with the description "Kendi uzay kolonini kur, kaynakları topla, otomasyon sistemleri geliştir ve diğer kolonilerle stratejik savaşlara girerek galaksinin hakimi ol!". No text on banner!, Uzay istasyonu
Fullscreen modern App Store landscape banner, 16:9, high definition, for a game titled "Gezegen" and with the description "Kendi uzay kolonini kur, kaynakları topla, otomasyon sistemleri geliştir ve diğer kolonilerle stratejik savaşlara girerek galaksinin hakimi ol!". No text on banner!, Uzay istasyonu, Gezegen
Astreroit cobalt. In-Game asset. 2d. High contrast. No shadows
asteroid gold. In-Game asset. 2d. High contrast. No shadows
asteroid helium. In-Game asset. 2d. High contrast. No shadows
Asteroid Iron - Yazısız. In-Game asset. 2d. High contrast. No shadows
asteroid manganese - yazısız. In-Game asset. 2d. High contrast. No shadows
Asteroid Nikel - Yazısız. In-Game asset. 2d. High contrast. No shadows
Cobalt cevheri. In-Game asset. 2d. High contrast. No shadows
Platinum Cevheri - Yazısız. In-Game asset. 2d. High contrast. No shadows
Ateş - Patlama. In-Game asset. 2d. High contrast. No shadows
Ateş. In-Game asset. 2d. High contrast. No shadows
Maden toplayıcı uzay mekiği, Gerçekçi. In-Game asset. High contrast. No shadows
Uzay savaş gemisi - Gerçekçi - Yazısız. In-Game asset. High contrast. No shadows
Altın Cevheri - Yazısız. In-Game asset. 2d. High contrast. No shadows
Helium cevheri - yazısız. In-Game asset. 2d. High contrast. No shadows
Iron cevheri - yazısız. In-Game asset. 2d. High contrast. No shadows
Manganese cevheri - yazısız. In-Game asset. 2d. High contrast. No shadows
HP BAR - yazısız. In-Game asset. 2d. High contrast. No shadows
Fullscreen modern App Store landscape banner, 16:9, high definition, for a game titled "Galactic Colony Command" and with the description "Kendi uzay kolonini kur, kaynakları topla, otomasyon sistemleri geliştir ve diğer kolonilerle stratejik savaşlara girerek galaksinin hakimi ol!". No text on banner!
uzay savaş gemisi. In-Game asset. 2d. High contrast. No shadows
uzay savaş gemisi - gerçekçi - yazısız. In-Game asset. High contrast. No shadows
uzay savaş gemisi - gerçekçi - yazısız. In-Game asset. High contrast. No shadows
Uzay Savunma Kulesi - Yazısız - Gerçekçi. In-Game asset. High contrast. No shadows
Uzay Savunma Kulesi - Yazısız - Gerçekçi. In-Game asset. High contrast. No shadows
Uzay Savunma Kulesi - Yazısız - Gerçekçi. In-Game asset. High contrast. No shadows
Uzay Savunma Kulesi - Yazısız - Gerçekçi. In-Game asset. High contrast. No shadows
Uzay savaş istasyonu - Gerçekçi. In-Game asset. High contrast. No shadows
Uzay savaş istasyonu - Gerçekçi. In-Game asset. High contrast. No shadows
Uzay savaş istasyonu - Gerçekçi. In-Game asset. High contrast. No shadows
Hoparlör. In-Game asset. 2d. High contrast. No shadows