/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ // Bomba var Bomb = Container.expand(function (sx, sy, tx, ty) { var self = Container.call(this); self.asset = self.attachAsset('bomb', { anchorX: 0.5, anchorY: 0.5 }); self.x = sx; self.y = sy; self.tx = tx; self.ty = ty; self.speed = 18; self.toRemove = false; self.update = function () { var dx = self.tx - self.x; var dy = self.ty - self.y; var d = Math.sqrt(dx * dx + dy * dy); if (d < 30) { // Çarpışma kontrolü for (var i = pirateShips.length - 1; i >= 0; i--) { var ship = pirateShips[i]; // Sadece PirateShip sınıfı örneklerini hedef al, devriye gemilerini asla hedef alma var isNavy = false; for (var ni = 0; ni < navyShips.length; ni++) { if (ship === navyShips[ni]) { isNavy = true; break; } } if (ship && ship.constructor && ship.constructor === PirateShip && self.intersects(ship) && !isNavy && typeof ship.hp !== "undefined" && ship.hp > 0) { var dead = ship.takeDamage(25); // Her bomba vuruşu 25 hasar if (dead) { pirateShips.splice(i, 1); } self.toRemove = true; break; } } if (!self.toRemove) { self.toRemove = true; } } else { self.x += self.speed * dx / d; self.y += self.speed * dy / d; } // Ekran dışı if (self.x < -100 || self.x > 2148 || self.y < -100 || self.y > 2832) { self.toRemove = true; } }; return self; }); // Ada var Island = Container.expand(function () { var self = Container.call(this); self.asset = self.attachAsset('island', { anchorX: 0.5, anchorY: 0.5 }); return self; }); // Ordu Gemisi var NavyShip = Container.expand(function () { var self = Container.call(this); self.asset = self.attachAsset('navy', { anchorX: 0.5, anchorY: 0.5 }); // (No hp or takeDamage logic for NavyShip) self.bombCooldown = 0; self.target = null; self.speed = 1.8; //{G} // Devriye gemisi hızı azaltıldı (daha yavaş) self.bombs = []; self.patrolPoints = [[2048 / 2, 300], [2048 - 300, 700], [2048 - 300, 2000], [300, 2000], [300, 700]]; self.patrolIndex = 0; self.patrolWait = 0; self.radarRange = 600 * 600; // radar menzili (kare mesafe) self.update = function () { // 0-60sn: 2.8, 60-120sn: 3.5, 120-180sn: 4.2, 180+sn: 4.9 var elapsedSeconds = Math.floor(LK.ticks / 60); if (elapsedSeconds < 60) { self.speed = 2.8; } else if (elapsedSeconds < 120) { self.speed = 3.5; } else if (elapsedSeconds < 180) { self.speed = 4.2; } else { self.speed = 4.9; } // Önce radar menziline giren bir korsan gemisi var mı bak var foundTarget = null; var minDist = 999999; for (var i = 0; i < pirateShips.length; i++) { var candidate = pirateShips[i]; // Sadece PirateShip sınıfı örneklerini hedef al, diğer devriye gemilerini asla hedef alma var isNavyCandidate = false; for (var ni = 0; ni < navyShips.length; ni++) { if (candidate === navyShips[ni]) { isNavyCandidate = true; break; } } if (!candidate || !candidate.constructor || candidate.constructor !== PirateShip || candidate === self || isNavyCandidate) continue; var dx = candidate.x - self.x; var dy = candidate.y - self.y; var dist = dx * dx + dy * dy; if (dist < self.radarRange && dist < minDist) { minDist = dist; foundTarget = candidate; } } if (foundTarget) { self.target = foundTarget; } else { self.target = null; } // Eğer hedef varsa ona yönel ve bomba at if (self.target) { var dx = self.target.x - self.x; var dy = self.target.y - self.y; var d = Math.sqrt(dx * dx + dy * dy); if (d > 10) { self.x += self.speed * dx / d; self.y += self.speed * dy / d; } // Bomba at self.bombCooldown--; if (self.bombCooldown <= 0) { self.bombCooldown = 90 + Math.floor(Math.random() * 60); self.shootBomb(); } self.patrolWait = 0; // hedef varken bekleme yok } else { // Devriye rotasında gez if (self.patrolPoints && self.patrolPoints.length > 0) { var pt = self.patrolPoints[self.patrolIndex]; var dx = pt[0] - self.x; var dy = pt[1] - self.y; var d = Math.sqrt(dx * dx + dy * dy); if (d > 10) { self.x += self.speed * dx / d; self.y += self.speed * dy / d; self.patrolWait = 0; } else { // Noktaya ulaştı, biraz bekle if (self.patrolWait < 30) { self.patrolWait++; } else { self.patrolWait = 0; self.patrolIndex = (self.patrolIndex + 1) % self.patrolPoints.length; } } } } // Bombaları güncelle for (var i = self.bombs.length - 1; i >= 0; i--) { var bomb = self.bombs[i]; bomb.update(); if (bomb.toRemove) { bomb.destroy(); self.bombs.splice(i, 1); } } }; self.shootBomb = function () { if (!self.target) return; var bomb = new Bomb(self.x, self.y, self.target.x, self.target.y); game.addChild(bomb); self.bombs.push(bomb); LK.getSound('bomb').play(); }; // Devriye gemisi hasar alma fonksiyonu return self; }); // Korsan Gemisi var PirateShip = Container.expand(function () { var self = Container.call(this); self.level = 1; // 1-5 self.hp = 3; // Her seviye için can self.maxHp = 3; self.isDragging = false; self.isMerging = false; self.mergeTarget = null; self.collecting = false; self.collectTimeout = null; self.shootCooldown = 0; // 4 ve 5. seviye için ateş etme bekleme süresi self.bullets = []; // kendi mermileri // Sağlık barı için Container ve bar asset'i self.hpBarContainer = new Container(); self.hpBarBg = LK.getAsset('bullet', { width: 80, height: 14, color: 0x333333, anchorX: 0.5, anchorY: 0.5 }); self.hpBarFg = LK.getAsset('bullet', { width: 76, height: 10, color: 0x4caf50, anchorX: 0.5, anchorY: 0.5 }); self.hpBarContainer.addChild(self.hpBarBg); self.hpBarContainer.addChild(self.hpBarFg); self.hpBarFg.x = 0; // Foreground bar centered on background self.hpBarContainer.y = 0; // Yükseklik asset'e göre ayarlanacak // Seviye ve cana göre asset seçimi function updateGraphics() { if (self.asset) { self.removeChild(self.asset); } // Seviye 1-5 arası assetId belirle var assetId; if (self.level === 1) { assetId = 'pirate1'; } else if (self.level === 2) { assetId = 'pirate2'; } else if (self.level === 3) { assetId = 'pirate3'; } else if (self.level === 4) { assetId = 'pirate4'; } else if (self.level >= 5) { // 5 ve üstü seviye için en büyük asseti kullan assetId = 'pirate5'; } self.asset = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); // Görünürlük ve işlevsellik: 3 ve üstü seviyeler için de asset ve etkileşim aktif self.visible = true; self.interactive = true; // Asset boyutunu güncelle (gerekirse) if (self.hpText && self.asset) { self.hpText.x = 0; self.hpText.y = self.asset.height * 0.6; } // Sağlık barını asset boyutuna göre konumlandır if (self.hpBarContainer && self.asset) { self.hpBarContainer.x = 0; self.hpBarContainer.y = -self.asset.height * 0.55; } } updateGraphics(); // Can göstergesi self.hpText = new Text2(self.hp + '', { size: 60, fill: "#fff" }); self.hpText.anchor.set(0.5, 1.2); self.addChild(self.hpText); // Sağlık barını ekle self.addChild(self.hpBarContainer); // Sağlık barını güncelle self.updateHpBar = function () { // Bar genişliği ve oranı var ratio = Math.max(0, Math.min(1, self.hp / self.maxHp)); self.hpBarFg.width = 76 * ratio; self.hpBarFg.x = 0; // Keep bar centered as width changes // Renk değişimi (kırmızıya yaklaşsın) if (ratio > 0.5) { self.hpBarFg.tint = 0x4caf50; } else if (ratio > 0.2) { self.hpBarFg.tint = 0xffc107; } else { self.hpBarFg.tint = 0xf44336; } }; self.updateHp = function () { self.hpText.setText(self.hp + ''); self.updateHpBar(); }; // Seviye başına sabit can değerleri uygula self.setLevel = function (lvl) { self.level = lvl; // Seviye başına can değerleri if (self.level === 1) { self.maxHp = 100; } else if (self.level === 2) { self.maxHp = 125; } else if (self.level === 3) { self.maxHp = 150; } else if (self.level === 4) { self.maxHp = 175; } else if (self.level >= 5) { self.maxHp = 200; } self.hp = self.maxHp; updateGraphics(); self.updateHp(); }; self.takeDamage = function (dmg) { self.hp -= dmg; if (self.hp < 0) self.hp = 0; self.updateHp(); LK.effects.flashObject(self, 0xff0000, 400); LK.getSound('hit').play(); if (self.hp <= 0) { self.hp = 0; self.updateHp(); self.destroy(); return true; } return false; }; self.heal = function () { self.hp = self.maxHp; self.updateHp(); }; self.collectGold = function (island) { if (self.collecting) return; self.collecting = true; LK.getSound('gold').play(); // Altın animasyonu var gold = LK.getAsset('gold', { anchorX: 0.5, anchorY: 0.5, x: island.x, y: island.y }); game.addChild(gold); tween(gold, { x: self.x, y: self.y }, { duration: 500, easing: tween.cubicOut, onFinish: function onFinish() { gold.destroy(); } }); // Altın ekle goldCount += 1; updateGoldText(); // Skor: Altın toplama başına +2 puan if (typeof score !== "undefined") { score += 2; if (typeof updateScoreText === "function") updateScoreText(); } // Kısa süre sonra tekrar toplayabilsin self.collectTimeout = LK.setTimeout(function () { self.collecting = false; }, 1200); }; // (No PirateBullet or shootAtNavy logic) self.update = function () { // Mermileri güncelle for (var i = self.bullets.length - 1; i >= 0; i--) { var bullet = self.bullets[i]; if (bullet && typeof bullet.update === "function" && typeof self.hp !== "undefined" && self.hp > 0) bullet.update(); if (bullet && bullet.toRemove) { bullet.destroy(); self.bullets.splice(i, 1); } } // Ateş etme cooldown if (self.shootCooldown > 0) self.shootCooldown--; // (No self-defense for pirate ships) }; return self; }); // Tersane Adası (Shipyard Island) var ShipyardIsland = Container.expand(function () { var self = Container.call(this); self.asset = self.attachAsset('shipyard_island', { anchorX: 0.5, anchorY: 0.5 }); self.isShipyard = true; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1a237e }); /**** * Game Code ****/ // Sesler // Altın simgesi // Bomba // Arka plan ekle var background = LK.getAsset('ocean_bg', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, scaleX: 1, scaleY: 1 }); background.alpha = 1; game.addChildAt(background, 0); // Ordu gemisi // Ada (altın kaynağı) // Korsan gemisi seviyelerine göre farklı renk ve boyutlarda kutular // Oyun değişkenleri var pirateShips = []; var islands = []; var navyShips = []; // Birden fazla devriye gemisi için dizi var goldCount = 0; var goldText = null; var score = 0; var scoreText = null; var spawnBtn = null; var draggingShip = null; var dragOffsetX = 0; var dragOffsetY = 0; var mergeCandidate = null; var mergeAnim = false; // Skor göstergesi scoreText = new Text2('Skor: 0', { size: 90, fill: 0xFFFFFF }); scoreText.anchor.set(1, 0); // sağ üst köşe için anchorX=1 LK.gui.topRight.addChild(scoreText); function updateScoreText() { scoreText.setText('Skor: ' + score); } // Altın göstergesi goldText = new Text2('Altın: 0', { size: 90, fill: 0xFFD700 }); goldText.anchor.set(0, 0); // sol üst köşe için anchorX=0 LK.gui.topLeft.addChild(goldText); function updateGoldText() { goldText.setText('Altın: ' + goldCount); } // Korsan gemisi üretme butonu kaldırıldı // Ada yerleşimi function spawnIslands() { var positions = [[400, 700], [1648, 700], [400, 2000], [1648, 2000], [1024, 1400]]; for (var i = 0; i < positions.length; i++) { // Son ada Shipyard olarak atanacak var island; if (i === positions.length - 1) { island = new ShipyardIsland(); island.isShipyard = true; } else { island = new Island(); island.isShipyard = false; } island.x = positions[i][0]; island.y = positions[i][1]; game.addChild(island); islands.push(island); } } // Başlangıç korsan gemisi function spawnPirateShip(level, x, y) { var ship = new PirateShip(); ship.setLevel(level); ship.x = x; ship.y = y; pirateShips.push(ship); game.addChild(ship); LK.getSound('spawn').play(); return ship; } // Ordu gemisi başlat function spawnNavyShip() { var newNavy = new NavyShip(); // Rastgele bir devriye rotası oluştur var patrolTemplates = [[[2048 / 2, 300], [2048 - 300, 700], [2048 - 300, 2000], [300, 2000], [300, 700]], [[300, 300], [2048 - 300, 300], [2048 - 300, 2732 - 300], [300, 2732 - 300]], [[1024, 400], [1800, 1000], [1024, 2200], [300, 1000]], [[400, 700], [1648, 700], [1648, 2000], [400, 2000]], [[600, 600], [2048 - 600, 600], [2048 - 600, 2732 - 600], [600, 2732 - 600]]]; var idx = Math.floor(Math.random() * patrolTemplates.length); newNavy.patrolPoints = patrolTemplates[idx]; newNavy.patrolIndex = 0; // Başlangıç noktası rotanın ilk noktası newNavy.x = newNavy.patrolPoints[0][0]; newNavy.y = newNavy.patrolPoints[0][1]; game.addChild(newNavy); navyShips.push(newNavy); return newNavy; } // Gemi birleştirme function tryMergeShips(ship1, ship2) { if (ship1.level !== ship2.level) return false; if (ship1.isMerging || ship2.isMerging) return false; if (ship1 === ship2) return false; if (ship1.level >= 5) return false; ship1.isMerging = true; ship2.isMerging = true; mergeAnim = true; // Birleştirme animasyonu var mx = (ship1.x + ship2.x) / 2; var my = (ship1.y + ship2.y) / 2; tween(ship1, { x: mx, y: my, scaleX: 1.2, scaleY: 1.2 }, { duration: 300, easing: tween.cubicInOut }); tween(ship2, { x: mx, y: my, scaleX: 1.2, scaleY: 1.2 }, { duration: 300, easing: tween.cubicInOut, onFinish: function onFinish() { // Yeni üst seviye gemi // Eski gemileri silmeden önce indexlerini al var idx1 = pirateShips.indexOf(ship1); var idx2 = pirateShips.indexOf(ship2); // Eski gemileri sil if (idx1 > -1) pirateShips.splice(idx1, 1); if (idx2 > -1) pirateShips.splice(idx2, 1); ship1.destroy(); ship2.destroy(); // Yeni üst seviye gemiyi ekle var newShip = spawnPirateShip(ship1.level + 1, mx, my); // --- EK: yeni geminin event handler'larını ve state'ini sıfırla --- newShip.isDragging = false; newShip.isMerging = false; newShip.mergeTarget = null; newShip.collecting = false; newShip.collectTimeout = null; LK.getSound('merge').play(); mergeAnim = false; // Skor: Birleştirme başına +10 puan score += 10; updateScoreText(); // --- YENİ EKLEME: yeni gemiyle hemen birleştirme ve altın toplama kontrolü --- // Merge sonrası yeni gemiyle hemen tekrar merge veya altın toplama kontrolü // 1. Merge kontrolü mergeCandidate = null; for (var i = 0; i < pirateShips.length; i++) { var other = pirateShips[i]; if (other === newShip) continue; if (other.level !== newShip.level) continue; var dx = newShip.x - other.x; var dy = newShip.y - other.y; var r = Math.max(newShip.asset.width, other.asset.width) / 2 + 30; if (dx * dx + dy * dy < r * r) { mergeCandidate = other; break; } } if (mergeCandidate) { tryMergeShips(newShip, mergeCandidate); } // 2. Altın toplama kontrolü for (var j = 0; j < islands.length; j++) { var island = islands[j]; if (newShip.intersects(island)) { newShip.collectGold(island); } } } }); } // Gemi ekleme tuşu kaldırıldı, otomatik üretim eklenecek // Gemi sürükleme ve birleştirme game.down = function (x, y, obj) { if (mergeAnim) return; // Eğer zaten bir gemi sürükleniyorsa ve o gemi hala pirateShips içindeyse yeni bir sürükleme başlatma if (draggingShip && draggingShip.isDragging && pirateShips.indexOf(draggingShip) !== -1) return; // Gemilerden birine tıklandı mı? for (var i = pirateShips.length - 1; i >= 0; i--) { var ship = pirateShips[i]; var dx = x - ship.x; var dy = y - ship.y; var r = Math.max(ship.asset.width, ship.asset.height) / 2; if (dx * dx + dy * dy < r * r) { // Sadece bir gemi sürüklenebilir, başka bir gemi sürükleniyorsa bırak if (draggingShip && draggingShip !== ship) { draggingShip.isDragging = false; } draggingShip = ship; dragOffsetX = ship.x - x; dragOffsetY = ship.y - y; ship.isDragging = true; break; } } }; game.move = function (x, y, obj) { if (mergeAnim) return; // draggingShip pirateShips'ten silindiyse veya draggingShip yoksa sürüklemeyi bırak if (!draggingShip || pirateShips.indexOf(draggingShip) === -1) { if (draggingShip) draggingShip.isDragging = false; draggingShip = null; mergeCandidate = null; return; } // Sadece draggingShip.isDragging true ise ve draggingShip hala pirateShips içinde ise sürüklemeye izin ver if (draggingShip && draggingShip.isDragging && pirateShips.indexOf(draggingShip) !== -1) { draggingShip.x = x + dragOffsetX; draggingShip.y = y + dragOffsetY; // Sınır dışına çıkmasın if (draggingShip.x < 120) draggingShip.x = 120; if (draggingShip.x > 2048 - 120) draggingShip.x = 2048 - 120; if (draggingShip.y < 200) draggingShip.y = 200; if (draggingShip.y > 2732 - 120) draggingShip.y = 2732 - 120; // Birleştirme adayı bul mergeCandidate = null; for (var i = 0; i < pirateShips.length; i++) { var other = pirateShips[i]; if (other === draggingShip) continue; if (other.level !== draggingShip.level) continue; var dx = draggingShip.x - other.x; var dy = draggingShip.y - other.y; var r = Math.max(draggingShip.asset.width, other.asset.width) / 2 + 30; if (dx * dx + dy * dy < r * r) { mergeCandidate = other; break; } } } }; game.up = function (x, y, obj) { if (mergeAnim) return; if (draggingShip && draggingShip.isDragging) { draggingShip.isDragging = false; // Birleştirme varsa if (mergeCandidate) { tryMergeShips(draggingShip, mergeCandidate); } draggingShip = null; mergeCandidate = null; } }; // Oyun güncelleme game.update = function () { // Ordu gemileri hareket ve bomba for (var n = 0; n < navyShips.length; n++) { if (navyShips[n]) { navyShips[n].update(); } } // Her yeni 4. seviye korsan gemisi için yeni devriye gemisi çağır if (typeof game.lastLevel4Count === "undefined") { game.lastLevel4Count = 0; } var currentLevel4Count = 0; for (var i = 0; i < pirateShips.length; i++) { var ship = pirateShips[i]; if (ship.level === 4) { currentLevel4Count++; } for (var j = 0; j < islands.length; j++) { var island = islands[j]; if (ship.intersects(island)) { ship.collectGold(island); } } } if (typeof game.lastLevel4ShipIds === "undefined") { game.lastLevel4ShipIds = []; } // Şu anki 4. seviye gemilerin referanslarını topla var currentLevel4ShipIds = []; for (var i = 0; i < pirateShips.length; i++) { if (pirateShips[i].level === 4) { currentLevel4ShipIds.push(pirateShips[i]); } } // Sadece yeni eklenen 4. seviye gemiler için devriye gemisi çağır for (var i = 0; i < currentLevel4ShipIds.length; i++) { var found = false; for (var j = 0; j < game.lastLevel4ShipIds.length; j++) { if (currentLevel4ShipIds[i] === game.lastLevel4ShipIds[j]) { found = true; break; } } if (!found) { spawnNavyShip(); } } game.lastLevel4ShipIds = currentLevel4ShipIds.slice(); // Oyun bitti mi? (Hiç korsan gemisi kalmadıysa) if (pirateShips.length === 0) { LK.effects.flashScreen(0x000000, 800); LK.showGameOver(); } }; // Oyun başlat spawnIslands(); spawnPirateShip(1, 2048 / 2, 2200); spawnNavyShip(); // İlk devriye gemisi updateGoldText(); // --- Otomatik gemi üretimi için değişkenler --- var autoSpawnInterval = null; var autoSpawnActive = false; var lastShipOnShipyard = false; // --- Otomatik gemi üretim fonksiyonu --- function tryAutoSpawnPirateShip() { // Shipyard adasını bul var shipyard = null; for (var i = 0; i < islands.length; i++) { if (islands[i].isShipyard) { shipyard = islands[i]; break; } } if (!shipyard) return; // Shipyard adasında bir korsan gemisi var mı? var shipOnShipyard = false; for (var j = 0; j < pirateShips.length; j++) { var ship = pirateShips[j]; if (ship.intersects(shipyard)) { shipOnShipyard = true; break; } } // Sadece bir kere interval başlatmak için state takibi if (shipOnShipyard && !autoSpawnActive) { autoSpawnActive = true; autoSpawnInterval = LK.setInterval(function () { // Her 5 saniyede bir, shipyard adasında hala gemi varsa yeni gemi üret var stillShipOnShipyard = false; for (var k = 0; k < pirateShips.length; k++) { if (pirateShips[k].intersects(shipyard)) { stillShipOnShipyard = true; break; } } if (stillShipOnShipyard) { // Haritanın rastgele bir adasına (shipyard hariç) yeni gemi ekle var possibleIslands = []; for (var m = 0; m < islands.length; m++) { if (!islands[m].isShipyard) { possibleIslands.push(islands[m]); } } if (possibleIslands.length > 0) { var targetIsland = possibleIslands[Math.floor(Math.random() * possibleIslands.length)]; var px = targetIsland.x + (Math.random() - 0.5) * 40; var py = targetIsland.y + (Math.random() - 0.5) * 40; spawnPirateShip(1, px, py); } } else { // Shipyard'da gemi yoksa intervali durdur LK.clearInterval(autoSpawnInterval); autoSpawnActive = false; } }, 5000); } else if (!shipOnShipyard && autoSpawnActive) { // Shipyard'da gemi yoksa intervali durdur LK.clearInterval(autoSpawnInterval); autoSpawnActive = false; } } // Oyun update fonksiyonuna shipyard kontrolü ekle var originalGameUpdate = game.update; game.update = function () { if (typeof originalGameUpdate === "function") { originalGameUpdate(); } tryAutoSpawnPirateShip(); };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
// Bomba
var Bomb = Container.expand(function (sx, sy, tx, ty) {
var self = Container.call(this);
self.asset = self.attachAsset('bomb', {
anchorX: 0.5,
anchorY: 0.5
});
self.x = sx;
self.y = sy;
self.tx = tx;
self.ty = ty;
self.speed = 18;
self.toRemove = false;
self.update = function () {
var dx = self.tx - self.x;
var dy = self.ty - self.y;
var d = Math.sqrt(dx * dx + dy * dy);
if (d < 30) {
// Çarpışma kontrolü
for (var i = pirateShips.length - 1; i >= 0; i--) {
var ship = pirateShips[i];
// Sadece PirateShip sınıfı örneklerini hedef al, devriye gemilerini asla hedef alma
var isNavy = false;
for (var ni = 0; ni < navyShips.length; ni++) {
if (ship === navyShips[ni]) {
isNavy = true;
break;
}
}
if (ship && ship.constructor && ship.constructor === PirateShip && self.intersects(ship) && !isNavy && typeof ship.hp !== "undefined" && ship.hp > 0) {
var dead = ship.takeDamage(25); // Her bomba vuruşu 25 hasar
if (dead) {
pirateShips.splice(i, 1);
}
self.toRemove = true;
break;
}
}
if (!self.toRemove) {
self.toRemove = true;
}
} else {
self.x += self.speed * dx / d;
self.y += self.speed * dy / d;
}
// Ekran dışı
if (self.x < -100 || self.x > 2148 || self.y < -100 || self.y > 2832) {
self.toRemove = true;
}
};
return self;
});
// Ada
var Island = Container.expand(function () {
var self = Container.call(this);
self.asset = self.attachAsset('island', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
// Ordu Gemisi
var NavyShip = Container.expand(function () {
var self = Container.call(this);
self.asset = self.attachAsset('navy', {
anchorX: 0.5,
anchorY: 0.5
});
// (No hp or takeDamage logic for NavyShip)
self.bombCooldown = 0;
self.target = null;
self.speed = 1.8; //{G} // Devriye gemisi hızı azaltıldı (daha yavaş)
self.bombs = [];
self.patrolPoints = [[2048 / 2, 300], [2048 - 300, 700], [2048 - 300, 2000], [300, 2000], [300, 700]];
self.patrolIndex = 0;
self.patrolWait = 0;
self.radarRange = 600 * 600; // radar menzili (kare mesafe)
self.update = function () {
// 0-60sn: 2.8, 60-120sn: 3.5, 120-180sn: 4.2, 180+sn: 4.9
var elapsedSeconds = Math.floor(LK.ticks / 60);
if (elapsedSeconds < 60) {
self.speed = 2.8;
} else if (elapsedSeconds < 120) {
self.speed = 3.5;
} else if (elapsedSeconds < 180) {
self.speed = 4.2;
} else {
self.speed = 4.9;
}
// Önce radar menziline giren bir korsan gemisi var mı bak
var foundTarget = null;
var minDist = 999999;
for (var i = 0; i < pirateShips.length; i++) {
var candidate = pirateShips[i];
// Sadece PirateShip sınıfı örneklerini hedef al, diğer devriye gemilerini asla hedef alma
var isNavyCandidate = false;
for (var ni = 0; ni < navyShips.length; ni++) {
if (candidate === navyShips[ni]) {
isNavyCandidate = true;
break;
}
}
if (!candidate || !candidate.constructor || candidate.constructor !== PirateShip || candidate === self || isNavyCandidate) continue;
var dx = candidate.x - self.x;
var dy = candidate.y - self.y;
var dist = dx * dx + dy * dy;
if (dist < self.radarRange && dist < minDist) {
minDist = dist;
foundTarget = candidate;
}
}
if (foundTarget) {
self.target = foundTarget;
} else {
self.target = null;
}
// Eğer hedef varsa ona yönel ve bomba at
if (self.target) {
var dx = self.target.x - self.x;
var dy = self.target.y - self.y;
var d = Math.sqrt(dx * dx + dy * dy);
if (d > 10) {
self.x += self.speed * dx / d;
self.y += self.speed * dy / d;
}
// Bomba at
self.bombCooldown--;
if (self.bombCooldown <= 0) {
self.bombCooldown = 90 + Math.floor(Math.random() * 60);
self.shootBomb();
}
self.patrolWait = 0; // hedef varken bekleme yok
} else {
// Devriye rotasında gez
if (self.patrolPoints && self.patrolPoints.length > 0) {
var pt = self.patrolPoints[self.patrolIndex];
var dx = pt[0] - self.x;
var dy = pt[1] - self.y;
var d = Math.sqrt(dx * dx + dy * dy);
if (d > 10) {
self.x += self.speed * dx / d;
self.y += self.speed * dy / d;
self.patrolWait = 0;
} else {
// Noktaya ulaştı, biraz bekle
if (self.patrolWait < 30) {
self.patrolWait++;
} else {
self.patrolWait = 0;
self.patrolIndex = (self.patrolIndex + 1) % self.patrolPoints.length;
}
}
}
}
// Bombaları güncelle
for (var i = self.bombs.length - 1; i >= 0; i--) {
var bomb = self.bombs[i];
bomb.update();
if (bomb.toRemove) {
bomb.destroy();
self.bombs.splice(i, 1);
}
}
};
self.shootBomb = function () {
if (!self.target) return;
var bomb = new Bomb(self.x, self.y, self.target.x, self.target.y);
game.addChild(bomb);
self.bombs.push(bomb);
LK.getSound('bomb').play();
};
// Devriye gemisi hasar alma fonksiyonu
return self;
});
// Korsan Gemisi
var PirateShip = Container.expand(function () {
var self = Container.call(this);
self.level = 1; // 1-5
self.hp = 3; // Her seviye için can
self.maxHp = 3;
self.isDragging = false;
self.isMerging = false;
self.mergeTarget = null;
self.collecting = false;
self.collectTimeout = null;
self.shootCooldown = 0; // 4 ve 5. seviye için ateş etme bekleme süresi
self.bullets = []; // kendi mermileri
// Sağlık barı için Container ve bar asset'i
self.hpBarContainer = new Container();
self.hpBarBg = LK.getAsset('bullet', {
width: 80,
height: 14,
color: 0x333333,
anchorX: 0.5,
anchorY: 0.5
});
self.hpBarFg = LK.getAsset('bullet', {
width: 76,
height: 10,
color: 0x4caf50,
anchorX: 0.5,
anchorY: 0.5
});
self.hpBarContainer.addChild(self.hpBarBg);
self.hpBarContainer.addChild(self.hpBarFg);
self.hpBarFg.x = 0; // Foreground bar centered on background
self.hpBarContainer.y = 0; // Yükseklik asset'e göre ayarlanacak
// Seviye ve cana göre asset seçimi
function updateGraphics() {
if (self.asset) {
self.removeChild(self.asset);
}
// Seviye 1-5 arası assetId belirle
var assetId;
if (self.level === 1) {
assetId = 'pirate1';
} else if (self.level === 2) {
assetId = 'pirate2';
} else if (self.level === 3) {
assetId = 'pirate3';
} else if (self.level === 4) {
assetId = 'pirate4';
} else if (self.level >= 5) {
// 5 ve üstü seviye için en büyük asseti kullan
assetId = 'pirate5';
}
self.asset = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
// Görünürlük ve işlevsellik: 3 ve üstü seviyeler için de asset ve etkileşim aktif
self.visible = true;
self.interactive = true;
// Asset boyutunu güncelle (gerekirse)
if (self.hpText && self.asset) {
self.hpText.x = 0;
self.hpText.y = self.asset.height * 0.6;
}
// Sağlık barını asset boyutuna göre konumlandır
if (self.hpBarContainer && self.asset) {
self.hpBarContainer.x = 0;
self.hpBarContainer.y = -self.asset.height * 0.55;
}
}
updateGraphics();
// Can göstergesi
self.hpText = new Text2(self.hp + '', {
size: 60,
fill: "#fff"
});
self.hpText.anchor.set(0.5, 1.2);
self.addChild(self.hpText);
// Sağlık barını ekle
self.addChild(self.hpBarContainer);
// Sağlık barını güncelle
self.updateHpBar = function () {
// Bar genişliği ve oranı
var ratio = Math.max(0, Math.min(1, self.hp / self.maxHp));
self.hpBarFg.width = 76 * ratio;
self.hpBarFg.x = 0; // Keep bar centered as width changes
// Renk değişimi (kırmızıya yaklaşsın)
if (ratio > 0.5) {
self.hpBarFg.tint = 0x4caf50;
} else if (ratio > 0.2) {
self.hpBarFg.tint = 0xffc107;
} else {
self.hpBarFg.tint = 0xf44336;
}
};
self.updateHp = function () {
self.hpText.setText(self.hp + '');
self.updateHpBar();
};
// Seviye başına sabit can değerleri uygula
self.setLevel = function (lvl) {
self.level = lvl;
// Seviye başına can değerleri
if (self.level === 1) {
self.maxHp = 100;
} else if (self.level === 2) {
self.maxHp = 125;
} else if (self.level === 3) {
self.maxHp = 150;
} else if (self.level === 4) {
self.maxHp = 175;
} else if (self.level >= 5) {
self.maxHp = 200;
}
self.hp = self.maxHp;
updateGraphics();
self.updateHp();
};
self.takeDamage = function (dmg) {
self.hp -= dmg;
if (self.hp < 0) self.hp = 0;
self.updateHp();
LK.effects.flashObject(self, 0xff0000, 400);
LK.getSound('hit').play();
if (self.hp <= 0) {
self.hp = 0;
self.updateHp();
self.destroy();
return true;
}
return false;
};
self.heal = function () {
self.hp = self.maxHp;
self.updateHp();
};
self.collectGold = function (island) {
if (self.collecting) return;
self.collecting = true;
LK.getSound('gold').play();
// Altın animasyonu
var gold = LK.getAsset('gold', {
anchorX: 0.5,
anchorY: 0.5,
x: island.x,
y: island.y
});
game.addChild(gold);
tween(gold, {
x: self.x,
y: self.y
}, {
duration: 500,
easing: tween.cubicOut,
onFinish: function onFinish() {
gold.destroy();
}
});
// Altın ekle
goldCount += 1;
updateGoldText();
// Skor: Altın toplama başına +2 puan
if (typeof score !== "undefined") {
score += 2;
if (typeof updateScoreText === "function") updateScoreText();
}
// Kısa süre sonra tekrar toplayabilsin
self.collectTimeout = LK.setTimeout(function () {
self.collecting = false;
}, 1200);
};
// (No PirateBullet or shootAtNavy logic)
self.update = function () {
// Mermileri güncelle
for (var i = self.bullets.length - 1; i >= 0; i--) {
var bullet = self.bullets[i];
if (bullet && typeof bullet.update === "function" && typeof self.hp !== "undefined" && self.hp > 0) bullet.update();
if (bullet && bullet.toRemove) {
bullet.destroy();
self.bullets.splice(i, 1);
}
}
// Ateş etme cooldown
if (self.shootCooldown > 0) self.shootCooldown--;
// (No self-defense for pirate ships)
};
return self;
});
// Tersane Adası (Shipyard Island)
var ShipyardIsland = Container.expand(function () {
var self = Container.call(this);
self.asset = self.attachAsset('shipyard_island', {
anchorX: 0.5,
anchorY: 0.5
});
self.isShipyard = true;
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a237e
});
/****
* Game Code
****/
// Sesler
// Altın simgesi
// Bomba
// Arka plan ekle
var background = LK.getAsset('ocean_bg', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
scaleX: 1,
scaleY: 1
});
background.alpha = 1;
game.addChildAt(background, 0);
// Ordu gemisi
// Ada (altın kaynağı)
// Korsan gemisi seviyelerine göre farklı renk ve boyutlarda kutular
// Oyun değişkenleri
var pirateShips = [];
var islands = [];
var navyShips = []; // Birden fazla devriye gemisi için dizi
var goldCount = 0;
var goldText = null;
var score = 0;
var scoreText = null;
var spawnBtn = null;
var draggingShip = null;
var dragOffsetX = 0;
var dragOffsetY = 0;
var mergeCandidate = null;
var mergeAnim = false;
// Skor göstergesi
scoreText = new Text2('Skor: 0', {
size: 90,
fill: 0xFFFFFF
});
scoreText.anchor.set(1, 0); // sağ üst köşe için anchorX=1
LK.gui.topRight.addChild(scoreText);
function updateScoreText() {
scoreText.setText('Skor: ' + score);
}
// Altın göstergesi
goldText = new Text2('Altın: 0', {
size: 90,
fill: 0xFFD700
});
goldText.anchor.set(0, 0); // sol üst köşe için anchorX=0
LK.gui.topLeft.addChild(goldText);
function updateGoldText() {
goldText.setText('Altın: ' + goldCount);
}
// Korsan gemisi üretme butonu kaldırıldı
// Ada yerleşimi
function spawnIslands() {
var positions = [[400, 700], [1648, 700], [400, 2000], [1648, 2000], [1024, 1400]];
for (var i = 0; i < positions.length; i++) {
// Son ada Shipyard olarak atanacak
var island;
if (i === positions.length - 1) {
island = new ShipyardIsland();
island.isShipyard = true;
} else {
island = new Island();
island.isShipyard = false;
}
island.x = positions[i][0];
island.y = positions[i][1];
game.addChild(island);
islands.push(island);
}
}
// Başlangıç korsan gemisi
function spawnPirateShip(level, x, y) {
var ship = new PirateShip();
ship.setLevel(level);
ship.x = x;
ship.y = y;
pirateShips.push(ship);
game.addChild(ship);
LK.getSound('spawn').play();
return ship;
}
// Ordu gemisi başlat
function spawnNavyShip() {
var newNavy = new NavyShip();
// Rastgele bir devriye rotası oluştur
var patrolTemplates = [[[2048 / 2, 300], [2048 - 300, 700], [2048 - 300, 2000], [300, 2000], [300, 700]], [[300, 300], [2048 - 300, 300], [2048 - 300, 2732 - 300], [300, 2732 - 300]], [[1024, 400], [1800, 1000], [1024, 2200], [300, 1000]], [[400, 700], [1648, 700], [1648, 2000], [400, 2000]], [[600, 600], [2048 - 600, 600], [2048 - 600, 2732 - 600], [600, 2732 - 600]]];
var idx = Math.floor(Math.random() * patrolTemplates.length);
newNavy.patrolPoints = patrolTemplates[idx];
newNavy.patrolIndex = 0;
// Başlangıç noktası rotanın ilk noktası
newNavy.x = newNavy.patrolPoints[0][0];
newNavy.y = newNavy.patrolPoints[0][1];
game.addChild(newNavy);
navyShips.push(newNavy);
return newNavy;
}
// Gemi birleştirme
function tryMergeShips(ship1, ship2) {
if (ship1.level !== ship2.level) return false;
if (ship1.isMerging || ship2.isMerging) return false;
if (ship1 === ship2) return false;
if (ship1.level >= 5) return false;
ship1.isMerging = true;
ship2.isMerging = true;
mergeAnim = true;
// Birleştirme animasyonu
var mx = (ship1.x + ship2.x) / 2;
var my = (ship1.y + ship2.y) / 2;
tween(ship1, {
x: mx,
y: my,
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 300,
easing: tween.cubicInOut
});
tween(ship2, {
x: mx,
y: my,
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 300,
easing: tween.cubicInOut,
onFinish: function onFinish() {
// Yeni üst seviye gemi
// Eski gemileri silmeden önce indexlerini al
var idx1 = pirateShips.indexOf(ship1);
var idx2 = pirateShips.indexOf(ship2);
// Eski gemileri sil
if (idx1 > -1) pirateShips.splice(idx1, 1);
if (idx2 > -1) pirateShips.splice(idx2, 1);
ship1.destroy();
ship2.destroy();
// Yeni üst seviye gemiyi ekle
var newShip = spawnPirateShip(ship1.level + 1, mx, my);
// --- EK: yeni geminin event handler'larını ve state'ini sıfırla ---
newShip.isDragging = false;
newShip.isMerging = false;
newShip.mergeTarget = null;
newShip.collecting = false;
newShip.collectTimeout = null;
LK.getSound('merge').play();
mergeAnim = false;
// Skor: Birleştirme başına +10 puan
score += 10;
updateScoreText();
// --- YENİ EKLEME: yeni gemiyle hemen birleştirme ve altın toplama kontrolü ---
// Merge sonrası yeni gemiyle hemen tekrar merge veya altın toplama kontrolü
// 1. Merge kontrolü
mergeCandidate = null;
for (var i = 0; i < pirateShips.length; i++) {
var other = pirateShips[i];
if (other === newShip) continue;
if (other.level !== newShip.level) continue;
var dx = newShip.x - other.x;
var dy = newShip.y - other.y;
var r = Math.max(newShip.asset.width, other.asset.width) / 2 + 30;
if (dx * dx + dy * dy < r * r) {
mergeCandidate = other;
break;
}
}
if (mergeCandidate) {
tryMergeShips(newShip, mergeCandidate);
}
// 2. Altın toplama kontrolü
for (var j = 0; j < islands.length; j++) {
var island = islands[j];
if (newShip.intersects(island)) {
newShip.collectGold(island);
}
}
}
});
}
// Gemi ekleme tuşu kaldırıldı, otomatik üretim eklenecek
// Gemi sürükleme ve birleştirme
game.down = function (x, y, obj) {
if (mergeAnim) return;
// Eğer zaten bir gemi sürükleniyorsa ve o gemi hala pirateShips içindeyse yeni bir sürükleme başlatma
if (draggingShip && draggingShip.isDragging && pirateShips.indexOf(draggingShip) !== -1) return;
// Gemilerden birine tıklandı mı?
for (var i = pirateShips.length - 1; i >= 0; i--) {
var ship = pirateShips[i];
var dx = x - ship.x;
var dy = y - ship.y;
var r = Math.max(ship.asset.width, ship.asset.height) / 2;
if (dx * dx + dy * dy < r * r) {
// Sadece bir gemi sürüklenebilir, başka bir gemi sürükleniyorsa bırak
if (draggingShip && draggingShip !== ship) {
draggingShip.isDragging = false;
}
draggingShip = ship;
dragOffsetX = ship.x - x;
dragOffsetY = ship.y - y;
ship.isDragging = true;
break;
}
}
};
game.move = function (x, y, obj) {
if (mergeAnim) return;
// draggingShip pirateShips'ten silindiyse veya draggingShip yoksa sürüklemeyi bırak
if (!draggingShip || pirateShips.indexOf(draggingShip) === -1) {
if (draggingShip) draggingShip.isDragging = false;
draggingShip = null;
mergeCandidate = null;
return;
}
// Sadece draggingShip.isDragging true ise ve draggingShip hala pirateShips içinde ise sürüklemeye izin ver
if (draggingShip && draggingShip.isDragging && pirateShips.indexOf(draggingShip) !== -1) {
draggingShip.x = x + dragOffsetX;
draggingShip.y = y + dragOffsetY;
// Sınır dışına çıkmasın
if (draggingShip.x < 120) draggingShip.x = 120;
if (draggingShip.x > 2048 - 120) draggingShip.x = 2048 - 120;
if (draggingShip.y < 200) draggingShip.y = 200;
if (draggingShip.y > 2732 - 120) draggingShip.y = 2732 - 120;
// Birleştirme adayı bul
mergeCandidate = null;
for (var i = 0; i < pirateShips.length; i++) {
var other = pirateShips[i];
if (other === draggingShip) continue;
if (other.level !== draggingShip.level) continue;
var dx = draggingShip.x - other.x;
var dy = draggingShip.y - other.y;
var r = Math.max(draggingShip.asset.width, other.asset.width) / 2 + 30;
if (dx * dx + dy * dy < r * r) {
mergeCandidate = other;
break;
}
}
}
};
game.up = function (x, y, obj) {
if (mergeAnim) return;
if (draggingShip && draggingShip.isDragging) {
draggingShip.isDragging = false;
// Birleştirme varsa
if (mergeCandidate) {
tryMergeShips(draggingShip, mergeCandidate);
}
draggingShip = null;
mergeCandidate = null;
}
};
// Oyun güncelleme
game.update = function () {
// Ordu gemileri hareket ve bomba
for (var n = 0; n < navyShips.length; n++) {
if (navyShips[n]) {
navyShips[n].update();
}
}
// Her yeni 4. seviye korsan gemisi için yeni devriye gemisi çağır
if (typeof game.lastLevel4Count === "undefined") {
game.lastLevel4Count = 0;
}
var currentLevel4Count = 0;
for (var i = 0; i < pirateShips.length; i++) {
var ship = pirateShips[i];
if (ship.level === 4) {
currentLevel4Count++;
}
for (var j = 0; j < islands.length; j++) {
var island = islands[j];
if (ship.intersects(island)) {
ship.collectGold(island);
}
}
}
if (typeof game.lastLevel4ShipIds === "undefined") {
game.lastLevel4ShipIds = [];
}
// Şu anki 4. seviye gemilerin referanslarını topla
var currentLevel4ShipIds = [];
for (var i = 0; i < pirateShips.length; i++) {
if (pirateShips[i].level === 4) {
currentLevel4ShipIds.push(pirateShips[i]);
}
}
// Sadece yeni eklenen 4. seviye gemiler için devriye gemisi çağır
for (var i = 0; i < currentLevel4ShipIds.length; i++) {
var found = false;
for (var j = 0; j < game.lastLevel4ShipIds.length; j++) {
if (currentLevel4ShipIds[i] === game.lastLevel4ShipIds[j]) {
found = true;
break;
}
}
if (!found) {
spawnNavyShip();
}
}
game.lastLevel4ShipIds = currentLevel4ShipIds.slice();
// Oyun bitti mi? (Hiç korsan gemisi kalmadıysa)
if (pirateShips.length === 0) {
LK.effects.flashScreen(0x000000, 800);
LK.showGameOver();
}
};
// Oyun başlat
spawnIslands();
spawnPirateShip(1, 2048 / 2, 2200);
spawnNavyShip(); // İlk devriye gemisi
updateGoldText();
// --- Otomatik gemi üretimi için değişkenler ---
var autoSpawnInterval = null;
var autoSpawnActive = false;
var lastShipOnShipyard = false;
// --- Otomatik gemi üretim fonksiyonu ---
function tryAutoSpawnPirateShip() {
// Shipyard adasını bul
var shipyard = null;
for (var i = 0; i < islands.length; i++) {
if (islands[i].isShipyard) {
shipyard = islands[i];
break;
}
}
if (!shipyard) return;
// Shipyard adasında bir korsan gemisi var mı?
var shipOnShipyard = false;
for (var j = 0; j < pirateShips.length; j++) {
var ship = pirateShips[j];
if (ship.intersects(shipyard)) {
shipOnShipyard = true;
break;
}
}
// Sadece bir kere interval başlatmak için state takibi
if (shipOnShipyard && !autoSpawnActive) {
autoSpawnActive = true;
autoSpawnInterval = LK.setInterval(function () {
// Her 5 saniyede bir, shipyard adasında hala gemi varsa yeni gemi üret
var stillShipOnShipyard = false;
for (var k = 0; k < pirateShips.length; k++) {
if (pirateShips[k].intersects(shipyard)) {
stillShipOnShipyard = true;
break;
}
}
if (stillShipOnShipyard) {
// Haritanın rastgele bir adasına (shipyard hariç) yeni gemi ekle
var possibleIslands = [];
for (var m = 0; m < islands.length; m++) {
if (!islands[m].isShipyard) {
possibleIslands.push(islands[m]);
}
}
if (possibleIslands.length > 0) {
var targetIsland = possibleIslands[Math.floor(Math.random() * possibleIslands.length)];
var px = targetIsland.x + (Math.random() - 0.5) * 40;
var py = targetIsland.y + (Math.random() - 0.5) * 40;
spawnPirateShip(1, px, py);
}
} else {
// Shipyard'da gemi yoksa intervali durdur
LK.clearInterval(autoSpawnInterval);
autoSpawnActive = false;
}
}, 5000);
} else if (!shipOnShipyard && autoSpawnActive) {
// Shipyard'da gemi yoksa intervali durdur
LK.clearInterval(autoSpawnInterval);
autoSpawnActive = false;
}
}
// Oyun update fonksiyonuna shipyard kontrolü ekle
var originalGameUpdate = game.update;
game.update = function () {
if (typeof originalGameUpdate === "function") {
originalGameUpdate();
}
tryAutoSpawnPirateShip();
};