/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { highScores: [] }); /**** * Classes ****/ // Asteroid - SAĞDAN SOLA var Asteroid = Container.expand(function () { var self = Container.call(this); var width = 120 + Math.random() * 60; var height = 120 + Math.random() * 60; var objAsset = self.attachAsset('spaceObject', { anchorX: 0.5, anchorY: 0.5 }); objAsset.width = width; objAsset.height = height; objAsset.color = 0x888888; self.radius = width / 2; // Always spawn at right edge, random Y, move left self.x = 2048 + width; self.y = 200 + Math.random() * (2732 - 400); // Dynamic spawn effect: scale up and fade in self.scaleX = 0.6; self.scaleY = 0.6; self.alpha = 0.0; tween(self, { scaleX: 1, scaleY: 1, alpha: 1 }, { duration: 400, easing: tween.easeOut }); // Speed will be set on spawn self.vx = -20 - (typeof difficulty !== "undefined" ? (difficulty - 1) * 2.2 : 0); self.vy = (Math.random() - 0.5) * (3.5 + (typeof difficulty !== "undefined" ? difficulty * 0.5 : 0)); self.update = function () { self.x += self.vx; self.y += self.vy; }; return self; }); // Mermi (Bullet) - SAĞA DOĞRU var Bullet = Container.expand(function () { var self = Container.call(this); var bulletAsset = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); // Asset: ellipse, width: 32, height: 32, color: 0xffe066 bulletAsset.width = 32; bulletAsset.height = 32; bulletAsset.color = 0xffe066; self.speed = typeof game !== "undefined" && game._bulletSpeedUp ? 38 : 22; // bulletspeed power-up aktifse daha hızlı, normalde biraz daha hızlı // Dynamic spawn effect: scale up and fade in self.scaleX = 0.5; self.scaleY = 0.5; self.alpha = 0.0; tween(self, { scaleX: 1, scaleY: 1, alpha: 1 }, { duration: 200, easing: tween.easeOut }); self.update = function () { self.x += self.speed; }; return self; }); // EnemyBullet - DÜŞMAN MERMİSİ (sola doğru) var EnemyBullet = Container.expand(function () { var self = Container.call(this); var bulletAsset = self.attachAsset('dusmanmermi', { anchorX: 0.5, anchorY: 0.5 }); bulletAsset.width = 32; bulletAsset.height = 32; bulletAsset.color = 0xff4444; self.speed = -24 - (typeof difficulty !== "undefined" ? (difficulty - 1) * 1.7 : 0); // Sola doğru (daha hızlı) // Dynamic spawn effect: scale up and fade in self.scaleX = 0.5; self.scaleY = 0.5; self.alpha = 0.0; tween(self, { scaleX: 1, scaleY: 1, alpha: 1 }, { duration: 200, easing: tween.easeOut }); self.update = function () { self.x += self.speed; }; return self; }); // EnemyShip - SAĞDAN SOLA var EnemyShip = Container.expand(function () { var self = Container.call(this); var width = 100; var height = 100; var objAsset = self.attachAsset('uzayNesnesi2', { anchorX: 0.5, anchorY: 0.5 }); objAsset.width = width; objAsset.height = height; objAsset.color = 0xff4444; self.radius = width / 2; self.x = 2048 + width; self.y = 200 + Math.random() * (2732 - 400); // Dynamic spawn effect: scale up and fade in self.scaleX = 0.6; self.scaleY = 0.6; self.alpha = 0.0; tween(self, { scaleX: 1, scaleY: 1, alpha: 1 }, { duration: 400, easing: tween.easeOut }); // Speed will be set on spawn self.vx = -22 - (typeof difficulty !== "undefined" ? (difficulty - 1) * 2.0 : 0); self.vy = (Math.random() - 0.5) * (5 + (typeof difficulty !== "undefined" ? difficulty * 0.5 : 0)); self.update = function () { self.x += self.vx; self.y += self.vy; }; return self; }); // MeteorStone - SAĞDAN SOLA, rastgele gelen düşman türü var MeteorStone = Container.expand(function () { var self = Container.call(this); var width = 120 + Math.random() * 60; var height = 120 + Math.random() * 60; var objAsset = self.attachAsset('meteorstone', { anchorX: 0.5, anchorY: 0.5 }); objAsset.width = width; objAsset.height = height; self.radius = width / 2; // Always spawn at right edge, random Y, move left self.x = 2048 + width; self.y = 200 + Math.random() * (2732 - 400); // Dynamic spawn effect: scale up and fade in self.scaleX = 0.6; self.scaleY = 0.6; self.alpha = 0.0; tween(self, { scaleX: 1, scaleY: 1, alpha: 1 }, { duration: 400, easing: tween.easeOut }); // Hız: asteroidlerden biraz daha hızlı olabilir var baseSpeed = 10 + (typeof difficulty !== "undefined" ? (difficulty - 1) * 1.7 : 0) + Math.random() * 4.5; self.vx = -baseSpeed; self.vy = (Math.random() - 0.5) * (4.5 + (typeof difficulty !== "undefined" ? difficulty * 0.5 : 0)); self.update = function () { // Oyuncu gemisi varsa ona doğru yönel if (typeof playerShip !== "undefined" && playerShip && typeof playerShip.x === "number" && typeof playerShip.y === "number") { var dx = playerShip.x - self.x; var dy = playerShip.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); // Hedefe doğru normalize edilmiş hız vektörü if (dist > 1) { var speed = Math.sqrt(self.vx * self.vx + self.vy * self.vy); // Hız sabit kalsın, sadece yön değişsin var nx = dx / dist; var ny = dy / dist; self.vx += (nx * speed - self.vx) * 0.08; // yumuşak yön değiştirme self.vy += (ny * speed - self.vy) * 0.08; } } self.x += self.vx; self.y += self.vy; }; return self; }); // Uzay Aracı (Player Ship) var PlayerShip = Container.expand(function () { var self = Container.call(this); // Ship asset: use selected asset if set, otherwise default to 'playerShip' var assetId = typeof game !== "undefined" && game.selectedShipAssetId ? game.selectedShipAssetId : 'playerShip'; var shipAsset = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); // Asset will be created as: ellipse, width: 140, height: 100, color: 0x3a9cff shipAsset.width = 140; shipAsset.height = 100; // playership2 ve playership3 için kendi görseli kullanılsın, renk override etme if (assetId === "playership2" || assetId === "playership3") { // playership2 ve playership3'ün kendi görseli kullanılsın, renk override etme } else { shipAsset.color = 0x3a9cff; } self.radius = 70; // For collision self.update = function () { // Otomatik sağa ilerleme kaldırıldı, sadece otomatik portal hareketi sırasında hareket etsin }; return self; }); // Uzay Cismi (Asteroid/Enemy) - SAĞDAN SOLA var SpaceObject = Container.expand(function () { var self = Container.call(this); // Randomly choose asteroid or enemy var isAsteroid = Math.random() < 0.7; var color = isAsteroid ? 0x888888 : 0xff4444; var width = isAsteroid ? 120 + Math.random() * 60 : 100; var height = isAsteroid ? 120 + Math.random() * 60 : 100; var objAsset = self.attachAsset('spaceObject', { anchorX: 0.5, anchorY: 0.5 }); objAsset.width = width; objAsset.height = height; objAsset.color = color; self.radius = width / 2; // Always spawn at right edge, random Y, move left self.x = 2048 + width; self.y = 200 + Math.random() * (2732 - 400); // Dynamic spawn effect: scale up and fade in self.scaleX = 0.6; self.scaleY = 0.6; self.alpha = 0.0; tween(self, { scaleX: 1, scaleY: 1, alpha: 1 }, { duration: 400, easing: tween.easeOut }); var speed = 18 + (typeof difficulty !== "undefined" ? (difficulty - 1) * 1.7 : 0) + Math.random() * 7; self.vx = -speed; self.vy = (Math.random() - 0.5) * (4 + (typeof difficulty !== "undefined" ? difficulty * 0.5 : 0)); // daha fazla varyasyon self.update = function () { self.x += self.vx; self.y += self.vy; }; return self; }); /**** * Initialize Game ****/ // Create and add stars to the background var game = new LK.Game({ backgroundColor: 0x000010 }); /**** * Game Code ****/ // Yıldızlar: Parallax ve hafif dönen yıldızlar // Galaksi arka planı kaldırıldı var starBgCount = 90; var stars = []; var starBgContainer = new Container(); for (var i = 0; i < starBgCount; i++) { var starSize = 2 + Math.random() * 4; var star = LK.getAsset('background', { anchorX: 0.5, anchorY: 0.5, x: Math.random() * 2048, y: Math.random() * 2732, width: starSize, height: starSize }); // Farklı parlaklıklar star.alpha = 0.3 + Math.random() * 0.7; // Farklı hızlar (parallax) star._vx = 0.7 + Math.random() * 1.2; // Hafif döndürme efekti star._rotSpeed = (Math.random() - 0.5) * 0.01; stars.push(star); starBgContainer.addChild(star); } game.addChild(starBgContainer); // Yıldız arka planı ekle (addChildAt yerine addChild ile, out of bounds hatasını önler) // --- BAŞLANGIÇ MENÜSÜ --- var startMenuContainer = new Container(); // Oyun başı intro sahnesi kaldırıldı, menü doğrudan gösteriliyor if (!startMenuContainer.parent) { startMenuContainer.alpha = 1; startMenuContainer.scaleX = 1; startMenuContainer.scaleY = 1; game.addChild(startMenuContainer); } // Menü renklerini dinamik olarak yönetmek için global değişkenler var menuBgColor = 0x181c2b; var menuButtonColors = [0x3a9cff, 0x4e5d94, 0x7cbb37, 0xf7b32b]; var menuWidth = 1000; var menuHeight = 1100; // Menü arka planına renkli kutu ekle (görsel yerine) var startMenuBg = LK.getAsset('can', { anchorX: 0.5, anchorY: 0.5, x: menuWidth / 2, y: menuHeight / 2, width: menuWidth, height: menuHeight }); startMenuBg.alpha = 0.0; // Tamamen şeffaf yap startMenuBg.color = menuBgColor; startMenuContainer.addChild(startMenuBg); // Menü arka planına border efekti kaldırıldı (menu image ile uyumlu) // Başlık ve alt başlık var titleText = new Text2("UZAY MACERASI", { size: 120, fill: 0xFFE066 }); titleText.anchor.set(0.5, 0.5); titleText.x = menuWidth / 2; titleText.y = 140; startMenuContainer.addChild(titleText); // Subtitle text removed as requested // Dinamik butonlar var menuButtons = [{ label: "Yeni Oyun", key: "start", color: 0x3a9cff }, { label: "Mağaza", key: "options", color: 0x4e5d94 }, { label: "Rekorlar", key: "scores", color: 0x7cbb37 }, { label: "Hakkında", key: "about", color: 0xf7b32b }]; var buttonHeight = 140; var buttonWidth = 600; var buttonSpacing = 48; var firstBtnY = 400; var btnBgList = []; var btnTextList = []; for (var i = 0; i < menuButtons.length; i++) { var btnY = firstBtnY + i * (buttonHeight + buttonSpacing); // Butonun arka planı (hafif gölgeli, modern) var btnBgShadow = LK.getAsset('can', { anchorX: 0.5, anchorY: 0.5, x: menuWidth / 2 + 8, y: btnY + 10, width: buttonWidth + 24, height: buttonHeight + 18 }); btnBgShadow.alpha = 0.18; btnBgShadow.color = 0x000000; startMenuContainer.addChild(btnBgShadow); var btnBg = LK.getAsset('can', { anchorX: 0.5, anchorY: 0.5, x: menuWidth / 2, y: btnY, width: buttonWidth, height: buttonHeight }); btnBg.alpha = 0.92; btnBg.color = menuButtonColors[i % menuButtonColors.length]; btnBg.menuKey = menuButtons[i].key; btnBg.buttonIndex = i; btnBg.interactive = true; // Buton tıklanabilir olsun btnBg.defaultAlpha = btnBg.alpha; // Tıklama efekti için orijinal alpha btnBg.down = function (btn) { return function (x, y, obj) { // Tıklama efekti: sadece bu buton için kısa bir görsel geri bildirim uygula btn.alpha = 0.65; tween(btn, { alpha: btn.defaultAlpha }, { duration: 120 }); // Her butonun kendi işlevi if (btn.menuKey === "start") { // Menü animasyonla kaybolsun ve oyun başlasın tween(startMenuContainer, { alpha: 0, scaleX: 1.2, scaleY: 1.2 }, { duration: 350, onFinish: function onFinish() { if (startMenuContainer && startMenuContainer.parent) startMenuContainer.destroy(); // Oyun başladığında süreyi 3 dakikaya (180 saniye) sıfırla timeLeft = gameDuration; updateTimerDisplay(); gameStarted = true; } }); } else { // Her menü butonu için yeni bir ekran (modal) aç // Ana menü ekranını gizle if (startMenuContainer && startMenuContainer.parent) { startMenuContainer.visible = false; } var modalW = 1200; var modalH = 1000; var modalContainer = new Container(); var modalBg = LK.getAsset('can', { anchorX: 0.5, anchorY: 0.5, x: modalW / 2, y: modalH / 2, width: modalW, height: modalH }); modalBg.alpha = 0.0; // Tamamen şeffaf yap modalBg.color = 0x181c2b; modalContainer.addChild(modalBg); var modalTitle = ""; var modalContent = ""; if (btn.menuKey === "options") { modalTitle = "Mağaza"; modalContent = ""; // Satın alınabilir ürünler var storeProducts = []; // Ürünleri listele ve satın al butonları ekle var productBtnH = 110; var productBtnW = 600; var productBtnSpacing = 24; var firstProductY = 260; for (var p = 0; p < storeProducts.length; p++) { var prod = storeProducts[p]; var prodY = firstProductY + p * (productBtnH + productBtnSpacing); // Ürün kutusu var prodBg = LK.getAsset('can', { anchorX: 0.5, anchorY: 0.5, x: modalW / 2, y: prodY, width: productBtnW, height: productBtnH }); prodBg.alpha = 0.0; // Tamamen şeffaf yap prodBg.color = 0x232a3d; modalContainer.addChild(prodBg); // Ürün açıklaması (isim kaldırıldığı için üstte hizalanacak) var prodDesc = new Text2(prod.desc, { size: 36, fill: 0xB0E0FF, maxWidth: productBtnW - 220 }); // Açıklamayı butonun üstüne hizala prodDesc.anchor.set(0, 1); prodDesc.x = modalW / 2 - productBtnW / 2 + 32; prodDesc.y = prodY - productBtnH / 2 + 18; modalContainer.addChild(prodDesc); // Fiyat etiketi var priceTag = new Text2(prod.price + " 💎", { size: 44, fill: 0xFFE066 }); priceTag.anchor.set(1, 0.5); priceTag.x = modalW / 2 + productBtnW / 2 - 120; priceTag.y = prodY; modalContainer.addChild(priceTag); // Satın al butonu var buyBtn = LK.getAsset('can', { anchorX: 0.5, anchorY: 0.5, x: modalW / 2 + productBtnW / 2 - 60, y: prodY, width: 100, height: 80 }); buyBtn.alpha = 0.85; buyBtn.color = 0x3a9cff; // Mavi ton, kırmızı arka plan kaldırıldı buyBtn.interactive = true; buyBtn.down = function (prod, buyBtnRef) { return function (x, y, obj) { // Satın alma işlemi (örnek: elmas bakiyesi yok, sadece görsel feedback) buyBtnRef.alpha = 0.65; tween(buyBtnRef, { alpha: 0.85 }, { duration: 120 }); // Satın alma bildirimi var boughtText = new Text2("Satın alındı!", { size: 44, fill: 0x7CBB37 }); boughtText.anchor.set(0.5, 0.5); boughtText.x = buyBtnRef.x; boughtText.y = buyBtnRef.y - 60; modalContainer.addChild(boughtText); tween(boughtText, { alpha: 0 }, { duration: 900, onFinish: function onFinish() { boughtText.destroy(); } }); }; }(prod, buyBtn); modalContainer.addChild(buyBtn); // Satın al butonu yazısı var buyBtnText = new Text2("Satın Al", { size: 36, fill: "#fff" }); buyBtnText.anchor.set(0.5, 0.5); buyBtnText.x = buyBtn.x; buyBtnText.y = buyBtn.y; buyBtnText.interactive = true; buyBtnText.down = function (buyBtnRef) { return function (x, y, obj) { if (buyBtnRef && buyBtnRef.down) buyBtnRef.down(x, y, obj); }; }(buyBtn); modalContainer.addChild(buyBtnText); } } else if (btn.menuKey === "scores") { modalTitle = ""; // --- High Scores Modal Content --- var scoresArr = getHighScores(); if (scoresArr.length === 0) { modalContent = "Henüz rekor yok!"; } else { modalContent = "En Yüksek 5 Skor:\n"; for (var s = 0; s < scoresArr.length; s++) { modalContent += s + 1 + ". " + scoresArr[s] + "\n"; } } } else if (btn.menuKey === "about") { modalTitle = "Hakkında"; modalContent = "Uzay Macerası - made in TE"; } var modalTitleText = new Text2(modalTitle, { size: 100, fill: 0xFFE066, maxWidth: modalW - 80 // kutu kenarından taşmasın }); modalTitleText.anchor.set(0.5, 0.5); modalTitleText.x = modalW / 2; modalTitleText.y = 120; modalContainer.addChild(modalTitleText); // --- 3x3 Kare Slotlar: Mağaza başlığı ile kapat tuşu arasına --- // Sadece mağaza menüsünde slotlar görünsün if (btn.menuKey === "options") { // Kare slotlar için parametreler var slotSize = 280; // Daha büyük slotlar var slotSpacing = 64; // Slotlar arası biraz daha fazla boşluk var slotsPerRow = 3; var slotsPerCol = 1; // Artık sadece 1 satır olacak // Slotların başlık ile kapat tuşu arasında ortalanması ve kapat tuşu ile çakışmaması için Y konumunu ayarla // Kapat tuşu modalın en altında, slotlar başlığın hemen altından başlasın ve slotların altı ile kapat tuşu arasında yeterli boşluk kalsın var slotsTotalWidth = slotsPerRow * slotSize + (slotsPerRow - 1) * slotSpacing; var slotsTotalHeight = slotSize; // Sadece 1 satır var closeBtnH = 100; var closeBtnY = modalH - closeBtnH / 2 - 24; // Slotları modalın ortasına dikeyde ortala, başlık ile kapat tuşu arasında var availableHeight = closeBtnY - (modalTitleText.y + 120) - 40; var slotsStartY = modalTitleText.y + 120 + Math.max(0, (availableHeight - slotsTotalHeight) / 2); // Slotları yatayda tam merkeze hizala var slotsStartX = modalW / 2 - slotsTotalWidth / 2 + slotSize / 2; var slotList = []; for (var row = 0; row < slotsPerCol; row++) { for (var col = 0; col < slotsPerRow; col++) { var slotX = slotsStartX + col * (slotSize + slotSpacing); var slotY = slotsStartY + row * (slotSize + slotSpacing); var slot = LK.getAsset('can', { anchorX: 0.5, anchorY: 0.5, x: slotX, y: slotY, width: slotSize, height: slotSize }); slot.alpha = 0.18; slot.color = 0xB0E0FF; modalContainer.addChild(slot); slotList.push(slot); // 1. slot ise playership görselini ortala ve sığdır if (row === 0 && col === 0) { // Playership assetini tekrar kullanılabilir şekilde oluştur if (!modalContainer._playershipAsset) { var psMargin = 0.07 * slotSize; var psSize = slotSize - 2 * psMargin; var ps = LK.getAsset('playerShip', { anchorX: 0.5, anchorY: 0.5, x: slotX, y: slotY, width: psSize, height: psSize }); ps.alpha = 1; modalContainer._playershipAsset = ps; } else { // Varsa mevcut asseti yeni konuma taşı var ps = modalContainer._playershipAsset; ps.x = slotX; ps.y = slotY; ps.width = slotSize - 2 * (0.07 * slotSize); ps.height = slotSize - 2 * (0.07 * slotSize); ps.alpha = 1; } modalContainer.addChild(ps); } // 2. slot ise playership2 görselini ortala ve sığdır if (row === 0 && col === 1) { // slotSize'ın %86'sı kadar bir kareye sığdır var ps2Margin = 0.07 * slotSize; var ps2Size = slotSize - 2 * ps2Margin; var ps2 = LK.getAsset('playership2', { anchorX: 0.5, anchorY: 0.5, x: slotX, y: slotY, width: ps2Size, height: ps2Size }); ps2.alpha = 1; modalContainer.addChild(ps2); } // 3. slot ise playership3 görselini ortala ve sığdır if (row === 0 && col === 2) { var ps3Margin = 0.07 * slotSize; var ps3Size = slotSize - 2 * ps3Margin; var ps3 = LK.getAsset('playership3', { anchorX: 0.5, anchorY: 0.5, x: slotX, y: slotY, width: ps3Size, height: ps3Size }); ps3.alpha = 1; modalContainer.addChild(ps3); } // Satın Al butonu ekle (her slotun altına) // Fiyat etiketleri: örnek olarak her slot için farklı fiyatlar var slotPrices = [0, 100, 0]; // 1. slot ücretsiz, 2. slot 100 elmas, 3. slot yakında olduğu için fiyat 0 var buyBtnW = 180; var buyBtnH = 90; var buyBtnY = slotY + slotSize / 2 + 44; var priceLabelY = buyBtnY + buyBtnH / 2 + 16; var price = slotPrices[col]; // Fiyat etiketi: Satın al butonunun hemen altına if (row === 0 && col === 2) { // 3. slotun satın al butonu pasif olsun var buyBtn = LK.getAsset('can', { anchorX: 0.5, anchorY: 0.5, x: slotX, y: buyBtnY, width: buyBtnW, height: buyBtnH }); buyBtn.alpha = 0.45; buyBtn.color = 0x888888; buyBtn.interactive = false; // Butonun üstüne "Satın Al" yazısı (gri ve pasif) var buyBtnText = new Text2("Satın Al", { size: 32, fill: "#bbb" }); buyBtnText.anchor.set(0.5, 0.5); buyBtnText.x = buyBtn.x; buyBtnText.y = buyBtn.y; modalContainer.addChild(buyBtnText); // Fiyat etiketi (gri, pasif) var priceText = new Text2("-", { size: 28, fill: "#bbb" }); priceText.anchor.set(0.5, 0); priceText.x = slotX; priceText.y = priceLabelY; modalContainer.addChild(priceText); // 3. slotun altına "Yakında" yazısı ekle var yakindaText = new Text2("Yakında", { size: 32, fill: 0xFFE066 }); yakindaText.anchor.set(0.5, 0); yakindaText.x = slotX; yakindaText.y = priceLabelY + 38; modalContainer.addChild(yakindaText); } else { var buyBtn = LK.getAsset('can', { anchorX: 0.5, anchorY: 0.5, x: slotX, y: buyBtnY, width: buyBtnW, height: buyBtnH }); buyBtn.alpha = 0.92; buyBtn.color = 0x3a9cff; buyBtn.interactive = true; buyBtn.defaultAlpha = buyBtn.alpha; buyBtn.down = function (btnRef, price) { return function (x, y, obj) { btnRef.alpha = 0.65; tween(btnRef, { alpha: btnRef.defaultAlpha }, { duration: 120 }); // Elmas kontrolü: yeterli elmas yoksa satın alma başarısız if (diamondCount < price) { var failText = new Text2("Yetersiz elmas!", { size: 36, fill: 0xf75b5b }); failText.anchor.set(0.5, 0.5); failText.x = btnRef.x; failText.y = btnRef.y - 48; modalContainer.addChild(failText); tween(failText, { alpha: 0 }, { duration: 900, onFinish: function onFinish() { failText.destroy(); } }); return; } // Elmasları harca diamondCount -= price; updateDiamondCounter(); // Satın alındı bildirimi var boughtText = new Text2("Satın alındı!", { size: 36, fill: 0x7CBB37 }); boughtText.anchor.set(0.5, 0.5); boughtText.x = btnRef.x; boughtText.y = btnRef.y - 48; modalContainer.addChild(boughtText); tween(boughtText, { alpha: 0 }, { duration: 900, onFinish: function onFinish() { boughtText.destroy(); } }); // Satın al butonunu kaldır, yerine kullan butonu ekle if (btnRef && btnRef.parent) { var parent = btnRef.parent; var btnX = btnRef.x; var btnY = btnRef.y; var btnW = btnRef.width; var btnH = btnRef.height; // Fiyat etiketini kaldır for (var ci = 0; ci < parent.children.length; ci++) { var child = parent.children[ci]; if (child && child instanceof Text2 && child.text && (child.text.indexOf("+") !== -1 || child.text === price + "")) { child.destroy(); // parent.children.splice(ci, 1); // Gerek yok, destroy yeterli } } // Satın al butonunu kaldır btnRef.destroy(); // "Kullan" butonu ekle var useBtn = LK.getAsset('can', { anchorX: 0.5, anchorY: 0.5, x: btnX, y: btnY, width: btnW, height: btnH }); // Hangi slotun hangi gemiye ait olduğunu belirle var shipName = ""; if (col === 0) { shipName = "playerShip"; } else if (col === 1) { shipName = "playership2"; } else if (col === 2) { shipName = "playership3"; } else { shipName = ""; } // Seçili gemiyle karşılaştır, aktifse butonu pasif yap var isSelected = (game.selectedShipAssetId ? game.selectedShipAssetId : "playerShip") === shipName; if (isSelected) { useBtn.alpha = 0.45; useBtn.color = 0x888888; useBtn.interactive = false; } else { useBtn.alpha = 0.92; useBtn.color = 0x7cbb37; useBtn.interactive = true; useBtn.defaultAlpha = useBtn.alpha; useBtn.down = function (btnRef) { return function (x, y, obj) { btnRef.alpha = 0.65; tween(btnRef, { alpha: btnRef.defaultAlpha }, { duration: 120 }); var usedText = new Text2("Kullanıldı!", { size: 36, fill: 0x3a9cff }); usedText.anchor.set(0.5, 0.5); usedText.x = btnRef.x; usedText.y = btnRef.y - 48; modalContainer.addChild(usedText); tween(usedText, { alpha: 0 }, { duration: 900, onFinish: function onFinish() { usedText.destroy(); } }); // --- Aktif gemiyi değiştir --- // shipName'i kullanarak ilgili gemiyi aktif et var newShipAssetId = shipName && typeof shipName === "string" && shipName.length > 0 ? shipName : "playerShip"; game.selectedShipAssetId = newShipAssetId; // Eski gemiyi yok et if (typeof playerShip !== "undefined" && playerShip && playerShip.parent) { playerShip.destroy(); } // Yeni gemiyi oluştur ve ekle playerShip = new PlayerShip(); // Gemiyi uygun pozisyona yerleştir playerShip.x = 350; playerShip.y = 2732 / 2; game.addChild(playerShip); // Sağlık barı ve diğer göstergeleri güncelle // Seçilen gemiye göre max health güncelle if (game.selectedShipAssetId === "playership2") { playerMaxHealth = 15; } else if (game.selectedShipAssetId === "playership3") { playerMaxHealth = 20; } else { playerMaxHealth = 10; } setPlayerHealth(playerMaxHealth); updateCanBar(); updatePlayershipCanBar(); // Mağaza slotlarındaki tüm "Kullan" butonlarını güncelle (aktif/pasif) if (parent && parent.children) { for (var ci = 0; ci < parent.children.length; ci++) { var child = parent.children[ci]; if (child && child !== btnRef && child.down && typeof child.interactive !== "undefined") { // Sadece diğer "Kullan" butonlarını pasif yap child.alpha = 0.45; child.color = 0x888888; child.interactive = false; } } // Seçilen butonu aktif yap btnRef.alpha = 0.45; btnRef.color = 0x888888; btnRef.interactive = false; } }; }(useBtn); } parent.addChild(useBtn); // "Kullan" butonu yazısı var useBtnLabel = ""; if (shipName === "playerShip") { useBtnLabel = "playership Kullan"; } else if (shipName === "playership2") { useBtnLabel = "playership2 Kullan"; } else if (shipName === "playership3") { useBtnLabel = "playership3 Kullan"; } else { useBtnLabel = "Kullan"; } var useBtnText = new Text2(useBtnLabel, { size: 32, fill: "#fff" }); useBtnText.anchor.set(0.5, 0.5); useBtnText.x = useBtn.x; useBtnText.y = useBtn.y; useBtnText.interactive = !isSelected; useBtnText.down = function (btnRef) { return function (x, y, obj) { if (btnRef && btnRef.down) btnRef.down(x, y, obj); }; }(useBtn); parent.addChild(useBtnText); } }; }(buyBtn, price); modalContainer.addChild(buyBtn); // Butonun üstüne "Satın Al" yazısı var buyBtnText = new Text2("Satın Al", { size: 32, fill: "#fff" }); buyBtnText.anchor.set(0.5, 0.5); buyBtnText.x = buyBtn.x; buyBtnText.y = buyBtn.y; buyBtnText.interactive = true; buyBtnText.down = function (btnRef) { return function (x, y, obj) { if (btnRef && btnRef.down) btnRef.down(x, y, obj); }; }(buyBtn); modalContainer.addChild(buyBtnText); // Fiyat etiketi: Satın al butonunun hemen altına // Fiyat etiketi: sembolü + fiyat var priceText = new Text2("💎 " + price, { size: 38, fill: 0xFFE066 }); priceText.anchor.set(0.5, 0); priceText.x = slotX; priceText.y = priceLabelY + 24; modalContainer.addChild(priceText); } } } } var modalContentText = new Text2(modalContent, { size: 60, fill: "#fff", maxWidth: modalW - 80 // kutu kenarından taşmasın }); modalContentText.anchor.set(0.5, 0); // İçerik, slotların hemen altına gelsin ve slotlarla çakışmasın // Slotların altı ile kapat tuşu arasında yeterli boşluk bırak var contentMinY = slotsStartY + slotsPerCol * slotSize + (slotsPerCol - 1) * slotSpacing + 32; var contentMaxY = closeBtnY - closeBtnH / 2 - 40; modalContentText.y = Math.min(contentMinY, contentMaxY); modalContentText.x = modalW / 2; modalContainer.addChild(modalContentText); // Kapat butonu var closeBtnW = 320; var closeBtnH = 100; // Move close button to the very bottom of the modal var closeBtnY = modalH - closeBtnH / 2 - 24; // Modern gradient effect: use two overlapping containers with different colors and alpha for a faux-gradient var closeBtnBgBase = LK.getAsset('can', { anchorX: 0.5, anchorY: 0.5, x: modalW / 2, y: closeBtnY, width: closeBtnW, height: closeBtnH }); closeBtnBgBase.alpha = 0.95; closeBtnBgBase.color = 0x232a3d; // dark base modalContainer.addChild(closeBtnBgBase); var closeBtnBg = LK.getAsset('can', { anchorX: 0.5, anchorY: 0.5, x: modalW / 2, y: closeBtnY, width: closeBtnW, height: closeBtnH }); closeBtnBg.alpha = 0.92; closeBtnBg.color = 0x3a9cff; // blue overlay closeBtnBg.interactive = true; closeBtnBg.defaultAlpha = closeBtnBg.alpha; closeBtnBg.down = function () { return function (x, y, obj) { // Visual feedback: animate alpha closeBtnBg.alpha = 0.65; tween(closeBtnBg, { alpha: closeBtnBg.defaultAlpha }, { duration: 120 }); if (modalContainer && modalContainer.parent) modalContainer.destroy(); // Modal kapatıldığında ana menüyü tekrar göster if (startMenuContainer && !startMenuContainer.parent) { startMenuContainer.visible = true; game.addChild(startMenuContainer); } }; }(); modalContainer.addChild(closeBtnBg); // Dynamic hover/press highlight (top highlight) var closeBtnHighlight = LK.getAsset('can', { anchorX: 0.5, anchorY: 0.5, x: modalW / 2, y: closeBtnY - closeBtnH * 0.22, width: closeBtnW * 0.92, height: closeBtnH * 0.38 }); closeBtnHighlight.alpha = 0.18; closeBtnHighlight.color = 0xffffff; modalContainer.addChild(closeBtnHighlight); var closeBtnText = new Text2("Kapat", { size: 70, fill: "#fff", font: "'GillSans-Bold', 'Segoe UI', 'Arial', 'Tahoma'" }); closeBtnText.anchor.set(0.5, 0.5); closeBtnText.x = modalW / 2; closeBtnText.y = closeBtnY; closeBtnText.interactive = true; closeBtnText.down = function (bgRef) { return function (x, y, obj) { if (bgRef && bgRef.down) bgRef.down(x, y, obj); }; }(closeBtnBg); modalContainer.addChild(closeBtnText); // Kapat butonu artık ana menüye döndürür closeBtnBg.down = function () { return function (x, y, obj) { if (modalContainer && modalContainer.parent) modalContainer.destroy(); // Modal kapatıldığında ana menüyü tekrar göster if (startMenuContainer) { startMenuContainer.visible = true; if (!startMenuContainer.parent) { game.addChild(startMenuContainer); } } }; }(); // Ortala ve ekrana ekle modalContainer.x = 2048 / 2 - modalW / 2; modalContainer.y = 2732 / 2 - modalH / 2; game.addChild(modalContainer); } }; }(btnBg); btnBgList.push(btnBg); startMenuContainer.addChild(btnBg); // Butonun üstüne hafif bir parlaklık efekti (degrade gibi) var btnHighlight = LK.getAsset('can', { anchorX: 0.5, anchorY: 0.5, x: menuWidth / 2, y: btnY - buttonHeight / 3, width: buttonWidth * 0.92, height: buttonHeight * 0.38 }); btnHighlight.alpha = 0.18; btnHighlight.color = 0xffffff; startMenuContainer.addChild(btnHighlight); var btnText = new Text2(menuButtons[i].label, { size: 100, fill: "#fff", maxWidth: buttonWidth - 60 // buton kenarından taşmasın }); btnText.anchor.set(0.5, 0.5); btnText.x = menuWidth / 2; btnText.y = btnY; btnText.menuKey = menuButtons[i].key; btnText.buttonIndex = i; btnText.interactive = true; btnText.defaultAlpha = 1; btnText.down = function (btnBgRef, btnTextRef) { return function (x, y, obj) { // Text label dokunulduğunda kısa bir görsel geri bildirim uygula btnTextRef.alpha = 0.65; tween(btnTextRef, { alpha: btnTextRef.defaultAlpha }, { duration: 120 }); // Sadece kendi butonunun down fonksiyonunu tetikle if (btnBgRef && btnBgRef.down) { btnBgRef.down(x, y, obj); } }; }(btnBg, btnText); btnTextList.push(btnText); startMenuContainer.addChild(btnText); } // Bilgilendirici kısa açıklama var infoText = new Text2("Gemiyi sürükle, mermilerle uzay cisimlerini vur!", { size: 70, fill: "#fff", maxWidth: menuWidth - 80 // kutu kenarından taşmasın }); infoText.anchor.set(0.5, 0.5); infoText.x = menuWidth / 2; // Kırmızı bölümün altına hizala: kırmızı bölümün altı = startMenuBg.y + startMenuBg.height/2 infoText.y = startMenuBg.y + startMenuBg.height / 2 + 48; startMenuContainer.addChild(infoText); // Alt kısımda küçük bir imza var copyrightText = new Text2("© 2024 FRVR.Ava.Combo[POGAAS]", { size: 38, fill: 0xB0E0FF }); copyrightText.anchor.set(0.5, 0.5); copyrightText.x = menuWidth / 2; copyrightText.y = menuHeight - 32; startMenuContainer.addChild(copyrightText); // Ortala ve ekrana ekle startMenuContainer.x = 2048 / 2 - menuWidth / 2; startMenuContainer.y = 2732 / 2 - menuHeight / 2; // Oyun başında menü ekrana eklenmez, intro bitince eklenir // game.addChild(startMenuContainer); // Oyun başlamadan tüm kontrolleri ve update'i devre dışı bırak var gameStarted = false; // Ava: Dinamik duraklatma menüsü (Devam et, Yeniden başlat, Menü) var pauseMenuContainer = null; function showPauseMenu() { // Pause menu should not be shown in the main menu if (!gameStarted) return; if (pauseMenuContainer && pauseMenuContainer.parent) return; if (pauseMenuContainer) pauseMenuContainer.destroy(); var pauseMenuW = 800; var pauseMenuH = 700; pauseMenuContainer = new Container(); var pauseBg = LK.getAsset('can', { anchorX: 0.5, anchorY: 0.5, x: pauseMenuW / 2, y: pauseMenuH / 2, width: pauseMenuW, height: pauseMenuH }); pauseBg.alpha = 0.0; // Tamamen şeffaf yap pauseBg.color = 0x181c2b; pauseMenuContainer.addChild(pauseBg); var pauseTitle = new Text2("Oyun Duraklatıldı", { size: 110, fill: 0xFFE066 }); pauseTitle.anchor.set(0.5, 0.5); pauseTitle.x = pauseMenuW / 2; pauseTitle.y = 140; pauseMenuContainer.addChild(pauseTitle); // Yeni seçenek menüsü: Oyun duraklatıldığında ekrana gelsin var optionsMenuButtons = [{ label: "Devam et", key: "resume", color: 0x3a9cff }, { label: "Yeniden başlat", key: "restart", color: 0x7cbb37 }, { label: "Menü", key: "menu", color: 0xf7b32b }, { label: "Ses Ayarları", key: "sound", color: 0x4e5d94 }, { label: "Yardım", key: "help", color: 0x9b59b6 }]; var pBtnH = 110; var pBtnW = 420; var pBtnSpacing = 28; var pFirstBtnY = 260; for (var i = 0; i < optionsMenuButtons.length; i++) { var pBtnY = pFirstBtnY + i * (pBtnH + pBtnSpacing); var pBtnBg = LK.getAsset('can', { anchorX: 0.5, anchorY: 0.5, x: pauseMenuW / 2, y: pBtnY, width: pBtnW, height: pBtnH }); pBtnBg.alpha = 0.85; pBtnBg.color = optionsMenuButtons[i].color; pBtnBg.pauseKey = optionsMenuButtons[i].key; pBtnBg.defaultAlpha = pBtnBg.alpha; pBtnBg.interactive = true; pBtnBg.down = function (btn) { return function (x, y, obj) { btn.alpha = 0.65; tween(btn, { alpha: btn.defaultAlpha }, { duration: 120 }); if (btn.pauseKey === "resume") { // Devam et: menüyü kapat, oyuna devam et if (pauseMenuContainer && pauseMenuContainer.parent) pauseMenuContainer.destroy(); gameStarted = true; } else if (btn.pauseKey === "restart") { // Yeniden başlat: oyunu baştan başlat LK.restartGame(); } else if (btn.pauseKey === "menu") { // Menü: ana menüyü göster, pause menüsünü kapat if (pauseMenuContainer && pauseMenuContainer.parent) pauseMenuContainer.destroy(); showMenu(); } else if (btn.pauseKey === "sound") { // Ses ayarları: yeni bir modal aç var modalW = 700; var modalH = 400; var modalContainer = new Container(); var modalBg = LK.getAsset('can', { anchorX: 0.5, anchorY: 0.5, x: modalW / 2, y: modalH / 2, width: modalW, height: modalH }); modalBg.alpha = 0.0; // Tamamen şeffaf yap modalBg.color = 0x181c2b; modalContainer.addChild(modalBg); var modalTitle = new Text2("Ses Ayarları", { size: 80, fill: 0xFFE066, maxWidth: modalW - 60 }); modalTitle.anchor.set(0.5, 0.5); modalTitle.x = modalW / 2; modalTitle.y = 80; modalContainer.addChild(modalTitle); var modalContent = new Text2("Ses ayarları burada olacak.", { size: 50, fill: "#fff", maxWidth: modalW - 60 }); modalContent.anchor.set(0.5, 0); modalContent.x = modalW / 2; modalContent.y = 160; modalContainer.addChild(modalContent); // Kapat butonu var closeBtnW = 220; var closeBtnH = 80; var closeBtnY = modalH - 80; var closeBtnBg = LK.getAsset('can', { anchorX: 0.5, anchorY: 0.5, x: modalW / 2, y: closeBtnY, width: closeBtnW, height: closeBtnH }); closeBtnBg.alpha = 0.85; closeBtnBg.color = 0x3a9cff; closeBtnBg.interactive = true; closeBtnBg.down = function () { return function (x, y, obj) { if (modalContainer && modalContainer.parent) modalContainer.destroy(); }; }(); modalContainer.addChild(closeBtnBg); var closeBtnText = new Text2("Kapat", { size: 60, fill: "#fff", font: "'GillSans-Bold', 'Segoe UI', 'Arial', 'Tahoma'" // Modern font stack }); closeBtnText.anchor.set(0.5, 0.5); closeBtnText.x = modalW / 2; closeBtnText.y = closeBtnY; closeBtnText.interactive = true; closeBtnText.down = function (bgRef) { return function (x, y, obj) { if (bgRef && bgRef.down) bgRef.down(x, y, obj); }; }(closeBtnBg); modalContainer.addChild(closeBtnText); // Ortala ve ekrana ekle modalContainer.x = 2048 / 2 - modalW / 2; modalContainer.y = 2732 / 2 - modalH / 2; game.addChild(modalContainer); } else if (btn.pauseKey === "help") { // Yardım: yeni bir modal aç var modalW = 700; var modalH = 400; var modalContainer = new Container(); var modalBg = LK.getAsset('can', { anchorX: 0.5, anchorY: 0.5, x: modalW / 2, y: modalH / 2, width: modalW, height: modalH }); modalBg.alpha = 0.0; // Tamamen şeffaf yap modalBg.color = 0x181c2b; modalContainer.addChild(modalBg); var modalTitle = new Text2("Yardım", { size: 80, fill: 0xFFE066, maxWidth: modalW - 60 }); modalTitle.anchor.set(0.5, 0.5); modalTitle.x = modalW / 2; modalTitle.y = 80; modalContainer.addChild(modalTitle); var modalContent = new Text2("Gemiyi sürükle, mermilerle uzay cisimlerini vur!", { size: 50, fill: "#fff", maxWidth: modalW - 60 }); modalContent.anchor.set(0.5, 0); modalContent.x = modalW / 2; modalContent.y = 160; modalContainer.addChild(modalContent); // Kapat butonu var closeBtnW = 220; var closeBtnH = 80; var closeBtnY = modalH - 80; var closeBtnBg = LK.getAsset('can', { anchorX: 0.5, anchorY: 0.5, x: modalW / 2, y: closeBtnY, width: closeBtnW, height: closeBtnH }); closeBtnBg.alpha = 0.85; closeBtnBg.color = 0x3a9cff; closeBtnBg.interactive = true; closeBtnBg.down = function () { return function (x, y, obj) { if (modalContainer && modalContainer.parent) modalContainer.destroy(); }; }(); modalContainer.addChild(closeBtnBg); var closeBtnText = new Text2("Kapat", { size: 60, fill: "#fff", font: "'GillSans-Bold', 'Segoe UI', 'Arial', 'Tahoma'" // Modern font stack }); closeBtnText.anchor.set(0.5, 0.5); closeBtnText.x = modalW / 2; closeBtnText.y = closeBtnY; closeBtnText.interactive = true; closeBtnText.down = function (bgRef) { return function (x, y, obj) { if (bgRef && bgRef.down) bgRef.down(x, y, obj); }; }(closeBtnBg); modalContainer.addChild(closeBtnText); // Ortala ve ekrana ekle modalContainer.x = 2048 / 2 - modalW / 2; modalContainer.y = 2732 / 2 - modalH / 2; game.addChild(modalContainer); } }; }(pBtnBg); pauseMenuContainer.addChild(pBtnBg); var pBtnText = new Text2(optionsMenuButtons[i].label, { size: 80, fill: "#fff", maxWidth: pBtnW - 40 // buton kenarından taşmasın }); pBtnText.anchor.set(0.5, 0.5); pBtnText.x = pauseMenuW / 2; pBtnText.y = pBtnY; pBtnText.interactive = true; pBtnText.defaultAlpha = 1; pBtnText.down = function (btnBgRef, btnTextRef) { return function (x, y, obj) { btnTextRef.alpha = 0.65; tween(btnTextRef, { alpha: btnTextRef.defaultAlpha }, { duration: 120 }); if (btnBgRef && btnBgRef.down) btnBgRef.down(x, y, obj); }; }(pBtnBg, pBtnText); pauseMenuContainer.addChild(pBtnText); } // Ortala ve ekrana ekle pauseMenuContainer.x = 2048 / 2 - pauseMenuW / 2; pauseMenuContainer.y = 2732 / 2 - pauseMenuH / 2; game.addChild(pauseMenuContainer); gameStarted = false; } // Ava: Menü oyun durduğunda tekrar gösterilsin function showMenu() { if (!startMenuContainer.parent) { startMenuContainer.alpha = 1; startMenuContainer.scaleX = 1; startMenuContainer.scaleY = 1; game.addChild(startMenuContainer); } // Oyun yeniden başlatıldığında süreyi 3 dakikaya (180 saniye) sıfırla timeLeft = gameDuration; updateTimerDisplay(); gameStarted = false; // Boss diamond resetle if (typeof bossDiamondObj !== "undefined" && bossDiamondObj) { bossDiamondObj.destroy(); bossDiamondObj = null; } if (typeof game.bossDiamondSpawned !== "undefined") { game.bossDiamondSpawned = false; } } // Ava: Oyun durdurulduğunda dinamik pause menüsünü göster game.onPause = function () { showPauseMenu(); }; // Ava: Oyun başlatıldığında menüyü gizle (mevcut animasyonlu kod korunuyor) // (Yukarıdaki "start" butonunun down fonksiyonu zaten menüyü yok ediyor ve gameStarted=true yapıyor.) // Sağlık, skor ve zaman göstergeleri her zaman görünür (oyun başlamadan önce de) // Bu kod bloğu kaldırıldı, göstergeler her zaman görünür olacak // Her butonun kendi down fonksiyonu var, menü container'ı routing yapmaz. // Tüm ekrana tıklama ile başlatma özelliği kaldırıldı, sadece butonlar bağımsız çalışır. // Power-up türleri ve süreleri var powerUpTypes = [{ type: "rapidfire", label: "Ateş Hızı", color: 0x3a9cff, duration: 600 }, // 10 sn { type: "shield", label: "Kalkan", color: 0x7cbb37, duration: 480 }, // 8 sn { type: "scorex2", label: "2x Skor", color: 0xf7b32b, duration: 600 }, // 10 sn { type: "speedup", label: "Hız", color: 0xd729b6, duration: 480 } // 8 sn ]; var activePowerUp = null; var powerUpEndTick = 0; var powerUpIcon = null; var giftBg = null; var giftSpawnCooldown = 900; // gift nadiren spawn olsun (900 tick ~15 saniye) var lastGiftSpawnTick = -10000; // ilk başta hemen spawn olmasın function spawnGift() { if (giftBg) return; // gift zaten varsa tekrar oluşturma // 3 farklı gift: shield, health, bulletspeed var powerUpOptions = [{ type: "shield", // Kalkan label: "Kalkan", color: 0x7cbb37, assetId: "gift" // Kalkan için gift görseli }, { type: "health", // Can label: "Can", color: 0xf75b5b, assetId: "healthgift" }, { type: "bulletspeed", // Mermi hızlandırma label: "Mermi Hızı", color: 0x3a9cff, assetId: "mermispeedgift" }]; // Rastgele birini seç var pType = powerUpOptions[Math.floor(Math.random() * powerUpOptions.length)]; var assetId = pType.assetId; giftBg = LK.getAsset(assetId, { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2 + 600, y: 2732 / 2 - 400, width: 120, height: 120 }); giftBg.alpha = 0.95; giftBg.powerUpType = pType.type; giftBg.powerUpColor = pType.color; giftBg.interactive = true; // Hareket için rastgele hızlar belirle giftBg.vx = -4 - Math.random() * 3; // sola doğru hareket giftBg.vy = (Math.random() - 0.5) * 2.5; // hafif yukarı/aşağı // Parlaklık efekti tween(giftBg, { alpha: 0.7 }, { duration: 400, yoyo: true, repeat: 9999 }); // Dokunma/çarpışma ile alınabilir ve hareketli giftBg.update = function () { // Hareket giftBg.x += giftBg.vx; giftBg.y += giftBg.vy; // Ekran dışına çıkarsa yok et if (giftBg.x < -150 || giftBg.x > 2048 + 150 || giftBg.y < -150 || giftBg.y > 2732 + 150) { giftBg.destroy(); giftBg = null; return; } // Oyuncu ile çarpışma if (playerShip && isCircleHit(giftBg, playerShip)) { // Elmas artık gift ile değil, sadece çok nadir çıkan özel bir diamond objesiyle kazanılır // Gift yakalandığında elmas verilmez, sadece power-up veya can verir if (giftBg.powerUpType === "health") { // Can hediyesi: canı artır var healAmount = 2; // Artık can hediyesi 2 can veriyor setPlayerHealth(playerHealth + healAmount); } else if (giftBg.powerUpType === "shield") { // Kalkan power-up'ı uygula activatePowerUp("shield"); } else if (giftBg.powerUpType === "bulletspeed") { // Mermi hızlandırma power-up'ı uygula activatePowerUp("bulletspeed"); } // Efekt: patlama var effect = LK.getAsset('patlamaeffekt', { anchorX: 0.5, anchorY: 0.5, x: giftBg.x, y: giftBg.y, width: 120, height: 120 }); effect.alpha = 0.7; game.addChild(effect); tween(effect, { alpha: 0, scaleX: 2, scaleY: 2 }, { duration: 400, onFinish: function onFinish() { effect.destroy(); } }); giftBg.destroy(); giftBg = null; } // --- Nadiren çıkan diamond objesiyle elmas kazanma sistemi --- // Diamond objesi oyunda görünmesin, sadece bossDiamondObj ile elmas verilsin if (diamondObj) { diamondObj.destroy(); diamondObj = null; } }; game.addChild(giftBg); lastGiftSpawnTick = LK.ticks; } function activatePowerUp(type) { // Önceki power-up'ı sıfırla if (activePowerUp && powerUpIcon) { powerUpIcon.destroy(); powerUpIcon = null; } activePowerUp = type; var pType = powerUpTypes.filter(function (p) { return p.type === type; })[0]; powerUpEndTick = LK.ticks + (pType ? pType.duration : 600); // Power-up ikonunu ekle powerUpIcon = LK.getAsset('can', { anchorX: 0, anchorY: 0.5, x: 0, y: 100, width: 120, height: 120 }); powerUpIcon.alpha = 0.92; powerUpIcon.color = pType ? pType.color : 0xffffff; LK.gui.topLeft.addChild(powerUpIcon); // Üzerine metin var txt = new Text2(pType ? pType.label : "Power", { size: 38, fill: "#fff" }); txt.anchor.set(0.5, 0.5); txt.x = 60; txt.y = 60; powerUpIcon.addChild(txt); // Efekt: kısa parlama tween(powerUpIcon, { alpha: 1 }, { duration: 120, yoyo: true, repeat: 1 }); // Power-up efektini uygula if (type === "rapidfire") { shootInterval = 80; // Süper hızlı ateş } else if (type === "shield") { // Kalkan: bir sonraki hasarı engelle playerShip._shielded = true; // Görsel: geminin etrafında halka if (!playerShip._shieldCircle) { // Shield asset boyutunu playership'in etrafını tam sarmalayacak şekilde ayarla // PlayerShip'in en büyük boyutunu baz al (ellipse ise genişlik/yükseklik farklı olabilir) var maxDim = Math.max(playerShip.width, playerShip.height); var shieldMargin = 18; // Gemi ile kalkan arasında küçük bir boşluk bırak var shield = LK.getAsset('shield', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 0, width: maxDim + shieldMargin * 2, height: maxDim + shieldMargin * 2 }); // Shield'ı tam olarak playership'in merkezine ortala shield.x = 0; shield.y = 0; shield.alpha = 0.7; // Kalkanı tam olarak geminin merkezine hizala (anchor 0.5,0.5 ile tam ortalanır) playerShip.addChild(shield); playerShip._shieldCircle = shield; } } else if (type === "scorex2") { // Skor çarpanı game._scoreMultiplier = 2; } else if (type === "speedup") { // Geminin hızı artsın (daha hızlı sürüklenebilsin) playerShip._speedUp = true; } else if (type === "bulletspeed") { // Mermi hızı power-up: yeni mermiler daha hızlı gitsin game._bulletSpeedUp = true; // Ateş sıklığını da artır (daha hızlı ateş et) shootInterval = 120; // Normalde 250, burada daha hızlı (daha düşük değer = daha sık ateş) // Aktifken yeni mermiler hızlı olacak, Bullet sınıfı zaten bu flag'i kontrol ediyor game._multiBullet = 3; // 3 mermi birden ateşle } } function deactivatePowerUp() { if (!activePowerUp) return; // Efektleri sıfırla if (activePowerUp === "rapidfire") { shootInterval = 250; } else if (activePowerUp === "shield") { playerShip._shielded = false; if (playerShip._shieldCircle) { playerShip._shieldCircle.destroy(); playerShip._shieldCircle = null; } // Kalkan kaybolduğunda üstteki kalkan yazısı da kaybolsun if (powerUpIcon) { powerUpIcon.destroy(); powerUpIcon = null; } } else if (activePowerUp === "scorex2") { game._scoreMultiplier = 1; } else if (activePowerUp === "speedup") { playerShip._speedUp = false; } else if (activePowerUp === "bulletspeed") { game._bulletSpeedUp = false; // Artık yeni mermiler normal hızda olacak shootInterval = 250; // Ateş sıklığını normale döndür game._multiBullet = 1; // Tek mermiye dön } if (activePowerUp !== "shield" && powerUpIcon) { powerUpIcon.destroy(); powerUpIcon = null; } activePowerUp = null; powerUpEndTick = 0; } // Oyun değişkenleri var playerShip = new PlayerShip(); // Oyuncu gemisi sol alt köşeden sağa hareket edecek şekilde konumlandırılır playerShip.x = 350; playerShip.y = 2732 / 2; game.addChild(playerShip); // Oyuncu gemisinin maksimum ve başlangıç sağlığı oyuna uygun şekilde ayarlandı var playerMaxHealth = 10; // Başlangıçta 10 can if (typeof game !== "undefined" && game.selectedShipAssetId === "playership2") { playerMaxHealth = 15; // playership2 için sağlık 15 olsun } else if (typeof game !== "undefined" && game.selectedShipAssetId === "playership3") { playerMaxHealth = 20; // playership3 için sağlık 20 olsun } var playerHealth = playerMaxHealth; // Sağlık değerini güvenli şekilde ayarlayan fonksiyon function setPlayerHealth(newHealth) { playerHealth = Math.max(0, Math.min(playerMaxHealth, newHealth)); updateCanBar(); updatePlayershipCanBar(); } var bullets = []; var spaceObjects = []; var canShoot = true; var shootInterval = 250; // ms var lastShootTick = 0; game._multiBullet = 1; // Başlangıçta tek mermi var score = 0; var difficulty = 2; // Başlangıç zorluğu 2 olsun var spawnInterval = 80; // ticks, daha hızlı başlasın var lastSpawnTick = 0; shootInterval = 180; // daha hızlı başlasın, updateDifficulty ile güncellenecek // Bölüm bitişi için toplam düşman sayacı ve kontrol değişkeni var totalEnemiesSpawned = 0; var levelFinished = false; // --- High Scores (Top 5) --- var highScores = storage.highScores && Array.isArray(storage.highScores) ? storage.highScores.slice() : []; function saveHighScores() { storage.highScores = highScores.slice(0, 5); } function addHighScore(newScore) { highScores.push(newScore); highScores.sort(function (a, b) { return b - a; }); if (highScores.length > 5) highScores.length = 5; saveHighScores(); } function getHighScores() { return highScores.slice(0, 5); } // --- PLAYERSHIP CAN BAR (HEALTH BAR) --- // Health bar dimensions // Sağlık barı genişliği ve yüksekliği yeni maksimum sağlığa uygun şekilde ayarlandı var playershipCanBarWidth = 320; // Daha kısa bar, 6 can için uygun var playershipCanBarHeight = 38; // Background bar var playershipCanBarBg = new Container(); var playershipCanBarBgRect = playershipCanBarBg.attachAsset('can', { anchorX: 0, anchorY: 0.5, x: 0, y: playershipCanBarHeight / 2, width: playershipCanBarWidth, height: playershipCanBarHeight }); playershipCanBarBgRect.alpha = 0.25; // Foreground bar var playershipCanBarFg = new Container(); var playershipCanBarFgRect = playershipCanBarFg.attachAsset('can', { anchorX: 0, anchorY: 0.5, x: 0, y: playershipCanBarHeight / 2, width: playershipCanBarWidth, height: playershipCanBarHeight }); playershipCanBarFgRect.alpha = 1; // Health bar container for positioning var playershipCanBarContainer = new Container(); playershipCanBarContainer.addChild(playershipCanBarBg); playershipCanBarContainer.addChild(playershipCanBarFg); // Position: top left, but not overlapping menu (leave 100px left and top margin) playershipCanBarContainer.x = 20; playershipCanBarContainer.y = 20; // Move to top left, just below top margin LK.gui.topLeft.addChild(playershipCanBarContainer); playershipCanBarContainer.visible = true; // Her zaman görünür // Animate health bar width and color function updatePlayershipCanBar() { // Yeni maksimum sağlığa göre oran var targetWidth = playershipCanBarWidth * Math.max(0, playerHealth) / playerMaxHealth; // Animate width using tween tween(playershipCanBarFgRect, { width: targetWidth }, { duration: 300 }); // Calculate color: green (full) to red (empty) // 0x00FF00 (green) to 0xFF0000 (red) var healthRatio = Math.max(0, Math.min(1, playerHealth / playerMaxHealth)); var r = Math.round(0xFF * (1 - healthRatio)); var g = Math.round(0xFF * healthRatio); var b = 0; var color = r << 16 | g << 8 | b; // Animate color using tween tween(playershipCanBarFgRect, { color: color }, { duration: 300 }); } updatePlayershipCanBar(); updateDifficulty(); // Oyun başında kolay zorluk ayarı uygula // --- Only one health bar is visible (playershipCanBar) --- // Animate health bar width and color function updateCanBar() { // Forward to playershipCanBar update for compatibility updatePlayershipCanBar(); } updateCanBar(); // Skor gösterimi var scoreTxt = new Text2('0', { size: 120, fill: "#fff" }); scoreTxt.anchor.set(0.5, 0); // --- Elmas sayacı --- // Elmas sayısı için global değişken (storage'dan yükle, yoksa 0) var diamondCount = 0; // Elmas simgesi ve sayaç için container var diamondCounterContainer = new Container(); // Elmas simgesi (diamond asset'i ile) var diamondIcon = LK.getAsset('diamond', { anchorX: 0, anchorY: 0.5, x: 0, y: 60, width: 80, height: 80 }); diamondIcon.alpha = 0.95; diamondCounterContainer.addChild(diamondIcon); // Elmas sayısı metni var diamondTxt = new Text2('0', { size: 60, fill: "#fff" }); diamondTxt.anchor.set(0, 0.5); diamondTxt.x = diamondIcon.x + diamondIcon.width + 18; diamondTxt.y = 60; diamondCounterContainer.addChild(diamondTxt); // Elmas sayacını güncelleyen fonksiyon function updateDiamondCounter() { diamondTxt.setText(diamondCount + ""); // Elmas sayısını storage'a kaydet storage.diamondCount = diamondCount; } updateDiamondCounter(); // Skor ve elmas sayaçlarını yan yana göstermek için ortak bir container oluştur var scoreDiamondContainer = new Container(); scoreDiamondContainer.addChild(scoreTxt); // Elmas sayacını skorun sağına hizala diamondCounterContainer.x = scoreTxt.width / 2 + 32; // skorun sağında 32px boşluk diamondCounterContainer.y = 0; scoreDiamondContainer.addChild(diamondCounterContainer); // Ortak container'ı GUI'de üstte ortala scoreDiamondContainer.x = 0; scoreDiamondContainer.y = 0; LK.gui.top.addChild(scoreDiamondContainer); scoreTxt.visible = true; // Her zaman görünür // Ava: Skor panelinin kaybolmasını engellemek için her frame tekrar ekle if (!game._scoreDiamondContainerCheckAdded) { game._scoreDiamondContainerCheckAdded = true; game.updateScoreDiamondContainerVisibility = function () { if (!scoreDiamondContainer.parent) { LK.gui.top.addChild(scoreDiamondContainer); } scoreDiamondContainer.visible = true; scoreTxt.visible = true; diamondCounterContainer.visible = true; }; // Her frame kontrol et var _scoreDiamondContainerInterval = LK.setInterval(function () { if (typeof game.updateScoreDiamondContainerVisibility === "function") { game.updateScoreDiamondContainerVisibility(); } }, 200); } // Süre göstergesi (3 dakika = 180 saniye) var gameDuration = 180; // saniye var timeLeft = gameDuration; var timerTxt = new Text2('03:00', { size: 100, fill: "#fff" }); timerTxt.anchor.set(1, 0); // Anchor right edge LK.gui.topRight.addChild(timerTxt); // Add to right side of GUI timerTxt.visible = true; // Her zaman görünür // Timer'ı güncelleyen fonksiyon function updateTimerDisplay() { var min = Math.floor(timeLeft / 60); var sec = Math.floor(timeLeft % 60); var minStr = min < 10 ? "0" + min : "" + min; var secStr = sec < 10 ? "0" + sec : "" + sec; timerTxt.setText(minStr + ":" + secStr); } updateTimerDisplay(); // Her saniye zaman azaltıcı timer var timerInterval = LK.setInterval(function () { if (!gameStarted) return; if (levelFinished) return; if (timeLeft > 0) { timeLeft -= 1; if (timeLeft < 0) timeLeft = 0; updateTimerDisplay(); // Zaman bittiğinde oyunu otomatik olarak yeniden başlat if (timeLeft === 0) { LK.restartGame(); } } }, 1000); // Animate health bar width and color updateCanBar(); // Dokunma/sürükleme ile gemi hareketi var dragging = false; function handleMove(x, y, obj) { if (!gameStarted) return; if (dragging) { // Portal büyüme animasyonu sırasında oyuncu hareket etmesin, ancak büyüme bittiyse tekrar izin ver var portalGrowing = false; if (game.portal && !game.portal.isShrinking) { // Portal büyüme animasyonu devam ediyor mu? // 1.2'den 3.0'a büyüme: scaleX < 3.0 ise büyüme devam ediyor if (typeof game.portal._growTweenStarted !== "undefined" && game.portal._growTweenStarted && game.portal.scaleX < 3.0 - 0.01) { portalGrowing = true; } } if (portalGrowing) { return; } // Sınırları aşmasın - boss sonrası üst/alt bar varsa daraltılmış alanda hareket var minX = playerShip.width / 2 + 40; var maxX = 2048 - playerShip.width / 2 - 40; var minY, maxY; if (game._screenNarrowed && typeof game._playAreaTop !== "undefined" && typeof game._playAreaBottom !== "undefined") { minY = game._playAreaTop + playerShip.height / 2 + 20; maxY = game._playAreaBottom - playerShip.height / 2 - 20; } else { minY = playerShip.height / 2 + 40; maxY = 2732 - playerShip.height / 2 - 40; } // Sadece sürükleme sırasında, gemi mouse/touch ile birlikte hareket eder if (activePowerUp === "speedup") { // Hız power-up'ı: gemi daha hızlı hareket etsin (pozisyona yaklaşma) playerShip.x += (Math.max(minX, Math.min(maxX, x)) - playerShip.x) * 0.45; playerShip.y += (Math.max(minY, Math.min(maxY, y)) - playerShip.y) * 0.45; } else { playerShip.x = Math.max(minX, Math.min(maxX, x)); playerShip.y = Math.max(minY, Math.min(maxY, y)); } } } game.move = handleMove; game.down = function (x, y, obj) { // Sadece geminin üstüne tıklanırsa sürükleme başlasın if (!gameStarted) return; var dx = x - playerShip.x; var dy = y - playerShip.y; var r = playerShip.radius || (playerShip.width ? playerShip.width / 2 : 70); // Portal büyüme animasyonu devam ediyorsa sürükleme başlatılamasın var portalGrowing = false; if (game.portal && !game.portal.isShrinking) { if (!game.portal._growTweenStarted || game.portal.scaleX < 1.8 - 0.01) { portalGrowing = true; } } if (portalGrowing) { dragging = false; return; } if (dx * dx + dy * dy <= r * r) { dragging = true; handleMove(x, y, obj); } else { dragging = false; } }; game.up = function (x, y, obj) { if (!gameStarted) return; dragging = false; }; // Otomatik ateş (her shootInterval ms'de bir) function tryShoot() { if (!canShoot) return; var multi = typeof game._multiBullet !== "undefined" ? game._multiBullet : 1; var spread = 38; // mermiler arası dikey mesafe for (var i = 0; i < multi; i++) { var bullet = new Bullet(); bullet.x = playerShip.x + playerShip.width / 2 + 10; // Ortadaki mermi tam ortada, diğerleri yukarı ve aşağıya kaydırılır bullet.y = playerShip.y + (i - (multi - 1) / 2) * spread; bullets.push(bullet); game.addChild(bullet); } canShoot = false; LK.setTimeout(function () { canShoot = true; }, shootInterval); } // Uzay cismi oluştur function spawnSpaceObject() { // 0: uzayNesnesi2 (enemy), 1: spaceObject (asteroid), 2: meteorstone (yeni düşman) // Düşman gemilerinin sıklığını artırmak için oranı yükselttik var rand = Math.random(); var obj; // enemyship2 sadece zorluk 4 ve üstünde görünsün if (rand < 0.6 && difficulty >= 4 && typeof game.enemiesKilled !== "undefined" && game.enemiesKilled >= 20) { // Only allow one enemyship2 on screen at a time (use ._isEnemyship2 flag for reliability) var hasEnemyship2 = false; for (var i = 0; i < spaceObjects.length; i++) { var so = spaceObjects[i]; if (so && so._isEnemyship2) { hasEnemyship2 = true; break; } } if (hasEnemyship2) { // Do not spawn another enemyship2 return; } // enemyship2 (yeni düşman tipi) obj = new Container(); obj._isEnemyship2 = true; // Reliable type flag for enemyship2 obj.health = 20; // enemyship2 canı 20 olarak başlatıldı var width = 300; var height = 300; var objAsset = obj.attachAsset('enemyship2', { anchorX: 0.5, anchorY: 0.5 }); objAsset.width = width; objAsset.height = height; objAsset.color = 0xff4444; obj.radius = width / 2; obj.x = 2048 + width; obj.y = 200 + Math.random() * (2732 - 400); // Düşman hızı: kolayda yavaş, zorda hızlı var baseSpeed = 4 + (difficulty - 4) * 0.8; var speed = baseSpeed + Math.random() * (2.0 + difficulty * 0.3); obj.vx = -speed; obj.vy = (Math.random() - 0.5) * (3.5 + difficulty * 0.3); // --- EN AZ 10 SANİYE EKRANDA KALMA --- // enemyship2 ekranda kalma süresi (tick cinsinden) obj._minScreenTicks = 600; // 10 saniye (60fps) // enemyship2'nin ekranda kalmaya başladığı tick obj._spawnTick = LK.ticks; // enemyship2 yok edilebilir mi? (başta false, 10sn sonra true) obj._canBeDestroyed = false; // --- RANDOM SALDIRI MEKANİĞİ --- // Rastgele saldırı için bir sonraki saldırı tick'i obj._nextRandomAttackTick = LK.ticks + 60 + Math.floor(Math.random() * 120); // 1-3 sn arası ilk saldırı // Enemy bullet fire timer obj.enemyBulletCooldown = 7 + Math.floor(Math.random() * 7); // DAHA DA SIK ateş (daha seri) obj.lastEnemyBulletTick = LK.ticks; // --- LAZER IŞINI: enemyship2 özel saldırısı --- // Lazer ışını için state ve timerlar obj.laserCooldown = 240 + Math.floor(Math.random() * 120); // 4-6 saniyede bir obj.lastLaserTick = LK.ticks; obj.laserActive = false; obj.laserDuration = 60; // lazer açık kalma süresi (1 saniye) obj.laserBeam = null; // Lazer ateşleme etkin: enemyship2 için lazer saldırısı aktif // --- YAPAY ZEKA: Oyuncuya yaklaşma ve akıllı ateş etme --- obj.update = function () { // Akıllı hareket: oyuncuya doğru yavaşça yönel if (playerShip && typeof playerShip.x !== "undefined" && typeof playerShip.y !== "undefined") { var dx = playerShip.x - obj.x; var dy = playerShip.y - obj.y; var dist = Math.sqrt(dx * dx + dy * dy); // X ekseninde oyuncuya yaklaşmak için vx'yi ayarla var targetVx = -Math.max(3, Math.min(12, Math.abs(dx) / 30)); if (obj.x > playerShip.x) { obj.vx += (targetVx - obj.vx) * 0.10; } // Y ekseninde oyuncuya yaklaşmak için vy'yi ayarla var targetVy = 0; if (dist > 1) { targetVy = dy / Math.max(60, Math.abs(dx)); if (targetVy > 6) targetVy = 6; if (targetVy < -6) targetVy = -6; } obj.vy += (targetVy - obj.vy) * 0.15; } obj.x += obj.vx; obj.y += obj.vy; // --- EKRANA GİRİNCE ATEŞ ETME BAŞLASIN --- // Ekrana ilk kez girdiği anı tespit et if (typeof obj._hasStartedFiring === "undefined") obj._hasStartedFiring = false; if (!obj._hasStartedFiring && obj.x <= 2048) { obj._hasStartedFiring = true; // İlk ateş için timerları hemen başlat obj.lastEnemyBulletTick = LK.ticks; if (typeof obj._nextRandomAttackTick !== "undefined") { obj._nextRandomAttackTick = LK.ticks + 10 + Math.floor(Math.random() * 30); // Hemen random saldırı başlat } if (typeof obj.laserStartTick !== "undefined") { obj.laserStartTick = LK.ticks; } } // --- EN AZ 10 SANİYE EKRANDA KALMA KONTROLÜ --- if (!obj._canBeDestroyed && LK.ticks - obj._spawnTick >= obj._minScreenTicks) { obj._canBeDestroyed = true; } // --- RANDOM SALDIRI MEKANİĞİ --- // 10 saniye dolduysa random saldırı yapabilir if (LK.ticks - obj._spawnTick >= obj._minScreenTicks && LK.ticks >= obj._nextRandomAttackTick) { // Saldırı türünü rastgele seç: 0=normal mermi, 1=lazer, 2=çift mermi, 3=ani hızlanma var attackType = Math.floor(Math.random() * 4); if (attackType === 0) { // Normal mermi ateşi (hedefli) var eb = new EnemyBullet(); eb.x = obj.x - 60; eb.y = obj.y; if (!game.enemyBullets) game.enemyBullets = []; game.enemyBullets.push(eb); game.addChild(eb); } else if (attackType === 1 && !obj.laserActive) { // Lazer saldırısı başlat (lazer zaten aktif değilse) obj.laserActive = true; obj.laserStartTick = LK.ticks; var laserLength = obj.x - 0; var laserWidth = 38 + Math.random() * 18; var laserY = obj.y; obj.laserBeam = LK.getAsset('lazer', { anchorX: 1.0, anchorY: 0.5, x: obj.x - width / 2 - 10, y: laserY, width: laserLength, height: laserWidth }); obj.laserBeam.alpha = 0.38 + Math.random() * 0.18; obj.laserBeam.laserOwner = obj; obj.laserBeam._baseY = laserY; obj.laserBeam._baseWidth = laserWidth; obj.laserBeam.update = function () { if (!obj.laserActive) return; obj.laserBeam.y = obj.y; obj.laserBeam.width = obj.x - 0; obj.laserBeam.height = obj.laserBeam._baseWidth + Math.sin(LK.ticks / 2) * 8; obj.laserBeam.alpha = 0.38 + Math.abs(Math.sin(LK.ticks / 8)) * 0.22; }; game.addChild(obj.laserBeam); } else if (attackType === 2) { // Çift mermi ateşi (yukarı ve aşağı) for (var i = -1; i <= 1; i += 2) { var eb2 = new EnemyBullet(); eb2.x = obj.x - 60; eb2.y = obj.y + i * 60; if (!game.enemyBullets) game.enemyBullets = []; game.enemyBullets.push(eb2); game.addChild(eb2); } } else if (attackType === 3) { // Ani hızlanma (kısa süre için vx artır) obj.vx -= 6 + Math.random() * 4; } // Bir sonraki random saldırı için tick ayarla (her seferinde 1-3 sn arası) obj._nextRandomAttackTick = LK.ticks + 60 + Math.floor(Math.random() * 120); } // --- LAZER IŞINI AKTİVASYONU --- // Lazer aktif değilse ve cooldown dolduysa lazeri başlat if (!obj.laserActive && LK.ticks - obj.lastLaserTick > obj.laserCooldown) { obj.laserActive = true; obj.laserStartTick = LK.ticks; // Lazer ışını görseli: lazer image asset'i ile (kırmızı, şeffaf) var laserLength = obj.x - 0; // Ekranın soluna kadar var laserWidth = 38 + Math.random() * 18; // 38-56px arası var laserY = obj.y; obj.laserBeam = LK.getAsset('lazer', { anchorX: 1.0, anchorY: 0.5, x: obj.x - width / 2 - 10, y: laserY, width: laserLength, height: laserWidth }); obj.laserBeam.alpha = 0.38 + Math.random() * 0.18; obj.laserBeam.laserOwner = obj; // Hafif titreme efekti için orijinal y ve width kaydet obj.laserBeam._baseY = laserY; obj.laserBeam._baseWidth = laserWidth; // Lazer update fonksiyonu: objenin y'sini takip etsin, titreme efekti obj.laserBeam.update = function () { if (!obj.laserActive) return; // Lazerin y'si enemyship2'nin y'sini takip etsin obj.laserBeam.y = obj.y; // Lazerin uzunluğu obj.x'den ekrandaki en sol noktaya kadar obj.laserBeam.width = obj.x - 0; // Hafif titreme efekti obj.laserBeam.height = obj.laserBeam._baseWidth + Math.sin(LK.ticks / 2) * 8; obj.laserBeam.alpha = 0.38 + Math.abs(Math.sin(LK.ticks / 8)) * 0.22; }; game.addChild(obj.laserBeam); } // Lazer aktifse, süresi dolduysa kapat if (obj.laserActive) { if (LK.ticks - obj.laserStartTick > obj.laserDuration) { obj.laserActive = false; obj.lastLaserTick = LK.ticks; obj.laserCooldown = 240 + Math.floor(Math.random() * 120); if (obj.laserBeam && obj.laserBeam.parent) { obj.laserBeam.destroy(); } obj.laserBeam = null; } else if (obj.laserBeam && obj.laserBeam.update) { obj.laserBeam.update(); // Lazer ışını ile oyuncu çarpışma kontrolü (dikdörtgen-çember) // Lazerin dikdörtgeni: (x1, y1, x2, y2) var lx1 = obj.laserBeam.x - obj.laserBeam.width; var lx2 = obj.laserBeam.x; var ly1 = obj.laserBeam.y - obj.laserBeam.height / 2; var ly2 = obj.laserBeam.y + obj.laserBeam.height / 2; // Oyuncu çemberi if (playerShip) { var px = playerShip.x; var py = playerShip.y; var pr = playerShip.radius || (playerShip.width ? playerShip.width / 2 : 70); // Çember-dikdörtgen çarpışma var closestX = Math.max(lx1, Math.min(px, lx2)); var closestY = Math.max(ly1, Math.min(py, ly2)); var dx = px - closestX; var dy = py - closestY; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < pr - 8) { // Sadece ilk çarpışmada hasar uygula (her frame değil) if (!obj.laserBeam._playerHit) { obj.laserBeam._playerHit = true; // Patlama efekti var explosion = LK.getAsset('patlamaeffekt', { anchorX: 0.5, anchorY: 0.5, x: playerShip.x, y: playerShip.y, width: playerShip.width || 140, height: playerShip.height || 100 }); game.addChild(explosion); tween(explosion, { alpha: 0, scaleX: 2, scaleY: 2 }, { duration: 400, onFinish: function onFinish() { explosion.destroy(); } }); // Kalkan power-up aktifse ilk hasarı engelle if (activePowerUp === "shield" && playerShip._shielded) { playerShip._shielded = false; if (playerShip._shieldCircle) { tween(playerShip._shieldCircle, { alpha: 0 }, { duration: 300, onFinish: function onFinish() { playerShip._shieldCircle.destroy(); playerShip._shieldCircle = null; } }); } var shieldHit = LK.getAsset('can', { anchorX: 0.5, anchorY: 0.5, x: playerShip.x, y: playerShip.y, width: playerShip.width * 1.7, height: playerShip.height * 1.7 }); shieldHit.alpha = 0.5; shieldHit.color = 0x7cbb37; game.addChild(shieldHit); tween(shieldHit, { alpha: 0, scaleX: 2, scaleY: 2 }, { duration: 400, onFinish: function onFinish() { shieldHit.destroy(); } }); // Hasarı engelle, can azalmasın } else { setPlayerHealth(playerHealth - 4); // Lazer ışını hasarı } if (playerHealth <= 0) { LK.showGameOver(); return; } } } else { obj.laserBeam._playerHit = false; } } } } // Ateş etme (her cooldown süresi dolduğunda) if (LK.ticks - obj.lastEnemyBulletTick > obj.enemyBulletCooldown) { // Oyuncuya odaklı ateş: eğer oyuncu yatayda önünde ve menzildeyse ateş et, yoksa rastgele daha az ateş etsin var shouldFire = false; if (playerShip && obj.x > playerShip.x) { // Düşman oyuncunun sağında olmalı var dy = Math.abs(obj.y - playerShip.y); // Y ekseninde yakınlık arttıkça ateş olasılığı artsın if (dy < 80) { shouldFire = true; // Çok yakınsa kesin ateş et } else if (dy < 180 && Math.random() < 0.5) { shouldFire = true; // Orta mesafede %50 olasılıkla ateş et } else if (dy < 300 && Math.random() < 0.15) { shouldFire = true; // Uzakta ise nadiren ateş et } } else if (Math.random() < 0.03) { // Ekranda oyuncu yoksa veya çok uzaktaysa çok nadiren ateş etsin shouldFire = true; } if (shouldFire) { var eb = new EnemyBullet(); eb.x = obj.x - 60; eb.y = obj.y; if (!game.enemyBullets) game.enemyBullets = []; game.enemyBullets.push(eb); game.addChild(eb); obj.lastEnemyBulletTick = LK.ticks; // Oyuncuya yakınken daha kısa cooldown, uzaktayken daha uzun if (playerShip && Math.abs(obj.y - playerShip.y) < 80) { obj.enemyBulletCooldown = 14 + Math.floor(Math.random() * 8); // Çok yakınsa çok sık ateş } else if (playerShip && Math.abs(obj.y - playerShip.y) < 180) { obj.enemyBulletCooldown = 22 + Math.floor(Math.random() * 12); // Orta mesafe } else { obj.enemyBulletCooldown = 38 + Math.floor(Math.random() * 22); // Uzakta daha seyrek ateş } } } }; } else if (rand < 0.6) { // uzayNesnesi2 (enemy ship) - eski düşman, sadece zorluk 4'ten önce obj = new Container(); var width = 100; var height = 100; var objAsset = obj.attachAsset('uzayNesnesi2', { anchorX: 0.5, anchorY: 0.5 }); objAsset.width = width; objAsset.height = height; objAsset.color = 0xff4444; obj.radius = width / 2; obj.x = 2048 + width; obj.y = 200 + Math.random() * (2732 - 400); // Düşman hızı: kolayda yavaş, zorda hızlı // 1. zorlukta ~3, 10. zorlukta ~9 var baseSpeed = 3 + (difficulty - 1) * 0.7; var speed = baseSpeed + Math.random() * (1.5 + difficulty * 0.2); obj.vx = -speed; obj.vy = (Math.random() - 0.5) * (2.5 + difficulty * 0.2); // Enemy bullet fire timer obj.enemyBulletCooldown = 10 + Math.floor(Math.random() * 10); // DAHA DA SIK ateş (daha seri) obj.lastEnemyBulletTick = LK.ticks; // --- YAPAY ZEKA: Oyuncuya yaklaşma ve akıllı ateş etme --- obj.update = function () { // Akıllı hareket: oyuncuya doğru yavaşça yönel if (playerShip && typeof playerShip.x !== "undefined" && typeof playerShip.y !== "undefined") { // Yalnızca ekranda ise takip et var dx = playerShip.x - obj.x; var dy = playerShip.y - obj.y; var dist = Math.sqrt(dx * dx + dy * dy); // X ekseninde oyuncuya yaklaşmak için vx'yi ayarla (mantıklı takip) var targetVx = -Math.max(2, Math.min(10, Math.abs(dx) / 40)); if (obj.x > playerShip.x) { obj.vx += (targetVx - obj.vx) * 0.08; } // Y ekseninde oyuncuya yaklaşmak için vy'yi ayarla (smooth takip) var targetVy = 0; if (dist > 1) { targetVy = dy / Math.max(80, Math.abs(dx)); // X uzaklığı arttıkça daha az dikey hareket // Sınırla, çok hızlı olmasın if (targetVy > 4) targetVy = 4; if (targetVy < -4) targetVy = -4; } // Yavaşça vy'ye yaklaş obj.vy += (targetVy - obj.vy) * 0.12; } obj.x += obj.vx; obj.y += obj.vy; // --- EKRANA GİRİNCE ATEŞ ETME BAŞLASIN --- // Ekrana ilk kez girdiği anı tespit et if (typeof obj._hasStartedFiring === "undefined") obj._hasStartedFiring = false; if (!obj._hasStartedFiring && obj.x <= 2048) { obj._hasStartedFiring = true; // İlk ateş için timerı hemen başlat obj.lastEnemyBulletTick = LK.ticks; } // Ateş etme (her cooldown süresi dolduğunda) if (LK.ticks - obj.lastEnemyBulletTick > obj.enemyBulletCooldown) { // Oyuncuya odaklı ateş: eğer oyuncu yatayda önünde ve menzildeyse ateş et, yoksa rastgele daha az ateş etsin var shouldFire = false; if (playerShip && obj.x > playerShip.x) { var dy = Math.abs(obj.y - playerShip.y); if (dy < 60) { shouldFire = true; // Çok yakınsa kesin ateş et } else if (dy < 140 && Math.random() < 0.5) { shouldFire = true; // Orta mesafe %50 olasılıkla ateş et } else if (dy < 220 && Math.random() < 0.12) { shouldFire = true; // Uzakta ise nadiren ateş et } } else if (Math.random() < 0.02) { // Ekranda oyuncu yoksa veya çok uzaktaysa çok nadiren ateş etsin shouldFire = true; } if (shouldFire) { var eb = new EnemyBullet(); eb.x = obj.x - 60; eb.y = obj.y; if (!game.enemyBullets) game.enemyBullets = []; game.enemyBullets.push(eb); game.addChild(eb); obj.lastEnemyBulletTick = LK.ticks; // Oyuncuya yakınken daha kısa cooldown, uzaktayken daha uzun if (playerShip && Math.abs(obj.y - playerShip.y) < 60) { obj.enemyBulletCooldown = 18 + Math.floor(Math.random() * 8); // Çok yakınsa çok sık ateş } else if (playerShip && Math.abs(obj.y - playerShip.y) < 140) { obj.enemyBulletCooldown = 28 + Math.floor(Math.random() * 10); // Orta mesafe } else { obj.enemyBulletCooldown = 54 + Math.floor(Math.random() * 24); // Uzakta daha seyrek ateş } } } }; } else if (rand < 0.3) { // spaceObject (asteroid) obj = new Container(); var width = 120 + Math.random() * 60; var height = 120 + Math.random() * 60; var objAsset = obj.attachAsset('spaceObject', { anchorX: 0.5, anchorY: 0.5 }); objAsset.width = width; objAsset.height = height; objAsset.color = 0x888888; obj.radius = width / 2; obj.x = 2048 + width; obj.y = 200 + Math.random() * (2732 - 400); // Asteroid hızı: kolayda yavaş, zorda hızlı // 1. zorlukta ~2.5, 10. zorlukta ~8 var baseSpeed = 2.5 + (difficulty - 1) * 0.6; var speed = baseSpeed + Math.random() * (1.5 + difficulty * 0.2); obj.vx = -speed; obj.vy = (Math.random() - 0.5) * (2 + difficulty * 0.2); obj.update = function () { obj.x += obj.vx; obj.y += obj.vy; }; } else { // meteorstone (yeni düşman) // MeteorStone: kolayda yavaş, zorda hızlı obj = new MeteorStone(); if (obj && obj.vx !== undefined) { // 1. zorlukta ~-3, 10. zorlukta ~-8 var meteorBaseSpeed = 3 + (difficulty - 1) * 0.6; obj.vx = -meteorBaseSpeed - Math.random() * (1.5 + difficulty * 0.2); obj.vy = (Math.random() - 0.5) * (2.5 + difficulty * 0.2); } } spaceObjects.push(obj); game.addChild(obj); // Düşman sayısını artır ve 10'a ulaştıysa win kontrolü totalEnemiesSpawned++; // (Kazanan kontrolü kaldırıldı) } // Çarpışma kontrolü (daire-çarpışma) function isCircleHit(a, b) { var dx = a.x - b.x; var dy = a.y - b.y; var dist = Math.sqrt(dx * dx + dy * dy); var r1 = a.radius || (a.width ? a.width / 2 : 0); var r2 = b.radius || (b.width ? b.width / 2 : 0); return dist < r1 + r2 - 10; } // Zorluk arttırma ve oyun hızını kademeli olarak artır function updateDifficulty() { // Zorluk: 1-20 arası, her 3 puanda bir artar, maksimum 20 (daha hızlı ve daha yüksek artış) var newDifficulty = 1 + Math.floor(score / 3); if (newDifficulty > 20) newDifficulty = 20; if (newDifficulty > difficulty) { difficulty = newDifficulty; } // spawnInterval: Kolayda yavaş (60), zorda çok hızlı (4) // 1. zorlukta 60, 20. zorlukta 4 spawnInterval = Math.round(60 - (difficulty - 1) * 2.9); if (spawnInterval < 4) spawnInterval = 4; // Mermi hızını ve ateş sıklığını zorlukla birlikte daha fazla artır // shootInterval: 1. zorlukta 120, 20. zorlukta 12 shootInterval = Math.round(120 - (difficulty - 1) * 5.7); if (shootInterval < 12) shootInterval = 12; // Düşman mermisi hızı ve spawn oranı da zorlukla birlikte artacak şekilde ayarlanabilir // (EnemyShip ve Asteroid spawn fonksiyonlarında da difficulty kullanılıyor) } // Oyun döngüsü game.update = function () { // (Geri alındı: ekran sağa doğru ilerlemesin, scrollX ve scrollSpeed kaldırıldı) // Galaksi arka planı kaldırıldı // Yıldızlar: parallax ve hafif döndürme if (typeof starBgContainer !== "undefined" && stars && stars.length) { for (var si = 0; si < stars.length; si++) { var s = stars[si]; s.x -= s._vx; s.rotation += s._rotSpeed; // Ekrandan soldan çıkarsa sağa wrap et if (s.x < -10) { s.x = 2048 + 10; s.y = Math.random() * 2732; } } } if (!gameStarted) return; // Playership sağlık barı 0 olduğunda oyun bitsin, aksi takdirde bitmesin if (playerHealth <= 0) { updateCanBar(); updatePlayershipCanBar(); // --- High Score Save --- addHighScore(score); // Boss diamond resetle if (typeof bossDiamondObj !== "undefined" && bossDiamondObj) { bossDiamondObj.destroy(); bossDiamondObj = null; } if (typeof game.bossDiamondSpawned !== "undefined") { game.bossDiamondSpawned = false; } LK.showGameOver(); return; } // Süreyi azalt (her frame ~1/60 saniye) // Artık sadece timerInterval ile zaman azalacak, burada azaltma yapılmıyor // 10 düşman spawn olduysa ve can > 0 ve süre > 0 ise win // (Kazanan kontrolü kaldırıldı) // Planets removed // Otomatik ateş // Portal büyüme veya küçülme animasyonu sırasında mermi atılmasın var portalBlockingShoot = false; if (game.portal && !game.portal.isShrinking && typeof game.portal.lastWasIntersecting !== "undefined" && game.portal.lastWasIntersecting) { portalBlockingShoot = true; } if (!portalBlockingShoot && LK.ticks - lastShootTick > Math.floor(shootInterval / 16)) { tryShoot(); lastShootTick = LK.ticks; } // Uzay cismi oluşturma if (!levelFinished && LK.ticks - lastSpawnTick > spawnInterval) { spawnSpaceObject(); lastSpawnTick = LK.ticks; } // Mermileri güncelle if (!(game.portal && !game.portal.isShrinking && game.portal.scaleX < (typeof maxScale !== "undefined" ? maxScale : 999))) { // Portal büyüme animasyonu sırasında mermiler yok edilir for (var i = bullets.length - 1; i >= 0; i--) { var b = bullets[i]; b.update(); // Ekran dışıysa sil if (b.x > 2048 + 50) { b.destroy(); bullets.splice(i, 1); } } } else { // Portal büyüme animasyonu sırasında tüm mermileri yok et for (var i = bullets.length - 1; i >= 0; i--) { var b = bullets[i]; if (b && b.parent) { tween(b, { alpha: 0, scaleX: 0.2, scaleY: 0.2 }, { duration: 200, onFinish: function (bb) { return function () { if (bb && bb.parent) bb.destroy(); }; }(b) }); } } bullets = []; } // Uzay cisimlerini güncelle for (var j = spaceObjects.length - 1; j >= 0; j--) { var obj = spaceObjects[j]; obj.update(); // Ekran dışıysa sil if (obj.x < -200 || obj.y < -200 || obj.y > 2732 + 200) { obj.destroy(); spaceObjects.splice(j, 1); continue; } // Gemiye çarptı mı? if (isCircleHit(obj, playerShip)) { // Eğer kalkan aktifse, hiçbir şey olmasın, düşman da yok olmasın if (activePowerUp === "shield" && playerShip._shielded) { // Kalkan varken düşman çarpışması tamamen etkisiz, hiçbir efekt, hasar veya yok etme işlemi yapılmaz continue; } // Patlama efekti (patlamaeffekt görseli ile) oyuncu gemisinin üstünde göster var explosion = LK.getAsset('patlamaeffekt', { anchorX: 0.5, anchorY: 0.5, x: playerShip.x, y: playerShip.y, width: playerShip.width || 140, height: playerShip.height || 100 }); game.addChild(explosion); tween(explosion, { alpha: 0, scaleX: 2, scaleY: 2 }, { duration: 400, onFinish: function onFinish() { explosion.destroy(); } }); // Farklı düşman türlerine göre hasar uygula var damage = 1; if (obj instanceof MeteorStone) { damage = 3; } else if (obj._isEnemyship2) { // enemyship2 ise 3 birim hasar damage = 3; } else if (obj.attachAsset && obj.attachAsset('uzayNesnesi2', { anchorX: 0.5, anchorY: 0.5 })) { // EnemyShip ise 2 birim (uzayNesnesi2) damage = 2; } else if (obj.attachAsset && obj.attachAsset('spaceObject', { anchorX: 0.5, anchorY: 0.5 })) { // SpaceObject asteroid ise 1 birim damage = 1; } setPlayerHealth(playerHealth - damage); if (playerHealth <= 0) { LK.showGameOver(); return; } obj.destroy(); spaceObjects.splice(j, 1); continue; } // Mermiyle çarpışma var _loop = function _loop() { b = bullets[k]; if (isCircleHit(obj, b)) { // Patlama efekti (patlamaeffekt görseli ile) explosion = LK.getAsset('patlamaeffekt', { anchorX: 0.5, anchorY: 0.5, x: obj.x, y: obj.y, width: obj.width || 100, height: obj.height || 100 }); game.addChild(explosion); tween(explosion, { alpha: 0, scaleX: 2, scaleY: 2 }, { duration: 400, onFinish: function onFinish() { explosion.destroy(); } }); // enemyship2 ise (büyük kırmızı gemi), 2 mermi isabet edince yok olsun if (obj._isEnemyship2) { // Skor: enemyship2 için 5 puan verelim (isteğe bağlı, 3 de olabilir) // --- Ava: 2 mermi isabet edince yok olma sistemi --- if (typeof obj._hitCount === "undefined") obj._hitCount = 0; obj._hitCount++; b.destroy(); bullets.splice(k, 1); if (obj._hitCount >= 2) { var scoreToAdd = 5; obj.destroy(); spaceObjects.splice(j, 1); var multiplier = game._scoreMultiplier && game._scoreMultiplier > 1 ? game._scoreMultiplier : 1; score += scoreToAdd * multiplier; scoreTxt.setText(score); updateDifficulty(); // Bölüm sonu: 10 düşman öldürüldüyse bitir if (!levelFinished) { if (typeof game.enemiesKilled === "undefined") game.enemiesKilled = 0; game.enemiesKilled++; if (game.enemiesKilled >= 50) { levelFinished = true; // Bölüm sonu canavarı görselini göster if (typeof game.bossImageShown === "undefined" || !game.bossImageShown) { var _flashBoss = function flashBoss() { if (!game.bossImg) return; tween(game.bossImg, { alpha: 1 }, { duration: 120, onFinish: function onFinish() { tween(game.bossImg, { alpha: 0 }, { duration: 120, onFinish: function onFinish() { flashCount++; if (flashCount < 3) { _flashBoss(); } else { // Sonunda kalıcı olarak görünür olsun tween(game.bossImg, { alpha: 1 }, { duration: 120 }); } } }); } }); }; // Sağda, birden yanıp sönerek beliren ve aşağı yukarı hareket eden boss bossImg = LK.getAsset('bolumsonucanavar', { anchorX: 0.5, anchorY: 0.5, // Ekranın sağında, ortalanmış şekilde göster x: 2048 - 200, y: 2732 / 2, width: 400, height: 400 }); bossImg.alpha = 0; game.addChild(bossImg); game.bossImageShown = true; game.bossImg = bossImg; game.bossAppearTick = LK.ticks; // Yanıp sönme animasyonu (3 kez) flashCount = 0; _flashBoss(); // Boss'un aşağı yukarı hareketi için tick kaydı game.bossBaseY = bossImg.y; // --- SADECE BÖLÜM SONU CANAVARI KALSIN --- // Tüm uzay cisimlerini sil for (var jj = spaceObjects.length - 1; jj >= 0; jj--) { if (spaceObjects[jj]) { spaceObjects[jj].destroy(); } } spaceObjects = []; // Tüm mermileri sil for (var ii = bullets.length - 1; ii >= 0; ii--) { if (bullets[ii]) { bullets[ii].destroy(); } } bullets = []; // Tüm düşman mermilerini sil if (game.enemyBullets) { for (var eb = game.enemyBullets.length - 1; eb >= 0; eb--) { if (game.enemyBullets[eb]) { game.enemyBullets[eb].destroy(); } } game.enemyBullets = []; } // Gift varsa sil if (giftBg) { giftBg.destroy(); giftBg = null; } } // Oyun bitmesin, win popup gösterme return { v: void 0 }; } } return 0; // break } } else { obj.destroy(); spaceObjects.splice(j, 1); b.destroy(); bullets.splice(k, 1); // Skor: meteorstone=2, spaceObject=1, enemy ship=3 var scoreToAdd = 1; // MeteorStone ise 2 puan if (obj instanceof MeteorStone) { scoreToAdd = 2; } // EnemyShip ise 3 puan else if (obj._isEnemyship2) { scoreToAdd = 5; } // EnemyShip (eski tip) ise 3 puan else if (obj.attachAsset && obj.attachAsset('uzayNesnesi2', { anchorX: 0.5, anchorY: 0.5 })) { scoreToAdd = 3; } // SpaceObject asteroid ise 1 puan (default) else if (obj.attachAsset && obj.attachAsset('spaceObject', { anchorX: 0.5, anchorY: 0.5 })) { scoreToAdd = 1; } } // Power-up skor çarpanı uygula var multiplier = game._scoreMultiplier && game._scoreMultiplier > 1 ? game._scoreMultiplier : 1; score += scoreToAdd * multiplier; scoreTxt.setText(score); updateDifficulty(); // Bölüm sonu: 10 düşman öldürüldüyse bitir if (!levelFinished) { if (typeof game.enemiesKilled === "undefined") game.enemiesKilled = 0; game.enemiesKilled++; if (game.enemiesKilled >= 50) { levelFinished = true; // Bölüm sonu canavarı görselini göster if (typeof game.bossImageShown === "undefined" || !game.bossImageShown) { var _flashBoss = function flashBoss() { if (!game.bossImg) return; tween(game.bossImg, { alpha: 1 }, { duration: 120, onFinish: function onFinish() { tween(game.bossImg, { alpha: 0 }, { duration: 120, onFinish: function onFinish() { flashCount++; if (flashCount < 3) { _flashBoss(); } else { // Sonunda kalıcı olarak görünür olsun tween(game.bossImg, { alpha: 1 }, { duration: 120 }); } } }); } }); }; // Sağda, birden yanıp sönerek beliren ve aşağı yukarı hareket eden boss bossImg = LK.getAsset('bolumsonucanavar', { anchorX: 0.5, anchorY: 0.5, // Ekranın sağında, ortalanmış şekilde göster x: 2048 - 200, y: 2732 / 2, width: 400, height: 400 }); bossImg.alpha = 0; game.addChild(bossImg); game.bossImageShown = true; game.bossImg = bossImg; game.bossAppearTick = LK.ticks; // Yanıp sönme animasyonu (3 kez) flashCount = 0; _flashBoss(); // Boss'un aşağı yukarı hareketi için tick kaydı game.bossBaseY = bossImg.y; // --- SADECE BÖLÜM SONU CANAVARI KALSIN --- // Tüm uzay cisimlerini sil for (var jj = spaceObjects.length - 1; jj >= 0; jj--) { if (spaceObjects[jj]) { spaceObjects[jj].destroy(); } } spaceObjects = []; // Tüm mermileri sil for (var ii = bullets.length - 1; ii >= 0; ii--) { if (bullets[ii]) { bullets[ii].destroy(); } } bullets = []; // Tüm düşman mermilerini sil if (game.enemyBullets) { for (var eb = game.enemyBullets.length - 1; eb >= 0; eb--) { if (game.enemyBullets[eb]) { game.enemyBullets[eb].destroy(); } } game.enemyBullets = []; } // Gift varsa sil if (giftBg) { giftBg.destroy(); giftBg = null; } } // Oyun bitmesin, win popup gösterme return { v: void 0 }; } } return 0; // break } }, b, explosion, scoreToAdd, bossImg, flashCount, _ret; for (var k = bullets.length - 1; k >= 0; k--) { _ret = _loop(); if (_ret === 0) break; if (_ret) return _ret.v; } } // Düşman mermileri güncelle ve çarpışma kontrolü if (game.enemyBullets) { for (var eb = game.enemyBullets.length - 1; eb >= 0; eb--) { var enemyBullet = game.enemyBullets[eb]; enemyBullet.update(); // Ekran dışıysa sil if (enemyBullet.x < -100) { enemyBullet.destroy(); game.enemyBullets.splice(eb, 1); continue; } // Oyuncuya çarptı mı? if (isCircleHit(enemyBullet, playerShip)) { // Patlama efekti (patlamaeffekt görseli ile) oyuncu gemisinin üstünde göster var explosion = LK.getAsset('patlamaeffekt', { anchorX: 0.5, anchorY: 0.5, x: playerShip.x, y: playerShip.y, width: playerShip.width || 140, height: playerShip.height || 100 }); game.addChild(explosion); tween(explosion, { alpha: 0, scaleX: 2, scaleY: 2 }, { duration: 400, onFinish: function onFinish() { explosion.destroy(); } }); // Kalkan power-up aktifse ilk hasarı engelle if (activePowerUp === "shield" && playerShip._shielded) { playerShip._shielded = false; if (playerShip._shieldCircle) { tween(playerShip._shieldCircle, { alpha: 0 }, { duration: 300, onFinish: function onFinish() { playerShip._shieldCircle.destroy(); playerShip._shieldCircle = null; } }); } var shieldHit = LK.getAsset('can', { anchorX: 0.5, anchorY: 0.5, x: playerShip.x, y: playerShip.y, width: playerShip.width * 1.7, height: playerShip.height * 1.7 }); shieldHit.alpha = 0.5; shieldHit.color = 0x7cbb37; game.addChild(shieldHit); tween(shieldHit, { alpha: 0, scaleX: 2, scaleY: 2 }, { duration: 400, onFinish: function onFinish() { shieldHit.destroy(); } }); // Hasarı engelle, can azalmasın } else { setPlayerHealth(playerHealth - 2); } if (playerHealth <= 0) { LK.showGameOver(); return; } enemyBullet.destroy(); game.enemyBullets.splice(eb, 1); continue; } } } // Boss varsa, ekranda merkeze kadar her yönde hareket ettir if (game.bossImg && game.bossBaseY !== undefined) { // --- BOSS MERMİSİ ATEŞLEME --- if (typeof game.bossBulletCooldown === "undefined") { game.bossBulletCooldown = 60 + Math.floor(Math.random() * 40); // 1-1.5 sn arası game.lastBossBulletTick = LK.ticks; if (!game.bossBullets) game.bossBullets = []; } // Boss 8 saniyede bir bossfire ateşlesin if (typeof game.lastBossFireTick === "undefined") { game.lastBossFireTick = LK.ticks; } // Bossfire ve bossmermi aynı anda ateşlenmesin var bossFireJustFired = false; // --- Bossfire spiral ve dairesel atış kaldırıldı, sadece klasik yayılma atışı kaldı --- if (!bossFireJustFired && LK.ticks - game.lastBossFireTick > 480) { // 8 saniye (60fps*8=480) // Sadece klasik yayılma atışı var fireCount = 5; var spread = 220; for (var f = 0; f < fireCount; f++) { var offsetY = -spread / 2 + spread / (fireCount - 1) * f; var bossFire = LK.getAsset('bossfire', { anchorX: 0.5, anchorY: 0.5, x: game.bossImg.x - (game.bossImg.width || 400) / 2 - 60, y: game.bossImg.y + offsetY, width: 80, height: 80 }); bossFire.vx = -13; bossFire.vy = 0; bossFire.burning = false; bossFire.burnTicks = 0; bossFire.update = function (fire) { return function () { fire.x += fire.vx; fire.y += fire.vy; if (fire.burning) { fire.alpha = 0.7 + 0.3 * Math.sin(LK.ticks / 4); } }; }(bossFire); if (!game.bossFires) game.bossFires = []; game.bossFires.push(bossFire); game.addChild(bossFire); } game.lastBossFireTick = LK.ticks; bossFireJustFired = true; } // Boss mermisi ateşle if (!bossFireJustFired && LK.ticks - game.lastBossBulletTick > game.bossBulletCooldown) { // --- GELİŞTİRİLMİŞ: Zigzag ve spiral boss mermileri --- var slotCount = 5; var slotOffsets = []; var bossImgHeight = game.bossImg.height || 400; var slotSpacing = bossImgHeight / (slotCount + 1); for (var si = 0; si < slotCount; si++) { var slotY = -bossImgHeight / 2 + slotSpacing * (si + 1); slotOffsets.push({ y: slotY, angle: 0 }); } // Zigzag boss mermileri for (var si = 0; si < slotOffsets.length; si++) { var slot = slotOffsets[si]; var bossBullet = LK.getAsset('bossmermi', { anchorX: 0.5, anchorY: 0.5, x: game.bossImg.x - (game.bossImg.width || 400) / 2 - 40, y: game.bossImg.y + slot.y, width: 48, height: 48 }); // Zigzag için başlangıç fazı bossBullet._zigzagPhase = Math.random() * Math.PI * 2; bossBullet._zigzagSpeed = 2.5 + Math.random() * 1.5; bossBullet._zigzagAmp = 38 + Math.random() * 22; var speed = 10; bossBullet.vx = -speed; bossBullet.vy = 0; bossBullet._baseY = bossBullet.y; bossBullet._bornTick = LK.ticks; bossBullet.update = function (bullet) { return function () { bullet.x += bullet.vx; // Zigzag hareket: y = baseY + amp * sin(frekans * t + faz) var t = (LK.ticks - bullet._bornTick) / 12; bullet.y = bullet._baseY + Math.sin(t * bullet._zigzagSpeed + bullet._zigzagPhase) * bullet._zigzagAmp; }; }(bossBullet); game.bossBullets.push(bossBullet); game.addChild(bossBullet); } // Spiral boss mermileri (daha zor için) if (game.bossHealth < game.bossMaxHealth * 0.5) { var spiralCount = 8; var spiralRadius = 0; var spiralSpeed = 7; for (var sp = 0; sp < spiralCount; sp++) { var angle = Math.PI * 2 / spiralCount * sp + LK.ticks % 60 / 60 * Math.PI * 2; var spiralBullet = LK.getAsset('bossmermi', { anchorX: 0.5, anchorY: 0.5, x: game.bossImg.x - (game.bossImg.width || 400) / 2 - 40, y: game.bossImg.y, width: 40, height: 40 }); spiralBullet._angle = angle; spiralBullet._radius = spiralRadius; spiralBullet._speed = spiralSpeed; spiralBullet._bornTick = LK.ticks; spiralBullet.update = function (bullet) { return function () { // Spiral hareket: açı artar, x ve y ona göre değişir bullet._angle += 0.07; bullet.x += Math.cos(bullet._angle) * bullet._speed - 6; bullet.y += Math.sin(bullet._angle) * bullet._speed; }; }(spiralBullet); game.bossBullets.push(spiralBullet); game.addChild(spiralBullet); } } game.lastBossBulletTick = LK.ticks; game.bossBulletCooldown = 60 + Math.floor(Math.random() * 40); } // Bossfire mermilerini güncelle ve çarpışma kontrolü if (game.bossFires) { for (var bf = game.bossFires.length - 1; bf >= 0; bf--) { var fire = game.bossFires[bf]; if (fire.update) fire.update(); // Ekran dışıysa sil if (fire.x < -150 || fire.x > 2048 + 150 || fire.y < -150 || fire.y > 2732 + 150) { fire.destroy(); game.bossFires.splice(bf, 1); continue; } // Oyuncuya çarptı mı? if (isCircleHit(fire, playerShip)) { // Eğer bossfire zaten yanıcı değilse, yanıcı etki başlat if (!fire.burning) { fire.burning = true; fire.burnTicks = 0; fire.burnMaxTicks = 90; // 1.5 saniye boyunca yanıcı etki (60fps*1.5) fire.burnDamageInterval = 18; // Her 0.3 saniyede bir hasar uygula fire.lastBurnDamageTick = LK.ticks; // Patlama efekti var bossFireHit = LK.getAsset('patlamaeffekt', { anchorX: 0.5, anchorY: 0.5, x: playerShip.x, y: playerShip.y, width: playerShip.width || 140, height: playerShip.height || 100 }); game.addChild(bossFireHit); tween(bossFireHit, { alpha: 0, scaleX: 2, scaleY: 2 }, { duration: 400, onFinish: function onFinish() { bossFireHit.destroy(); } }); // Kalkan power-up aktifse ilk hasarı engelle if (activePowerUp === "shield" && playerShip._shielded) { playerShip._shielded = false; if (playerShip._shieldCircle) { tween(playerShip._shieldCircle, { alpha: 0 }, { duration: 300, onFinish: function onFinish() { playerShip._shieldCircle.destroy(); playerShip._shieldCircle = null; } }); } var shieldHit = LK.getAsset('can', { anchorX: 0.5, anchorY: 0.5, x: playerShip.x, y: playerShip.y, width: playerShip.width * 1.7, height: playerShip.height * 1.7 }); shieldHit.alpha = 0.5; shieldHit.color = 0x7cbb37; game.addChild(shieldHit); tween(shieldHit, { alpha: 0, scaleX: 2, scaleY: 2 }, { duration: 400, onFinish: function onFinish() { shieldHit.destroy(); } }); // Hasarı engelle, can azalmasın } else { setPlayerHealth(playerHealth - 8); // bossfire hasarı 8 (daha fazla) } if (playerHealth <= 0) { LK.showGameOver(); return; } } // Yanıcı etkiyi oyuncunun üstünde bırak, mermiyi hemen yok etme // Mermiyi ekranda bırak, yanıcı etki bitince yok edilecek continue; } // Yanıcı (yakıcı) bossfire oyuncunun üstündeyse, periyodik hasar uygula if (fire.burning) { fire.burnTicks++; // Her burnDamageInterval tick'te bir hasar uygula if (fire.burnTicks === 1 || fire.burnTicks % fire.burnDamageInterval === 0) { setPlayerHealth(playerHealth - 1); // Yanıcı efektin üstünde küçük bir alev efekti gösterebiliriz (isteğe bağlı) var burnEffect = LK.getAsset('patlamaeffekt', { anchorX: 0.5, anchorY: 0.5, x: playerShip.x, y: playerShip.y, width: 80, height: 80 }); burnEffect.alpha = 0.5; game.addChild(burnEffect); tween(burnEffect, { alpha: 0, scaleX: 1.5, scaleY: 1.5 }, { duration: 200, onFinish: function onFinish() { burnEffect.destroy(); } }); if (playerHealth <= 0) { updateCanBar(); LK.showGameOver(); return; } } // Yanıcı etki süresi dolduysa bossfire'ı yok et if (fire.burnTicks > fire.burnMaxTicks) { fire.destroy(); game.bossFires.splice(bf, 1); continue; } } } } // Boss mermilerini güncelle ve çarpışma kontrolü for (var bb = game.bossBullets.length - 1; bb >= 0; bb--) { var bBullet = game.bossBullets[bb]; if (bBullet.update) bBullet.update(); // Ekran dışıysa sil if (bBullet.x < -100 || bBullet.x > 2048 + 100 || bBullet.y < -100 || bBullet.y > 2732 + 100) { bBullet.destroy(); game.bossBullets.splice(bb, 1); continue; } // Oyuncuya çarptı mı? if (isCircleHit(bBullet, playerShip)) { // Patlama efekti var bossBulletHit = LK.getAsset('patlamaeffekt', { anchorX: 0.5, anchorY: 0.5, x: playerShip.x, y: playerShip.y, width: playerShip.width || 140, height: playerShip.height || 100 }); game.addChild(bossBulletHit); tween(bossBulletHit, { alpha: 0, scaleX: 2, scaleY: 2 }, { duration: 400, onFinish: function onFinish() { bossBulletHit.destroy(); } }); // Kalkan power-up aktifse ilk hasarı engelle if (activePowerUp === "shield" && playerShip._shielded) { playerShip._shielded = false; if (playerShip._shieldCircle) { tween(playerShip._shieldCircle, { alpha: 0 }, { duration: 300, onFinish: function onFinish() { playerShip._shieldCircle.destroy(); playerShip._shieldCircle = null; } }); } var shieldHit = LK.getAsset('can', { anchorX: 0.5, anchorY: 0.5, x: playerShip.x, y: playerShip.y, width: playerShip.width * 1.7, height: playerShip.height * 1.7 }); shieldHit.alpha = 0.5; shieldHit.color = 0x7cbb37; game.addChild(shieldHit); tween(shieldHit, { alpha: 0, scaleX: 2, scaleY: 2 }, { duration: 400, onFinish: function onFinish() { shieldHit.destroy(); } }); // Hasarı engelle, can azalmasın } else { setPlayerHealth(playerHealth - 6); // bossmermi hasarı 6 (daha fazla) } if (playerHealth <= 0) { LK.showGameOver(); return; } bBullet.destroy(); game.bossBullets.splice(bb, 1); continue; } } // Boss'un hareket yarıçapı: ekranın sağ yarısında, merkeze kadar gidebilsin // Merkez: (2048/2, 2732/2) // Boss'un hareket merkezi: ekranın sağında başlar, merkeze kadar hareket edebilir var centerX = 2048 / 2; var centerY = 2732 / 2; var rightEdgeX = 2048 - 200; var bossMoveRadiusX = (rightEdgeX - centerX) / 2; // sağdan merkeze kadar yarıçap var bossMoveRadiusY = (centerY - 0) * 0.8; // üstten alta merkeze kadar (biraz daha az) var bossCenterX = centerX + bossMoveRadiusX; var bossCenterY = centerY; // --- GELİŞTİRİLMİŞ: Boss hareketine ileri-geri ve yukarı-aşağı dalga ekle --- var t = LK.ticks / 60; // yavaş hareket için var bossTargetX = bossCenterX + Math.cos(t) * bossMoveRadiusX + Math.sin(t * 2.2) * 60; var bossTargetY = bossCenterY + Math.sin(t * 0.8) * bossMoveRadiusY + Math.cos(t * 1.7) * 40; var lerp = function lerp(a, b, t) { return a + (b - a) * t; }; game.bossImg.x = lerp(game.bossImg.x, bossTargetX, 0.18); game.bossImg.y = lerp(game.bossImg.y, bossTargetY, 0.18); // --- BOSS CAN, HASAR ALMA, HASAR VERME --- // Boss canı başlat if (typeof game.bossHealth === "undefined") { game.bossMaxHealth = 200; // Boss'un toplam canı artık 200 game.bossHealth = game.bossMaxHealth; // Boss can barı game.bossHealthBarBg = new Container(); var bossBarBgRect = game.bossHealthBarBg.attachAsset('can', { anchorX: 0, anchorY: 0.5, x: 0, y: 20, width: 400, height: 40 }); bossBarBgRect.alpha = 0.25; game.bossHealthBarFg = new Container(); var bossBarFgRect = game.bossHealthBarFg.attachAsset('can', { anchorX: 0, anchorY: 0.5, x: 0, y: 20, width: 400, height: 40 }); bossBarFgRect.alpha = 1; game.bossHealthBarContainer = new Container(); game.bossHealthBarContainer.addChild(game.bossHealthBarBg); game.bossHealthBarContainer.addChild(game.bossHealthBarFg); // Boss can barı ekranın sağ üst köşesinde, timer'ın hemen altında göster game.bossHealthBarContainer.x = -400; // Offset for right alignment in gui.topRight game.bossHealthBarContainer.y = 100; // Just below timer LK.gui.topRight.addChild(game.bossHealthBarContainer); } // Boss can barını güncelle var bossTargetWidth = 400 * Math.max(0, game.bossHealth) / (game.bossMaxHealth || 30); tween(game.bossHealthBarFg.children[0], { width: bossTargetWidth }, { duration: 200 }); // Boss can barı rengi: yeşil (full) -> kırmızı (az) var bossHealthRatio = Math.max(0, Math.min(1, game.bossHealth / (game.bossMaxHealth || 30))); var br = Math.round(0xFF * (1 - bossHealthRatio)); var bg = Math.round(0xFF * bossHealthRatio); var bb = 0; var bossColor = br << 16 | bg << 8 | bb; tween(game.bossHealthBarFg.children[0], { color: bossColor }, { duration: 200 }); // Boss'a mermi çarpması kontrolü for (var bi = bullets.length - 1; bi >= 0; bi--) { var bossBullet = bullets[bi]; // Boss'un çarpışma yarıçapı: görselin yarısı var bossRadius = (game.bossImg.width || 400) / 2; var dx = bossBullet.x - game.bossImg.x; var dy = bossBullet.y - game.bossImg.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < bossRadius + 16) { // Patlama efekti var bossHit = LK.getAsset('patlamaeffekt', { anchorX: 0.5, anchorY: 0.5, x: bossBullet.x, y: bossBullet.y, width: 80, height: 80 }); game.addChild(bossHit); tween(bossHit, { alpha: 0, scaleX: 2, scaleY: 2 }, { duration: 300, onFinish: function onFinish() { bossHit.destroy(); } }); // Boss canı azalt game.bossHealth -= 2; if (game.bossHealth < 0) game.bossHealth = 0; // --- BOSS 2. FAZ GEÇİŞİ --- // Boss faz 2 iptal: Boss her zaman faz 1'de kalacak, faz geçişi ve faz 2 saldırı güçlendirmeleri kaldırıldı. if (typeof game.bossPhase === "undefined") { game.bossPhase = 1; } // Faz geçişi sırasında boss hasar almasın if (game.bossInvulnerableTicks && game.bossInvulnerableTicks > 0) { game.bossInvulnerableTicks--; // Mermiyi yok et ama boss canı azaltma bossBullet.destroy(); bullets.splice(bi, 1); continue; } // Boss öldü mü? if (game.bossHealth <= 0) { // Boss patlama efekti var bossExplosion = LK.getAsset('patlamaeffekt', { anchorX: 0.5, anchorY: 0.5, x: game.bossImg.x, y: game.bossImg.y, width: game.bossImg.width || 400, height: game.bossImg.height || 400 }); game.addChild(bossExplosion); tween(bossExplosion, { alpha: 0, scaleX: 3, scaleY: 3 }, { duration: 800, onFinish: function onFinish() { bossExplosion.destroy(); } }); // Boss'u yok et if (game.bossImg) { game.bossImg.destroy(); game.bossImg = null; } // Boss can barını yok et if (game.bossHealthBarContainer) { game.bossHealthBarContainer.destroy(); game.bossHealthBarContainer = null; } // Boss ile ilgili tüm mermileri ve ateşleri yok et if (game.bossBullets) { for (var bb = game.bossBullets.length - 1; bb >= 0; bb--) { if (game.bossBullets[bb]) game.bossBullets[bb].destroy(); } game.bossBullets = []; } if (game.bossFires) { for (var bf = game.bossFires.length - 1; bf >= 0; bf--) { if (game.bossFires[bf]) game.bossFires[bf].destroy(); } game.bossFires = []; } // Boss öldüğünde boss ile ilgili tüm objeleri yok et ve elmas puanını 10 arttır diamondCount += 10; updateDiamondCounter(); // Boss ile ilgili tüm objeleri yok et if (game.bossImg) { game.bossImg.destroy(); game.bossImg = null; } if (game.bossHealthBarContainer) { game.bossHealthBarContainer.destroy(); game.bossHealthBarContainer = null; } if (game.bossBullets) { for (var bb = game.bossBullets.length - 1; bb >= 0; bb--) { if (game.bossBullets[bb]) game.bossBullets[bb].destroy(); } game.bossBullets = []; } if (game.bossFires) { for (var bf = game.bossFires.length - 1; bf >= 0; bf--) { if (game.bossFires[bf]) game.bossFires[bf].destroy(); } game.bossFires = []; } // Boss diamond ve portal spawn işlemleri ve skor bonusu score += 20; scoreTxt.setText(score); updateDifficulty(); // --- BOSS ÖLDÜ: Portalı aktif et --- if (!game.portal) { // Portalı ekranın sağında ortalanmış şekilde oluştur, ekran dışına taşmayacak şekilde var portalWidth = 120; var portalHeight = 120; var portalScale = 3.0; // Büyüme sonrası maksimum scale var portalX = 2048 - portalWidth * portalScale / 2 - 40; // Sağdan 40px boşluk bırak var portalY = 2732 / 2; var portal = LK.getAsset('portal', { anchorX: 0.5, anchorY: 0.5, x: portalX, y: portalY, width: portalWidth, height: portalHeight }); portal.scaleX = 1.2; portal.scaleY = 1.2; portal.alpha = 1; portal.isShrinking = false; portal.lastWasIntersecting = false; game.portal = portal; game.addChild(portal); // Portal büyüme animasyonu: 1.2'den 3.0'a kadar büyüsün portal._growTweenStarted = true; tween(portal, { scaleX: 3.0, scaleY: 3.0 }, { duration: 1200, easing: tween.easeOut, onFinish: function onFinish() { portal._growTweenStarted = false; // --- EKRAN DARALTMA: Boss öldükten sonra üstten ve alttan siyah barlar gelsin --- if (!game._screenNarrowed) { // Bar yüksekliği: toplam 600px (üst 300, alt 300) gibi, animasyonlu gelsin var barHeight = 0; var targetBarHeight = 300; // Üst bar var topBar = LK.getAsset('background', { anchorX: 0, anchorY: 0, x: 0, y: 0, width: 2048, height: 1 }); topBar.alpha = 0.95; topBar.color = 0x000000; // Alt bar var bottomBar = LK.getAsset('background', { anchorX: 0, anchorY: 1, x: 0, y: 2732, width: 2048, height: 1 }); bottomBar.alpha = 0.95; bottomBar.color = 0x000000; // Ekrana ekle game.addChild(topBar); game.addChild(bottomBar); // Animasyonla barları büyüt tween(topBar, { height: targetBarHeight }, { duration: 900, easing: tween.easeInOut }); tween(bottomBar, { height: targetBarHeight, y: 2732 - targetBarHeight }, { duration: 900, easing: tween.easeInOut }); // Oyun alanı sınırlarını daraltmak için global değişken game._screenNarrowed = true; game._topBar = topBar; game._bottomBar = bottomBar; // Oyun alanı sınırlarını güncelle (handleMove ve diğer kontrollerde kullanılabilir) game._playAreaTop = targetBarHeight; game._playAreaBottom = 2732 - targetBarHeight; } } }); } return; // Elmas sadece skor panelinde gösterilecek, oyun alanında diamond objesi spawn edilmez. // --- High Score Save on Win --- addHighScore(score); // --- PORTAL EKLE --- if (!game.portal) { // Portalı ekranın sağında ortalanmış şekilde oluştur, ekran dışına taşmayacak şekilde var portalWidth = 120; var portalHeight = 120; var portalScale = 3.0; // Büyüme sonrası maksimum scale var portalX = 2048 - portalWidth * portalScale / 2 - 40; // Sağdan 40px boşluk bırak var portalY = 2732 / 2; var portal = LK.getAsset('portal', { anchorX: 0.5, anchorY: 0.5, x: portalX, y: portalY, width: portalWidth, height: portalHeight }); portal.scaleX = 1.2; portal.scaleY = 1.2; portal.alpha = 1; portal.isShrinking = false; portal.lastWasIntersecting = false; game.portal = portal; game.addChild(portal); // Portal büyüme animasyonu: 1.2'den 3.0'a kadar büyüsün portal._growTweenStarted = true; tween(portal, { scaleX: 3.0, scaleY: 3.0 }, { duration: 1200, easing: tween.easeOut, onFinish: function onFinish() { portal._growTweenStarted = false; // --- EKRAN DARALTMA: Boss öldükten sonra üstten ve alttan siyah barlar gelsin --- if (!game._screenNarrowed) { // Bar yüksekliği: toplam 600px (üst 300, alt 300) gibi, animasyonlu gelsin var barHeight = 0; var targetBarHeight = 300; // Üst bar var topBar = LK.getAsset('background', { anchorX: 0, anchorY: 0, x: 0, y: 0, width: 2048, height: 1 }); topBar.alpha = 0.95; topBar.color = 0x000000; // Alt bar var bottomBar = LK.getAsset('background', { anchorX: 0, anchorY: 1, x: 0, y: 2732, width: 2048, height: 1 }); bottomBar.alpha = 0.95; bottomBar.color = 0x000000; // Ekrana ekle game.addChild(topBar); game.addChild(bottomBar); // Animasyonla barları büyüt tween(topBar, { height: targetBarHeight }, { duration: 900, easing: tween.easeInOut }); tween(bottomBar, { height: targetBarHeight, y: 2732 - targetBarHeight }, { duration: 900, easing: tween.easeInOut }); // Oyun alanı sınırlarını daraltmak için global değişken game._screenNarrowed = true; game._topBar = topBar; game._bottomBar = bottomBar; // Oyun alanı sınırlarını güncelle (handleMove ve diğer kontrollerde kullanılabilir) game._playAreaTop = targetBarHeight; game._playAreaBottom = 2732 - targetBarHeight; } } }); } // Oyun bitmesin, win popup gösterme return; } } } // Boss oyuncuya çarparsa hasar versin if (playerShip && game.bossImg) { var dxp = playerShip.x - game.bossImg.x; var dyp = playerShip.y - game.bossImg.y; var distp = Math.sqrt(dxp * dxp + dyp * dyp); var bossRadius = (game.bossImg.width || 400) / 2; var playerRadius = playerShip.radius || (playerShip.width ? playerShip.width / 2 : 70); if (distp < bossRadius + playerRadius - 20) { // Sadece ilk çarpışmada hasar uygula (her frame değil) if (!game.bossLastPlayerHit) { // Patlama efekti var bossPlayerHit = LK.getAsset('patlamaeffekt', { anchorX: 0.5, anchorY: 0.5, x: playerShip.x, y: playerShip.y, width: playerShip.width || 140, height: playerShip.height || 100 }); game.addChild(bossPlayerHit); tween(bossPlayerHit, { alpha: 0, scaleX: 2, scaleY: 2 }, { duration: 400, onFinish: function onFinish() { bossPlayerHit.destroy(); } }); setPlayerHealth(playerHealth - 10); // boss çarpışma hasarı 10 (daha fazla) if (playerHealth <= 0) { LK.showGameOver(); return; } game.bossLastPlayerHit = true; } } else { game.bossLastPlayerHit = false; } } } // (Geri alındı: scrollX += scrollSpeed ile sağa doğru ilerleme efekti yok) // --- Ava: playerShip ve portal da scrollX ile sağa kaymalı (otomatik hareket yoksa) --- // (Geri alındı: playerShip ve portal scrollSpeed ile sağa kaydırılmıyor) // Portal dinamik efekt: sadece büyüme ve renk döngüsü (nabız efekti kaldırıldı) if (game.portal) { // Portal'ın konumu ve büyümesi: portal ekranın tam ortasında sabit kalır, büyüme animasyonu yok if (game.portal) { // Renk döngüsü (HSV'den RGB'ye basit dönüşüm) var t = LK.ticks % 360 / 360; var h = t, s = 0.7, v = 1.0; var i = Math.floor(h * 6); var f = h * 6 - i; var p = v * (1 - s); var q = v * (1 - f * s); var r, g, b; switch (i % 6) { case 0: r = v, g = q, b = p; break; case 1: r = q, g = v, b = p; break; case 2: r = p, g = v, b = q; break; case 3: r = p, g = q, b = v; break; case 4: r = q, g = p, b = v; break; case 5: r = v, g = p, b = q; break; } var color = Math.round(r * 255) << 16 | Math.round(g * 255) << 8 | Math.round(b * 255); game.portal.color = color; } if (typeof game.portal.isShrinking === "undefined") game.portal.isShrinking = false; if (typeof game.portal.lastWasIntersecting === "undefined") game.portal.lastWasIntersecting = false; // --- Portal büyümesi bittikten sonra playership otomatik geçişi için ek kodlar --- if (game.portal && !game.portal.isShrinking && !game.portal._autoMoveStarted && !game.portal.lastWasIntersecting) { // Portal büyüme animasyonu bittiyse (scaleX >= 3.0 - 0.01) if (!game.portal._growTweenStarted && Math.abs(game.portal.scaleX - 3.0) < 0.01 && playerShip && !playerShip._autoMovingToPortal) { // Otomatik hareket başlatılmadan önce 2 saniye bekle game.portal._autoMoveStarted = true; playerShip._autoMovingToPortal = true; // Hedef portalın merkezi var portalTargetX = game.portal.x; var portalTargetY = game.portal.y; LK.setTimeout(function () { // 2 saniye sonra otomatik hareket başlasın tween(playerShip, { x: portalTargetX, y: portalTargetY }, { duration: 2000, easing: tween.easeInOut, onFinish: function onFinish() { // Hareket bittiğinde flag kaldır playerShip._autoMovingToPortal = false; } }); }, 2000); } } // Oyuncu gemisi portal ile temas etti mi? var portalIntersect = false; if (playerShip && !game.portal.isShrinking) { // Portal ve gemi çarpışma kontrolü (daire-çarpışma) var dx = playerShip.x - game.portal.x; var dy = playerShip.y - game.portal.y; var portalRadius = (game.portal.width ? game.portal.width / 2 : 60) * game.portal.scaleX; var playerRadius = playerShip.radius || (playerShip.width ? playerShip.width / 2 : 70); var dist = Math.sqrt(dx * dx + dy * dy); portalIntersect = dist < portalRadius + playerRadius - 10; if (!game.portal.lastWasIntersecting && portalIntersect) { // Gemi portalın içine girdi: gemi ve mermiler kaybolsun, portal küçülüp ışık patlamasıyla kaybolsun // Gemi kaybolsun (görsel olarak) if (playerShip && playerShip.parent) { tween(playerShip, { alpha: 0, scaleX: 0.2, scaleY: 0.2 }, { duration: 400, onFinish: function onFinish() { if (playerShip && playerShip.parent) { playerShip.destroy(); } } }); } // Tüm mermileri kaybolma animasyonuyla yok et for (var i = bullets.length - 1; i >= 0; i--) { var b = bullets[i]; if (b && b.parent) { b.visible = false; // Portal geçildikten sonra mermiler görünmesin b.alpha = 0; b.destroy(); } } bullets = []; // Portal küçülmeye başlasın game.portal.isShrinking = true; tween(game.portal, { scaleX: 0.1, scaleY: 0.1, alpha: 0.0 }, { duration: 900, easing: tween.easeIn, onFinish: function onFinish() { // Işık patlaması efekti if (game.portal && game.portal.parent) { var portalExplosion = LK.getAsset('portalblast', { anchorX: 0.5, anchorY: 0.5, x: game.portal.x, y: game.portal.y, width: (game.portal.width || 120) * (game.portal.scaleX || 1.0) * 2.2, height: (game.portal.height || 120) * (game.portal.scaleY || 1.0) * 2.2 }); portalExplosion.alpha = 0.85; game.addChild(portalExplosion); tween(portalExplosion, { alpha: 0, scaleX: 2.5, scaleY: 2.5 }, { duration: 500, onFinish: function onFinish() { if (portalExplosion && portalExplosion.parent) portalExplosion.destroy(); // Portal tamamen kaybolduktan sonra win ekranı göster // LK.showYouWin(); // Win ekranı gösterme KALDIRILDI // --- Ava: Ekrana 'continius' yazısı ekle --- var continiusText = new Text2("continius", { size: 140, fill: 0xFFE066, font: "'GillSans-Bold', 'Segoe UI', 'Arial', 'Tahoma'", maxWidth: 1800 }); continiusText.anchor.set(0.5, 0.5); continiusText.x = 2048 / 2; continiusText.y = 2732 / 2; continiusText.alpha = 0; game.addChild(continiusText); tween(continiusText, { alpha: 1 }, { duration: 800, onFinish: function onFinish() { // Birkaç saniye sonra yavaşça kaybolsun tween(continiusText, { alpha: 0 }, { duration: 1800, delay: 2200, onFinish: function onFinish() { if (continiusText && continiusText.parent) continiusText.destroy(); } }); } }); } }); game.portal.destroy(); game.portal = null; } } }); } game.portal.lastWasIntersecting = portalIntersect; } } // --- Black Hole (Kara Delik) Mekaniği --- // Kara delik objesi ve spawn kontrolü if (typeof blackHoleObj === "undefined") blackHoleObj = null; if (typeof lastBlackHoleSpawnTick === "undefined") lastBlackHoleSpawnTick = -10000; var blackHoleSpawnCooldown = 4200 + Math.floor(Math.random() * 1800); // 70-100 sn arası if (!blackHoleObj && LK.ticks - lastBlackHoleSpawnTick > blackHoleSpawnCooldown) { // %5 olasılıkla kara delik spawn et (çok nadir) if (Math.random() < 0.05) { blackHoleObj = LK.getAsset('background', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2 + 400 + Math.random() * 400 - 200, y: 400 + Math.random() * (2732 - 800), width: 180, height: 180 }); blackHoleObj.alpha = 0.7; blackHoleObj.color = 0x222233; blackHoleObj.vx = -2.5 - Math.random() * 2.5; blackHoleObj.vy = (Math.random() - 0.5) * 2.0; blackHoleObj.radius = 90; blackHoleObj._pullStrength = 0.7 + Math.random() * 0.5; blackHoleObj._lifetime = 900 + Math.floor(Math.random() * 600); // 15-25 sn ekranda kalır blackHoleObj._spawnTick = LK.ticks; blackHoleObj.update = function () { // Hareket blackHoleObj.x += blackHoleObj.vx; blackHoleObj.y += blackHoleObj.vy; // Ekran dışına çıkarsa yok et if (blackHoleObj.x < -200 || blackHoleObj.x > 2048 + 200 || blackHoleObj.y < -200 || blackHoleObj.y > 2732 + 200) { blackHoleObj.destroy(); blackHoleObj = null; return; } // Süresi dolduysa yok et if (LK.ticks - blackHoleObj._spawnTick > blackHoleObj._lifetime) { // Fade out tween(blackHoleObj, { alpha: 0 }, { duration: 600, onFinish: function onFinish() { if (blackHoleObj && blackHoleObj.parent) blackHoleObj.destroy(); blackHoleObj = null; } }); return; } // Kara delik çekim etkisi: yakınındaki objeleri kendine çeker var pullRadius = 420; // Uzay cisimleri for (var i = 0; i < spaceObjects.length; i++) { var so = spaceObjects[i]; if (!so || !so.x || !so.y) continue; var dx = blackHoleObj.x - so.x; var dy = blackHoleObj.y - so.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < pullRadius && dist > 1) { var pull = blackHoleObj._pullStrength * (1 - dist / pullRadius); so.vx += dx / dist * pull; so.vy += dy / dist * pull; } } // Mermiler for (var i = 0; i < bullets.length; i++) { var b = bullets[i]; if (!b || !b.x || !b.y) continue; var dx = blackHoleObj.x - b.x; var dy = blackHoleObj.y - b.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < pullRadius && dist > 1) { var pull = blackHoleObj._pullStrength * 0.7 * (1 - dist / pullRadius); b.speed *= 0.98; // Kara delik yakınında mermiler yavaşlar b.x += dx / dist * pull * 0.7; b.y += dy / dist * pull * 0.7; } } // Oyuncu gemisi if (playerShip && playerShip.x && playerShip.y) { var dx = blackHoleObj.x - playerShip.x; var dy = blackHoleObj.y - playerShip.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < pullRadius && dist > 1) { var pull = blackHoleObj._pullStrength * 0.5 * (1 - dist / pullRadius); // Sürüklenmiyorsa gemiyi hafifçe çeksin if (!dragging && !playerShip._autoMovingToPortal) { playerShip.x += dx / dist * pull; playerShip.y += dy / dist * pull; } } // Kara deliğe çok yaklaşırsa (merkezine), anında yok olma if (dist < blackHoleObj.radius + (playerShip.radius || 70) - 10) { // Patlama efekti var bhExpl = LK.getAsset('patlamaeffekt', { anchorX: 0.5, anchorY: 0.5, x: playerShip.x, y: playerShip.y, width: playerShip.width || 140, height: playerShip.height || 100 }); game.addChild(bhExpl); tween(bhExpl, { alpha: 0, scaleX: 2, scaleY: 2 }, { duration: 400, onFinish: function onFinish() { bhExpl.destroy(); } }); setPlayerHealth(0); if (playerHealth <= 0) { LK.showGameOver(); return; } } } // Hafif nabız efekti var t = LK.ticks % 60 / 60; var scale = 1.0 + 0.08 * Math.sin(t * Math.PI * 2); blackHoleObj.scaleX = scale; blackHoleObj.scaleY = scale; }; game.addChild(blackHoleObj); lastBlackHoleSpawnTick = LK.ticks; } else { // spawn denemesi başarısızsa tekrar denemek için tick'i güncelleme lastBlackHoleSpawnTick = LK.ticks; } } // Kara delik güncellemesi if (blackHoleObj && blackHoleObj.update) { blackHoleObj.update(); } // --- Nadiren çıkan diamond objesi için global değişken ve spawn sistemi --- if (typeof diamondObj === "undefined") diamondObj = null; if (typeof lastDiamondSpawnTick === "undefined") lastDiamondSpawnTick = -10000; var diamondSpawnCooldown = 3600 + Math.floor(Math.random() * 1800); // 1-1.5 dakika arası (60fps*60=3600) if (!diamondObj && LK.ticks - lastDiamondSpawnTick > diamondSpawnCooldown) { // %7 olasılıkla diamond spawn et (çok nadir) if (Math.random() < 0.07) { diamondObj = LK.getAsset('diamond', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2 + 600 + Math.random() * 400 - 200, y: 400 + Math.random() * (2732 - 800), width: 100, height: 100 }); diamondObj.alpha = 0.95; diamondObj.vx = -3 - Math.random() * 2.5; diamondObj.vy = (Math.random() - 0.5) * 2.0; diamondObj.update = function () { diamondObj.x += diamondObj.vx; diamondObj.y += diamondObj.vy; // Ekran dışına çıkarsa yok et if (diamondObj.x < -150 || diamondObj.x > 2048 + 150 || diamondObj.y < -150 || diamondObj.y > 2732 + 150) { diamondObj.destroy(); diamondObj = null; return; } }; game.addChild(diamondObj); lastDiamondSpawnTick = LK.ticks; } else { // spawn denemesi başarısızsa tekrar denemek için tick'i güncelleme lastDiamondSpawnTick = LK.ticks; } } // --- Time Freeze Power-up (Zamanı Dondur) --- // Sadece bir tane ekranda olabilir if (typeof timeFreezeObj === "undefined") timeFreezeObj = null; if (typeof lastTimeFreezeSpawnTick === "undefined") lastTimeFreezeSpawnTick = -10000; var timeFreezeSpawnCooldown = 2400 + Math.floor(Math.random() * 1200); // 40-60 sn arası if (!timeFreezeObj && LK.ticks - lastTimeFreezeSpawnTick > timeFreezeSpawnCooldown) { // %08 olasılıkla zaman dondur spawn et if (Math.random() < 0.08) { timeFreezeObj = LK.getAsset('background', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2 + 400 + Math.random() * 400 - 200, y: 400 + Math.random() * (2732 - 800), width: 120, height: 120 }); timeFreezeObj.alpha = 0.92; timeFreezeObj.color = 0x66e0ff; timeFreezeObj.vx = -3 - Math.random() * 2.5; timeFreezeObj.vy = (Math.random() - 0.5) * 2.0; timeFreezeObj.radius = 60; timeFreezeObj._lifetime = 600 + Math.floor(Math.random() * 400); // 10-16 sn ekranda kalır timeFreezeObj._spawnTick = LK.ticks; timeFreezeObj.update = function () { timeFreezeObj.x += timeFreezeObj.vx; timeFreezeObj.y += timeFreezeObj.vy; // Ekran dışına çıkarsa yok et if (timeFreezeObj.x < -150 || timeFreezeObj.x > 2048 + 150 || timeFreezeObj.y < -150 || timeFreezeObj.y > 2732 + 150) { timeFreezeObj.destroy(); timeFreezeObj = null; return; } // Süresi dolduysa yok et if (LK.ticks - timeFreezeObj._spawnTick > timeFreezeObj._lifetime) { tween(timeFreezeObj, { alpha: 0 }, { duration: 400, onFinish: function onFinish() { if (timeFreezeObj && timeFreezeObj.parent) timeFreezeObj.destroy(); timeFreezeObj = null; } }); return; } // Oyuncu toplarsa zamanı dondur if (playerShip && isCircleHit(timeFreezeObj, playerShip)) { // Efekt: patlama var tfEffect = LK.getAsset('patlamaeffekt', { anchorX: 0.5, anchorY: 0.5, x: timeFreezeObj.x, y: timeFreezeObj.y, width: 120, height: 120 }); tfEffect.alpha = 0.7; game.addChild(tfEffect); tween(tfEffect, { alpha: 0, scaleX: 2, scaleY: 2 }, { duration: 400, onFinish: function onFinish() { tfEffect.destroy(); } }); // Zamanı dondur: tüm düşmanlar ve mermiler 3 saniye boyunca hareket etmesin game._timeFreezeActive = true; game._timeFreezeEndTick = LK.ticks + 180; // 3 saniye // Görsel: ekranın üstünde "Zaman Dondu!" yazısı var freezeText = new Text2("Zaman Dondu!", { size: 110, fill: 0x66e0ff, font: "'GillSans-Bold', 'Segoe UI', 'Arial', 'Tahoma'", maxWidth: 1800 }); freezeText.anchor.set(0.5, 0.5); freezeText.x = 2048 / 2; freezeText.y = 2732 / 2 - 300; freezeText.alpha = 0; game.addChild(freezeText); tween(freezeText, { alpha: 1 }, { duration: 400, onFinish: function onFinish() { tween(freezeText, { alpha: 0 }, { duration: 800, delay: 1800, onFinish: function onFinish() { if (freezeText && freezeText.parent) freezeText.destroy(); } }); } }); timeFreezeObj.destroy(); timeFreezeObj = null; } // Hafif parıltı efekti var t = LK.ticks % 60 / 60; var scale = 1.0 + 0.12 * Math.sin(t * Math.PI * 2); timeFreezeObj.scaleX = scale; timeFreezeObj.scaleY = scale; }; game.addChild(timeFreezeObj); lastTimeFreezeSpawnTick = LK.ticks; } else { lastTimeFreezeSpawnTick = LK.ticks; } } // Time freeze güncellemesi if (timeFreezeObj && timeFreezeObj.update) { timeFreezeObj.update(); } // Time freeze aktifse, düşmanlar ve mermiler hareket etmesin if (game._timeFreezeActive) { if (LK.ticks >= game._timeFreezeEndTick) { game._timeFreezeActive = false; } else { // Düşmanlar ve mermiler update fonksiyonlarını atla for (var i = 0; i < spaceObjects.length; i++) { if (spaceObjects[i]) spaceObjects[i].vx = 0, spaceObjects[i].vy = 0; } if (game.enemyBullets) { for (var i = 0; i < game.enemyBullets.length; i++) { if (game.enemyBullets[i]) game.enemyBullets[i].speed = 0; } } if (game.bossBullets) { for (var i = 0; i < game.bossBullets.length; i++) { if (game.bossBullets[i]) game.bossBullets[i].vx = 0, game.bossBullets[i].vy = 0; } } if (game.bossFires) { for (var i = 0; i < game.bossFires.length; i++) { if (game.bossFires[i]) game.bossFires[i].vx = 0, game.bossFires[i].vy = 0; } } } } // Gift spawn: gift yoksa ve spawn süresi dolduysa nadiren spawn et // OYUNUN BAŞINDA HEDİYE/ÖDÜL VERİLMEZ: ilk 10 saniye (600 tick) ödül yok var minGiftSpawnTick = 600; // 10 saniye (60fps*10) if (LK.ticks <= minGiftSpawnTick) { // İlk 10 saniye ödül/gift/diamond verilmeyecek } else if (!giftBg && LK.ticks - lastGiftSpawnTick > giftSpawnCooldown && LK.ticks > minGiftSpawnTick) { // Rastgele olasılıkla gift spawn et (ör: %60 olasılık) if (Math.random() < 0.6) { spawnGift(); } else { // spawn denemesi başarısızsa tekrar denemek için tick'i güncelleme lastGiftSpawnTick = LK.ticks; } } // Gift güncellemesi (power-up çarpışma kontrolü) if (giftBg && giftBg.update) { giftBg.update(); } // Diamond objesi güncellemesi if (diamondObj && diamondObj.update) { diamondObj.update(); } // Boss öldüğünde çıkan diamond objesi güncellemesi if (typeof bossDiamondObj !== "undefined" && bossDiamondObj && bossDiamondObj.update) { bossDiamondObj.update(); } // Aktif power-up süresini kontrol et if (activePowerUp && LK.ticks >= powerUpEndTick) { deactivatePowerUp(); } // Power-up efektleri: hız, kalkan, skor çarpanı if (activePowerUp === "speedup" && playerShip && dragging) { // Sürükleme hızını artırmak için handleMove fonksiyonunda hız limiti artırılabilir // (Burada ek bir kod gerekmez, handleMove zaten sınırları kontrol ediyor) } if (activePowerUp === "shield" && playerShip && playerShip._shieldCircle) { // Kalkan efekti: hafif nabız animasyonu var t = LK.ticks % 60 / 60; var scale = 1.3 + 0.1 * Math.sin(t * Math.PI * 2); playerShip._shieldCircle.scaleX = scale; playerShip._shieldCircle.scaleY = scale; } // Power-up skor çarpanı: skor eklenirken game._scoreMultiplier kullanılır if (!game._scoreMultiplier) game._scoreMultiplier = 1; // --- Orijinal kod --- };
===================================================================
--- original.js
+++ change.js
@@ -266,10 +266,10 @@
/****
* Game Code
****/
-// Galaksi arka planı kaldırıldı
// Yıldızlar: Parallax ve hafif dönen yıldızlar
+// Galaksi arka planı kaldırıldı
var starBgCount = 90;
var stars = [];
var starBgContainer = new Container();
for (var i = 0; i < starBgCount; i++) {
@@ -544,9 +544,9 @@
}
}
} else if (btn.menuKey === "about") {
modalTitle = "Hakkında";
- modalContent = "Uzay Macerası - FRVR.Ava.Combo[POGAAS].v1.0";
+ modalContent = "Uzay Macerası - made in TE";
}
var modalTitleText = new Text2(modalTitle, {
size: 100,
fill: 0xFFE066,
düşman uzay gemisi. In-Game asset. 2d. High contrast. No shadows
patlama efekti. In-Game asset. 2d. High contrast. No shadows
mermi yönünü sağa çevir ve yat
satürn. In-Game asset. 2d. High contrast. No shadows
meteor taşı. In-Game asset. 2d. High contrast. No shadows
bölüm sonu canavar için devasa uzay gemisi. In-Game asset. 2d. High contrast. No shadows
rengini değiştir
ışın mermisi. In-Game asset. 2d. High contrast. No shadows
yanan ateş topları. In-Game asset. 2d. High contrast. No shadows
oyunda açılacak bir uzay portalı için görüntüyü netleştir
A magical sci-fi starburst explosion for a 2D game effect, with a bright blue and white energy core bursting outward in radiant spikes, surrounded by glowing particles, swirling light trails, and a soft nebula-like aura. The effect should feel like a powerful portal discharge or dimensional rift opening, with dynamic energy and cinematic glow. Transparent background, digital art style, top-down angle, ideal for sprite use in games.. In-Game asset. 2d. High contrast. No shadows
A stunning 2D top-down galaxy for a space-themed game background, featuring a massive spiral galaxy with swirling arms in vibrant shades of blue, purple, and pink, a bright glowing core, scattered star clusters, distant nebulae, and a few small planets orbiting around. The galaxy should feel colorful, mysterious, and vast, with soft glowing effects and high contrast for a sci-fi aesthetic. Style: digital art, seamless background, suitable for looping game parallax layers.. In-Game asset. 2d. High contrast. No shadows
kalkanın içinde gemi olmasın
A 2D sci-fi gift box or power-up crate floating in space, with a glowing metallic surface, futuristic design, bright neon blue and silver accents, and a soft pulsing light effect. The box should look valuable and mysterious, slightly levitating with subtle sparkles or energy rings around it. Designed for a top-down space shooter game. Transparent background, digital art, ideal for sprite use.. In-Game asset. 2d. High contrast. No shadows
A 2D sci-fi power-up gift box that grants a shield, designed with a glowing blue energy core inside a metallic futuristic container. The box features holographic shield symbols, neon cyan highlights, and soft pulsing light. It is slightly levitating, surrounded by sparkles and a faint energy ring. The design should clearly suggest it gives protective power. Transparent background, digital art style, ideal for sprite use in a top-down space shooter game.. In-Game asset. 2d. High contrast. No shadows
bu görseli hız için değiştir
Design a basic 2D top-down spaceship with a compact, angular body and minimal detailing. The ship should have a small central cockpit, two modest rear thrusters, and one weapon mount. Colors are simple — grays and blues — suggesting a utilitarian design. It should look like a beginner’s ship: reliable but not advanced. In-Game asset. 2d. High contrast. No shadows
Upgrade the Level 1 ship into a more capable 2D top-down design. Add wing extensions with subtle glowing lines, a larger engine section with animated thrusters, and two visible weapon hardpoints. Add more color variation (blues, steel, light glow effects) to indicate progress and increased power.. In-Game asset. 2d. High contrast. No shadows
Transform the ship into a high-tech 2D top-down spacecraft. Add shield emitters with rotating energy halos, four weapon slots, side thrusters, and an enhanced cockpit with a golden or crystal-like glow. The silhouette is wider and more refined. Visuals should include detailed paneling, moving parts, and advanced energy flows.. In-Game asset. 2d. High contrast. No shadows
elmas. In-Game asset. 2d. High contrast. No shadows
uzay 2d etkileyici lazer ışını. In-Game asset. 2d. High contrast. No shadows