User prompt
Baştan da kaliteli Flappy Bird kuşu oluştur.
User prompt
Anladım, Flappy Bird oyunundaki takılma ve oyun bitirme mantığı sorunlarının hala devam ettiğini belirtiyorsun. Bu, önceki talimatlarımın tam olarak uygulanmadığı veya ek düzenlemelere ihtiyaç duyulduğu anlamına geliyor. Bu sorunları kesin olarak çözmek için, yapay zekaya daha keskin ve öncelikli talimatlar veriyorum. Flappy Bird Oyunu: Takılma ve Oyun Bitti Sorunları İçin Kesin Talimatlar **1. Performans Sorunu (Takılma/Donma) - Öncelik 1: Tamamen Ortadan Kaldırılmalı! * Sorun Tespiti: "Takılma hala az da olsa var." Bu, oyunun temel akışkanlığını etkiliyor ve kullanıcı deneyimi için kritik bir engel. * Çözüm Yolu (Kesin Talimat): * Tüm Görsel Değişimler Anında Olmalı: Kuşun zıplaması, yere düşmesi, boruların ve arka planın ilerlemesi gibi tüm görsel güncellemeler anında, milisaniyelik gecikme olmaksızın gerçekleşmelidir. Yapay zekanın "anlık görsel değişim" yeteneği bunu desteklemeli ve en ufak bir takılmaya izin vermemelidir. * Tıklama Tepkisi Gecikmesiz Olmalı: Oyuncu ekrana her tıkladığında, kuşun dikey konumu aynı anda, gecikmesiz bir şekilde yukarı doğru güncellenmelidir. Herhangi bir "sıraya alma" veya "işlem gecikmesi" olmamalıdır. Tıklama ile zıplama arasında hissedilebilir bir fark olmamalıdır. * Optimizasyon Kontrolü: İç algoritmaların, görsel güncellemeleri ve çarpışma kontrollerini en verimli şekilde işlediğinden emin ol. Bu, oyunun hızlı tempoya ayak uydurabilmesi için hayati önem taşır. Eğer bu performans seviyesi mevcut kısıtlamalarla (2D, anlık değişim) yapılabilecek en iyi seviyeyse, bana bu konuda açık bir geri bildirim vermen gerekiyor. **2. Oyun Bitirme Mantığı (Yere Düşünce Ölmemesi) - Öncelik 1: Mutlak Düzeltilmeli! * Sorun Tespiti: "Hala yere düşünce ölmüyor yani oyun bitmiyor." Bu, oyunun temel kuralını ve oynanabilirliğini doğrudan etkileyen bir hata. * Çözüm Yolu (Kesin Talimat): * Zemin Çarpışması Anında Tespit: Kuşun dikey konumu, zemin görselinin bulunduğu seviyeye ulaştığı AN, oyunun anında çarpışmayı algılaması ve tetiklemesi gerekmektedir. Burada hiçbir gecikme kabul edilemez. * Boru Çarpışması Anında Tespit: Benzer şekilde, kuşun konumu bir boru görselinin bulunduğu hücreyle herhangi bir anda çakıştığı AN, oyunun anında çarpışmayı algılaması ve tetiklemesi gerekmektedir. * Anında Oyun Durumu Değişikliği: Çarpışma (zemine veya boruya) tespit edildiği milisaniyede: * Oyun Durdurulmalı: Kuşun otomatik düşüşü, boruların ve arka planın yatay ilerlemesi hemen durmalıdır. Skor artışı da durmalıdır. * Mesaj Anında Belirmeli: "OYUN BİTTİ!" veya "ÇARPTIN!" mesajı, ekranın ortasında gecikme olmadan, anında belirmelidir. * Görsel Geri Bildirim: Kuşun görseli, çarptığı anda anlık olarak "hasarlı" veya "düşmüş" bir versiyonuna geçmeli veya rengi kısa bir an için kırmızıya dönmelidir. * Kontroller Devre Dışı: Oyun "bitti" durumuna geçtiği andan itibaren, oyuncunun ekrana yapacağı herhangi bir tıklama kesinlikle yok sayılmalı ve kuşun hareketini etkilememelidir. Sadece "Tekrar Oyna" ve "Ana Menüye Dön" butonları işlevsel kalmalıdır. Bu butonlar da oyun bittikten hemen sonra anında görünür olmalı ve tıklanabilir olmalıdır. Bu talimatlar, oyunun en temel mekanik sorunlarını çözmeye odaklanmıştır. Bu sorunların giderilmesi, diğer geliştirmelerden önce kesinlikle sağlanmalıdır.
User prompt
Anladım. Flappy Bird oyunundaki performans sorunları ve oyun sonu mantığındaki aksaklıkları düzeltmek için yapay zekaya daha net ve spesifik talimatlar veriyorum. Flappy Bird Oyunu Düzeltme ve İyileştirme Talimatları 1. Performans Sorunları (Kasma/Donma Düzeltmesi): * Sorun Tespiti: "Hızlı tıklayınca kasma donma oluyor." Bu, muhtemelen görsellerin anlık değişimi veya çarpışma algılama döngülerinin hızlı tıklamalarla senkronize olamamasından kaynaklanıyor. * Düzeltme İsteği: * Anlık Tepki Garantisi: Kullanıcı ekrana her tıkladığında, kuşun anında yukarı zıplamasını sağla. Hiçbir gecikme veya donma yaşanmamalıdır. * Optimal Görsel Geçiş Hızı: Arka plan ve boruların yatay ilerlemesi ile kuşun dikey hareketinin akıcıymış gibi hissettiren en stabil hızı bul ve bu hızda çalışmasını sağla. Aşırı hızlı değişimler kasma yapabilir. Bu, yapay zekanın sahip olduğu "anlık görsel değişim" yeteneğinin en verimli şekilde kullanılmasını gerektirir. * Kaynak Kullanımı Optimizasyonu: Eğer mümkünse, görsel değişimlerin ve çarpışma kontrollerinin işlemci üzerindeki yükünü minimuma indir. Bu, arka planda çalışan komutların daha verimli hale getirilmesi anlamına gelir. 2. Oyun Sonu Mantığı Düzeltmesi: * Sorun Tespiti: "Kuş yere çarpınca değil yere çarpıp bizim tıklamamızla beraber daha yeni oyun bitti diyor." Bu, oyunun bitiş anının yanlış zamanda tetiklendiği veya geri bildirimin geciktiği anlamına geliyor. * Düzeltme İsteği: * Anlık Çarpışma Tespiti: Kuşun zemine (yere) veya borulara çarptığı AN, çarpışma anlık olarak tespit edilsin. Bu tespitte hiçbir gecikme olmamalıdır. * Anında Oyun Bitti Durumu: Çarpışma tespit edildiği an, oyun hemen durmalı (kuşun hareketi, boruların ilerlemesi, skor artışı hepsi dursun). * Gecikmesiz Geri Bildirim: Oyunun durmasıyla eş zamanlı olarak ve gecikme olmadan "OYUN BİTTİ!" mesajı ekranda belirmelidir. Ayrıca kuşun görseli anında "düşmüş/hasarlı" versiyonuna geçmeli veya kısa bir an için rengi değişmelidir. * Tıklama Engellemesi: Oyun "bitti" durumuna geçtiği andan itibaren, oyuncunun ekrana yapacağı herhangi bir tıklama yok sayılmalı ve kuşun hareketini etkilememelidir. "Tekrar Oyna" veya "Ana Menüye Dön" butonları ise oyun bittikten hemen sonra görünür olmalı ve çalışmalıdır. Bu talimatlar, hem performans hem de oyun sonu mantığındaki temel sorunları gidermeyi hedeflemektedir. Yapay zekanın "anlık görsel değişim" ve "tıklama tabanlı etkileşim" yetenekleri bu düzeltmeler için anahtar olacaktır.
Code edit (1 edits merged)
Please save this source code
User prompt
Flappy Bird - Zıplayan Kuş
Initial prompt
Anladım! Ayrı ayrı geliştirdiğimiz prensibini koruyarak, Flappy Bird oyununu, yapay zekanın yetenek kısıtlamaları (2 boyutlu, anlık görsel değişimler, tıklama/basma tabanlı etkileşimler, akıcı animasyonlar veya kaydırma yok) dahilinde, tüm detaylarıyla sıfırdan tanımlıyorum. Modül Tanımı: 2 Boyutlu "Flappy Bird" Benzeri Oyun Bu modül, oyuncunun bir kuşu (veya benzeri bir karakteri) ekrana tıklayarak zıplatıp engellerden kaçırdığı, puan topladığı ve sonsuz bir ilerleme hissi veren basit bir beceri oyunudur. 1. Temel UI ve Oyun Alanı Tanımı * Ekran Boyutu: Oyun, açıldığında kendisine ayrılan ekran alanını tamamen kaplasın. * Arka Plan: Oyun alanı, sonsuz bir ilerleme illüzyonu vermek için yatay olarak sürekli "kayan" (aslında anlık olarak değişen) bir arka plana sahip olsun. * Görsel: Açık mavi bir gökyüzü (gündüz) veya koyu mavi/mor bir gece gökyüzü (gece modu için) gibi bir tema seçilebilir. * Detaylar: Uzakta sabit duran (ama oyun ilerledikçe değişen) bulutlar, dağlar, şehir siluetleri gibi öğeler ekleyebiliriz. Bunlar, ana arka plan görselinin bir parçası olarak anlık olarak değişerek ilerleme hissi verecektir. * Zemin/Yer: Ekranın en alt kısmında, karakterin üzerine düşebileceği, yeşil çim veya şehir yolu gibi sabit bir zemin görseli bulunsun. Karakter bu zemine çarptığında oyun biter. * Karakter (Kuş): * Görsel: Oyuncuyu temsil eden, yandan görünüşlü, sade ve sevimli 2 boyutlu bir kuş (veya top, kare gibi bir figür) görseli. Rengi, arka plandan ve borulardan belirgin bir şekilde ayrılsın (örneğin parlak sarı veya kırmızı). * Kanat Çırpma (Basit İllüzyon): Kuşun iki farklı statik kanat pozisyonu görseli olsun (kanatlar yukarıda ve kanatlar aşağıda). Oyuncu tıklama yaptığında, kuşun görseli anlık olarak kanatları yukarıda olan versiyona geçsin ve kısa bir süre sonra anlık olarak kanatları aşağıda olan versiyona geri dönsün. Bu, basit bir "çırpma" illüzyonu yaratır. * Konum: Kuş, ekranın sol orta kısmında, yatayda sabit bir konumda dursun. Sadece dikeyde (yukarı-aşağı) hareket edecek. * Borular/Engeller: * Görsel: Ekranın sağ tarafından sola doğru "gelen" (anlık olarak beliren ve değişen) dikey boru (veya sütun) çiftleri. Bu borular, ekranın üstünden ve altından gelerek ortalarında belirli bir geçiş boşluğu bırakır. Boruların rengi (örneğin yeşil veya metalik gri) ve dokusu olsun. * Oluşum: Boru çiftleri, ekranda belirli aralıklarla (örneğin her 2-3 saniyede bir) sağ taraftan anlık olarak belirsin ve sola doğru anlık olarak ilerleyerek (yani farklı boru segmenti görselleriyle değişerek) hareket illüzyonu yaratsın. * Boşluk: Her boru çiftinin ortasındaki boşluk dikeyde rastgele bir yükseklikte konumlandırılsın. Bu boşluğun boyutu sabit kalsın. 2. UI ve Göstergeler * Skor Paneli: Ekranın üst kısmında, ortalanmış, büyük ve okunabilir bir metin paneli bulunsun: "SKOR: [Miktar]" (başlangıçta SKOR: 0). * Puan Kazanımı: Kuş, bir boru çiftinin boşluğundan her başarılı geçtiğinde (yani boru çifti ekranın solundan tamamen çıktığında), skor anlık olarak artsın (örneğin her başarılı geçiş için 1 puan). * Oyun Durumu Mesajı: Oyun başladığında "Başlamak İçin Tıkla", çarpışma durumunda "OYUN BİTTİ!" gibi mesajları gösterecek boş bir metin alanı ekranın ortasında bulunabilir. 3. Kontrol Mekaniği ve İlerleme (Anlık Değişimler) * Karakter Kontrolü: * Tıklama/Basma: Oyuncu, ekrana herhangi bir yere tıklayabilir veya tek bir "Zıpla" düğmesine basabilir. * Zıplama: Her tıklamada, kuş anlık olarak belirli bir miktar yukarıya zıplasın (örneğin 3-4 hücre yukarı). * Yerçekimi: Kuş, tıklanmadığı sürece, sabit bir hızla anlık olarak aşağıya düşsün. Bu, her zamanlayıcı döngüsünde kuşun dikey konumunun anlık olarak birer birer azalmasıyla simüle edilir. * Oyunun İlerlemesi (Otomatik): * Arka plan ve borular, belirlediğimiz bir zaman aralığıyla (örneğin her 100-200 milisaniyede bir) otomatik olarak soldan sağa doğru anlık olarak ilerlesin. Bu, sürekli hareket ve sonsuz yol hissi yaratır. * İlerleme hızı, oyun ilerledikçe (belirli bir skora ulaşıldığında) anlık olarak artırılabilir (zorluk artışı). * Çarpışma Kontrolü (Anlık): * Boru Çarpışması: Kuşun konumu, bir boru görselinin bulunduğu bir hücreyle çakıştığında, çarpışma anlık olarak tespit edilsin. * Zemin Çarpışması: Kuşun dikey konumu, zemin seviyesine ulaştığında, çarpışma anlık olarak tespit edilsin. * Çarpışma Durumu: Çarpışma tespit edildiğinde: * Oyun Durumu Mesajı alanında "OYUN BİTTİ!" gibi bir mesaj anlık olarak belirtsin. * Skor paneli dursun. * Kuşun görseli anlık olarak "düşmüş" veya "hasar görmüş" bir versiyonuyla değişebilir. * Oyun dursun (ilerleme durur, tıklamalar işe yaramaz). 4. Oyun Sonlandırma ve Yeniden Başlatma * Oyun Bitti Ekranı: Oyun bittiğinde, oyun alanı ve kuş sabit kalsın. * Butonlar: Ekranın alt kısmında veya sonuç mesajının altında iki belirgin buton olsun: * "Tekrar Oyna" Butonu: Bu butona tıklanınca, oyun anlık olarak sıfırlansın, skor sıfırlansın, kuş başlangıç konumuna dönsün, yeni borular belirmeye başlasın ve yeni bir oyun başlasın. * "Ana Menüye Dön" Butonu: Bu butona tıklanınca, oyuncu anlık olarak telefon simülasyonunun ana ekranına geri dönsün. Bu detaylı tanım, Flappy Bird benzeri bir oyunu, yapay zekanın 2 boyutlu ve anlık değişim yetenekleriyle eksiksiz bir şekilde simüle etmesini sağlayacaktır. Akıcı animasyonlar yerine anlık görsel değişimlerle "zıplama", "kanat çırpma" ve "ilerleme" hissi yaratılacaktır.
/**** * Plugins ****/ var storage = LK.import("@upit/storage.v1"); var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Bird = Container.expand(function () { var self = Container.call(this); // Create bird graphics with proper anchoring var birdGraphics = self.attachAsset('bird', { anchorX: 0.5, anchorY: 0.5 }); // Initialize bird properties self.velocity = 0; self.flapCooldown = 0; // Optimized flap function self.flap = function () { // Prevent rapid flapping if (self.flapCooldown > 0) return; if (gameOver) return; self.flapCooldown = 8; // Frames to wait before next flap // Set velocity with improved scaling for better responsiveness self.velocity = jumpStrength; // Play flap sound with minimal error handling if (LK.getSound('flap')) { LK.getSound('flap').play(); } }; // Optimized update method self.update = function () { // Update cooldowns if (self.flapCooldown > 0) self.flapCooldown--; if (!gameStarted) { // Pre-game idle state self.y = 1366; self.x = 300; return; } // Simple physics with improved scaling if (!gameOver) { // Only update position if game is not over self.velocity += gravity; self.y += self.velocity; } // Update rotation only when velocity changes significantly if (Math.abs(self.velocity - (self.lastVelocity || 0)) > 2) { birdGraphics.rotation = self.velocity > 0 ? 0.8 : -0.4; self.lastVelocity = self.velocity; } // Screen bounds collision if (self.y < 40) { self.y = 40; self.velocity = 0; } if (self.y > 2582) { self.y = 2582; self.velocity = 0; if (!gameOver) { gameOver = true; // Trigger game over showGameOverScreen(LK.getScore()); // Show game over screen with score } } }; return self; }); var Pipe = Container.expand(function (gapCenterY) { var self = Container.call(this); // Fixed gap size for consistent gameplay self.gapSize = 850; // Normal gap - increased for easier passage self.speed = pipeSpeed; self.passed = false; self.gapCenterY = gapCenterY; self.pipeWidth = 120; // Calculate pipe heights var topPipeHeight = Math.max(200, gapCenterY - self.gapSize / 2); var bottomPipeHeight = Math.max(200, 2732 - 150 - (gapCenterY + self.gapSize / 2)); // --- Flappy Bird style: dark base, highlight, and shadow for realism --- // Top pipe main body (dark green) var topPipe = self.attachAsset('topPipe', { anchorX: 0.5, anchorY: 1 }); topPipe.y = gapCenterY - self.gapSize / 2; topPipe.height = topPipeHeight; topPipe.width = self.pipeWidth; topPipe.tint = 0x1a3c1a; // dark green // Top pipe highlight (lighter green, left side) var topPipeHighlight = self.attachAsset('pipeHighlight', { anchorX: 0.5, anchorY: 1 }); topPipeHighlight.y = gapCenterY - self.gapSize / 2; topPipeHighlight.height = topPipeHeight; topPipeHighlight.width = 32; topPipeHighlight.x = -self.pipeWidth / 2 + 16; topPipeHighlight.tint = 0x3be24d; // bright highlight // Top pipe shadow (darker, right side) var topPipeShadow = self.attachAsset('pipeHighlight', { anchorX: 0.5, anchorY: 1 }); topPipeShadow.y = gapCenterY - self.gapSize / 2; topPipeShadow.height = topPipeHeight; topPipeShadow.width = 32; topPipeShadow.x = self.pipeWidth / 2 - 16; topPipeShadow.tint = 0x0d1a0d; // very dark green // Bottom pipe main body (dark green) var bottomPipe = self.attachAsset('bottomPipe', { anchorX: 0.5, anchorY: 0 }); bottomPipe.y = gapCenterY + self.gapSize / 2; bottomPipe.height = bottomPipeHeight; bottomPipe.width = self.pipeWidth; bottomPipe.tint = 0x1a3c1a; // dark green // Bottom pipe highlight (lighter green, left side) var bottomPipeHighlight = self.attachAsset('pipeHighlight', { anchorX: 0.5, anchorY: 0 }); bottomPipeHighlight.y = gapCenterY + self.gapSize / 2; bottomPipeHighlight.height = bottomPipeHeight; bottomPipeHighlight.width = 32; bottomPipeHighlight.x = -self.pipeWidth / 2 + 16; bottomPipeHighlight.tint = 0x3be24d; // bright highlight // Bottom pipe shadow (darker, right side) var bottomPipeShadow = self.attachAsset('pipeHighlight', { anchorX: 0.5, anchorY: 0 }); bottomPipeShadow.y = gapCenterY + self.gapSize / 2; bottomPipeShadow.height = bottomPipeHeight; bottomPipeShadow.width = 32; bottomPipeShadow.x = self.pipeWidth / 2 - 16; bottomPipeShadow.tint = 0x0d1a0d; // very dark green // Pipe caps (yellowish, like Flappy Bird) var topPipeCap = self.attachAsset('pipeTop', { anchorX: 0.5, anchorY: 1 }); topPipeCap.y = gapCenterY - self.gapSize / 2; topPipeCap.width = self.pipeWidth + 20; topPipeCap.height = 25; topPipeCap.tint = 0xfaf4a0; // yellowish var bottomPipeCap = self.attachAsset('pipeBottom', { anchorX: 0.5, anchorY: 0 }); bottomPipeCap.y = gapCenterY + self.gapSize / 2; bottomPipeCap.width = self.pipeWidth + 20; bottomPipeCap.height = 25; bottomPipeCap.tint = 0xfaf4a0; // yellowish self.update = function () { if (!gameStarted) { return; } // Move pipes to the left (negative speed) so bird appears to move forward self.x += self.speed; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game(); /**** * Game Code ****/ // Initialize persistent storage using storage plugin var currentLanguage = storage.language || 'tr'; var gameHighScore = storage.highScore || 0; // Smooth visual feedback function using tween function simpleColorTint(target, color, duration, callback) { var originalTint = target.tint; target.tint = color; // Smooth transition back to original color tween(target, { tint: originalTint }, { duration: duration || 150, easing: tween.easeOut, onFinish: callback }); } var bird; var pipes = []; var ground; var gameStarted = false; var gameOver = false; var showMainMenu = true; var showGameOver = false; // Button click time tracking removed to eliminate delays var gravity = 0.55; // Gravity for bird - fine-tuned for better control var jumpStrength = -9.5; // Jump strength for bird - fine-tuned for better balance var pipeSpeed = -3.5; // Pipe movement speed - increased for better challenge // Score display var scoreText = new Text2('0', { size: 120, fill: 0xFFFFFF }); scoreText.anchor.set(0.5, 0); scoreText.stroke = 0x000000; scoreText.strokeThickness = 6; scoreText.visible = false; // Initially hidden, shown when game starts LK.gui.top.addChild(scoreText); scoreText.y = 100; // Position below the top menu area // Create cup shape for score var cupShape = LK.getAsset('cup', { anchorX: 0.5, anchorY: 0 }); cupShape.tint = 0xFFD700; LK.gui.bottomRight.addChild(cupShape); cupShape.y = -230; cupShape.x = -100; // Create main menu elements var mainMenuTitle = new Text2('FLAPPY BIRD', { size: 90, fill: 0xFFD700 }); mainMenuTitle.anchor.set(0.5, 0.5); mainMenuTitle.stroke = 0x000000; mainMenuTitle.strokeThickness = 5; LK.gui.center.addChild(mainMenuTitle); mainMenuTitle.y = -280; // Create instruction text var instructionTxt = new Text2('TIKLA VE OYNA!', { size: 50, fill: 0xFFFFFF }); instructionTxt.anchor.set(0.5, 0.5); instructionTxt.stroke = 0x000000; instructionTxt.strokeThickness = 3; instructionTxt.visible = false; instructionTxt.y = -50; // Remove background shape for instruction text - no longer needed LK.gui.center.addChild(instructionTxt); // Create game over screen elements var gameOverBg = LK.getAsset('topPipe', { anchorX: 0.5, anchorY: 0.5, width: 1600, height: 1200, alpha: 0.95 }); gameOverBg.tint = 0x2F4F4F; gameOverBg.visible = false; LK.gui.center.addChild(gameOverBg); // Create high score screen elements var highScoreBg = LK.getAsset('topPipe', { anchorX: 0.5, anchorY: 0.5, width: 1400, height: 800, alpha: 0.95 }); highScoreBg.tint = 0x2F4F4F; highScoreBg.visible = false; LK.gui.center.addChild(highScoreBg); var highScoreTitle = new Text2('EN YÜKSEK SKOR', { size: 100, fill: 0xFFD700 }); highScoreTitle.anchor.set(0.5, 0.5); highScoreTitle.stroke = 0x000000; highScoreTitle.strokeThickness = 5; highScoreTitle.visible = false; LK.gui.center.addChild(highScoreTitle); highScoreTitle.y = -200; var highScoreValue = new Text2('0', { size: 150, fill: 0xFFFFFF }); highScoreValue.anchor.set(0.5, 0.5); highScoreValue.stroke = 0x000000; highScoreValue.strokeThickness = 6; highScoreValue.visible = false; LK.gui.center.addChild(highScoreValue); highScoreValue.y = 0; var highScoreCloseButton = LK.getAsset('playButtonOval', { anchorX: 0.5, anchorY: 0.5, width: 300, height: 80, alpha: 1.0 }); highScoreCloseButton.tint = 0x7F8C8D; highScoreCloseButton.visible = false; LK.gui.center.addChild(highScoreCloseButton); highScoreCloseButton.y = 200; var highScoreCloseText = new Text2('KAPAT', { size: 40, fill: 0xFFFFFF }); highScoreCloseText.anchor.set(0.5, 0.5); highScoreCloseText.stroke = 0x566573; highScoreCloseText.strokeThickness = 3; highScoreCloseText.visible = false; LK.gui.center.addChild(highScoreCloseText); highScoreCloseText.y = 200; var gameOverTitle = new Text2('OYUN BİTTİ', { size: 120, fill: 0xFFFFFF }); gameOverTitle.anchor.set(0.5, 0.5); gameOverTitle.stroke = 0x000000; gameOverTitle.strokeThickness = 6; gameOverTitle.visible = false; LK.gui.center.addChild(gameOverTitle); gameOverTitle.y = -300; var finalScoreText = new Text2('SKOR: 0', { size: 80, fill: 0xFFFFFF }); finalScoreText.anchor.set(0.5, 0.5); finalScoreText.stroke = 0x000000; finalScoreText.strokeThickness = 4; finalScoreText.visible = false; LK.gui.center.addChild(finalScoreText); finalScoreText.y = -150; var bestScoreText = new Text2('EN İYİ: 0', { size: 60, fill: 0xFFD700 }); bestScoreText.anchor.set(0.5, 0.5); bestScoreText.stroke = 0x000000; bestScoreText.strokeThickness = 3; bestScoreText.visible = false; LK.gui.center.addChild(bestScoreText); bestScoreText.y = -50; // Create retry button with enhanced styling var retryButton = LK.getAsset('playButtonOval', { anchorX: 0.5, anchorY: 0.5, width: 380, height: 110, alpha: 1.0 }); retryButton.tint = 0xFF9800; // Orange like original Flappy Bird retryButton.visible = false; LK.gui.center.addChild(retryButton); retryButton.y = 100; // Add retry button shadow for depth var retryButtonShadow = LK.getAsset('playButtonOval', { anchorX: 0.5, anchorY: 0.5, width: 380, height: 110, alpha: 0.3 }); retryButtonShadow.tint = 0xE65100; // Darker orange shadow retryButtonShadow.visible = false; LK.gui.center.addChild(retryButtonShadow); retryButtonShadow.y = 108; // Offset shadow slightly down retryButtonShadow.x = 4; // Offset shadow slightly right // Add retry button highlight var retryButtonHighlight = LK.getAsset('playButtonOval', { anchorX: 0.5, anchorY: 0.5, width: 350, height: 85, alpha: 0.4 }); retryButtonHighlight.tint = 0xFFB74D; // Lighter orange highlight retryButtonHighlight.visible = false; LK.gui.center.addChild(retryButtonHighlight); retryButtonHighlight.y = 92; // Offset highlight slightly up var retryButtonText = new Text2('TEKRAR DENE', { size: 44, fill: 0xFFFFFF }); retryButtonText.anchor.set(0.5, 0.5); retryButtonText.stroke = 0xE65100; retryButtonText.strokeThickness = 3; retryButtonText.visible = false; LK.gui.center.addChild(retryButtonText); retryButtonText.y = 100; // Create menu button with enhanced styling var menuButton = LK.getAsset('playButtonOval', { anchorX: 0.5, anchorY: 0.5, width: 380, height: 110, alpha: 1.0 }); menuButton.tint = 0xF44336; // Red like original Flappy Bird menuButton.visible = false; LK.gui.center.addChild(menuButton); menuButton.y = 250; // Add menu button shadow for depth var menuButtonShadow = LK.getAsset('playButtonOval', { anchorX: 0.5, anchorY: 0.5, width: 380, height: 110, alpha: 0.3 }); menuButtonShadow.tint = 0xD32F2F; // Darker red shadow menuButtonShadow.visible = false; LK.gui.center.addChild(menuButtonShadow); menuButtonShadow.y = 258; // Offset shadow slightly down menuButtonShadow.x = 4; // Offset shadow slightly right // Add menu button highlight var menuButtonHighlight = LK.getAsset('playButtonOval', { anchorX: 0.5, anchorY: 0.5, width: 350, height: 85, alpha: 0.4 }); menuButtonHighlight.tint = 0xEF5350; // Lighter red highlight menuButtonHighlight.visible = false; LK.gui.center.addChild(menuButtonHighlight); menuButtonHighlight.y = 242; // Offset highlight slightly up var menuButtonText = new Text2('ANA MENÜ', { size: 44, fill: 0xFFFFFF }); menuButtonText.anchor.set(0.5, 0.5); menuButtonText.stroke = 0xD32F2F; menuButtonText.strokeThickness = 3; menuButtonText.visible = false; LK.gui.center.addChild(menuButtonText); menuButtonText.y = 250; // Simple background setup var background = game.addChild(LK.getAsset('background', { anchorX: 0, anchorY: 0 })); background.x = 0; background.y = 0; background.scaleX = 2; background.scaleY = 2; // Create ground ground = game.addChild(LK.getAsset('ground', { anchorX: 0, anchorY: 1 })); ground.x = 0; ground.y = 2732; ground.tint = 0x654321; // Create bird bird = game.addChild(new Bird()); bird.x = 300; bird.y = 1366; // Pre-generate initial pipes function with better performance function generateAllPipes() { // Define safe boundaries for gap center to ensure both pipes have reasonable heights var minGapY = 700; // Minimum gap center position for better clearance var maxGapY = 1900; // Maximum gap center position for better clearance // Generate initial set of pipes only - generate more as needed during gameplay var initialPipesNeeded = 10; // Start with fewer pipes for better performance var currentX = 2500; // Starting position to the right of screen since pipes move left var pipeSpacing = 600; // Spacing between pipes // Clear existing pipes first for (var i = pipes.length - 1; i >= 0; i--) { if (pipes[i] && typeof pipes[i].destroy === "function") { pipes[i].destroy(); } } pipes = []; for (var pipeIndex = 0; pipeIndex < initialPipesNeeded; pipeIndex++) { var gapCenterY; // Create varied random patterns with better distribution var randomPattern = Math.random(); if (randomPattern < 0.4) { // 40% chance for high gaps (easier to navigate) gapCenterY = minGapY + Math.random() * 300; } else if (randomPattern < 0.7) { // 30% chance for middle gaps (moderate difficulty) gapCenterY = 1000 + Math.random() * 500; } else { // 30% chance for low gaps (more challenging but still passable) gapCenterY = maxGapY - Math.random() * 300; } // Ensure the gap stays within safe boundaries gapCenterY = Math.max(minGapY, Math.min(maxGapY, gapCenterY)); var pipe = new Pipe(gapCenterY); pipe.x = currentX; pipe.passed = false; pipes.push(pipe); game.addChild(pipe); // Move to next pipe position currentX += pipeSpacing; } } // Function to generate new pipes as needed during gameplay function generateNewPipe() { var minGapY = 700; var maxGapY = 1900; var pipeSpacing = 600; // Find rightmost pipe position var rightmostX = 2500; for (var i = 0; i < pipes.length; i++) { if (pipes[i] && pipes[i].x > rightmostX) { rightmostX = pipes[i].x; } } // Create new pipe to the right of the rightmost pipe var newX = rightmostX + pipeSpacing; var randomPattern = Math.random(); var gapCenterY; if (randomPattern < 0.4) { gapCenterY = minGapY + Math.random() * 300; } else if (randomPattern < 0.7) { gapCenterY = 1000 + Math.random() * 500; } else { gapCenterY = maxGapY - Math.random() * 300; } gapCenterY = Math.max(minGapY, Math.min(maxGapY, gapCenterY)); var pipe = new Pipe(gapCenterY); pipe.x = newX; pipe.passed = false; pipes.push(pipe); game.addChild(pipe); } // Reset game function function resetGame() { // Reset bird position bird.x = 300; bird.y = 1366; bird.velocity = 0; // Clear pipes for (var i = pipes.length - 1; i >= 0; i--) { if (pipes[i] && typeof pipes[i].destroy === "function") { pipes[i].destroy(); } } pipes = []; // Reset variables gameStarted = false; gameOver = false; showGameOver = false; // Hide game over screen hideGameOverScreen(); LK.setScore(0); // Reset score display if (scoreText) { scoreText.setText('0'); } // Show main menu with smooth fade in showMainMenu = true; var menuElements = [{ element: mainMenuTitle, targetAlpha: 1, delay: 0 }, { element: playButton, targetAlpha: 1, delay: 100 }, { element: playButtonShadow, targetAlpha: 0.4, delay: 100 }, { element: playButtonHighlight, targetAlpha: 0.5, delay: 100 }, { element: playButtonText, targetAlpha: 1, delay: 100 }, { element: cupShape, targetAlpha: 1, delay: 200 }, { element: mainLanguageButton, targetAlpha: 1, delay: 300 }, { element: mainLanguageButtonShadow, targetAlpha: 0.3, delay: 300 }, { element: mainLanguageButtonHighlight, targetAlpha: 0.4, delay: 300 }, { element: mainLanguageButtonText, targetAlpha: 1, delay: 300 }]; menuElements.forEach(function (item) { if (item.element) { item.element.alpha = 0; item.element.visible = true; LK.setTimeout(function () { tween(item.element, { alpha: item.targetAlpha }, { duration: 400, easing: tween.easeOut }); }, item.delay); } }); // Hide instruction instructionTxt.visible = false; // Hide score display scoreText.visible = false; generateAllPipes(); } // Function to start game from main menu function startGameFromMenu() { showMainMenu = false; // Fade out main menu elements smoothly tween(mainMenuTitle, { alpha: 0 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { mainMenuTitle.visible = false; mainMenuTitle.alpha = 1; } }); // Hide play button elements with fade if (playButton) { tween(playButton, { alpha: 0 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { playButton.visible = false; playButton.alpha = 1; } }); } if (playButtonShadow) { tween(playButtonShadow, { alpha: 0 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { playButtonShadow.visible = false; playButtonShadow.alpha = 0.4; } }); } if (playButtonHighlight) { tween(playButtonHighlight, { alpha: 0 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { playButtonHighlight.visible = false; playButtonHighlight.alpha = 0.5; } }); } if (playButtonText) { tween(playButtonText, { alpha: 0 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { playButtonText.visible = false; playButtonText.alpha = 1; } }); } // Hide cup shape (high score indicator) if (cupShape) { tween(cupShape, { alpha: 0 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { cupShape.visible = false; cupShape.alpha = 1; } }); } // Hide main language button elements if (mainLanguageButton) { tween(mainLanguageButton, { alpha: 0 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { mainLanguageButton.visible = false; mainLanguageButton.alpha = 1; } }); } if (mainLanguageButtonShadow) { tween(mainLanguageButtonShadow, { alpha: 0 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { mainLanguageButtonShadow.visible = false; mainLanguageButtonShadow.alpha = 0.3; } }); } if (mainLanguageButtonHighlight) { tween(mainLanguageButtonHighlight, { alpha: 0 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { mainLanguageButtonHighlight.visible = false; mainLanguageButtonHighlight.alpha = 0.4; } }); } if (mainLanguageButtonText) { tween(mainLanguageButtonText, { alpha: 0 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { mainLanguageButtonText.visible = false; mainLanguageButtonText.alpha = 1; } }); } // Show instruction and score with fade in instructionTxt.alpha = 0; instructionTxt.visible = true; tween(instructionTxt, { alpha: 1 }, { duration: 400, easing: tween.easeOut }); scoreText.alpha = 0; scoreText.visible = true; scoreText.setText('0'); tween(scoreText, { alpha: 1 }, { duration: 400, easing: tween.easeOut }); } // Function to show game over screen function showGameOverScreen(finalScore) { if (showGameOver) return; showGameOver = true; gameStarted = false; // Hide all other menus first to prevent overlap hideLanguageControls(); hideHighScoreScreen(); // Hide instruction and score with fade tween(instructionTxt, { alpha: 0 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { instructionTxt.visible = false; instructionTxt.alpha = 1; } }); tween(scoreText, { alpha: 0 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { scoreText.visible = false; scoreText.alpha = 1; } }); // Show game over elements with smooth fade in gameOverBg.alpha = 0; gameOverBg.visible = true; tween(gameOverBg, { alpha: 0.95 }, { duration: 400, easing: tween.easeOut }); gameOverTitle.alpha = 0; gameOverTitle.visible = true; tween(gameOverTitle, { alpha: 1 }, { duration: 500, easing: tween.easeOut }); finalScoreText.alpha = 0; finalScoreText.visible = true; // Update final score text var currentScore = LK.getScore(); finalScoreText.setText(getText('score') + ': ' + currentScore); tween(finalScoreText, { alpha: 1 }, { duration: 600, easing: tween.easeOut }); bestScoreText.alpha = 0; bestScoreText.visible = true; // Show buttons with staggered animation retryButton.alpha = 0; retryButton.visible = true; retryButtonText.alpha = 0; retryButtonText.visible = true; retryButtonShadow.alpha = 0; retryButtonShadow.visible = true; retryButtonHighlight.alpha = 0; retryButtonHighlight.visible = true; menuButton.alpha = 0; menuButton.visible = true; menuButtonText.alpha = 0; menuButtonText.visible = true; menuButtonShadow.alpha = 0; menuButtonShadow.visible = true; menuButtonHighlight.alpha = 0; menuButtonHighlight.visible = true; // Remove score display - do not show final score // Always show the current high score from persistent storage var currentHighScore = storage.highScore || 0; // Update high score if current score is higher if (finalScore > currentHighScore) { storage.highScore = finalScore; currentHighScore = finalScore; // Smooth visual feedback for new high score if (bestScoreText && bestScoreText.visible) { tween(bestScoreText, { tint: 0xFF0000 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(bestScoreText, { tint: 0xFFD700 }, { duration: 300, easing: tween.easeOut }); } }); } } bestScoreText.setText(getText('bestScore') + ': ' + currentHighScore); tween(bestScoreText, { alpha: 1 }, { duration: 700, easing: tween.easeOut }); // Use proper text sizing if (bestScoreText.width > 600) { var newSize = Math.max(40, Math.floor(60 * 600 / bestScoreText.width)); bestScoreText.style = { size: newSize, fill: bestScoreText.style.fill }; } // Animate buttons in with delay LK.setTimeout(function () { tween(retryButton, { alpha: 1 }, { duration: 300, easing: tween.easeOut }); tween(retryButtonShadow, { alpha: 0.3 }, { duration: 300, easing: tween.easeOut }); tween(retryButtonHighlight, { alpha: 0.4 }, { duration: 300, easing: tween.easeOut }); tween(retryButtonText, { alpha: 1 }, { duration: 300, easing: tween.easeOut }); }, 400); LK.setTimeout(function () { tween(menuButton, { alpha: 1 }, { duration: 300, easing: tween.easeOut }); tween(menuButtonShadow, { alpha: 0.3 }, { duration: 300, easing: tween.easeOut }); tween(menuButtonHighlight, { alpha: 0.4 }, { duration: 300, easing: tween.easeOut }); tween(menuButtonText, { alpha: 1 }, { duration: 300, easing: tween.easeOut }); }, 600); } // Function to hide game over screen function hideGameOverScreen() { showGameOver = false; // Fade out game over elements smoothly var elementsToHide = [gameOverBg, gameOverTitle, finalScoreText, bestScoreText, retryButton, retryButtonText, retryButtonShadow, retryButtonHighlight, menuButton, menuButtonText, menuButtonShadow, menuButtonHighlight]; elementsToHide.forEach(function (element) { if (element && element.visible) { tween(element, { alpha: 0 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { element.visible = false; element.alpha = element === gameOverBg ? 0.95 : element === retryButtonShadow || element === menuButtonShadow ? 0.3 : element === retryButtonHighlight || element === menuButtonHighlight ? 0.4 : 1; } }); } }); } // Function to show high score screen function showHighScoreScreen() { // Hide any other screens to prevent overlap hideGameOverScreen(); hideLanguageControls(); // Hide main menu elements first to prevent overlap if (showMainMenu) { tween(mainMenuTitle, { alpha: 0 }, { duration: 250, easing: tween.easeOut, onFinish: function onFinish() { mainMenuTitle.visible = false; mainMenuTitle.alpha = 1; } }); if (playButton) { tween(playButton, { alpha: 0 }, { duration: 250, easing: tween.easeOut, onFinish: function onFinish() { playButton.visible = false; playButton.alpha = 1; } }); } if (playButtonShadow) { tween(playButtonShadow, { alpha: 0 }, { duration: 250, easing: tween.easeOut, onFinish: function onFinish() { playButtonShadow.visible = false; playButtonShadow.alpha = 0.4; } }); } if (playButtonHighlight) { tween(playButtonHighlight, { alpha: 0 }, { duration: 250, easing: tween.easeOut, onFinish: function onFinish() { playButtonHighlight.visible = false; playButtonHighlight.alpha = 0.5; } }); } if (playButtonText) { tween(playButtonText, { alpha: 0 }, { duration: 250, easing: tween.easeOut, onFinish: function onFinish() { playButtonText.visible = false; playButtonText.alpha = 1; } }); } if (mainLanguageButton) { tween(mainLanguageButton, { alpha: 0 }, { duration: 250, easing: tween.easeOut, onFinish: function onFinish() { mainLanguageButton.visible = false; mainLanguageButton.alpha = 1; } }); } if (mainLanguageButtonShadow) { tween(mainLanguageButtonShadow, { alpha: 0 }, { duration: 250, easing: tween.easeOut, onFinish: function onFinish() { mainLanguageButtonShadow.visible = false; mainLanguageButtonShadow.alpha = 0.3; } }); } if (mainLanguageButtonHighlight) { tween(mainLanguageButtonHighlight, { alpha: 0 }, { duration: 250, easing: tween.easeOut, onFinish: function onFinish() { mainLanguageButtonHighlight.visible = false; mainLanguageButtonHighlight.alpha = 0.4; } }); } if (mainLanguageButtonText) { tween(mainLanguageButtonText, { alpha: 0 }, { duration: 250, easing: tween.easeOut, onFinish: function onFinish() { mainLanguageButtonText.visible = false; mainLanguageButtonText.alpha = 1; } }); } } // Update high score value var currentHighScore = storage.highScore || 0; highScoreValue.setText(currentHighScore.toString()); highScoreTitle.setText(getText('highestScore')); highScoreCloseText.setText(getText('close') || 'KAPAT'); // Show high score elements with fade in var highScoreElements = [{ element: highScoreBg, targetAlpha: 0.95, delay: 0 }, { element: highScoreTitle, targetAlpha: 1, delay: 100 }, { element: highScoreValue, targetAlpha: 1, delay: 200 }, { element: highScoreCloseButton, targetAlpha: 1, delay: 300 }, { element: highScoreCloseText, targetAlpha: 1, delay: 300 }]; highScoreElements.forEach(function (item) { if (item.element) { item.element.alpha = 0; item.element.visible = true; LK.setTimeout(function () { tween(item.element, { alpha: item.targetAlpha }, { duration: 300, easing: tween.easeOut }); }, item.delay); } }); } // Function to hide high score screen function hideHighScoreScreen() { // Fade out high score elements var highScoreElements = [highScoreBg, highScoreTitle, highScoreValue, highScoreCloseButton, highScoreCloseText]; var fadeOutCompleted = 0; highScoreElements.forEach(function (element) { if (element && element.visible) { tween(element, { alpha: 0 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { element.visible = false; element.alpha = element === highScoreBg ? 0.95 : 1; fadeOutCompleted++; // Show main menu after all high score elements have faded out if (fadeOutCompleted === highScoreElements.length && showMainMenu && !showGameOver && !gameOverBg.visible && !languageOverlay.visible) { // Fade in main menu elements var menuElements = [mainMenuTitle, playButton, playButtonShadow, playButtonHighlight, playButtonText, mainLanguageButton, mainLanguageButtonShadow, mainLanguageButtonHighlight, mainLanguageButtonText]; menuElements.forEach(function (menuElement, index) { if (menuElement) { menuElement.alpha = 0; menuElement.visible = true; tween(menuElement, { alpha: menuElement === playButtonShadow ? 0.4 : menuElement === playButtonHighlight ? 0.5 : menuElement === mainLanguageButtonShadow ? 0.3 : menuElement === mainLanguageButtonHighlight ? 0.4 : 1 }, { duration: 300, delay: index * 30, easing: tween.easeOut }); } }); } } }); } }); } // Create language overlay background var languageOverlay = LK.getAsset('topPipe', { anchorX: 0.5, anchorY: 0.5, width: 2048, height: 2732, alpha: 1.0 }); languageOverlay.tint = 0x2F4F4F; languageOverlay.visible = false; LK.gui.center.addChild(languageOverlay); // Create language control title var languageTitle = new Text2('DİL SEÇENEKLERİ', { size: 80, fill: 0xFFFFFF }); languageTitle.anchor.set(0.5, 0.5); languageTitle.stroke = 0x000000; languageTitle.strokeThickness = 4; languageTitle.visible = false; LK.gui.center.addChild(languageTitle); languageTitle.y = -200; // Create language option buttons with modern rectangular design var turkishButton = LK.getAsset('settingsButtonRect', { anchorX: 0.5, anchorY: 0.5, width: 260, height: 65, alpha: 1.0 }); turkishButton.tint = 0x27AE60; turkishButton.visible = false; LK.gui.center.addChild(turkishButton); turkishButton.y = -80; turkishButton.x = -220; // Add Turkish button shadow var turkishButtonShadow = LK.getAsset('settingsButtonRect', { anchorX: 0.5, anchorY: 0.5, width: 260, height: 65, alpha: 0.3 }); turkishButtonShadow.tint = 0x1E8449; turkishButtonShadow.visible = false; LK.gui.center.addChild(turkishButtonShadow); turkishButtonShadow.y = -75; turkishButtonShadow.x = -217; // Add Turkish button highlight var turkishButtonHighlight = LK.getAsset('settingsButtonRect', { anchorX: 0.5, anchorY: 0.5, width: 240, height: 50, alpha: 0.4 }); turkishButtonHighlight.tint = 0x58D68D; turkishButtonHighlight.visible = false; LK.gui.center.addChild(turkishButtonHighlight); turkishButtonHighlight.y = -85; turkishButtonHighlight.x = -220; var turkishText = new Text2('TÜRKÇE', { size: 32, fill: 0xFFFFFF }); turkishText.anchor.set(0.5, 0.5); turkishText.stroke = 0x1E8449; turkishText.strokeThickness = 2; turkishText.visible = false; LK.gui.center.addChild(turkishText); turkishText.y = -80; turkishText.x = -220; var englishButton = LK.getAsset('settingsButtonRect', { anchorX: 0.5, anchorY: 0.5, width: 260, height: 65, alpha: 1.0 }); englishButton.tint = 0x3498DB; englishButton.visible = false; LK.gui.center.addChild(englishButton); englishButton.y = -80; englishButton.x = 220; // Add English button shadow var englishButtonShadow = LK.getAsset('settingsButtonRect', { anchorX: 0.5, anchorY: 0.5, width: 260, height: 65, alpha: 0.3 }); englishButtonShadow.tint = 0x2980B9; englishButtonShadow.visible = false; LK.gui.center.addChild(englishButtonShadow); englishButtonShadow.y = -75; englishButtonShadow.x = 223; // Add English button highlight var englishButtonHighlight = LK.getAsset('settingsButtonRect', { anchorX: 0.5, anchorY: 0.5, width: 240, height: 50, alpha: 0.4 }); englishButtonHighlight.tint = 0x85C1E9; englishButtonHighlight.visible = false; LK.gui.center.addChild(englishButtonHighlight); englishButtonHighlight.y = -85; englishButtonHighlight.x = 220; var englishText = new Text2('ENGLISH', { size: 32, fill: 0xFFFFFF }); englishText.anchor.set(0.5, 0.5); englishText.stroke = 0x2980B9; englishText.strokeThickness = 2; englishText.visible = false; LK.gui.center.addChild(englishText); englishText.y = -80; englishText.x = 220; // Current language indicator var currentLanguageText = new Text2('MEVCUT: TÜRKÇE', { size: 50, fill: 0xFFD700 }); currentLanguageText.anchor.set(0.5, 0.5); currentLanguageText.stroke = 0x000000; currentLanguageText.strokeThickness = 3; currentLanguageText.visible = false; LK.gui.center.addChild(currentLanguageText); currentLanguageText.y = 30; // Create back button for language controls with modern rectangular design var languageBackButton = LK.getAsset('settingsButtonRect', { anchorX: 0.5, anchorY: 0.5, width: 220, height: 65, alpha: 1.0 }); languageBackButton.tint = 0x7F8C8D; languageBackButton.visible = false; LK.gui.center.addChild(languageBackButton); languageBackButton.y = 150; // Add language back button shadow var languageBackButtonShadow = LK.getAsset('settingsButtonRect', { anchorX: 0.5, anchorY: 0.5, width: 220, height: 65, alpha: 0.3 }); languageBackButtonShadow.tint = 0x566573; languageBackButtonShadow.visible = false; LK.gui.center.addChild(languageBackButtonShadow); languageBackButtonShadow.y = 155; languageBackButtonShadow.x = 3; // Add language back button highlight var languageBackButtonHighlight = LK.getAsset('settingsButtonRect', { anchorX: 0.5, anchorY: 0.5, width: 200, height: 50, alpha: 0.4 }); languageBackButtonHighlight.tint = 0xABB2B9; languageBackButtonHighlight.visible = false; LK.gui.center.addChild(languageBackButtonHighlight); languageBackButtonHighlight.y = 145; var languageBackText = new Text2('GERİ', { size: 36, fill: 0xFFFFFF }); languageBackText.anchor.set(0.5, 0.5); languageBackText.stroke = 0x566573; languageBackText.strokeThickness = 2; languageBackText.visible = false; LK.gui.center.addChild(languageBackText); languageBackText.y = 150; // Function to show language controls function showLanguageControls() { // Hide all other menus first to prevent overlap hideGameOverScreen(); hideHighScoreScreen(); // Hide main menu elements with fade tween(mainMenuTitle, { alpha: 0 }, { duration: 250, easing: tween.easeOut, onFinish: function onFinish() { mainMenuTitle.visible = false; mainMenuTitle.alpha = 1; } }); if (playButton) { tween(playButton, { alpha: 0 }, { duration: 250, easing: tween.easeOut, onFinish: function onFinish() { playButton.visible = false; playButton.alpha = 1; } }); } if (playButtonShadow) { tween(playButtonShadow, { alpha: 0 }, { duration: 250, easing: tween.easeOut, onFinish: function onFinish() { playButtonShadow.visible = false; playButtonShadow.alpha = 0.4; } }); } if (playButtonHighlight) { tween(playButtonHighlight, { alpha: 0 }, { duration: 250, easing: tween.easeOut, onFinish: function onFinish() { playButtonHighlight.visible = false; playButtonHighlight.alpha = 0.5; } }); } if (playButtonText) { tween(playButtonText, { alpha: 0 }, { duration: 250, easing: tween.easeOut, onFinish: function onFinish() { playButtonText.visible = false; playButtonText.alpha = 1; } }); } if (cupShape) { tween(cupShape, { alpha: 0 }, { duration: 250, easing: tween.easeOut, onFinish: function onFinish() { cupShape.visible = false; cupShape.alpha = 1; } }); } // Hide main language button elements if (mainLanguageButton) { tween(mainLanguageButton, { alpha: 0 }, { duration: 250, easing: tween.easeOut, onFinish: function onFinish() { mainLanguageButton.visible = false; mainLanguageButton.alpha = 1; } }); } if (mainLanguageButtonShadow) { tween(mainLanguageButtonShadow, { alpha: 0 }, { duration: 250, easing: tween.easeOut, onFinish: function onFinish() { mainLanguageButtonShadow.visible = false; mainLanguageButtonShadow.alpha = 0.3; } }); } if (mainLanguageButtonHighlight) { tween(mainLanguageButtonHighlight, { alpha: 0 }, { duration: 250, easing: tween.easeOut, onFinish: function onFinish() { mainLanguageButtonHighlight.visible = false; mainLanguageButtonHighlight.alpha = 0.4; } }); } if (mainLanguageButtonText) { tween(mainLanguageButtonText, { alpha: 0 }, { duration: 250, easing: tween.easeOut, onFinish: function onFinish() { mainLanguageButtonText.visible = false; mainLanguageButtonText.alpha = 1; } }); } // Show language controls with smooth fade in languageOverlay.alpha = 0; languageOverlay.visible = true; tween(languageOverlay, { alpha: 1 }, { duration: 350, easing: tween.easeOut }); languageTitle.alpha = 0; languageTitle.visible = true; tween(languageTitle, { alpha: 1 }, { duration: 400, easing: tween.easeOut }); // Show language buttons with staggered animation turkishButton.alpha = 0; turkishButton.visible = true; turkishButtonShadow.alpha = 0; turkishButtonShadow.visible = true; turkishButtonHighlight.alpha = 0; turkishButtonHighlight.visible = true; turkishText.alpha = 0; turkishText.visible = true; englishButton.alpha = 0; englishButton.visible = true; englishButtonShadow.alpha = 0; englishButtonShadow.visible = true; englishButtonHighlight.alpha = 0; englishButtonHighlight.visible = true; englishText.alpha = 0; englishText.visible = true; currentLanguageText.alpha = 0; currentLanguageText.visible = true; languageBackButton.alpha = 0; languageBackButton.visible = true; languageBackButtonShadow.alpha = 0; languageBackButtonShadow.visible = true; languageBackButtonHighlight.alpha = 0; languageBackButtonHighlight.visible = true; languageBackText.alpha = 0; languageBackText.visible = true; // Animate language buttons in with delays LK.setTimeout(function () { tween(turkishButton, { alpha: 1 }, { duration: 300, easing: tween.easeOut }); tween(turkishButtonShadow, { alpha: 0.3 }, { duration: 300, easing: tween.easeOut }); tween(turkishButtonHighlight, { alpha: 0.4 }, { duration: 300, easing: tween.easeOut }); tween(turkishText, { alpha: 1 }, { duration: 300, easing: tween.easeOut }); }, 200); LK.setTimeout(function () { tween(englishButton, { alpha: 1 }, { duration: 300, easing: tween.easeOut }); tween(englishButtonShadow, { alpha: 0.3 }, { duration: 300, easing: tween.easeOut }); tween(englishButtonHighlight, { alpha: 0.4 }, { duration: 300, easing: tween.easeOut }); tween(englishText, { alpha: 1 }, { duration: 300, easing: tween.easeOut }); }, 350); LK.setTimeout(function () { tween(currentLanguageText, { alpha: 1 }, { duration: 300, easing: tween.easeOut }); }, 500); LK.setTimeout(function () { tween(languageBackButton, { alpha: 1 }, { duration: 300, easing: tween.easeOut }); tween(languageBackButtonShadow, { alpha: 0.3 }, { duration: 300, easing: tween.easeOut }); tween(languageBackButtonHighlight, { alpha: 0.4 }, { duration: 300, easing: tween.easeOut }); tween(languageBackText, { alpha: 1 }, { duration: 300, easing: tween.easeOut }); }, 650); updateLanguageDisplay(); } // Function to hide language controls function hideLanguageControls() { // Fade out all language control elements var languageElements = [languageOverlay, languageTitle, turkishButton, turkishButtonShadow, turkishButtonHighlight, turkishText, englishButton, englishButtonShadow, englishButtonHighlight, englishText, currentLanguageText, languageBackButton, languageBackButtonShadow, languageBackButtonHighlight, languageBackText]; var fadeOutDuration = 250; var fadeOutCompleted = 0; languageElements.forEach(function (element) { if (element && element.visible) { tween(element, { alpha: 0 }, { duration: fadeOutDuration, easing: tween.easeOut, onFinish: function onFinish() { element.visible = false; element.alpha = element === languageOverlay ? 1 : element === turkishButtonShadow || element === englishButtonShadow || element === languageBackButtonShadow ? 0.3 : element === turkishButtonHighlight || element === englishButtonHighlight || element === languageBackButtonHighlight ? 0.4 : 1; fadeOutCompleted++; // Show main menu after all elements have faded out if (fadeOutCompleted === languageElements.length && showMainMenu && !showGameOver && !gameOverBg.visible && !highScoreBg.visible) { // Fade in main menu elements var menuElements = [mainMenuTitle, playButton, playButtonShadow, playButtonHighlight, playButtonText, cupShape, mainLanguageButton, mainLanguageButtonShadow, mainLanguageButtonHighlight, mainLanguageButtonText]; menuElements.forEach(function (menuElement, index) { if (menuElement) { menuElement.alpha = 0; menuElement.visible = true; tween(menuElement, { alpha: menuElement === playButtonShadow ? 0.4 : menuElement === playButtonHighlight ? 0.5 : menuElement === mainLanguageButtonShadow ? 0.3 : menuElement === mainLanguageButtonHighlight ? 0.4 : 1 }, { duration: 300, delay: index * 30, easing: tween.easeOut }); } }); } } }); } }); } // Language text objects var languageTexts = { tr: { mainTitle: 'FLAPPY BIRD', playButton: 'OYNA', instruction: 'TIKLA VE OYNA!', gameOver: 'OYUN BİTTİ', score: 'SKOR', bestScore: 'EN İYİ', retry: 'TEKRAR DENE', mainMenu: 'ANA MENÜ', language: 'DİL', languageTitle: 'DİL SEÇENEKLERİ', current: 'MEVCUT', highestScore: 'EN YÜKSEK SKOR', back: 'GERİ', close: 'KAPAT' }, en: { mainTitle: 'FLAPPY BIRD', playButton: 'PLAY', instruction: 'CLICK TO PLAY!', gameOver: 'GAME OVER', score: 'SCORE', bestScore: 'BEST', retry: 'RETRY', mainMenu: 'MAIN MENU', language: 'LANGUAGE', languageTitle: 'LANGUAGE OPTIONS', current: 'CURRENT', highestScore: 'HIGHEST SCORE', back: 'BACK', close: 'CLOSE' } }; // Function to get text for current language function getText(key) { return languageTexts[currentLanguage][key] || languageTexts['en'][key]; } // Function to update all text elements to current language function updateAllTexts() { if (instructionTxt) { instructionTxt.setText(getText('instruction')); } if (playButtonText) { playButtonText.setText(getText('playButton')); } if (gameOverTitle) { gameOverTitle.setText(getText('gameOver')); } if (retryButtonText) { retryButtonText.setText(getText('retry')); } if (menuButtonText) { menuButtonText.setText(getText('mainMenu')); } if (languageTitle) { languageTitle.setText(getText('languageTitle')); } if (languageBackText) { languageBackText.setText(getText('back')); } if (mainLanguageButtonText) { mainLanguageButtonText.setText(getText('language')); } // Update final and best score texts if (finalScoreText) { var currentScore = LK.getScore(); finalScoreText.setText(getText('score') + ': ' + currentScore); } if (bestScoreText) { var currentHighScore = storage.highScore || 0; bestScoreText.setText(getText('bestScore') + ': ' + currentHighScore); } } // Function to update language display function updateLanguageDisplay() { var langText = currentLanguage === 'tr' ? 'TÜRKÇE' : 'ENGLISH'; var currentText = currentLanguage === 'tr' ? 'MEVCUT' : 'CURRENT'; if (currentLanguageText) { currentLanguageText.setText(currentText + ': ' + langText); } // Update button colors to show selected language if (turkishButton) { turkishButton.tint = currentLanguage === 'tr' ? 0x2ECC71 : 0x27AE60; } if (englishButton) { englishButton.tint = currentLanguage === 'en' ? 0x5DADE2 : 0x3498DB; } } // Function to set language function setLanguage(lang) { currentLanguage = lang; // Save to persistent storage storage.language = lang; // Update all text elements immediately updateAllTexts(); // Update language display updateLanguageDisplay(); } // Initialize persistent storage with defaults if values don't exist if (typeof storage.highScore === 'undefined') storage.highScore = 0; if (typeof storage.lastScore === 'undefined') storage.lastScore = 0; if (!storage.language) storage.language = 'tr'; // Update current language from persistent storage currentLanguage = storage.language || 'tr'; // Create animated play button for main menu var playButton = LK.getAsset('playButtonMain', { anchorX: 0.5, anchorY: 0.5, width: 400, height: 120, alpha: 1.0 }); playButton.tint = 0xFF9800; // Flappy Bird orange LK.gui.center.addChild(playButton); playButton.y = -100; // Create language button for direct access from main menu var mainLanguageButton = LK.getAsset('playButtonOval', { anchorX: 0.5, anchorY: 0.5, width: 300, height: 80, alpha: 1.0 }); mainLanguageButton.tint = 0x9B59B6; LK.gui.center.addChild(mainLanguageButton); mainLanguageButton.y = 50; // Create language button shadow var mainLanguageButtonShadow = LK.getAsset('playButtonOval', { anchorX: 0.5, anchorY: 0.5, width: 300, height: 80, alpha: 0.3 }); mainLanguageButtonShadow.tint = 0x8E44AD; LK.gui.center.addChild(mainLanguageButtonShadow); mainLanguageButtonShadow.y = 55; mainLanguageButtonShadow.x = 3; // Create language button highlight var mainLanguageButtonHighlight = LK.getAsset('playButtonOval', { anchorX: 0.5, anchorY: 0.5, width: 280, height: 65, alpha: 0.4 }); mainLanguageButtonHighlight.tint = 0xBB8FCE; LK.gui.center.addChild(mainLanguageButtonHighlight); mainLanguageButtonHighlight.y = 45; // Create language button text var mainLanguageButtonText = new Text2('DİL', { size: 36, fill: 0xFFFFFF }); mainLanguageButtonText.anchor.set(0.5, 0.5); mainLanguageButtonText.stroke = 0x8E44AD; mainLanguageButtonText.strokeThickness = 2; LK.gui.center.addChild(mainLanguageButtonText); mainLanguageButtonText.y = 50; // Create separate play button shadow element var playButtonShadow = LK.getAsset('playButtonShadow', { anchorX: 0.5, anchorY: 0.5, width: 400, height: 120, alpha: 0.4 }); playButtonShadow.tint = 0xE65100; // Darker orange shadow LK.gui.center.addChild(playButtonShadow); playButtonShadow.y = -92; // Offset shadow slightly up playButtonShadow.x = 4; // Offset shadow slightly right // Create separate play button highlight element var playButtonHighlight = LK.getAsset('playButtonHighlight', { anchorX: 0.5, anchorY: 0.5, width: 370, height: 95, alpha: 0.5 }); playButtonHighlight.tint = 0xFFB74D; // Lighter orange highlight LK.gui.center.addChild(playButtonHighlight); playButtonHighlight.y = -108; // Offset highlight slightly down // Create separate play button text element var playButtonText = new Text2('OYNA', { size: 50, fill: 0xFFFFFF }); playButtonText.anchor.set(0.5, 0.5); playButtonText.stroke = 0xE65100; playButtonText.strokeThickness = 4; LK.gui.center.addChild(playButtonText); playButtonText.y = -100; // Initialize game resetGame(); // Use resetGame to properly initialize all states // Update all texts to current language updateAllTexts(); // Update language display to show current selection updateLanguageDisplay(); // Touch/click handler game.down = function (x, y, obj) { // Check if high score screen is visible if (highScoreBg.visible) { // Check close button click - centered at 1024x1566 (center.y = 1366 + 200), button is 300x80 if (x >= 874 && x <= 1174 && y >= 1526 && y <= 1606) { // Simple visual feedback simpleColorTint(highScoreCloseButton, 0xABB2B9, 0); hideHighScoreScreen(); return; } return; // Don't process other clicks when high score screen is open } // Check if language overlay is visible and handle language controls if (languageOverlay.visible) { // Turkish language button with isolated click area if (turkishButton.visible && x >= 654 && x <= 954 && y >= 1246 && y <= 1326) { // Simple visual feedback with color change simpleColorTint(turkishButton, 0x58D68D, 0); setLanguage('tr'); return; } // Barrier zone between Turkish and English buttons (x: 954-1094) if (x >= 954 && x <= 1094 && y >= 1246 && y <= 1326) { return; // Block clicks in barrier zone } // English language button with isolated click area if (englishButton.visible && x >= 1094 && x <= 1394 && y >= 1246 && y <= 1326) { // Simple visual feedback with color change simpleColorTint(englishButton, 0x85C1E9, 0); setLanguage('en'); return; } // Check language back button at x = 1024, y = 1516, size 300x100 if (languageBackButton.visible && x >= 874 && x <= 1174 && y >= 1466 && y <= 1566) { // Simple visual feedback with color change simpleColorTint(languageBackButton, 0xABB2B9, 0); hideLanguageControls(); return; } return; // Don't process other clicks when language overlay is open } // Check cup click - cup is positioned at bottomRight with offset var cupX = 2048 - 100; // bottomRight.x + cupShape.x offset var cupY = 2732 - 230; // bottomRight.y + cupShape.y offset var cupSize = 120; // Cup asset size if (x >= cupX - cupSize / 2 && x <= cupX + cupSize / 2 && y >= cupY && y <= cupY + cupSize) { // Show high score screen showHighScoreScreen(); // Simple visual feedback without animation if (cupShape) { cupShape.tint = 0xFFFFFF; cupShape.tint = 0xFFD700; } return; } if (gameOver || showGameOver) { // Check retry button (TEKRAR DENE) - centered at 1024x1466, button is 380x110 if (x >= 834 && x <= 1214 && y >= 1411 && y <= 1521) { // Simple visual feedback with color change simpleColorTint(retryButton, 0xFFB74D, 150, function () { // Fade out game over screen first hideGameOverScreen(); // Wait for fade out to complete before resetting LK.setTimeout(function () { resetGame(); // Show instruction screen instead of starting game directly startGameFromMenu(); }, 250); }); return; } // Check menu button (ANA MENÜ) - centered at 1024x1616, button is 380x110 if (x >= 834 && x <= 1214 && y >= 1561 && y <= 1671) { // Simple visual feedback with color change simpleColorTint(menuButton, 0xF1948A, 150, function () { // Fade out game over screen first hideGameOverScreen(); // Wait for fade out to complete before resetting LK.setTimeout(function () { resetGame(); }, 250); }); return; } return; } if (showMainMenu) { // Check play button click - centered at 1024x1266 (center.y = 1366 + playButton.y = -100), button is 400x120 if (playButton && playButton.visible && x >= 824 && x <= 1224 && y >= 1206 && y <= 1326) { // Simple visual feedback with color change simpleColorTint(playButton, 0xFFB74D, 0); startGameFromMenu(); return; } // Check main language button click - centered at 1024x1416 (center.y = 1366 + mainLanguageButton.y = 50), button is 300x80 if (mainLanguageButton && mainLanguageButton.visible && x >= 874 && x <= 1174 && y >= 1376 && y <= 1456) { // Simple visual feedback with color change simpleColorTint(mainLanguageButton, 0xBB8FCE, 0); showLanguageControls(); return; } return; } if (!gameStarted) { gameStarted = true; instructionTxt.visible = false; } bird.flap(); }; // Main game loop with optimized performance game.update = function () { if (gameOver || showMainMenu || showGameOver) return; // Only run game logic if game has started if (gameStarted) { // Check ground and ceiling collision with proper bird size (bird is 80px tall, 120px wide) var birdRadius = 40; // Half of bird height for collision detection if (bird.y + birdRadius >= ground.y || bird.y - birdRadius <= 0) { gameOver = true; var currentScore = LK.getScore(); // Save score to persistent storage if (currentScore > (storage.highScore || 0)) { storage.highScore = currentScore; } storage.lastScore = currentScore; // Add smooth transition to game over tween(instructionTxt, { alpha: 0 }, { duration: 200, easing: tween.easeOut }); tween(scoreText, { alpha: 0 }, { duration: 200, easing: tween.easeOut }); LK.setTimeout(function () { showGameOverScreen(LK.getScore()); }, 200); return; } // Dynamic pipe generation - generate new pipes as old ones are removed var rightmostPipeX = -1000; for (var i = 0; i < pipes.length; i++) { if (pipes[i] && pipes[i].x > rightmostPipeX) { rightmostPipeX = pipes[i].x; } } // Generate new pipe if the rightmost pipe is getting close to the screen if (rightmostPipeX < 3000) { generateNewPipe(); } // Optimized pipe cleanup - remove pipes that are far behind only for (var i = pipes.length - 1; i >= 0; i--) { var pipe = pipes[i]; // Only remove pipes that are far behind the bird if (pipe && pipe.x < bird.x - 800) { pipe.destroy(); pipes.splice(i, 1); } } // Find closest pipe for collision and scoring var closestPipe = null; var closestDistance = 99999; for (var i = 0; i < pipes.length; i++) { var pipe = pipes[i]; // Check pipes that are close to the bird if (pipe && pipe.x > bird.x - 100 && pipe.x < bird.x + 200) { var distance = Math.abs(pipe.x - bird.x); if (distance < closestDistance) { closestDistance = distance; closestPipe = pipe; } } } if (closestPipe) { // Initialize lastX tracking if (typeof closestPipe.lastX === 'undefined') { closestPipe.lastX = closestPipe.x; } // Scoring check - detect when bird passes through the pipe center // Since pipes move from right to left and bird stays at x=300, check when pipe center passes bird var pipeCenter = closestPipe.x; var birdPosition = bird.x; // Check if pipe center just passed the bird position (was on right, now on left) if (!closestPipe.passed && closestPipe.lastX > birdPosition && pipeCenter <= birdPosition) { // Check if bird is within the gap when pipe passes var gapTop = closestPipe.gapCenterY - closestPipe.gapSize / 2; var gapBottom = closestPipe.gapCenterY + closestPipe.gapSize / 2; // Mark pipe as passed if (bird.y > gapTop && bird.y < gapBottom) { closestPipe.passed = true; // Increment score LK.setScore(LK.getScore() + 1); var currentScore = LK.getScore(); // Update score display with smooth animation if (scoreText && scoreText.visible) { scoreText.setText(currentScore.toString()); // Smooth score flash animation tween(scoreText, { tint: 0xFFD700 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { tween(scoreText, { tint: 0xFFFFFF }, { duration: 200, easing: tween.easeOut }); } }); } // Save high score if current score is higher if (currentScore > (storage.highScore || 0)) { storage.highScore = currentScore; } // Check win condition - game ends at 100 points for better gameplay if (currentScore >= 100) { gameOver = true; storage.lastScore = currentScore; LK.showYouWin(); // Show win screen when reaching 100 points return; } if (LK.getSound('score')) { LK.getSound('score').play(); } } } // Update last position closestPipe.lastX = closestPipe.x; // Collision check - only if very close with better collision detection if (closestPipe.x > bird.x - 80 && closestPipe.x < bird.x + 80) { var gapTop = closestPipe.gapCenterY - closestPipe.gapSize / 2; var gapBottom = closestPipe.gapCenterY + closestPipe.gapSize / 2; // More forgiving collision detection if (bird.y < gapTop + 60 || bird.y > gapBottom - 60) { gameOver = true; // Add smooth transition before showing game over tween(instructionTxt, { alpha: 0 }, { duration: 200, easing: tween.easeOut }); tween(scoreText, { alpha: 0 }, { duration: 200, easing: tween.easeOut }); LK.setTimeout(function () { showGameOverScreen(LK.getScore()); }, 200); return; } } } } };
/****
* Plugins
****/
var storage = LK.import("@upit/storage.v1");
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Bird = Container.expand(function () {
var self = Container.call(this);
// Create bird graphics with proper anchoring
var birdGraphics = self.attachAsset('bird', {
anchorX: 0.5,
anchorY: 0.5
});
// Initialize bird properties
self.velocity = 0;
self.flapCooldown = 0;
// Optimized flap function
self.flap = function () {
// Prevent rapid flapping
if (self.flapCooldown > 0) return;
if (gameOver) return;
self.flapCooldown = 8; // Frames to wait before next flap
// Set velocity with improved scaling for better responsiveness
self.velocity = jumpStrength;
// Play flap sound with minimal error handling
if (LK.getSound('flap')) {
LK.getSound('flap').play();
}
};
// Optimized update method
self.update = function () {
// Update cooldowns
if (self.flapCooldown > 0) self.flapCooldown--;
if (!gameStarted) {
// Pre-game idle state
self.y = 1366;
self.x = 300;
return;
}
// Simple physics with improved scaling
if (!gameOver) {
// Only update position if game is not over
self.velocity += gravity;
self.y += self.velocity;
}
// Update rotation only when velocity changes significantly
if (Math.abs(self.velocity - (self.lastVelocity || 0)) > 2) {
birdGraphics.rotation = self.velocity > 0 ? 0.8 : -0.4;
self.lastVelocity = self.velocity;
}
// Screen bounds collision
if (self.y < 40) {
self.y = 40;
self.velocity = 0;
}
if (self.y > 2582) {
self.y = 2582;
self.velocity = 0;
if (!gameOver) {
gameOver = true; // Trigger game over
showGameOverScreen(LK.getScore()); // Show game over screen with score
}
}
};
return self;
});
var Pipe = Container.expand(function (gapCenterY) {
var self = Container.call(this);
// Fixed gap size for consistent gameplay
self.gapSize = 850; // Normal gap - increased for easier passage
self.speed = pipeSpeed;
self.passed = false;
self.gapCenterY = gapCenterY;
self.pipeWidth = 120;
// Calculate pipe heights
var topPipeHeight = Math.max(200, gapCenterY - self.gapSize / 2);
var bottomPipeHeight = Math.max(200, 2732 - 150 - (gapCenterY + self.gapSize / 2));
// --- Flappy Bird style: dark base, highlight, and shadow for realism ---
// Top pipe main body (dark green)
var topPipe = self.attachAsset('topPipe', {
anchorX: 0.5,
anchorY: 1
});
topPipe.y = gapCenterY - self.gapSize / 2;
topPipe.height = topPipeHeight;
topPipe.width = self.pipeWidth;
topPipe.tint = 0x1a3c1a; // dark green
// Top pipe highlight (lighter green, left side)
var topPipeHighlight = self.attachAsset('pipeHighlight', {
anchorX: 0.5,
anchorY: 1
});
topPipeHighlight.y = gapCenterY - self.gapSize / 2;
topPipeHighlight.height = topPipeHeight;
topPipeHighlight.width = 32;
topPipeHighlight.x = -self.pipeWidth / 2 + 16;
topPipeHighlight.tint = 0x3be24d; // bright highlight
// Top pipe shadow (darker, right side)
var topPipeShadow = self.attachAsset('pipeHighlight', {
anchorX: 0.5,
anchorY: 1
});
topPipeShadow.y = gapCenterY - self.gapSize / 2;
topPipeShadow.height = topPipeHeight;
topPipeShadow.width = 32;
topPipeShadow.x = self.pipeWidth / 2 - 16;
topPipeShadow.tint = 0x0d1a0d; // very dark green
// Bottom pipe main body (dark green)
var bottomPipe = self.attachAsset('bottomPipe', {
anchorX: 0.5,
anchorY: 0
});
bottomPipe.y = gapCenterY + self.gapSize / 2;
bottomPipe.height = bottomPipeHeight;
bottomPipe.width = self.pipeWidth;
bottomPipe.tint = 0x1a3c1a; // dark green
// Bottom pipe highlight (lighter green, left side)
var bottomPipeHighlight = self.attachAsset('pipeHighlight', {
anchorX: 0.5,
anchorY: 0
});
bottomPipeHighlight.y = gapCenterY + self.gapSize / 2;
bottomPipeHighlight.height = bottomPipeHeight;
bottomPipeHighlight.width = 32;
bottomPipeHighlight.x = -self.pipeWidth / 2 + 16;
bottomPipeHighlight.tint = 0x3be24d; // bright highlight
// Bottom pipe shadow (darker, right side)
var bottomPipeShadow = self.attachAsset('pipeHighlight', {
anchorX: 0.5,
anchorY: 0
});
bottomPipeShadow.y = gapCenterY + self.gapSize / 2;
bottomPipeShadow.height = bottomPipeHeight;
bottomPipeShadow.width = 32;
bottomPipeShadow.x = self.pipeWidth / 2 - 16;
bottomPipeShadow.tint = 0x0d1a0d; // very dark green
// Pipe caps (yellowish, like Flappy Bird)
var topPipeCap = self.attachAsset('pipeTop', {
anchorX: 0.5,
anchorY: 1
});
topPipeCap.y = gapCenterY - self.gapSize / 2;
topPipeCap.width = self.pipeWidth + 20;
topPipeCap.height = 25;
topPipeCap.tint = 0xfaf4a0; // yellowish
var bottomPipeCap = self.attachAsset('pipeBottom', {
anchorX: 0.5,
anchorY: 0
});
bottomPipeCap.y = gapCenterY + self.gapSize / 2;
bottomPipeCap.width = self.pipeWidth + 20;
bottomPipeCap.height = 25;
bottomPipeCap.tint = 0xfaf4a0; // yellowish
self.update = function () {
if (!gameStarted) {
return;
}
// Move pipes to the left (negative speed) so bird appears to move forward
self.x += self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game();
/****
* Game Code
****/
// Initialize persistent storage using storage plugin
var currentLanguage = storage.language || 'tr';
var gameHighScore = storage.highScore || 0;
// Smooth visual feedback function using tween
function simpleColorTint(target, color, duration, callback) {
var originalTint = target.tint;
target.tint = color;
// Smooth transition back to original color
tween(target, {
tint: originalTint
}, {
duration: duration || 150,
easing: tween.easeOut,
onFinish: callback
});
}
var bird;
var pipes = [];
var ground;
var gameStarted = false;
var gameOver = false;
var showMainMenu = true;
var showGameOver = false;
// Button click time tracking removed to eliminate delays
var gravity = 0.55; // Gravity for bird - fine-tuned for better control
var jumpStrength = -9.5; // Jump strength for bird - fine-tuned for better balance
var pipeSpeed = -3.5; // Pipe movement speed - increased for better challenge
// Score display
var scoreText = new Text2('0', {
size: 120,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
scoreText.stroke = 0x000000;
scoreText.strokeThickness = 6;
scoreText.visible = false; // Initially hidden, shown when game starts
LK.gui.top.addChild(scoreText);
scoreText.y = 100; // Position below the top menu area
// Create cup shape for score
var cupShape = LK.getAsset('cup', {
anchorX: 0.5,
anchorY: 0
});
cupShape.tint = 0xFFD700;
LK.gui.bottomRight.addChild(cupShape);
cupShape.y = -230;
cupShape.x = -100;
// Create main menu elements
var mainMenuTitle = new Text2('FLAPPY BIRD', {
size: 90,
fill: 0xFFD700
});
mainMenuTitle.anchor.set(0.5, 0.5);
mainMenuTitle.stroke = 0x000000;
mainMenuTitle.strokeThickness = 5;
LK.gui.center.addChild(mainMenuTitle);
mainMenuTitle.y = -280;
// Create instruction text
var instructionTxt = new Text2('TIKLA VE OYNA!', {
size: 50,
fill: 0xFFFFFF
});
instructionTxt.anchor.set(0.5, 0.5);
instructionTxt.stroke = 0x000000;
instructionTxt.strokeThickness = 3;
instructionTxt.visible = false;
instructionTxt.y = -50;
// Remove background shape for instruction text - no longer needed
LK.gui.center.addChild(instructionTxt);
// Create game over screen elements
var gameOverBg = LK.getAsset('topPipe', {
anchorX: 0.5,
anchorY: 0.5,
width: 1600,
height: 1200,
alpha: 0.95
});
gameOverBg.tint = 0x2F4F4F;
gameOverBg.visible = false;
LK.gui.center.addChild(gameOverBg);
// Create high score screen elements
var highScoreBg = LK.getAsset('topPipe', {
anchorX: 0.5,
anchorY: 0.5,
width: 1400,
height: 800,
alpha: 0.95
});
highScoreBg.tint = 0x2F4F4F;
highScoreBg.visible = false;
LK.gui.center.addChild(highScoreBg);
var highScoreTitle = new Text2('EN YÜKSEK SKOR', {
size: 100,
fill: 0xFFD700
});
highScoreTitle.anchor.set(0.5, 0.5);
highScoreTitle.stroke = 0x000000;
highScoreTitle.strokeThickness = 5;
highScoreTitle.visible = false;
LK.gui.center.addChild(highScoreTitle);
highScoreTitle.y = -200;
var highScoreValue = new Text2('0', {
size: 150,
fill: 0xFFFFFF
});
highScoreValue.anchor.set(0.5, 0.5);
highScoreValue.stroke = 0x000000;
highScoreValue.strokeThickness = 6;
highScoreValue.visible = false;
LK.gui.center.addChild(highScoreValue);
highScoreValue.y = 0;
var highScoreCloseButton = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 300,
height: 80,
alpha: 1.0
});
highScoreCloseButton.tint = 0x7F8C8D;
highScoreCloseButton.visible = false;
LK.gui.center.addChild(highScoreCloseButton);
highScoreCloseButton.y = 200;
var highScoreCloseText = new Text2('KAPAT', {
size: 40,
fill: 0xFFFFFF
});
highScoreCloseText.anchor.set(0.5, 0.5);
highScoreCloseText.stroke = 0x566573;
highScoreCloseText.strokeThickness = 3;
highScoreCloseText.visible = false;
LK.gui.center.addChild(highScoreCloseText);
highScoreCloseText.y = 200;
var gameOverTitle = new Text2('OYUN BİTTİ', {
size: 120,
fill: 0xFFFFFF
});
gameOverTitle.anchor.set(0.5, 0.5);
gameOverTitle.stroke = 0x000000;
gameOverTitle.strokeThickness = 6;
gameOverTitle.visible = false;
LK.gui.center.addChild(gameOverTitle);
gameOverTitle.y = -300;
var finalScoreText = new Text2('SKOR: 0', {
size: 80,
fill: 0xFFFFFF
});
finalScoreText.anchor.set(0.5, 0.5);
finalScoreText.stroke = 0x000000;
finalScoreText.strokeThickness = 4;
finalScoreText.visible = false;
LK.gui.center.addChild(finalScoreText);
finalScoreText.y = -150;
var bestScoreText = new Text2('EN İYİ: 0', {
size: 60,
fill: 0xFFD700
});
bestScoreText.anchor.set(0.5, 0.5);
bestScoreText.stroke = 0x000000;
bestScoreText.strokeThickness = 3;
bestScoreText.visible = false;
LK.gui.center.addChild(bestScoreText);
bestScoreText.y = -50;
// Create retry button with enhanced styling
var retryButton = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 380,
height: 110,
alpha: 1.0
});
retryButton.tint = 0xFF9800; // Orange like original Flappy Bird
retryButton.visible = false;
LK.gui.center.addChild(retryButton);
retryButton.y = 100;
// Add retry button shadow for depth
var retryButtonShadow = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 380,
height: 110,
alpha: 0.3
});
retryButtonShadow.tint = 0xE65100; // Darker orange shadow
retryButtonShadow.visible = false;
LK.gui.center.addChild(retryButtonShadow);
retryButtonShadow.y = 108; // Offset shadow slightly down
retryButtonShadow.x = 4; // Offset shadow slightly right
// Add retry button highlight
var retryButtonHighlight = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 350,
height: 85,
alpha: 0.4
});
retryButtonHighlight.tint = 0xFFB74D; // Lighter orange highlight
retryButtonHighlight.visible = false;
LK.gui.center.addChild(retryButtonHighlight);
retryButtonHighlight.y = 92; // Offset highlight slightly up
var retryButtonText = new Text2('TEKRAR DENE', {
size: 44,
fill: 0xFFFFFF
});
retryButtonText.anchor.set(0.5, 0.5);
retryButtonText.stroke = 0xE65100;
retryButtonText.strokeThickness = 3;
retryButtonText.visible = false;
LK.gui.center.addChild(retryButtonText);
retryButtonText.y = 100;
// Create menu button with enhanced styling
var menuButton = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 380,
height: 110,
alpha: 1.0
});
menuButton.tint = 0xF44336; // Red like original Flappy Bird
menuButton.visible = false;
LK.gui.center.addChild(menuButton);
menuButton.y = 250;
// Add menu button shadow for depth
var menuButtonShadow = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 380,
height: 110,
alpha: 0.3
});
menuButtonShadow.tint = 0xD32F2F; // Darker red shadow
menuButtonShadow.visible = false;
LK.gui.center.addChild(menuButtonShadow);
menuButtonShadow.y = 258; // Offset shadow slightly down
menuButtonShadow.x = 4; // Offset shadow slightly right
// Add menu button highlight
var menuButtonHighlight = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 350,
height: 85,
alpha: 0.4
});
menuButtonHighlight.tint = 0xEF5350; // Lighter red highlight
menuButtonHighlight.visible = false;
LK.gui.center.addChild(menuButtonHighlight);
menuButtonHighlight.y = 242; // Offset highlight slightly up
var menuButtonText = new Text2('ANA MENÜ', {
size: 44,
fill: 0xFFFFFF
});
menuButtonText.anchor.set(0.5, 0.5);
menuButtonText.stroke = 0xD32F2F;
menuButtonText.strokeThickness = 3;
menuButtonText.visible = false;
LK.gui.center.addChild(menuButtonText);
menuButtonText.y = 250;
// Simple background setup
var background = game.addChild(LK.getAsset('background', {
anchorX: 0,
anchorY: 0
}));
background.x = 0;
background.y = 0;
background.scaleX = 2;
background.scaleY = 2;
// Create ground
ground = game.addChild(LK.getAsset('ground', {
anchorX: 0,
anchorY: 1
}));
ground.x = 0;
ground.y = 2732;
ground.tint = 0x654321;
// Create bird
bird = game.addChild(new Bird());
bird.x = 300;
bird.y = 1366;
// Pre-generate initial pipes function with better performance
function generateAllPipes() {
// Define safe boundaries for gap center to ensure both pipes have reasonable heights
var minGapY = 700; // Minimum gap center position for better clearance
var maxGapY = 1900; // Maximum gap center position for better clearance
// Generate initial set of pipes only - generate more as needed during gameplay
var initialPipesNeeded = 10; // Start with fewer pipes for better performance
var currentX = 2500; // Starting position to the right of screen since pipes move left
var pipeSpacing = 600; // Spacing between pipes
// Clear existing pipes first
for (var i = pipes.length - 1; i >= 0; i--) {
if (pipes[i] && typeof pipes[i].destroy === "function") {
pipes[i].destroy();
}
}
pipes = [];
for (var pipeIndex = 0; pipeIndex < initialPipesNeeded; pipeIndex++) {
var gapCenterY;
// Create varied random patterns with better distribution
var randomPattern = Math.random();
if (randomPattern < 0.4) {
// 40% chance for high gaps (easier to navigate)
gapCenterY = minGapY + Math.random() * 300;
} else if (randomPattern < 0.7) {
// 30% chance for middle gaps (moderate difficulty)
gapCenterY = 1000 + Math.random() * 500;
} else {
// 30% chance for low gaps (more challenging but still passable)
gapCenterY = maxGapY - Math.random() * 300;
}
// Ensure the gap stays within safe boundaries
gapCenterY = Math.max(minGapY, Math.min(maxGapY, gapCenterY));
var pipe = new Pipe(gapCenterY);
pipe.x = currentX;
pipe.passed = false;
pipes.push(pipe);
game.addChild(pipe);
// Move to next pipe position
currentX += pipeSpacing;
}
}
// Function to generate new pipes as needed during gameplay
function generateNewPipe() {
var minGapY = 700;
var maxGapY = 1900;
var pipeSpacing = 600;
// Find rightmost pipe position
var rightmostX = 2500;
for (var i = 0; i < pipes.length; i++) {
if (pipes[i] && pipes[i].x > rightmostX) {
rightmostX = pipes[i].x;
}
}
// Create new pipe to the right of the rightmost pipe
var newX = rightmostX + pipeSpacing;
var randomPattern = Math.random();
var gapCenterY;
if (randomPattern < 0.4) {
gapCenterY = minGapY + Math.random() * 300;
} else if (randomPattern < 0.7) {
gapCenterY = 1000 + Math.random() * 500;
} else {
gapCenterY = maxGapY - Math.random() * 300;
}
gapCenterY = Math.max(minGapY, Math.min(maxGapY, gapCenterY));
var pipe = new Pipe(gapCenterY);
pipe.x = newX;
pipe.passed = false;
pipes.push(pipe);
game.addChild(pipe);
}
// Reset game function
function resetGame() {
// Reset bird position
bird.x = 300;
bird.y = 1366;
bird.velocity = 0;
// Clear pipes
for (var i = pipes.length - 1; i >= 0; i--) {
if (pipes[i] && typeof pipes[i].destroy === "function") {
pipes[i].destroy();
}
}
pipes = [];
// Reset variables
gameStarted = false;
gameOver = false;
showGameOver = false;
// Hide game over screen
hideGameOverScreen();
LK.setScore(0);
// Reset score display
if (scoreText) {
scoreText.setText('0');
}
// Show main menu with smooth fade in
showMainMenu = true;
var menuElements = [{
element: mainMenuTitle,
targetAlpha: 1,
delay: 0
}, {
element: playButton,
targetAlpha: 1,
delay: 100
}, {
element: playButtonShadow,
targetAlpha: 0.4,
delay: 100
}, {
element: playButtonHighlight,
targetAlpha: 0.5,
delay: 100
}, {
element: playButtonText,
targetAlpha: 1,
delay: 100
}, {
element: cupShape,
targetAlpha: 1,
delay: 200
}, {
element: mainLanguageButton,
targetAlpha: 1,
delay: 300
}, {
element: mainLanguageButtonShadow,
targetAlpha: 0.3,
delay: 300
}, {
element: mainLanguageButtonHighlight,
targetAlpha: 0.4,
delay: 300
}, {
element: mainLanguageButtonText,
targetAlpha: 1,
delay: 300
}];
menuElements.forEach(function (item) {
if (item.element) {
item.element.alpha = 0;
item.element.visible = true;
LK.setTimeout(function () {
tween(item.element, {
alpha: item.targetAlpha
}, {
duration: 400,
easing: tween.easeOut
});
}, item.delay);
}
});
// Hide instruction
instructionTxt.visible = false;
// Hide score display
scoreText.visible = false;
generateAllPipes();
}
// Function to start game from main menu
function startGameFromMenu() {
showMainMenu = false;
// Fade out main menu elements smoothly
tween(mainMenuTitle, {
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
mainMenuTitle.visible = false;
mainMenuTitle.alpha = 1;
}
});
// Hide play button elements with fade
if (playButton) {
tween(playButton, {
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
playButton.visible = false;
playButton.alpha = 1;
}
});
}
if (playButtonShadow) {
tween(playButtonShadow, {
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
playButtonShadow.visible = false;
playButtonShadow.alpha = 0.4;
}
});
}
if (playButtonHighlight) {
tween(playButtonHighlight, {
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
playButtonHighlight.visible = false;
playButtonHighlight.alpha = 0.5;
}
});
}
if (playButtonText) {
tween(playButtonText, {
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
playButtonText.visible = false;
playButtonText.alpha = 1;
}
});
}
// Hide cup shape (high score indicator)
if (cupShape) {
tween(cupShape, {
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
cupShape.visible = false;
cupShape.alpha = 1;
}
});
}
// Hide main language button elements
if (mainLanguageButton) {
tween(mainLanguageButton, {
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
mainLanguageButton.visible = false;
mainLanguageButton.alpha = 1;
}
});
}
if (mainLanguageButtonShadow) {
tween(mainLanguageButtonShadow, {
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
mainLanguageButtonShadow.visible = false;
mainLanguageButtonShadow.alpha = 0.3;
}
});
}
if (mainLanguageButtonHighlight) {
tween(mainLanguageButtonHighlight, {
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
mainLanguageButtonHighlight.visible = false;
mainLanguageButtonHighlight.alpha = 0.4;
}
});
}
if (mainLanguageButtonText) {
tween(mainLanguageButtonText, {
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
mainLanguageButtonText.visible = false;
mainLanguageButtonText.alpha = 1;
}
});
}
// Show instruction and score with fade in
instructionTxt.alpha = 0;
instructionTxt.visible = true;
tween(instructionTxt, {
alpha: 1
}, {
duration: 400,
easing: tween.easeOut
});
scoreText.alpha = 0;
scoreText.visible = true;
scoreText.setText('0');
tween(scoreText, {
alpha: 1
}, {
duration: 400,
easing: tween.easeOut
});
}
// Function to show game over screen
function showGameOverScreen(finalScore) {
if (showGameOver) return;
showGameOver = true;
gameStarted = false;
// Hide all other menus first to prevent overlap
hideLanguageControls();
hideHighScoreScreen();
// Hide instruction and score with fade
tween(instructionTxt, {
alpha: 0
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
instructionTxt.visible = false;
instructionTxt.alpha = 1;
}
});
tween(scoreText, {
alpha: 0
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
scoreText.visible = false;
scoreText.alpha = 1;
}
});
// Show game over elements with smooth fade in
gameOverBg.alpha = 0;
gameOverBg.visible = true;
tween(gameOverBg, {
alpha: 0.95
}, {
duration: 400,
easing: tween.easeOut
});
gameOverTitle.alpha = 0;
gameOverTitle.visible = true;
tween(gameOverTitle, {
alpha: 1
}, {
duration: 500,
easing: tween.easeOut
});
finalScoreText.alpha = 0;
finalScoreText.visible = true;
// Update final score text
var currentScore = LK.getScore();
finalScoreText.setText(getText('score') + ': ' + currentScore);
tween(finalScoreText, {
alpha: 1
}, {
duration: 600,
easing: tween.easeOut
});
bestScoreText.alpha = 0;
bestScoreText.visible = true;
// Show buttons with staggered animation
retryButton.alpha = 0;
retryButton.visible = true;
retryButtonText.alpha = 0;
retryButtonText.visible = true;
retryButtonShadow.alpha = 0;
retryButtonShadow.visible = true;
retryButtonHighlight.alpha = 0;
retryButtonHighlight.visible = true;
menuButton.alpha = 0;
menuButton.visible = true;
menuButtonText.alpha = 0;
menuButtonText.visible = true;
menuButtonShadow.alpha = 0;
menuButtonShadow.visible = true;
menuButtonHighlight.alpha = 0;
menuButtonHighlight.visible = true;
// Remove score display - do not show final score
// Always show the current high score from persistent storage
var currentHighScore = storage.highScore || 0;
// Update high score if current score is higher
if (finalScore > currentHighScore) {
storage.highScore = finalScore;
currentHighScore = finalScore;
// Smooth visual feedback for new high score
if (bestScoreText && bestScoreText.visible) {
tween(bestScoreText, {
tint: 0xFF0000
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(bestScoreText, {
tint: 0xFFD700
}, {
duration: 300,
easing: tween.easeOut
});
}
});
}
}
bestScoreText.setText(getText('bestScore') + ': ' + currentHighScore);
tween(bestScoreText, {
alpha: 1
}, {
duration: 700,
easing: tween.easeOut
});
// Use proper text sizing
if (bestScoreText.width > 600) {
var newSize = Math.max(40, Math.floor(60 * 600 / bestScoreText.width));
bestScoreText.style = {
size: newSize,
fill: bestScoreText.style.fill
};
}
// Animate buttons in with delay
LK.setTimeout(function () {
tween(retryButton, {
alpha: 1
}, {
duration: 300,
easing: tween.easeOut
});
tween(retryButtonShadow, {
alpha: 0.3
}, {
duration: 300,
easing: tween.easeOut
});
tween(retryButtonHighlight, {
alpha: 0.4
}, {
duration: 300,
easing: tween.easeOut
});
tween(retryButtonText, {
alpha: 1
}, {
duration: 300,
easing: tween.easeOut
});
}, 400);
LK.setTimeout(function () {
tween(menuButton, {
alpha: 1
}, {
duration: 300,
easing: tween.easeOut
});
tween(menuButtonShadow, {
alpha: 0.3
}, {
duration: 300,
easing: tween.easeOut
});
tween(menuButtonHighlight, {
alpha: 0.4
}, {
duration: 300,
easing: tween.easeOut
});
tween(menuButtonText, {
alpha: 1
}, {
duration: 300,
easing: tween.easeOut
});
}, 600);
}
// Function to hide game over screen
function hideGameOverScreen() {
showGameOver = false;
// Fade out game over elements smoothly
var elementsToHide = [gameOverBg, gameOverTitle, finalScoreText, bestScoreText, retryButton, retryButtonText, retryButtonShadow, retryButtonHighlight, menuButton, menuButtonText, menuButtonShadow, menuButtonHighlight];
elementsToHide.forEach(function (element) {
if (element && element.visible) {
tween(element, {
alpha: 0
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
element.visible = false;
element.alpha = element === gameOverBg ? 0.95 : element === retryButtonShadow || element === menuButtonShadow ? 0.3 : element === retryButtonHighlight || element === menuButtonHighlight ? 0.4 : 1;
}
});
}
});
}
// Function to show high score screen
function showHighScoreScreen() {
// Hide any other screens to prevent overlap
hideGameOverScreen();
hideLanguageControls();
// Hide main menu elements first to prevent overlap
if (showMainMenu) {
tween(mainMenuTitle, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
mainMenuTitle.visible = false;
mainMenuTitle.alpha = 1;
}
});
if (playButton) {
tween(playButton, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
playButton.visible = false;
playButton.alpha = 1;
}
});
}
if (playButtonShadow) {
tween(playButtonShadow, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
playButtonShadow.visible = false;
playButtonShadow.alpha = 0.4;
}
});
}
if (playButtonHighlight) {
tween(playButtonHighlight, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
playButtonHighlight.visible = false;
playButtonHighlight.alpha = 0.5;
}
});
}
if (playButtonText) {
tween(playButtonText, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
playButtonText.visible = false;
playButtonText.alpha = 1;
}
});
}
if (mainLanguageButton) {
tween(mainLanguageButton, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
mainLanguageButton.visible = false;
mainLanguageButton.alpha = 1;
}
});
}
if (mainLanguageButtonShadow) {
tween(mainLanguageButtonShadow, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
mainLanguageButtonShadow.visible = false;
mainLanguageButtonShadow.alpha = 0.3;
}
});
}
if (mainLanguageButtonHighlight) {
tween(mainLanguageButtonHighlight, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
mainLanguageButtonHighlight.visible = false;
mainLanguageButtonHighlight.alpha = 0.4;
}
});
}
if (mainLanguageButtonText) {
tween(mainLanguageButtonText, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
mainLanguageButtonText.visible = false;
mainLanguageButtonText.alpha = 1;
}
});
}
}
// Update high score value
var currentHighScore = storage.highScore || 0;
highScoreValue.setText(currentHighScore.toString());
highScoreTitle.setText(getText('highestScore'));
highScoreCloseText.setText(getText('close') || 'KAPAT');
// Show high score elements with fade in
var highScoreElements = [{
element: highScoreBg,
targetAlpha: 0.95,
delay: 0
}, {
element: highScoreTitle,
targetAlpha: 1,
delay: 100
}, {
element: highScoreValue,
targetAlpha: 1,
delay: 200
}, {
element: highScoreCloseButton,
targetAlpha: 1,
delay: 300
}, {
element: highScoreCloseText,
targetAlpha: 1,
delay: 300
}];
highScoreElements.forEach(function (item) {
if (item.element) {
item.element.alpha = 0;
item.element.visible = true;
LK.setTimeout(function () {
tween(item.element, {
alpha: item.targetAlpha
}, {
duration: 300,
easing: tween.easeOut
});
}, item.delay);
}
});
}
// Function to hide high score screen
function hideHighScoreScreen() {
// Fade out high score elements
var highScoreElements = [highScoreBg, highScoreTitle, highScoreValue, highScoreCloseButton, highScoreCloseText];
var fadeOutCompleted = 0;
highScoreElements.forEach(function (element) {
if (element && element.visible) {
tween(element, {
alpha: 0
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
element.visible = false;
element.alpha = element === highScoreBg ? 0.95 : 1;
fadeOutCompleted++;
// Show main menu after all high score elements have faded out
if (fadeOutCompleted === highScoreElements.length && showMainMenu && !showGameOver && !gameOverBg.visible && !languageOverlay.visible) {
// Fade in main menu elements
var menuElements = [mainMenuTitle, playButton, playButtonShadow, playButtonHighlight, playButtonText, mainLanguageButton, mainLanguageButtonShadow, mainLanguageButtonHighlight, mainLanguageButtonText];
menuElements.forEach(function (menuElement, index) {
if (menuElement) {
menuElement.alpha = 0;
menuElement.visible = true;
tween(menuElement, {
alpha: menuElement === playButtonShadow ? 0.4 : menuElement === playButtonHighlight ? 0.5 : menuElement === mainLanguageButtonShadow ? 0.3 : menuElement === mainLanguageButtonHighlight ? 0.4 : 1
}, {
duration: 300,
delay: index * 30,
easing: tween.easeOut
});
}
});
}
}
});
}
});
}
// Create language overlay background
var languageOverlay = LK.getAsset('topPipe', {
anchorX: 0.5,
anchorY: 0.5,
width: 2048,
height: 2732,
alpha: 1.0
});
languageOverlay.tint = 0x2F4F4F;
languageOverlay.visible = false;
LK.gui.center.addChild(languageOverlay);
// Create language control title
var languageTitle = new Text2('DİL SEÇENEKLERİ', {
size: 80,
fill: 0xFFFFFF
});
languageTitle.anchor.set(0.5, 0.5);
languageTitle.stroke = 0x000000;
languageTitle.strokeThickness = 4;
languageTitle.visible = false;
LK.gui.center.addChild(languageTitle);
languageTitle.y = -200;
// Create language option buttons with modern rectangular design
var turkishButton = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 260,
height: 65,
alpha: 1.0
});
turkishButton.tint = 0x27AE60;
turkishButton.visible = false;
LK.gui.center.addChild(turkishButton);
turkishButton.y = -80;
turkishButton.x = -220;
// Add Turkish button shadow
var turkishButtonShadow = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 260,
height: 65,
alpha: 0.3
});
turkishButtonShadow.tint = 0x1E8449;
turkishButtonShadow.visible = false;
LK.gui.center.addChild(turkishButtonShadow);
turkishButtonShadow.y = -75;
turkishButtonShadow.x = -217;
// Add Turkish button highlight
var turkishButtonHighlight = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 240,
height: 50,
alpha: 0.4
});
turkishButtonHighlight.tint = 0x58D68D;
turkishButtonHighlight.visible = false;
LK.gui.center.addChild(turkishButtonHighlight);
turkishButtonHighlight.y = -85;
turkishButtonHighlight.x = -220;
var turkishText = new Text2('TÜRKÇE', {
size: 32,
fill: 0xFFFFFF
});
turkishText.anchor.set(0.5, 0.5);
turkishText.stroke = 0x1E8449;
turkishText.strokeThickness = 2;
turkishText.visible = false;
LK.gui.center.addChild(turkishText);
turkishText.y = -80;
turkishText.x = -220;
var englishButton = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 260,
height: 65,
alpha: 1.0
});
englishButton.tint = 0x3498DB;
englishButton.visible = false;
LK.gui.center.addChild(englishButton);
englishButton.y = -80;
englishButton.x = 220;
// Add English button shadow
var englishButtonShadow = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 260,
height: 65,
alpha: 0.3
});
englishButtonShadow.tint = 0x2980B9;
englishButtonShadow.visible = false;
LK.gui.center.addChild(englishButtonShadow);
englishButtonShadow.y = -75;
englishButtonShadow.x = 223;
// Add English button highlight
var englishButtonHighlight = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 240,
height: 50,
alpha: 0.4
});
englishButtonHighlight.tint = 0x85C1E9;
englishButtonHighlight.visible = false;
LK.gui.center.addChild(englishButtonHighlight);
englishButtonHighlight.y = -85;
englishButtonHighlight.x = 220;
var englishText = new Text2('ENGLISH', {
size: 32,
fill: 0xFFFFFF
});
englishText.anchor.set(0.5, 0.5);
englishText.stroke = 0x2980B9;
englishText.strokeThickness = 2;
englishText.visible = false;
LK.gui.center.addChild(englishText);
englishText.y = -80;
englishText.x = 220;
// Current language indicator
var currentLanguageText = new Text2('MEVCUT: TÜRKÇE', {
size: 50,
fill: 0xFFD700
});
currentLanguageText.anchor.set(0.5, 0.5);
currentLanguageText.stroke = 0x000000;
currentLanguageText.strokeThickness = 3;
currentLanguageText.visible = false;
LK.gui.center.addChild(currentLanguageText);
currentLanguageText.y = 30;
// Create back button for language controls with modern rectangular design
var languageBackButton = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 220,
height: 65,
alpha: 1.0
});
languageBackButton.tint = 0x7F8C8D;
languageBackButton.visible = false;
LK.gui.center.addChild(languageBackButton);
languageBackButton.y = 150;
// Add language back button shadow
var languageBackButtonShadow = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 220,
height: 65,
alpha: 0.3
});
languageBackButtonShadow.tint = 0x566573;
languageBackButtonShadow.visible = false;
LK.gui.center.addChild(languageBackButtonShadow);
languageBackButtonShadow.y = 155;
languageBackButtonShadow.x = 3;
// Add language back button highlight
var languageBackButtonHighlight = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 200,
height: 50,
alpha: 0.4
});
languageBackButtonHighlight.tint = 0xABB2B9;
languageBackButtonHighlight.visible = false;
LK.gui.center.addChild(languageBackButtonHighlight);
languageBackButtonHighlight.y = 145;
var languageBackText = new Text2('GERİ', {
size: 36,
fill: 0xFFFFFF
});
languageBackText.anchor.set(0.5, 0.5);
languageBackText.stroke = 0x566573;
languageBackText.strokeThickness = 2;
languageBackText.visible = false;
LK.gui.center.addChild(languageBackText);
languageBackText.y = 150;
// Function to show language controls
function showLanguageControls() {
// Hide all other menus first to prevent overlap
hideGameOverScreen();
hideHighScoreScreen();
// Hide main menu elements with fade
tween(mainMenuTitle, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
mainMenuTitle.visible = false;
mainMenuTitle.alpha = 1;
}
});
if (playButton) {
tween(playButton, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
playButton.visible = false;
playButton.alpha = 1;
}
});
}
if (playButtonShadow) {
tween(playButtonShadow, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
playButtonShadow.visible = false;
playButtonShadow.alpha = 0.4;
}
});
}
if (playButtonHighlight) {
tween(playButtonHighlight, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
playButtonHighlight.visible = false;
playButtonHighlight.alpha = 0.5;
}
});
}
if (playButtonText) {
tween(playButtonText, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
playButtonText.visible = false;
playButtonText.alpha = 1;
}
});
}
if (cupShape) {
tween(cupShape, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
cupShape.visible = false;
cupShape.alpha = 1;
}
});
}
// Hide main language button elements
if (mainLanguageButton) {
tween(mainLanguageButton, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
mainLanguageButton.visible = false;
mainLanguageButton.alpha = 1;
}
});
}
if (mainLanguageButtonShadow) {
tween(mainLanguageButtonShadow, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
mainLanguageButtonShadow.visible = false;
mainLanguageButtonShadow.alpha = 0.3;
}
});
}
if (mainLanguageButtonHighlight) {
tween(mainLanguageButtonHighlight, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
mainLanguageButtonHighlight.visible = false;
mainLanguageButtonHighlight.alpha = 0.4;
}
});
}
if (mainLanguageButtonText) {
tween(mainLanguageButtonText, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
mainLanguageButtonText.visible = false;
mainLanguageButtonText.alpha = 1;
}
});
}
// Show language controls with smooth fade in
languageOverlay.alpha = 0;
languageOverlay.visible = true;
tween(languageOverlay, {
alpha: 1
}, {
duration: 350,
easing: tween.easeOut
});
languageTitle.alpha = 0;
languageTitle.visible = true;
tween(languageTitle, {
alpha: 1
}, {
duration: 400,
easing: tween.easeOut
});
// Show language buttons with staggered animation
turkishButton.alpha = 0;
turkishButton.visible = true;
turkishButtonShadow.alpha = 0;
turkishButtonShadow.visible = true;
turkishButtonHighlight.alpha = 0;
turkishButtonHighlight.visible = true;
turkishText.alpha = 0;
turkishText.visible = true;
englishButton.alpha = 0;
englishButton.visible = true;
englishButtonShadow.alpha = 0;
englishButtonShadow.visible = true;
englishButtonHighlight.alpha = 0;
englishButtonHighlight.visible = true;
englishText.alpha = 0;
englishText.visible = true;
currentLanguageText.alpha = 0;
currentLanguageText.visible = true;
languageBackButton.alpha = 0;
languageBackButton.visible = true;
languageBackButtonShadow.alpha = 0;
languageBackButtonShadow.visible = true;
languageBackButtonHighlight.alpha = 0;
languageBackButtonHighlight.visible = true;
languageBackText.alpha = 0;
languageBackText.visible = true;
// Animate language buttons in with delays
LK.setTimeout(function () {
tween(turkishButton, {
alpha: 1
}, {
duration: 300,
easing: tween.easeOut
});
tween(turkishButtonShadow, {
alpha: 0.3
}, {
duration: 300,
easing: tween.easeOut
});
tween(turkishButtonHighlight, {
alpha: 0.4
}, {
duration: 300,
easing: tween.easeOut
});
tween(turkishText, {
alpha: 1
}, {
duration: 300,
easing: tween.easeOut
});
}, 200);
LK.setTimeout(function () {
tween(englishButton, {
alpha: 1
}, {
duration: 300,
easing: tween.easeOut
});
tween(englishButtonShadow, {
alpha: 0.3
}, {
duration: 300,
easing: tween.easeOut
});
tween(englishButtonHighlight, {
alpha: 0.4
}, {
duration: 300,
easing: tween.easeOut
});
tween(englishText, {
alpha: 1
}, {
duration: 300,
easing: tween.easeOut
});
}, 350);
LK.setTimeout(function () {
tween(currentLanguageText, {
alpha: 1
}, {
duration: 300,
easing: tween.easeOut
});
}, 500);
LK.setTimeout(function () {
tween(languageBackButton, {
alpha: 1
}, {
duration: 300,
easing: tween.easeOut
});
tween(languageBackButtonShadow, {
alpha: 0.3
}, {
duration: 300,
easing: tween.easeOut
});
tween(languageBackButtonHighlight, {
alpha: 0.4
}, {
duration: 300,
easing: tween.easeOut
});
tween(languageBackText, {
alpha: 1
}, {
duration: 300,
easing: tween.easeOut
});
}, 650);
updateLanguageDisplay();
}
// Function to hide language controls
function hideLanguageControls() {
// Fade out all language control elements
var languageElements = [languageOverlay, languageTitle, turkishButton, turkishButtonShadow, turkishButtonHighlight, turkishText, englishButton, englishButtonShadow, englishButtonHighlight, englishText, currentLanguageText, languageBackButton, languageBackButtonShadow, languageBackButtonHighlight, languageBackText];
var fadeOutDuration = 250;
var fadeOutCompleted = 0;
languageElements.forEach(function (element) {
if (element && element.visible) {
tween(element, {
alpha: 0
}, {
duration: fadeOutDuration,
easing: tween.easeOut,
onFinish: function onFinish() {
element.visible = false;
element.alpha = element === languageOverlay ? 1 : element === turkishButtonShadow || element === englishButtonShadow || element === languageBackButtonShadow ? 0.3 : element === turkishButtonHighlight || element === englishButtonHighlight || element === languageBackButtonHighlight ? 0.4 : 1;
fadeOutCompleted++;
// Show main menu after all elements have faded out
if (fadeOutCompleted === languageElements.length && showMainMenu && !showGameOver && !gameOverBg.visible && !highScoreBg.visible) {
// Fade in main menu elements
var menuElements = [mainMenuTitle, playButton, playButtonShadow, playButtonHighlight, playButtonText, cupShape, mainLanguageButton, mainLanguageButtonShadow, mainLanguageButtonHighlight, mainLanguageButtonText];
menuElements.forEach(function (menuElement, index) {
if (menuElement) {
menuElement.alpha = 0;
menuElement.visible = true;
tween(menuElement, {
alpha: menuElement === playButtonShadow ? 0.4 : menuElement === playButtonHighlight ? 0.5 : menuElement === mainLanguageButtonShadow ? 0.3 : menuElement === mainLanguageButtonHighlight ? 0.4 : 1
}, {
duration: 300,
delay: index * 30,
easing: tween.easeOut
});
}
});
}
}
});
}
});
}
// Language text objects
var languageTexts = {
tr: {
mainTitle: 'FLAPPY BIRD',
playButton: 'OYNA',
instruction: 'TIKLA VE OYNA!',
gameOver: 'OYUN BİTTİ',
score: 'SKOR',
bestScore: 'EN İYİ',
retry: 'TEKRAR DENE',
mainMenu: 'ANA MENÜ',
language: 'DİL',
languageTitle: 'DİL SEÇENEKLERİ',
current: 'MEVCUT',
highestScore: 'EN YÜKSEK SKOR',
back: 'GERİ',
close: 'KAPAT'
},
en: {
mainTitle: 'FLAPPY BIRD',
playButton: 'PLAY',
instruction: 'CLICK TO PLAY!',
gameOver: 'GAME OVER',
score: 'SCORE',
bestScore: 'BEST',
retry: 'RETRY',
mainMenu: 'MAIN MENU',
language: 'LANGUAGE',
languageTitle: 'LANGUAGE OPTIONS',
current: 'CURRENT',
highestScore: 'HIGHEST SCORE',
back: 'BACK',
close: 'CLOSE'
}
};
// Function to get text for current language
function getText(key) {
return languageTexts[currentLanguage][key] || languageTexts['en'][key];
}
// Function to update all text elements to current language
function updateAllTexts() {
if (instructionTxt) {
instructionTxt.setText(getText('instruction'));
}
if (playButtonText) {
playButtonText.setText(getText('playButton'));
}
if (gameOverTitle) {
gameOverTitle.setText(getText('gameOver'));
}
if (retryButtonText) {
retryButtonText.setText(getText('retry'));
}
if (menuButtonText) {
menuButtonText.setText(getText('mainMenu'));
}
if (languageTitle) {
languageTitle.setText(getText('languageTitle'));
}
if (languageBackText) {
languageBackText.setText(getText('back'));
}
if (mainLanguageButtonText) {
mainLanguageButtonText.setText(getText('language'));
}
// Update final and best score texts
if (finalScoreText) {
var currentScore = LK.getScore();
finalScoreText.setText(getText('score') + ': ' + currentScore);
}
if (bestScoreText) {
var currentHighScore = storage.highScore || 0;
bestScoreText.setText(getText('bestScore') + ': ' + currentHighScore);
}
}
// Function to update language display
function updateLanguageDisplay() {
var langText = currentLanguage === 'tr' ? 'TÜRKÇE' : 'ENGLISH';
var currentText = currentLanguage === 'tr' ? 'MEVCUT' : 'CURRENT';
if (currentLanguageText) {
currentLanguageText.setText(currentText + ': ' + langText);
}
// Update button colors to show selected language
if (turkishButton) {
turkishButton.tint = currentLanguage === 'tr' ? 0x2ECC71 : 0x27AE60;
}
if (englishButton) {
englishButton.tint = currentLanguage === 'en' ? 0x5DADE2 : 0x3498DB;
}
}
// Function to set language
function setLanguage(lang) {
currentLanguage = lang;
// Save to persistent storage
storage.language = lang;
// Update all text elements immediately
updateAllTexts();
// Update language display
updateLanguageDisplay();
}
// Initialize persistent storage with defaults if values don't exist
if (typeof storage.highScore === 'undefined') storage.highScore = 0;
if (typeof storage.lastScore === 'undefined') storage.lastScore = 0;
if (!storage.language) storage.language = 'tr';
// Update current language from persistent storage
currentLanguage = storage.language || 'tr';
// Create animated play button for main menu
var playButton = LK.getAsset('playButtonMain', {
anchorX: 0.5,
anchorY: 0.5,
width: 400,
height: 120,
alpha: 1.0
});
playButton.tint = 0xFF9800; // Flappy Bird orange
LK.gui.center.addChild(playButton);
playButton.y = -100;
// Create language button for direct access from main menu
var mainLanguageButton = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 300,
height: 80,
alpha: 1.0
});
mainLanguageButton.tint = 0x9B59B6;
LK.gui.center.addChild(mainLanguageButton);
mainLanguageButton.y = 50;
// Create language button shadow
var mainLanguageButtonShadow = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 300,
height: 80,
alpha: 0.3
});
mainLanguageButtonShadow.tint = 0x8E44AD;
LK.gui.center.addChild(mainLanguageButtonShadow);
mainLanguageButtonShadow.y = 55;
mainLanguageButtonShadow.x = 3;
// Create language button highlight
var mainLanguageButtonHighlight = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 280,
height: 65,
alpha: 0.4
});
mainLanguageButtonHighlight.tint = 0xBB8FCE;
LK.gui.center.addChild(mainLanguageButtonHighlight);
mainLanguageButtonHighlight.y = 45;
// Create language button text
var mainLanguageButtonText = new Text2('DİL', {
size: 36,
fill: 0xFFFFFF
});
mainLanguageButtonText.anchor.set(0.5, 0.5);
mainLanguageButtonText.stroke = 0x8E44AD;
mainLanguageButtonText.strokeThickness = 2;
LK.gui.center.addChild(mainLanguageButtonText);
mainLanguageButtonText.y = 50;
// Create separate play button shadow element
var playButtonShadow = LK.getAsset('playButtonShadow', {
anchorX: 0.5,
anchorY: 0.5,
width: 400,
height: 120,
alpha: 0.4
});
playButtonShadow.tint = 0xE65100; // Darker orange shadow
LK.gui.center.addChild(playButtonShadow);
playButtonShadow.y = -92; // Offset shadow slightly up
playButtonShadow.x = 4; // Offset shadow slightly right
// Create separate play button highlight element
var playButtonHighlight = LK.getAsset('playButtonHighlight', {
anchorX: 0.5,
anchorY: 0.5,
width: 370,
height: 95,
alpha: 0.5
});
playButtonHighlight.tint = 0xFFB74D; // Lighter orange highlight
LK.gui.center.addChild(playButtonHighlight);
playButtonHighlight.y = -108; // Offset highlight slightly down
// Create separate play button text element
var playButtonText = new Text2('OYNA', {
size: 50,
fill: 0xFFFFFF
});
playButtonText.anchor.set(0.5, 0.5);
playButtonText.stroke = 0xE65100;
playButtonText.strokeThickness = 4;
LK.gui.center.addChild(playButtonText);
playButtonText.y = -100;
// Initialize game
resetGame(); // Use resetGame to properly initialize all states
// Update all texts to current language
updateAllTexts();
// Update language display to show current selection
updateLanguageDisplay();
// Touch/click handler
game.down = function (x, y, obj) {
// Check if high score screen is visible
if (highScoreBg.visible) {
// Check close button click - centered at 1024x1566 (center.y = 1366 + 200), button is 300x80
if (x >= 874 && x <= 1174 && y >= 1526 && y <= 1606) {
// Simple visual feedback
simpleColorTint(highScoreCloseButton, 0xABB2B9, 0);
hideHighScoreScreen();
return;
}
return; // Don't process other clicks when high score screen is open
}
// Check if language overlay is visible and handle language controls
if (languageOverlay.visible) {
// Turkish language button with isolated click area
if (turkishButton.visible && x >= 654 && x <= 954 && y >= 1246 && y <= 1326) {
// Simple visual feedback with color change
simpleColorTint(turkishButton, 0x58D68D, 0);
setLanguage('tr');
return;
}
// Barrier zone between Turkish and English buttons (x: 954-1094)
if (x >= 954 && x <= 1094 && y >= 1246 && y <= 1326) {
return; // Block clicks in barrier zone
}
// English language button with isolated click area
if (englishButton.visible && x >= 1094 && x <= 1394 && y >= 1246 && y <= 1326) {
// Simple visual feedback with color change
simpleColorTint(englishButton, 0x85C1E9, 0);
setLanguage('en');
return;
}
// Check language back button at x = 1024, y = 1516, size 300x100
if (languageBackButton.visible && x >= 874 && x <= 1174 && y >= 1466 && y <= 1566) {
// Simple visual feedback with color change
simpleColorTint(languageBackButton, 0xABB2B9, 0);
hideLanguageControls();
return;
}
return; // Don't process other clicks when language overlay is open
}
// Check cup click - cup is positioned at bottomRight with offset
var cupX = 2048 - 100; // bottomRight.x + cupShape.x offset
var cupY = 2732 - 230; // bottomRight.y + cupShape.y offset
var cupSize = 120; // Cup asset size
if (x >= cupX - cupSize / 2 && x <= cupX + cupSize / 2 && y >= cupY && y <= cupY + cupSize) {
// Show high score screen
showHighScoreScreen();
// Simple visual feedback without animation
if (cupShape) {
cupShape.tint = 0xFFFFFF;
cupShape.tint = 0xFFD700;
}
return;
}
if (gameOver || showGameOver) {
// Check retry button (TEKRAR DENE) - centered at 1024x1466, button is 380x110
if (x >= 834 && x <= 1214 && y >= 1411 && y <= 1521) {
// Simple visual feedback with color change
simpleColorTint(retryButton, 0xFFB74D, 150, function () {
// Fade out game over screen first
hideGameOverScreen();
// Wait for fade out to complete before resetting
LK.setTimeout(function () {
resetGame();
// Show instruction screen instead of starting game directly
startGameFromMenu();
}, 250);
});
return;
}
// Check menu button (ANA MENÜ) - centered at 1024x1616, button is 380x110
if (x >= 834 && x <= 1214 && y >= 1561 && y <= 1671) {
// Simple visual feedback with color change
simpleColorTint(menuButton, 0xF1948A, 150, function () {
// Fade out game over screen first
hideGameOverScreen();
// Wait for fade out to complete before resetting
LK.setTimeout(function () {
resetGame();
}, 250);
});
return;
}
return;
}
if (showMainMenu) {
// Check play button click - centered at 1024x1266 (center.y = 1366 + playButton.y = -100), button is 400x120
if (playButton && playButton.visible && x >= 824 && x <= 1224 && y >= 1206 && y <= 1326) {
// Simple visual feedback with color change
simpleColorTint(playButton, 0xFFB74D, 0);
startGameFromMenu();
return;
}
// Check main language button click - centered at 1024x1416 (center.y = 1366 + mainLanguageButton.y = 50), button is 300x80
if (mainLanguageButton && mainLanguageButton.visible && x >= 874 && x <= 1174 && y >= 1376 && y <= 1456) {
// Simple visual feedback with color change
simpleColorTint(mainLanguageButton, 0xBB8FCE, 0);
showLanguageControls();
return;
}
return;
}
if (!gameStarted) {
gameStarted = true;
instructionTxt.visible = false;
}
bird.flap();
};
// Main game loop with optimized performance
game.update = function () {
if (gameOver || showMainMenu || showGameOver) return;
// Only run game logic if game has started
if (gameStarted) {
// Check ground and ceiling collision with proper bird size (bird is 80px tall, 120px wide)
var birdRadius = 40; // Half of bird height for collision detection
if (bird.y + birdRadius >= ground.y || bird.y - birdRadius <= 0) {
gameOver = true;
var currentScore = LK.getScore();
// Save score to persistent storage
if (currentScore > (storage.highScore || 0)) {
storage.highScore = currentScore;
}
storage.lastScore = currentScore;
// Add smooth transition to game over
tween(instructionTxt, {
alpha: 0
}, {
duration: 200,
easing: tween.easeOut
});
tween(scoreText, {
alpha: 0
}, {
duration: 200,
easing: tween.easeOut
});
LK.setTimeout(function () {
showGameOverScreen(LK.getScore());
}, 200);
return;
}
// Dynamic pipe generation - generate new pipes as old ones are removed
var rightmostPipeX = -1000;
for (var i = 0; i < pipes.length; i++) {
if (pipes[i] && pipes[i].x > rightmostPipeX) {
rightmostPipeX = pipes[i].x;
}
}
// Generate new pipe if the rightmost pipe is getting close to the screen
if (rightmostPipeX < 3000) {
generateNewPipe();
}
// Optimized pipe cleanup - remove pipes that are far behind only
for (var i = pipes.length - 1; i >= 0; i--) {
var pipe = pipes[i];
// Only remove pipes that are far behind the bird
if (pipe && pipe.x < bird.x - 800) {
pipe.destroy();
pipes.splice(i, 1);
}
}
// Find closest pipe for collision and scoring
var closestPipe = null;
var closestDistance = 99999;
for (var i = 0; i < pipes.length; i++) {
var pipe = pipes[i];
// Check pipes that are close to the bird
if (pipe && pipe.x > bird.x - 100 && pipe.x < bird.x + 200) {
var distance = Math.abs(pipe.x - bird.x);
if (distance < closestDistance) {
closestDistance = distance;
closestPipe = pipe;
}
}
}
if (closestPipe) {
// Initialize lastX tracking
if (typeof closestPipe.lastX === 'undefined') {
closestPipe.lastX = closestPipe.x;
}
// Scoring check - detect when bird passes through the pipe center
// Since pipes move from right to left and bird stays at x=300, check when pipe center passes bird
var pipeCenter = closestPipe.x;
var birdPosition = bird.x;
// Check if pipe center just passed the bird position (was on right, now on left)
if (!closestPipe.passed && closestPipe.lastX > birdPosition && pipeCenter <= birdPosition) {
// Check if bird is within the gap when pipe passes
var gapTop = closestPipe.gapCenterY - closestPipe.gapSize / 2;
var gapBottom = closestPipe.gapCenterY + closestPipe.gapSize / 2;
// Mark pipe as passed
if (bird.y > gapTop && bird.y < gapBottom) {
closestPipe.passed = true;
// Increment score
LK.setScore(LK.getScore() + 1);
var currentScore = LK.getScore();
// Update score display with smooth animation
if (scoreText && scoreText.visible) {
scoreText.setText(currentScore.toString());
// Smooth score flash animation
tween(scoreText, {
tint: 0xFFD700
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(scoreText, {
tint: 0xFFFFFF
}, {
duration: 200,
easing: tween.easeOut
});
}
});
}
// Save high score if current score is higher
if (currentScore > (storage.highScore || 0)) {
storage.highScore = currentScore;
}
// Check win condition - game ends at 100 points for better gameplay
if (currentScore >= 100) {
gameOver = true;
storage.lastScore = currentScore;
LK.showYouWin(); // Show win screen when reaching 100 points
return;
}
if (LK.getSound('score')) {
LK.getSound('score').play();
}
}
}
// Update last position
closestPipe.lastX = closestPipe.x;
// Collision check - only if very close with better collision detection
if (closestPipe.x > bird.x - 80 && closestPipe.x < bird.x + 80) {
var gapTop = closestPipe.gapCenterY - closestPipe.gapSize / 2;
var gapBottom = closestPipe.gapCenterY + closestPipe.gapSize / 2;
// More forgiving collision detection
if (bird.y < gapTop + 60 || bird.y > gapBottom - 60) {
gameOver = true;
// Add smooth transition before showing game over
tween(instructionTxt, {
alpha: 0
}, {
duration: 200,
easing: tween.easeOut
});
tween(scoreText, {
alpha: 0
}, {
duration: 200,
easing: tween.easeOut
});
LK.setTimeout(function () {
showGameOverScreen(LK.getScore());
}, 200);
return;
}
}
}
}
};