User prompt
yüksek skor düğmesine basınca düğmeler birbirine gidiyor
User prompt
menülere birbirine girmesin ve birbirlerini göstermesin ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
oyun kasmasın dolmasın grafiksel olarak hataları düzelt ve duvarları da düzelt ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
grafiksel geçiş animasyon düzgün hale getir kasmasın donmasın ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Düğmelere basınca ekran aniden değişiyor. Hiç bekleme süresi falan yok. O yüzden donuyor. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
düğmelere basınca oyun bekletiyor
User prompt
düğmelere bastıktan sonra bir 3 saniye falan bekletiyor
User prompt
oyunda donma oluyor, kasma değil
User prompt
Tuşlara basınca bir gecikme oluyor
User prompt
hala tamamen gereksiz kodlar var
User prompt
düğmelere basınca bile oyun kasıyor
User prompt
oyunun kasmaması için oyunda şu an aktif olarak hiç kullanmadığımız %100 gereksiz kodları sil oyundaki hiç birşeyi bozma
User prompt
Fakat oyun sadece önündeki 5 tane duvarı algılasın, arkasına geçen 3 duvardan sonra arkasındaki 2 duvarı silsin.
User prompt
duvar 9'dan sonra devamı yok düzelt 1000'e kadar gitsin 1000 yapınca oyun bitsin
User prompt
en yüksek skor kupasına tıklayınca en yüksek skoru gösteren ekranı tekrar ekle
User prompt
Skor hep sıfırda kalıyor
User prompt
ve son olarak sadece skor yaptığımızda yukarıdaki sıfır sayısı ve skor tablosu ve en yüksek skor tablosunun değişmesiyle ilgili bir eklenti yapın ↪💡 Consider importing and using the following plugins: @upit/tween.v1, @upit/storage.v1
User prompt
skor tablolarını ve görünümlerini daha iyi hale getirip daha düzgün ve hatasız hale getirip tekrar oluştur. ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
oyun bittiğinde skor yazıyor onu da kaldır
User prompt
oyunda yapılan sadece şunları kaydetsin yapılan en yüksek skor ve seçilen dil ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
sayı sayan sistemi kaldır
User prompt
duvarların arasından geçtikçe sayı sayan yukarıdaki sıfır sayısı sıfırdan başlayıp arasından geçtikçe 1,2,3,4 diye ilerlemiyor onu düzelt veya baştan oluştur
User prompt
sıfır sayısı duvar arasından geçtikçe değişmiyor birden bine kadardı ya o sayı değişmiyor
User prompt
Evet artık ileri gidiyor fakat duvarların arasından geçtikçe sayı saymıyor
User prompt
Kuş arkaya doğru değil duvarlara doğru gitmesi lazım
/**** * Plugins ****/ var storage = LK.import("@upit/storage.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(); } }; // Remove idle animation function self.startIdleAnimation = function () { // No animation needed }; // Optimized update method self.update = function () { // Update cooldowns if (self.flapCooldown > 0) self.flapCooldown--; if (!gameStarted) { // Pre-game idle state self.velocity = 0; self.y = 1366; self.x = 300; // Force x position return; } // Simple physics with improved scaling if (!gameOver) { // Only update position if game is not over self.velocity += gravity; self.y += self.velocity; // Bird should stay at fixed x position - pipes move towards it // Force bird to stay at x=300, prevent any backward movement self.x = 300; } else { // Prevent any movement when game is over self.velocity = 0; self.x = 300; // Force x position even when game is over // Do not update self.y after game over } // Minimal rotation calculation - only every 10 frames if (LK.ticks % 10 === 0) { birdGraphics.rotation = self.velocity > 0 ? 0.8 : -0.4; } // 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 current 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 right so bird appears to move towards them 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; // Simple animation helpers without tween plugin function simpleScale(target, endScale, duration, callback) { var startScale = target.scaleX || 1; var startTime = LK.ticks; var totalFrames = Math.floor(duration / 16.67); // 60fps var frameCount = 0; var animateInterval = LK.setInterval(function () { frameCount++; var progress = frameCount / totalFrames; if (progress >= 1) { progress = 1; LK.clearInterval(animateInterval); if (callback) callback(); } var currentScale = startScale + (endScale - startScale) * progress; target.scaleX = currentScale; target.scaleY = currentScale; }, 16); } function simpleColorTint(target, color, duration, callback) { var originalTint = target.tint; target.tint = color; if (duration > 0) { LK.setTimeout(function () { target.tint = originalTint; if (callback) callback(); }, duration); } else if (callback) { callback(); } } var bird; var pipes = []; var ground; var gameStarted = false; var gameOver = false; var showMainMenu = true; var showGameOver = false; var lastButtonClickTime = 0; // Track last button click time 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 // Initialize storage with defaults var _storage = storage; // Create score text display var scoreTxt = new Text2('0', { size: 150, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); scoreTxt.stroke = 0x000000; scoreTxt.strokeThickness = 5; var lastScoreDisplayed = -1; // Cache last displayed score try { if (LK.gui && LK.gui.top) { LK.gui.top.addChild(scoreTxt); } } catch (e) { console.log("GUI score text error:", e); } // Create cup shape for score var cupShape; try { cupShape = LK.getAsset('cup', { anchorX: 0.5, anchorY: 0 }); cupShape.tint = 0xFFD700; if (LK.gui && LK.gui.bottomRight) { LK.gui.bottomRight.addChild(cupShape); cupShape.y = -230; cupShape.x = -100; } } catch (e) { console.log("Cup shape error:", e); } // 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; try { if (LK.gui && LK.gui.center) { LK.gui.center.addChild(mainMenuTitle); mainMenuTitle.y = -280; } } catch (e) { console.log("Main menu title error:", e); } // 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); 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 - position in open area away from any walls bird = game.addChild(new Bird()); bird.x = 300; // Position bird further back in open area bird.y = 1366; // Initialize bird properly bird.velocity = 0; // Pre-generate all pipes function function generateAllPipes() { // Define safe boundaries for gap center to ensure both pipes have reasonable heights var minGapY = 700; // Increased minimum gap center position for better clearance var maxGapY = 1900; // Adjusted maximum gap center position for better clearance // Generate fewer pipes to prevent memory issues var totalPipesNeeded = 100; // Reduced from 1000 to 100 var currentX = -600; // Starting position to the left of bird since pipes move right var pipeSpacing = 600; // Adjusted spacing between pipes for better gameplay // Ensure no pipes overlap at the start if (pipes && pipes.length > 0) { currentX = pipes[pipes.length - 1].x + pipeSpacing; } for (var pipeIndex = 0; pipeIndex < totalPipesNeeded; pipeIndex++) { var gapCenterY; // Create more 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; } // Add some variation based on pipe index for progressive difficulty if (pipeIndex > 10) { // After pipe 10, make gaps slightly more challenging var difficultyFactor = Math.min(0.8, pipeIndex / 50); // Max 80% difficulty increase var centerPull = 1300; // Pull towards center-high area gapCenterY = gapCenterY + (centerPull - gapCenterY) * difficultyFactor * 0.3; } // 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; } } // Reset game function function resetGame() { // Reset bird - position it in open area with no walls bird.x = 300; // Position bird in open area 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; showMainMenu = true; showGameOver = false; // Hide game over screen hideGameOverScreen(); LK.setScore(0); scoreTxt.setText('0'); lastScoreDisplayed = -1; // Show main menu mainMenuTitle.visible = true; // Show play button elements if (playButton) playButton.visible = true; if (playButtonShadow) playButtonShadow.visible = true; if (playButtonHighlight) playButtonHighlight.visible = true; if (playButtonText) playButtonText.visible = true; // Show cup shape (high score indicator) if (cupShape) cupShape.visible = true; // Show main language button elements if (mainLanguageButton) mainLanguageButton.visible = true; if (mainLanguageButtonShadow) mainLanguageButtonShadow.visible = true; if (mainLanguageButtonHighlight) mainLanguageButtonHighlight.visible = true; if (mainLanguageButtonText) mainLanguageButtonText.visible = true; // Hide instruction instructionTxt.visible = false; generateAllPipes(); } // Function to start game from main menu function startGameFromMenu() { showMainMenu = false; // Hide main menu elements mainMenuTitle.visible = false; // Hide play button elements if (playButton) playButton.visible = false; if (playButtonShadow) playButtonShadow.visible = false; if (playButtonHighlight) playButtonHighlight.visible = false; if (playButtonText) playButtonText.visible = false; // Hide cup shape (high score indicator) if (cupShape) cupShape.visible = false; // Hide main language button elements if (mainLanguageButton) mainLanguageButton.visible = false; if (mainLanguageButtonShadow) mainLanguageButtonShadow.visible = false; if (mainLanguageButtonHighlight) mainLanguageButtonHighlight.visible = false; if (mainLanguageButtonText) mainLanguageButtonText.visible = false; // Show instruction instructionTxt.visible = true; } // Function to show game over screen function showGameOverScreen(finalScore) { if (showGameOver) return; showGameOver = true; gameStarted = false; showMainMenu = false; // Hide instruction instructionTxt.visible = false; // Show game over elements gameOverBg.visible = true; gameOverTitle.visible = true; finalScoreText.visible = true; bestScoreText.visible = true; retryButton.visible = true; retryButtonText.visible = true; retryButtonShadow.visible = true; retryButtonHighlight.visible = true; menuButton.visible = true; menuButtonText.visible = true; menuButtonShadow.visible = true; menuButtonHighlight.visible = true; // Update score displays finalScoreText.setText(getText('score') + ': ' + finalScore); // Use proper text sizing if (finalScoreText.width > 600) { var newSize = Math.max(50, Math.floor(80 * 600 / finalScoreText.width)); if (finalScoreText.style.size !== newSize) { finalScoreText.style = { size: newSize, fill: finalScoreText.style.fill }; } } // Always show the current high score from persistent storage var currentHighScore = storage.highScore || 0; bestScoreText.setText(getText('bestScore') + ': ' + currentHighScore); // 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 }; } // Simple game over screen display - no animations } // Function to hide game over screen function hideGameOverScreen() { showGameOver = false; // Hide game over elements gameOverBg.visible = false; gameOverTitle.visible = false; finalScoreText.visible = false; bestScoreText.visible = false; retryButton.visible = false; retryButtonText.visible = false; retryButtonShadow.visible = false; retryButtonHighlight.visible = false; menuButton.visible = false; menuButtonText.visible = false; menuButtonShadow.visible = false; menuButtonHighlight.visible = false; } // 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 main menu elements mainMenuTitle.visible = false; if (playButton) playButton.visible = false; if (playButtonShadow) playButtonShadow.visible = false; if (playButtonHighlight) playButtonHighlight.visible = false; if (playButtonText) playButtonText.visible = false; if (cupShape) cupShape.visible = false; // Hide main language button elements if (mainLanguageButton) mainLanguageButton.visible = false; if (mainLanguageButtonShadow) mainLanguageButtonShadow.visible = false; if (mainLanguageButtonHighlight) mainLanguageButtonHighlight.visible = false; if (mainLanguageButtonText) mainLanguageButtonText.visible = false; // Show language controls languageOverlay.visible = true; languageTitle.visible = true; turkishButton.visible = true; turkishButtonShadow.visible = true; turkishButtonHighlight.visible = true; turkishText.visible = true; englishButton.visible = true; englishButtonShadow.visible = true; englishButtonHighlight.visible = true; englishText.visible = true; currentLanguageText.visible = true; languageBackButton.visible = true; languageBackButtonShadow.visible = true; languageBackButtonHighlight.visible = true; languageBackText.visible = true; updateLanguageDisplay(); } // Function to hide language controls function hideLanguageControls() { // Hide all language control elements languageOverlay.visible = false; languageTitle.visible = false; turkishButton.visible = false; turkishButtonShadow.visible = false; turkishButtonHighlight.visible = false; turkishText.visible = false; englishButton.visible = false; englishButtonShadow.visible = false; englishButtonHighlight.visible = false; englishText.visible = false; currentLanguageText.visible = false; languageBackButton.visible = false; languageBackButtonShadow.visible = false; languageBackButtonHighlight.visible = false; languageBackText.visible = false; // Show main menu elements again if (showMainMenu) { mainMenuTitle.visible = true; if (playButton) playButton.visible = true; if (playButtonShadow) playButtonShadow.visible = true; if (playButtonHighlight) playButtonHighlight.visible = true; if (playButtonText) playButtonText.visible = true; if (cupShape) cupShape.visible = true; if (mainLanguageButton) mainLanguageButton.visible = true; if (mainLanguageButtonShadow) mainLanguageButtonShadow.visible = true; if (mainLanguageButtonHighlight) mainLanguageButtonHighlight.visible = true; if (mainLanguageButtonText) mainLanguageButtonText.visible = true; } } // 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', back: 'GERİ' }, 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' } }; // 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() { try { if (instructionTxt && instructionTxt.setText) { try { instructionTxt.setText(getText('instruction')); } catch (e) {} } if (playButtonText && playButtonText.setText) { try { playButtonText.setText(getText('playButton')); } catch (e) {} } if (gameOverTitle && gameOverTitle.setText) { try { gameOverTitle.setText(getText('gameOver')); } catch (e) {} } if (retryButtonText && retryButtonText.setText) { try { retryButtonText.setText(getText('retry')); } catch (e) {} } if (menuButtonText && menuButtonText.setText) { try { menuButtonText.setText(getText('mainMenu')); } catch (e) {} } if (languageTitle && languageTitle.setText) { try { languageTitle.setText(getText('languageTitle')); } catch (e) {} } if (languageBackText && languageBackText.setText) { try { languageBackText.setText(getText('back')); } catch (e) {} } if (mainLanguageButtonText && mainLanguageButtonText.setText) { try { mainLanguageButtonText.setText(getText('language')); } catch (e) {} } // Update final and best score texts if (finalScoreText && finalScoreText.setText) { var currentScore = LK.getScore(); try { finalScoreText.setText(getText('score') + ': ' + currentScore); } catch (e) {} } if (bestScoreText && bestScoreText.setText) { var currentHighScore = storage.highScore || 0; try { bestScoreText.setText(getText('bestScore') + ': ' + currentHighScore); } catch (e) {} } } catch (e) { console.log("Text update error:", e); } } // 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) { try { currentLanguageText.setText(currentText + ': ' + langText); } catch (e) {} } // Update button colors to show selected language if (turkishButton) { turkishButton.tint = currentLanguage === 'tr' ? 0x2ECC71 : 0x27AE60; } if (englishButton) { englishButton.tint = currentLanguage === 'en' ? 0x5DADE2 : 0x3498DB; } // Ensure button text is always correct if (turkishText && turkishText.setText) { try { turkishText.setText('TÜRKÇE'); } catch (e) {} } if (englishText && englishText.setText) { try { englishText.setText('ENGLISH'); } catch (e) {} } } // 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 (!storage.globalLeaderboardNames) storage.globalLeaderboardNames = []; if (!storage.globalLeaderboardScores) storage.globalLeaderboardScores = []; if (typeof storage.highScore === 'undefined') storage.highScore = 0; if (typeof storage.lastScore === 'undefined') storage.lastScore = 0; if (!storage.language) storage.language = 'tr'; if (!storage.username) storage.username = 'Oyuncu1'; // Update current language from persistent storage currentLanguage = storage.language || 'tr'; // Initialize username if not exists if (!storage.username) { var playerNumber = 1; while (storage.globalLeaderboardNames.indexOf('Oyuncu ' + playerNumber) !== -1) { playerNumber++; } storage.username = 'Oyuncu ' + playerNumber; } // 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 try { if (LK.gui && LK.gui.center) { LK.gui.center.addChild(playButton); playButton.y = -100; } } catch (e) { console.log("Play button error:", e); } // 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; try { if (LK.gui && LK.gui.center) { LK.gui.center.addChild(mainLanguageButton); mainLanguageButton.y = 50; } } catch (e) { console.log("Main language button error:", e); } // 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; try { if (LK.gui && LK.gui.center) { LK.gui.center.addChild(mainLanguageButtonShadow); mainLanguageButtonShadow.y = 55; mainLanguageButtonShadow.x = 3; } } catch (e) { console.log("Main language button shadow error:", e); } // 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; try { if (LK.gui && LK.gui.center) { LK.gui.center.addChild(mainLanguageButtonHighlight); mainLanguageButtonHighlight.y = 45; } } catch (e) { console.log("Main language button highlight error:", e); } // 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; try { if (LK.gui && LK.gui.center) { LK.gui.center.addChild(mainLanguageButtonText); mainLanguageButtonText.y = 50; } } catch (e) { console.log("Main language button text error:", e); } // 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 try { if (LK.gui && LK.gui.center) { LK.gui.center.addChild(playButtonShadow); playButtonShadow.y = -92; // Offset shadow slightly up playButtonShadow.x = 4; // Offset shadow slightly right } } catch (e) { console.log("Play button shadow error:", e); } // 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 try { if (LK.gui && LK.gui.center) { LK.gui.center.addChild(playButtonHighlight); playButtonHighlight.y = -108; // Offset highlight slightly down } } catch (e) { console.log("Play button highlight error:", e); } // 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; try { if (LK.gui && LK.gui.center) { LK.gui.center.addChild(playButtonText); playButtonText.y = -100; } } catch (e) { console.log("Play button text error:", e); } // 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 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) { var currentTime = Date.now(); if (currentTime - lastButtonClickTime < 300) return; lastButtonClickTime = currentTime; // Simple visual feedback with color change simpleColorTint(turkishButton, 0x58D68D, 150); 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) { var currentTime = Date.now(); if (currentTime - lastButtonClickTime < 300) return; lastButtonClickTime = currentTime; // Simple visual feedback with color change simpleColorTint(englishButton, 0x85C1E9, 150); 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) { var currentTime = Date.now(); if (currentTime - lastButtonClickTime < 300) return; lastButtonClickTime = currentTime; // Simple visual feedback with color change simpleColorTint(languageBackButton, 0xABB2B9, 150); 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) { var currentTime = Date.now(); if (currentTime - lastButtonClickTime < 500) return; lastButtonClickTime = currentTime; // Simple high score display from persistent storage var highScore = storage.highScore || 0; console.log(getText('highestScore') + ': ' + highScore); return; } if (gameOver || showGameOver) { // Check retry button (TEKRAR DENE) - centered at 1024x1466, button is 380x110 if (x >= 834 && x <= 1214 && y >= 1411 && y <= 1521) { // Prevent rapid clicks var currentTime = Date.now(); if (currentTime - lastButtonClickTime < 300) { return; // Ignore click if too recent } lastButtonClickTime = currentTime; // Simple visual feedback with color change simpleColorTint(retryButton, 0xFFB74D, 150); hideGameOverScreen(); resetGame(); // Show instruction screen instead of starting game directly startGameFromMenu(); return; } // Check menu button (ANA MENÜ) - centered at 1024x1616, button is 380x110 if (x >= 834 && x <= 1214 && y >= 1561 && y <= 1671) { // Prevent rapid clicks var currentTime = Date.now(); if (currentTime - lastButtonClickTime < 300) { return; // Ignore click if too recent } lastButtonClickTime = currentTime; // Simple visual feedback with color change simpleColorTint(menuButton, 0xF1948A, 150); hideGameOverScreen(); resetGame(); 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) { // Prevent rapid clicks var currentTime = Date.now(); if (currentTime - lastButtonClickTime < 300) { return; // Ignore click if too recent } lastButtonClickTime = currentTime; // Simple visual feedback with color change simpleColorTint(playButton, 0xFFB74D, 100); 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) { var currentTime = Date.now(); if (currentTime - lastButtonClickTime < 300) { return; // Ignore click if too recent } lastButtonClickTime = currentTime; // Simple visual feedback with color change simpleColorTint(mainLanguageButton, 0xBB8FCE, 150); showLanguageControls(); return; } return; } if (!gameStarted) { gameStarted = true; instructionTxt.visible = false; } bird.flap(); }; // Main game loop game.update = function () { if (gameOver || showMainMenu || showGameOver) return; // Movement validation: ensure bird stays at its intended position if (bird) { var intendedX = 300; // Bird should always be at x=300 if (Math.abs(bird.x - intendedX) > 1) { console.log("Bird movement detected! Current x:", bird.x, "Expected x:", intendedX); bird.x = intendedX; // Force bird back to correct position } } // 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; showGameOverScreen(currentScore); return; } // Ultra-simplified pipe cleanup - only run every 60 frames if (LK.ticks % 60 === 0) { var cleanupCount = 0; for (var i = pipes.length - 1; i >= 0 && cleanupCount < 5; i--) { var pipe = pipes[i]; if (pipe && pipe.x > 2248) { // Remove pipes that moved off right side pipe.destroy(); pipes.splice(i, 1); cleanupCount++; } } } // Ultra-simplified collision - only check closest pipe var closestPipe = null; var minDistance = 1000; for (var i = 0; i < pipes.length; i++) { var pipe = pipes[i]; var distance = pipe.x - bird.x; if (distance > -100 && distance < 200 && distance < minDistance) { closestPipe = pipe; minDistance = distance; } } if (closestPipe) { // Initialize lastX tracking if (typeof closestPipe.lastX === 'undefined') { closestPipe.lastX = closestPipe.x; } // Scoring check - pipe passes bird when moving right to left if (!closestPipe.passed && closestPipe.lastX <= bird.x && closestPipe.x > bird.x) { closestPipe.passed = true; var newScore = LK.getScore() + 1; LK.setScore(newScore); scoreTxt.setText(newScore.toString()); try { LK.getSound('score').play(); } catch (e) {} } // Update last position closestPipe.lastX = closestPipe.x; // Collision check - only if very close if (closestPipe.x > bird.x - 60 && closestPipe.x < bird.x + 60) { var gapTop = closestPipe.gapCenterY - closestPipe.gapSize / 2; var gapBottom = closestPipe.gapCenterY + closestPipe.gapSize / 2; if (bird.y < gapTop + 40 || bird.y > gapBottom - 40) { gameOver = true; var currentScore = LK.getScore(); storage.lastScore = currentScore; if (currentScore > (storage.highScore || 0)) { storage.highScore = currentScore; } showGameOverScreen(currentScore); return; } } } } };
/****
* Plugins
****/
var storage = LK.import("@upit/storage.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();
}
};
// Remove idle animation function
self.startIdleAnimation = function () {
// No animation needed
};
// Optimized update method
self.update = function () {
// Update cooldowns
if (self.flapCooldown > 0) self.flapCooldown--;
if (!gameStarted) {
// Pre-game idle state
self.velocity = 0;
self.y = 1366;
self.x = 300; // Force x position
return;
}
// Simple physics with improved scaling
if (!gameOver) {
// Only update position if game is not over
self.velocity += gravity;
self.y += self.velocity;
// Bird should stay at fixed x position - pipes move towards it
// Force bird to stay at x=300, prevent any backward movement
self.x = 300;
} else {
// Prevent any movement when game is over
self.velocity = 0;
self.x = 300; // Force x position even when game is over
// Do not update self.y after game over
}
// Minimal rotation calculation - only every 10 frames
if (LK.ticks % 10 === 0) {
birdGraphics.rotation = self.velocity > 0 ? 0.8 : -0.4;
}
// 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 current 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 right so bird appears to move towards them
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;
// Simple animation helpers without tween plugin
function simpleScale(target, endScale, duration, callback) {
var startScale = target.scaleX || 1;
var startTime = LK.ticks;
var totalFrames = Math.floor(duration / 16.67); // 60fps
var frameCount = 0;
var animateInterval = LK.setInterval(function () {
frameCount++;
var progress = frameCount / totalFrames;
if (progress >= 1) {
progress = 1;
LK.clearInterval(animateInterval);
if (callback) callback();
}
var currentScale = startScale + (endScale - startScale) * progress;
target.scaleX = currentScale;
target.scaleY = currentScale;
}, 16);
}
function simpleColorTint(target, color, duration, callback) {
var originalTint = target.tint;
target.tint = color;
if (duration > 0) {
LK.setTimeout(function () {
target.tint = originalTint;
if (callback) callback();
}, duration);
} else if (callback) {
callback();
}
}
var bird;
var pipes = [];
var ground;
var gameStarted = false;
var gameOver = false;
var showMainMenu = true;
var showGameOver = false;
var lastButtonClickTime = 0; // Track last button click time
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
// Initialize storage with defaults
var _storage = storage;
// Create score text display
var scoreTxt = new Text2('0', {
size: 150,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
scoreTxt.stroke = 0x000000;
scoreTxt.strokeThickness = 5;
var lastScoreDisplayed = -1; // Cache last displayed score
try {
if (LK.gui && LK.gui.top) {
LK.gui.top.addChild(scoreTxt);
}
} catch (e) {
console.log("GUI score text error:", e);
}
// Create cup shape for score
var cupShape;
try {
cupShape = LK.getAsset('cup', {
anchorX: 0.5,
anchorY: 0
});
cupShape.tint = 0xFFD700;
if (LK.gui && LK.gui.bottomRight) {
LK.gui.bottomRight.addChild(cupShape);
cupShape.y = -230;
cupShape.x = -100;
}
} catch (e) {
console.log("Cup shape error:", e);
}
// 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;
try {
if (LK.gui && LK.gui.center) {
LK.gui.center.addChild(mainMenuTitle);
mainMenuTitle.y = -280;
}
} catch (e) {
console.log("Main menu title error:", e);
}
// 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);
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 - position in open area away from any walls
bird = game.addChild(new Bird());
bird.x = 300; // Position bird further back in open area
bird.y = 1366;
// Initialize bird properly
bird.velocity = 0;
// Pre-generate all pipes function
function generateAllPipes() {
// Define safe boundaries for gap center to ensure both pipes have reasonable heights
var minGapY = 700; // Increased minimum gap center position for better clearance
var maxGapY = 1900; // Adjusted maximum gap center position for better clearance
// Generate fewer pipes to prevent memory issues
var totalPipesNeeded = 100; // Reduced from 1000 to 100
var currentX = -600; // Starting position to the left of bird since pipes move right
var pipeSpacing = 600; // Adjusted spacing between pipes for better gameplay
// Ensure no pipes overlap at the start
if (pipes && pipes.length > 0) {
currentX = pipes[pipes.length - 1].x + pipeSpacing;
}
for (var pipeIndex = 0; pipeIndex < totalPipesNeeded; pipeIndex++) {
var gapCenterY;
// Create more 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;
}
// Add some variation based on pipe index for progressive difficulty
if (pipeIndex > 10) {
// After pipe 10, make gaps slightly more challenging
var difficultyFactor = Math.min(0.8, pipeIndex / 50); // Max 80% difficulty increase
var centerPull = 1300; // Pull towards center-high area
gapCenterY = gapCenterY + (centerPull - gapCenterY) * difficultyFactor * 0.3;
}
// 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;
}
}
// Reset game function
function resetGame() {
// Reset bird - position it in open area with no walls
bird.x = 300; // Position bird in open area
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;
showMainMenu = true;
showGameOver = false;
// Hide game over screen
hideGameOverScreen();
LK.setScore(0);
scoreTxt.setText('0');
lastScoreDisplayed = -1;
// Show main menu
mainMenuTitle.visible = true;
// Show play button elements
if (playButton) playButton.visible = true;
if (playButtonShadow) playButtonShadow.visible = true;
if (playButtonHighlight) playButtonHighlight.visible = true;
if (playButtonText) playButtonText.visible = true;
// Show cup shape (high score indicator)
if (cupShape) cupShape.visible = true;
// Show main language button elements
if (mainLanguageButton) mainLanguageButton.visible = true;
if (mainLanguageButtonShadow) mainLanguageButtonShadow.visible = true;
if (mainLanguageButtonHighlight) mainLanguageButtonHighlight.visible = true;
if (mainLanguageButtonText) mainLanguageButtonText.visible = true;
// Hide instruction
instructionTxt.visible = false;
generateAllPipes();
}
// Function to start game from main menu
function startGameFromMenu() {
showMainMenu = false;
// Hide main menu elements
mainMenuTitle.visible = false;
// Hide play button elements
if (playButton) playButton.visible = false;
if (playButtonShadow) playButtonShadow.visible = false;
if (playButtonHighlight) playButtonHighlight.visible = false;
if (playButtonText) playButtonText.visible = false;
// Hide cup shape (high score indicator)
if (cupShape) cupShape.visible = false;
// Hide main language button elements
if (mainLanguageButton) mainLanguageButton.visible = false;
if (mainLanguageButtonShadow) mainLanguageButtonShadow.visible = false;
if (mainLanguageButtonHighlight) mainLanguageButtonHighlight.visible = false;
if (mainLanguageButtonText) mainLanguageButtonText.visible = false;
// Show instruction
instructionTxt.visible = true;
}
// Function to show game over screen
function showGameOverScreen(finalScore) {
if (showGameOver) return;
showGameOver = true;
gameStarted = false;
showMainMenu = false;
// Hide instruction
instructionTxt.visible = false;
// Show game over elements
gameOverBg.visible = true;
gameOverTitle.visible = true;
finalScoreText.visible = true;
bestScoreText.visible = true;
retryButton.visible = true;
retryButtonText.visible = true;
retryButtonShadow.visible = true;
retryButtonHighlight.visible = true;
menuButton.visible = true;
menuButtonText.visible = true;
menuButtonShadow.visible = true;
menuButtonHighlight.visible = true;
// Update score displays
finalScoreText.setText(getText('score') + ': ' + finalScore);
// Use proper text sizing
if (finalScoreText.width > 600) {
var newSize = Math.max(50, Math.floor(80 * 600 / finalScoreText.width));
if (finalScoreText.style.size !== newSize) {
finalScoreText.style = {
size: newSize,
fill: finalScoreText.style.fill
};
}
}
// Always show the current high score from persistent storage
var currentHighScore = storage.highScore || 0;
bestScoreText.setText(getText('bestScore') + ': ' + currentHighScore);
// 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
};
}
// Simple game over screen display - no animations
}
// Function to hide game over screen
function hideGameOverScreen() {
showGameOver = false;
// Hide game over elements
gameOverBg.visible = false;
gameOverTitle.visible = false;
finalScoreText.visible = false;
bestScoreText.visible = false;
retryButton.visible = false;
retryButtonText.visible = false;
retryButtonShadow.visible = false;
retryButtonHighlight.visible = false;
menuButton.visible = false;
menuButtonText.visible = false;
menuButtonShadow.visible = false;
menuButtonHighlight.visible = false;
}
// 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 main menu elements
mainMenuTitle.visible = false;
if (playButton) playButton.visible = false;
if (playButtonShadow) playButtonShadow.visible = false;
if (playButtonHighlight) playButtonHighlight.visible = false;
if (playButtonText) playButtonText.visible = false;
if (cupShape) cupShape.visible = false;
// Hide main language button elements
if (mainLanguageButton) mainLanguageButton.visible = false;
if (mainLanguageButtonShadow) mainLanguageButtonShadow.visible = false;
if (mainLanguageButtonHighlight) mainLanguageButtonHighlight.visible = false;
if (mainLanguageButtonText) mainLanguageButtonText.visible = false;
// Show language controls
languageOverlay.visible = true;
languageTitle.visible = true;
turkishButton.visible = true;
turkishButtonShadow.visible = true;
turkishButtonHighlight.visible = true;
turkishText.visible = true;
englishButton.visible = true;
englishButtonShadow.visible = true;
englishButtonHighlight.visible = true;
englishText.visible = true;
currentLanguageText.visible = true;
languageBackButton.visible = true;
languageBackButtonShadow.visible = true;
languageBackButtonHighlight.visible = true;
languageBackText.visible = true;
updateLanguageDisplay();
}
// Function to hide language controls
function hideLanguageControls() {
// Hide all language control elements
languageOverlay.visible = false;
languageTitle.visible = false;
turkishButton.visible = false;
turkishButtonShadow.visible = false;
turkishButtonHighlight.visible = false;
turkishText.visible = false;
englishButton.visible = false;
englishButtonShadow.visible = false;
englishButtonHighlight.visible = false;
englishText.visible = false;
currentLanguageText.visible = false;
languageBackButton.visible = false;
languageBackButtonShadow.visible = false;
languageBackButtonHighlight.visible = false;
languageBackText.visible = false;
// Show main menu elements again
if (showMainMenu) {
mainMenuTitle.visible = true;
if (playButton) playButton.visible = true;
if (playButtonShadow) playButtonShadow.visible = true;
if (playButtonHighlight) playButtonHighlight.visible = true;
if (playButtonText) playButtonText.visible = true;
if (cupShape) cupShape.visible = true;
if (mainLanguageButton) mainLanguageButton.visible = true;
if (mainLanguageButtonShadow) mainLanguageButtonShadow.visible = true;
if (mainLanguageButtonHighlight) mainLanguageButtonHighlight.visible = true;
if (mainLanguageButtonText) mainLanguageButtonText.visible = true;
}
}
// 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',
back: 'GERİ'
},
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'
}
};
// 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() {
try {
if (instructionTxt && instructionTxt.setText) {
try {
instructionTxt.setText(getText('instruction'));
} catch (e) {}
}
if (playButtonText && playButtonText.setText) {
try {
playButtonText.setText(getText('playButton'));
} catch (e) {}
}
if (gameOverTitle && gameOverTitle.setText) {
try {
gameOverTitle.setText(getText('gameOver'));
} catch (e) {}
}
if (retryButtonText && retryButtonText.setText) {
try {
retryButtonText.setText(getText('retry'));
} catch (e) {}
}
if (menuButtonText && menuButtonText.setText) {
try {
menuButtonText.setText(getText('mainMenu'));
} catch (e) {}
}
if (languageTitle && languageTitle.setText) {
try {
languageTitle.setText(getText('languageTitle'));
} catch (e) {}
}
if (languageBackText && languageBackText.setText) {
try {
languageBackText.setText(getText('back'));
} catch (e) {}
}
if (mainLanguageButtonText && mainLanguageButtonText.setText) {
try {
mainLanguageButtonText.setText(getText('language'));
} catch (e) {}
}
// Update final and best score texts
if (finalScoreText && finalScoreText.setText) {
var currentScore = LK.getScore();
try {
finalScoreText.setText(getText('score') + ': ' + currentScore);
} catch (e) {}
}
if (bestScoreText && bestScoreText.setText) {
var currentHighScore = storage.highScore || 0;
try {
bestScoreText.setText(getText('bestScore') + ': ' + currentHighScore);
} catch (e) {}
}
} catch (e) {
console.log("Text update error:", e);
}
}
// 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) {
try {
currentLanguageText.setText(currentText + ': ' + langText);
} catch (e) {}
}
// Update button colors to show selected language
if (turkishButton) {
turkishButton.tint = currentLanguage === 'tr' ? 0x2ECC71 : 0x27AE60;
}
if (englishButton) {
englishButton.tint = currentLanguage === 'en' ? 0x5DADE2 : 0x3498DB;
}
// Ensure button text is always correct
if (turkishText && turkishText.setText) {
try {
turkishText.setText('TÜRKÇE');
} catch (e) {}
}
if (englishText && englishText.setText) {
try {
englishText.setText('ENGLISH');
} catch (e) {}
}
}
// 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 (!storage.globalLeaderboardNames) storage.globalLeaderboardNames = [];
if (!storage.globalLeaderboardScores) storage.globalLeaderboardScores = [];
if (typeof storage.highScore === 'undefined') storage.highScore = 0;
if (typeof storage.lastScore === 'undefined') storage.lastScore = 0;
if (!storage.language) storage.language = 'tr';
if (!storage.username) storage.username = 'Oyuncu1';
// Update current language from persistent storage
currentLanguage = storage.language || 'tr';
// Initialize username if not exists
if (!storage.username) {
var playerNumber = 1;
while (storage.globalLeaderboardNames.indexOf('Oyuncu ' + playerNumber) !== -1) {
playerNumber++;
}
storage.username = 'Oyuncu ' + playerNumber;
}
// 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
try {
if (LK.gui && LK.gui.center) {
LK.gui.center.addChild(playButton);
playButton.y = -100;
}
} catch (e) {
console.log("Play button error:", e);
}
// 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;
try {
if (LK.gui && LK.gui.center) {
LK.gui.center.addChild(mainLanguageButton);
mainLanguageButton.y = 50;
}
} catch (e) {
console.log("Main language button error:", e);
}
// 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;
try {
if (LK.gui && LK.gui.center) {
LK.gui.center.addChild(mainLanguageButtonShadow);
mainLanguageButtonShadow.y = 55;
mainLanguageButtonShadow.x = 3;
}
} catch (e) {
console.log("Main language button shadow error:", e);
}
// 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;
try {
if (LK.gui && LK.gui.center) {
LK.gui.center.addChild(mainLanguageButtonHighlight);
mainLanguageButtonHighlight.y = 45;
}
} catch (e) {
console.log("Main language button highlight error:", e);
}
// 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;
try {
if (LK.gui && LK.gui.center) {
LK.gui.center.addChild(mainLanguageButtonText);
mainLanguageButtonText.y = 50;
}
} catch (e) {
console.log("Main language button text error:", e);
}
// 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
try {
if (LK.gui && LK.gui.center) {
LK.gui.center.addChild(playButtonShadow);
playButtonShadow.y = -92; // Offset shadow slightly up
playButtonShadow.x = 4; // Offset shadow slightly right
}
} catch (e) {
console.log("Play button shadow error:", e);
}
// 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
try {
if (LK.gui && LK.gui.center) {
LK.gui.center.addChild(playButtonHighlight);
playButtonHighlight.y = -108; // Offset highlight slightly down
}
} catch (e) {
console.log("Play button highlight error:", e);
}
// 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;
try {
if (LK.gui && LK.gui.center) {
LK.gui.center.addChild(playButtonText);
playButtonText.y = -100;
}
} catch (e) {
console.log("Play button text error:", e);
}
// 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 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) {
var currentTime = Date.now();
if (currentTime - lastButtonClickTime < 300) return;
lastButtonClickTime = currentTime;
// Simple visual feedback with color change
simpleColorTint(turkishButton, 0x58D68D, 150);
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) {
var currentTime = Date.now();
if (currentTime - lastButtonClickTime < 300) return;
lastButtonClickTime = currentTime;
// Simple visual feedback with color change
simpleColorTint(englishButton, 0x85C1E9, 150);
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) {
var currentTime = Date.now();
if (currentTime - lastButtonClickTime < 300) return;
lastButtonClickTime = currentTime;
// Simple visual feedback with color change
simpleColorTint(languageBackButton, 0xABB2B9, 150);
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) {
var currentTime = Date.now();
if (currentTime - lastButtonClickTime < 500) return;
lastButtonClickTime = currentTime;
// Simple high score display from persistent storage
var highScore = storage.highScore || 0;
console.log(getText('highestScore') + ': ' + highScore);
return;
}
if (gameOver || showGameOver) {
// Check retry button (TEKRAR DENE) - centered at 1024x1466, button is 380x110
if (x >= 834 && x <= 1214 && y >= 1411 && y <= 1521) {
// Prevent rapid clicks
var currentTime = Date.now();
if (currentTime - lastButtonClickTime < 300) {
return; // Ignore click if too recent
}
lastButtonClickTime = currentTime;
// Simple visual feedback with color change
simpleColorTint(retryButton, 0xFFB74D, 150);
hideGameOverScreen();
resetGame();
// Show instruction screen instead of starting game directly
startGameFromMenu();
return;
}
// Check menu button (ANA MENÜ) - centered at 1024x1616, button is 380x110
if (x >= 834 && x <= 1214 && y >= 1561 && y <= 1671) {
// Prevent rapid clicks
var currentTime = Date.now();
if (currentTime - lastButtonClickTime < 300) {
return; // Ignore click if too recent
}
lastButtonClickTime = currentTime;
// Simple visual feedback with color change
simpleColorTint(menuButton, 0xF1948A, 150);
hideGameOverScreen();
resetGame();
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) {
// Prevent rapid clicks
var currentTime = Date.now();
if (currentTime - lastButtonClickTime < 300) {
return; // Ignore click if too recent
}
lastButtonClickTime = currentTime;
// Simple visual feedback with color change
simpleColorTint(playButton, 0xFFB74D, 100);
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) {
var currentTime = Date.now();
if (currentTime - lastButtonClickTime < 300) {
return; // Ignore click if too recent
}
lastButtonClickTime = currentTime;
// Simple visual feedback with color change
simpleColorTint(mainLanguageButton, 0xBB8FCE, 150);
showLanguageControls();
return;
}
return;
}
if (!gameStarted) {
gameStarted = true;
instructionTxt.visible = false;
}
bird.flap();
};
// Main game loop
game.update = function () {
if (gameOver || showMainMenu || showGameOver) return;
// Movement validation: ensure bird stays at its intended position
if (bird) {
var intendedX = 300; // Bird should always be at x=300
if (Math.abs(bird.x - intendedX) > 1) {
console.log("Bird movement detected! Current x:", bird.x, "Expected x:", intendedX);
bird.x = intendedX; // Force bird back to correct position
}
}
// 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;
showGameOverScreen(currentScore);
return;
}
// Ultra-simplified pipe cleanup - only run every 60 frames
if (LK.ticks % 60 === 0) {
var cleanupCount = 0;
for (var i = pipes.length - 1; i >= 0 && cleanupCount < 5; i--) {
var pipe = pipes[i];
if (pipe && pipe.x > 2248) {
// Remove pipes that moved off right side
pipe.destroy();
pipes.splice(i, 1);
cleanupCount++;
}
}
}
// Ultra-simplified collision - only check closest pipe
var closestPipe = null;
var minDistance = 1000;
for (var i = 0; i < pipes.length; i++) {
var pipe = pipes[i];
var distance = pipe.x - bird.x;
if (distance > -100 && distance < 200 && distance < minDistance) {
closestPipe = pipe;
minDistance = distance;
}
}
if (closestPipe) {
// Initialize lastX tracking
if (typeof closestPipe.lastX === 'undefined') {
closestPipe.lastX = closestPipe.x;
}
// Scoring check - pipe passes bird when moving right to left
if (!closestPipe.passed && closestPipe.lastX <= bird.x && closestPipe.x > bird.x) {
closestPipe.passed = true;
var newScore = LK.getScore() + 1;
LK.setScore(newScore);
scoreTxt.setText(newScore.toString());
try {
LK.getSound('score').play();
} catch (e) {}
}
// Update last position
closestPipe.lastX = closestPipe.x;
// Collision check - only if very close
if (closestPipe.x > bird.x - 60 && closestPipe.x < bird.x + 60) {
var gapTop = closestPipe.gapCenterY - closestPipe.gapSize / 2;
var gapBottom = closestPipe.gapCenterY + closestPipe.gapSize / 2;
if (bird.y < gapTop + 40 || bird.y > gapBottom - 40) {
gameOver = true;
var currentScore = LK.getScore();
storage.lastScore = currentScore;
if (currentScore > (storage.highScore || 0)) {
storage.highScore = currentScore;
}
showGameOverScreen(currentScore);
return;
}
}
}
}
};