User prompt
popup screen ı not see
User prompt
popup bacground new color
User prompt
yazıların arkasındaki katmanı kaldır açık gri
User prompt
katmanı kaldır
User prompt
butonları transparan yap
User prompt
daily revard biraz daha alta alhiçbir yazı üst üste binmesin
User prompt
dil seçme vekarekter seçme tuşu ground görselinin altında kalıyor
User prompt
renkler berbat seçenekleri düzenle
User prompt
play tuşu daha altta olsun
User prompt
ana menü çok karmaşık bütün butonlar birbirine giriyor dil seçme tuşu ve karekter seçme tuşunu en alta yan yana ekle
User prompt
oyunun pause butonuna ana menüye dön tuşu ekle
User prompt
ana menüye daily revard ekle
User prompt
karekterler karekter seçme ekranında gözükmüyor
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'en')' in or related to this line: 'var selectionTitle = new Text2(localizedText[currentLanguage].selectionTitle, {' Line Number: 306
User prompt
karekter seçme ekranı oluştur
User prompt
select your animal tuşuna bastığımızda karekterler ekrana gelmiyor
User prompt
play tuşuna bastıktan sonra oyun başlasın
User prompt
play tuşuna bastıktan sonra oyun başlamıyor tap to start ekranına tıklanmıyor
User prompt
oyunu geliştirelim yenilikler ekleyelim
User prompt
anamenüyü düzenle yazılar ve butonlar üst üste gelmesin
User prompt
Please fix the bug: 'playButton.getChildAt(...).setText is not a function' in or related to this line: 'playButton.getChildAt(0).setText(text.playButton);' Line Number: 577
User prompt
play button play yazısında olmalı
User prompt
oyunu modernize edelim
User prompt
select your animal tuşuna bastığımda oyun açılmaya çalışıyor
User prompt
select your animal tuşuna bastığımızda karekter seçim ekranı gelmeli karekteri seçip geri tuşuna basarak ana menüye dönebilmeliyiz
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Bird = Container.expand(function (characterType) { var self = Container.call(this); // Create bird graphics based on character type var assetName = characterType || 'bird'; var birdGraphics = self.attachAsset(assetName, { anchorX: 0.5, anchorY: 0.5 }); // Physics properties self.velocity = 0; self.gravity = 0.8; self.flapPower = -12; self.maxVelocity = 15; // Tracking properties self.lastY = 0; self.update = function () { // Store last position self.lastY = self.y; // Only apply physics if game has started and not paused if (gameStarted && !gamePaused) { // Apply gravity self.velocity += self.gravity; // Limit velocity if (self.velocity > self.maxVelocity) { self.velocity = self.maxVelocity; } // Update position self.y += self.velocity; // Rotate bird based on velocity birdGraphics.rotation = Math.min(Math.max(self.velocity * 0.05, -0.5), 1.2); } }; self.flap = function () { self.velocity = self.flapPower; LK.getSound('flap').play(); // Add smooth rotation animation when flapping tween(birdGraphics, { rotation: -0.3 }, { duration: 150, onFinish: function onFinish() { // Bird naturally rotates back down due to velocity in update } }); // Add scale animation for visual feedback tween(birdGraphics, { scaleX: 1.1, scaleY: 1.1 }, { duration: 100, onFinish: function onFinish() { tween(birdGraphics, { scaleX: 1, scaleY: 1 }, { duration: 100 }); } }); }; return self; }); var Ground = Container.expand(function () { var self = Container.call(this); // Create ground graphics var groundGraphics = self.attachAsset('ground', { anchorX: 0, anchorY: 0 }); // Movement properties self.speed = -4; self.update = function () { // Store last position self.lastX = self.x; // Only move ground if game is not paused if (!gamePaused) { // Move ground left self.x += self.speed; // Reset position when off screen for infinite scrolling if (self.x <= -2048) { self.x = 2048; } } }; return self; }); var ParticleSystem = Container.expand(function (config) { var self = Container.call(this); self.particles = []; self.maxParticles = config.maxParticles || 50; self.particleConfig = config; self.emit = function (x, y, count) { count = count || 10; for (var i = 0; i < count && self.particles.length < self.maxParticles; i++) { var particle = LK.getAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.1 + Math.random() * 0.2, scaleY: 0.1 + Math.random() * 0.2 }); particle.x = x + (Math.random() - 0.5) * 100; particle.y = y + (Math.random() - 0.5) * 100; particle.tint = self.particleConfig.color || 0xFFFFFF; particle.alpha = 0.8; particle.vx = (Math.random() - 0.5) * 10; particle.vy = (Math.random() - 0.5) * 10 - 5; particle.life = 1.0; particle.decay = 0.02; self.particles.push(particle); self.addChild(particle); } }; self.update = function () { for (var i = self.particles.length - 1; i >= 0; i--) { var particle = self.particles[i]; particle.x += particle.vx; particle.y += particle.vy; particle.vy += 0.3; // gravity particle.life -= particle.decay; particle.alpha = particle.life; if (particle.life <= 0) { self.removeChild(particle); self.particles.splice(i, 1); } } }; return self; }); // Game variables var Pipe = Container.expand(function () { var self = Container.call(this); // Create top and bottom pipe parts var topPipe = self.attachAsset('pipe', { anchorX: 0.5, anchorY: 1 }); var bottomPipe = self.attachAsset('pipe', { anchorX: 0.5, anchorY: 0 }); // Movement properties self.speed = -4; self.gapSize = 300; self.passed = false; // Tracking properties self.lastX = 0; self.setGapPosition = function (centerY) { // Position top pipe (anchor at bottom, so y is bottom edge) topPipe.y = centerY - self.gapSize / 2; // Position bottom pipe (anchor at top, so y is top edge) bottomPipe.y = centerY + self.gapSize / 2; }; self.update = function () { // Store last position self.lastX = self.x; // Only move pipe if game is not paused if (!gamePaused) { // Move pipe left self.x += self.speed; } }; self.getTopBounds = function () { return { x: self.x - 100, y: 0, width: 200, height: topPipe.y }; }; self.getBottomBounds = function () { return { x: self.x - 100, y: bottomPipe.y, width: 200, height: 2732 - bottomPipe.y }; }; return self; }); var PowerUp = Container.expand(function (type) { var self = Container.call(this); self.type = type || 'coin'; self.collected = false; var powerUpGraphics = self.attachAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.8 }); // Different colors for different power-ups if (self.type === 'coin') { powerUpGraphics.tint = 0xFFD700; } else if (self.type === 'shield') { powerUpGraphics.tint = 0x00FFFF; } self.speed = -4; self.floatOffset = 0; self.lastX = 0; // Initialize tracking property self.update = function () { // Store last position self.lastX = self.x; if (!gamePaused) { self.x += self.speed; // Floating animation self.floatOffset += 0.1; powerUpGraphics.y = Math.sin(self.floatOffset) * 20; // Rotation animation powerUpGraphics.rotation += 0.05; } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87CEEB }); /**** * Game Code ****/ // Initialize sound for flap // Initialize ground asset - brown rectangle for the ground // Initialize pipe assets - green rectangles for obstacles // Initialize bird asset - yellow circle for the flappy bird // Game variables var bird; var pipes = []; var ground1, ground2; var gameStarted = false; var gamePaused = false; var pipeTimer = 0; var pipeSpacing = 800; // Modern game features var comboCount = 0; var comboTimer = 0; var maxCombo = 0; var powerUps = []; var particleSystem; var shieldActive = false; var shieldTimer = 0; var coins = 0; var difficulty = 1; var difficultyTimer = 0; var currentLanguage = 'en'; // Default language // Wind system var wind = 0; // Current wind force, -2 to +2 var windTarget = 0; // Target wind force var windTimer = 0; // Timer for wind change var windChangeInterval = 600; // How often wind changes (in frames, 10s) var windTxt = new Text2('', { size: 40, fill: 0x00cfff }); windTxt.anchor.set(0.5, 0); windTxt.y = 210; LK.gui.top.addChild(windTxt); // Pause button var gameState = 'MAIN_MENU'; // 'MAIN_MENU', 'CHARACTER_SELECT', 'START_SCREEN', 'PLAYING' var selectedCharacter = 'bird'; var mainMenuScreen = new Container(); // Define main menu screen mainMenuScreen.visible = false; // Initialize main menu screen as hidden var characterTypes = ['bird', 'bird2', 'bird3', 'bird4']; var characterSelectionScreen = new Container(); characterSelectionScreen.visible = false; // (Removed duplicate character selection screen and button creation to avoid undefined localizedText error) mainMenuScreen.addChild(characterSelectionScreen); // Score display var scoreTxt = new Text2('0', { size: 80, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Best score display var bestScore = storage.bestScore || 0; var bestScoreTxt = new Text2('BEST: ' + bestScore, { size: 40, fill: 0xFFD700 }); bestScoreTxt.anchor.set(0.5, 0); bestScoreTxt.y = 100; LK.gui.top.addChild(bestScoreTxt); // Combo display var comboTxt = new Text2('', { size: 50, fill: 0xFF4500 }); comboTxt.anchor.set(0.5, 0.5); comboTxt.x = 0; comboTxt.y = 200; comboTxt.visible = false; LK.gui.center.addChild(comboTxt); // Coin counter var coinTxt = new Text2('💰 0', { size: 60, fill: 0xFFD700 }); coinTxt.anchor.set(0, 0); coinTxt.x = 20; coinTxt.y = 20; LK.gui.topLeft.addChild(coinTxt); // Shield indicator var shieldTxt = new Text2('🛡️', { size: 80, fill: 0x00FFFF }); shieldTxt.anchor.set(1, 0); shieldTxt.x = -120; shieldTxt.y = 20; shieldTxt.visible = false; LK.gui.topRight.addChild(shieldTxt); // Difficulty indicator var difficultyTxt = new Text2('LEVEL 1', { size: 35, fill: 0xFFFFFF }); difficultyTxt.anchor.set(0.5, 0); difficultyTxt.y = 160; LK.gui.top.addChild(difficultyTxt); // Localized Text var localizedText = { en: { welcomeTitle: 'FLAPPY ANIMAL', subtitleText: 'CLASSIC ARCADE GAME', tapToPlayInfo: 'TAP TO BEGIN YOUR ADVENTURE!', playButton: 'PLAY', selectionTitle: 'SELECT YOUR ANIMAL', characterNames: ['CLASSIC', 'RED', 'GREEN', 'BLUE'], confirmBtn: 'CONFIRM', gameTitle: 'FLAPPY ANIMAL', characterLabel: 'READY!', startBtn: 'START GAME', tapToPlayText: 'TAP BUTTON TO BEGIN!', backBtn: 'BACK', instructionTxt: 'TAP TO START', paused: 'PAUSED', resumeText: 'TAP TO RESUME', gameOver: 'GAME OVER', crashed: 'CRASHED!', hitCeiling: 'HIT CEILING!', bestScore: 'BEST: ', combo: 'COMBO x', level: 'LEVEL ' }, es: { welcomeTitle: 'ANIMAL ALETA', subtitleText: 'JUEGO CLÁSICO DE ARCADE', tapToPlayInfo: '¡TOCA PARA COMENZAR TU AVENTURA!', playButton: 'JUGAR', selectionTitle: 'SELECCIONA TU ANIMAL', characterNames: ['CLÁSICO', 'ROJO', 'VERDE', 'AZUL'], confirmBtn: 'CONFIRMAR', gameTitle: 'ANIMAL ALETA', characterLabel: '¡LISTO!', startBtn: 'COMENZAR JUEGO', tapToPlayText: '¡TOCA EL BOTÓN PARA EMPEZAR!', backBtn: 'ATRAS', instructionTxt: 'TOCA PARA EMPEZAR', paused: 'PAUSADO', resumeText: 'TOCA PARA REANUDAR', gameOver: 'FIN DEL JUEGO', crashed: '¡ESTRELLADO!', hitCeiling: '¡GOLPE CONTRA EL TECHO!', bestScore: 'MEJOR: ', combo: 'COMBO x', level: 'NIVEL ' }, fr: { welcomeTitle: 'ANIMAL BATTANT', subtitleText: 'JEU D\'ARCADE CLASSIQUE', tapToPlayInfo: 'APPUYEZ POUR COMMENCER VOTRE AVENTURE!', playButton: 'JOUER', selectionTitle: 'SÉLECTIONNEZ VOTRE ANIMAL', characterNames: ['CLASSIQUE', 'ROUGE', 'VERT', 'BLEU'], confirmBtn: 'CONFIRMER', gameTitle: 'ANIMAL BATTANT', characterLabel: 'PRÊT!', startBtn: 'COMMENCER LE JEU', tapToPlayText: 'APPUYEZ SUR LE BOUTON POUR COMMENCER!', backBtn: 'RETOUR', instructionTxt: 'APPUYEZ POUR COMMENCER', paused: 'EN PAUSE', resumeText: 'APPUYEZ POUR REPRENDRE', gameOver: 'FIN DU JEU', crashed: 'ÉCRASÉ!', hitCeiling: 'FRAPPÉ LE PLAFOND!', bestScore: 'MEILLEUR: ', combo: 'COMBO x', level: 'NIVEAU ' }, tr: { welcomeTitle: 'KANATLI HAYVAN', subtitleText: 'KLASİK ARCADE OYUNU', tapToPlayInfo: 'MACERANA BAŞLAMAK İÇİN DOKUN!', playButton: 'OYNA', selectionTitle: 'HAYVANINI SEÇ', characterNames: ['KLASİK', 'KIRMIZI', 'YEŞİL', 'MAVİ'], confirmBtn: 'ONAYLA', gameTitle: 'KANATLI HAYVAN', characterLabel: 'HAZIR!', startBtn: 'OYUNU BAŞLAT', tapToPlayText: 'BAŞLAMAK İÇİN DÜĞMEYE DOKUN!', backBtn: 'GERİ', instructionTxt: 'BAŞLAMAK İÇİN DOKUN', paused: 'DURAKLATILDI', resumeText: 'DEVAM ETMEK İÇİN DOKUN', gameOver: 'OYUN BİTTİ', crashed: 'ÇARPTI!', hitCeiling: 'TAVANA ÇARPTI!', bestScore: 'EN İYİ: ', combo: 'KOMBO x', level: 'SEVİYE ' } }; // Pause button var pauseBtn = new Text2('| |', { size: 60, fill: 0xFFFFFF }); pauseBtn.anchor.set(1, 0); pauseBtn.x = -20; // Position from right edge pauseBtn.y = 20; LK.gui.topRight.addChild(pauseBtn); // Pause overlay var pauseOverlay = new Container(); var pauseBackground = LK.getAsset('centerCircle', { width: 2048, height: 2732, anchorX: 0, anchorY: 0, alpha: 0.7, scaleX: 20, scaleY: 27 }); pauseOverlay.addChild(pauseBackground); var pauseText = new Text2(localizedText[currentLanguage].paused, { size: 120, fill: 0xFFFFFF }); pauseText.anchor.set(0.5, 0.5); pauseText.x = 1024; pauseText.y = 1200; pauseOverlay.addChild(pauseText); var resumeText = new Text2(localizedText[currentLanguage].resumeText, { size: 60, fill: 0xFFFFFF }); resumeText.anchor.set(0.5, 0.5); resumeText.x = 1024; resumeText.y = 1400; pauseOverlay.addChild(resumeText); pauseOverlay.visible = false; // Add 'Return to Main Menu' button to pause overlay var returnToMenuBtn = new Text2(localizedText[currentLanguage] && localizedText[currentLanguage].backBtn ? localizedText[currentLanguage].backBtn : "MAIN MENU", { size: 70, fill: 0x00cfff }); returnToMenuBtn.anchor.set(0.5, 0.5); returnToMenuBtn.x = 1024; returnToMenuBtn.y = 1600; pauseOverlay.addChild(returnToMenuBtn); // Handler for 'Return to Main Menu' button returnToMenuBtn.down = function (x, y, obj) { if (gamePaused) { // Animate button press tween(returnToMenuBtn, { scaleX: 0.92, scaleY: 0.92 }, { duration: 100, onFinish: function onFinish() { tween(returnToMenuBtn, { scaleX: 1, scaleY: 1 }, { duration: 100 }); } }); // Hide pause overlay with animation, then show main menu tween(pauseOverlay, { alpha: 0 }, { duration: 200, onFinish: function onFinish() { pauseOverlay.visible = false; gamePaused = false; // Show main menu showMainMenu(); gameState = 'MAIN_MENU'; } }); } }; game.addChild(pauseOverlay); // Localized Text var localizedText = { en: { welcomeTitle: 'FLAPPY ANIMAL', subtitleText: 'CLASSIC ARCADE GAME', tapToPlayInfo: 'TAP TO BEGIN YOUR ADVENTURE!', playButton: 'PLAY', selectionTitle: 'SELECT YOUR ANIMAL', characterNames: ['CLASSIC', 'RED', 'GREEN', 'BLUE'], confirmBtn: 'CONFIRM', gameTitle: 'FLAPPY ANIMAL', characterLabel: 'READY!', startBtn: 'START GAME', tapToPlayText: 'TAP BUTTON TO BEGIN!', backBtn: 'BACK', instructionTxt: 'TAP TO START', paused: 'PAUSED', resumeText: 'TAP TO RESUME', gameOver: 'GAME OVER', crashed: 'CRASHED!', hitCeiling: 'HIT CEILING!', bestScore: 'BEST: ', combo: 'COMBO x', level: 'LEVEL ' }, es: { welcomeTitle: 'ANIMAL ALETA', subtitleText: 'JUEGO CLÁSICO DE ARCADE', tapToPlayInfo: '¡TOCA PARA COMENZAR TU AVENTURA!', playButton: 'JUGAR', selectionTitle: 'SELECCIONA TU ANIMAL', characterNames: ['CLÁSICO', 'ROJO', 'VERDE', 'AZUL'], confirmBtn: 'CONFIRMAR', gameTitle: 'ANIMAL ALETA', characterLabel: '¡LISTO!', startBtn: 'COMENZAR JUEGO', tapToPlayText: '¡TOCA EL BOTÓN PARA EMPEZAR!', backBtn: 'ATRAS', instructionTxt: 'TOCA PARA EMPEZAR', paused: 'PAUSADO', resumeText: 'TOCA PARA REANUDAR', gameOver: 'FIN DEL JUEGO', crashed: '¡ESTRELLADO!', hitCeiling: '¡GOLPE CONTRA EL TECHO!', bestScore: 'MEJOR: ', combo: 'COMBO x', level: 'NIVEL ' }, fr: { welcomeTitle: 'ANIMAL BATTANT', subtitleText: 'JEU D\'ARCADE CLASSIQUE', tapToPlayInfo: 'APPUYEZ POUR COMMENCER VOTRE AVENTURE!', playButton: 'JOUER', selectionTitle: 'SÉLECTIONNEZ VOTRE ANIMAL', characterNames: ['CLASSIQUE', 'ROUGE', 'VERT', 'BLEU'], confirmBtn: 'CONFIRMER', gameTitle: 'ANIMAL BATTANT', characterLabel: 'PRÊT!', startBtn: 'COMMENCER LE JEU', tapToPlayText: 'APPUYEZ SUR LE BOUTON POUR COMMENCER!', backBtn: 'RETOUR', instructionTxt: 'APPUYEZ POUR COMMENCER', paused: 'EN PAUSE', resumeText: 'APPUYEZ POUR REPRENDRE', gameOver: 'FIN DU JEU', crashed: 'ÉCRASÉ!', hitCeiling: 'FRAPPÉ LE PLAFOND!', bestScore: 'MEILLEUR: ', combo: 'COMBO x', level: 'NIVEAU ' }, tr: { welcomeTitle: 'KANATLI HAYVAN', subtitleText: 'KLASİK ARCADE OYUNU', tapToPlayInfo: 'MACERANA BAŞLAMAK İÇİN DOKUN!', playButton: 'OYNA', selectionTitle: 'HAYVANINI SEÇ', characterNames: ['KLASİK', 'KIRMIZI', 'YEŞİL', 'MAVİ'], confirmBtn: 'ONAYLA', gameTitle: 'KANATLI HAYVAN', characterLabel: 'HAZIR!', startBtn: 'OYUNU BAŞLAT', tapToPlayText: 'BAŞLAMAK İÇİN DÜĞMEYE DOKUN!', backBtn: 'GERİ', instructionTxt: 'BAŞLAMAK İÇİN DOKUN', paused: 'DURAKLATILDI', resumeText: 'DEVAM ETMEK İÇİN DOKUN', gameOver: 'OYUN BİTTİ', crashed: 'ÇARPTI!', hitCeiling: 'TAVANA ÇARPTI!', bestScore: 'EN İYİ: ', combo: 'KOMBO x', level: 'SEVİYE ' } }; // Function to update all text elements based on the current language function updateLocalizedText() { var text = localizedText[currentLanguage]; // Main Menu welcomeTitle.setText(text.welcomeTitle); subtitleText.setText(text.subtitleText); tapToPlayInfo.setText(text.tapToPlayInfo); playButtonText.setText(text.playButton); // Character Selection selectionTitle.setText(text.selectionTitle); for (var i = 0; i < characterButtons.length; i++) { characterButtons[i].getChildAt(1).setText(text.characterNames[i]); } confirmBtn.setText(text.confirmBtn); // Update character selection button text on main menu if it exists if (typeof characterSelectBtnText !== "undefined") { characterSelectBtnText.setText(text.selectionTitle); } // Start Game Screen gameTitle.setText(text.gameTitle); characterLabel.setText(text.characterLabel); startBtn.setText(text.startBtn); tapToPlayText.setText(text.tapToPlayText); backBtn.setText(text.backBtn); // Language Button Text if (mainMenuLanguageBtn && mainMenuLanguageBtn.parent) { mainMenuLanguageBtn.setText(currentLanguage.toUpperCase()); } if (startLanguageBtn && startLanguageBtn.parent) { startLanguageBtn.setText(currentLanguage.toUpperCase()); } // In-game UI bestScoreTxt.setText(text.bestScore + bestScore); difficultyTxt.setText(text.level + difficulty); // Wind text localization if (windTxt) { var windLabel = { en: 'WIND', es: 'VIENTO', fr: 'VENT', tr: 'RÜZGAR' }[currentLanguage] || 'WIND'; if (Math.abs(wind) > 0.2) { windTxt.setText((wind > 0 ? '→' : '←') + ' ' + windLabel + ': ' + (wind > 0 ? '+' : '') + wind.toFixed(1)); } } // Pause Overlay pauseText.setText(text.paused); resumeText.setText(text.resumeText); // Instruction Text (if visible) if (instructionTxt && instructionTxt.parent) { instructionTxt.setText(text.instructionTxt); } } // Main Menu Screen - Welcome Screen var mainMenuScreen = new Container(); var menuBackground = LK.getAsset('centerCircle', { width: 2048, height: 2732, anchorX: 0, anchorY: 0, alpha: 0.85, scaleX: 20, scaleY: 27, color: 0xeaf6fb // Soft modern blue }); mainMenuScreen.addChild(menuBackground); var welcomeTitle = new Text2('FLAPPY ANIMAL', { size: 140, fill: 0xFFD700 }); welcomeTitle.anchor.set(0.5, 0.5); welcomeTitle.x = 1024; welcomeTitle.y = 700; mainMenuScreen.addChild(welcomeTitle); var subtitleText = new Text2('CLASSIC ARCADE GAME', { size: 60, fill: 0x00cfff, shadow: { color: 0x003366, blur: 8, angle: Math.PI / 2, distance: 4 } }); subtitleText.anchor.set(0.5, 0.5); subtitleText.x = 1024; subtitleText.y = 850; mainMenuScreen.addChild(subtitleText); // Preview bird animation var previewBird = LK.getAsset('bird', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.5, scaleY: 2.5 }); previewBird.x = 1024; previewBird.y = 1050; // higher up to avoid overlap mainMenuScreen.addChild(previewBird); // Add floating animation to preview bird var birdFloat = LK.setInterval(function () { if (previewBird && mainMenuScreen.visible) { tween(previewBird, { y: 1000 }, { duration: 1000, onFinish: function onFinish() { tween(previewBird, { y: 1100 }, { duration: 1000 }); } }); } }, 2000); // Play button as a Container for better hit area var playButton = new Container(); var playBtnBg = LK.getAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, scaleX: 3.5, scaleY: 1.3, alpha: 0.7, color: 0x00cfff // Modern blue accent }); playBtnBg.x = 0; playBtnBg.y = 0; playButton.addChild(playBtnBg); var playButtonText = new Text2('PLAY', { size: 100, fill: 0xffffff, // Modern white text shadow: { color: 0x00cfff, blur: 12, angle: Math.PI / 2, distance: 8 } // subtle drop shadow }); playButtonText.anchor.set(0.5, 0.5); playButton.addChild(playButtonText); playButton.x = 1024; playButton.y = 2000; // moved further down, well below character select and daily reward mainMenuScreen.addChild(playButton); // --- BOTTOM BUTTONS CONTAINER --- // Create a container to hold both language and character select buttons side by side var bottomButtonsContainer = new Container(); bottomButtonsContainer.x = 1024; bottomButtonsContainer.y = 2600; // Near the bottom, above safe area // Character selection button (bottom left) var characterSelectBtn = new Container(); var characterSelectBtnBg = LK.getAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.2, scaleY: 1.1, alpha: 0.7, color: 0x00cfff }); characterSelectBtnBg.x = 0; characterSelectBtnBg.y = 0; characterSelectBtn.addChild(characterSelectBtnBg); var characterSelectBtnText = new Text2(localizedText[currentLanguage].selectionTitle, { size: 48, fill: 0xffffff, shadow: { color: 0x003366, blur: 8, angle: Math.PI / 2, distance: 4 } }); characterSelectBtnText.anchor.set(0.5, 0.5); characterSelectBtn.addChild(characterSelectBtnText); characterSelectBtn.x = -220; // left of center in container characterSelectBtn.y = 0; bottomButtonsContainer.addChild(characterSelectBtn); // Language Selection Button (bottom right) characterSelectBtn.down = function (x, y, obj) { // Animate button press tween(characterSelectBtn, { scaleX: 0.92, scaleY: 0.92 }, { duration: 100, onFinish: function onFinish() { tween(characterSelectBtn, { scaleX: 1, scaleY: 1 }, { duration: 100 }); } }); // Hide main menu and show character selection tween(mainMenuScreen, { alpha: 0 }, { duration: 300, onFinish: function onFinish() { mainMenuScreen.visible = false; // Show character selection screen and make sure all buttons are visible characterSelectionScreen.visible = true; characterSelectionScreen.alpha = 0; for (var i = 0; i < characterButtons.length; i++) { characterButtons[i].visible = true; } tween(characterSelectionScreen, { alpha: 1 }, { duration: 300 }); gameState = 'CHARACTER_SELECT'; } }); }; // Add a touch/click handler to the play button playButton.down = function (x, y, obj) { // Clear animations LK.clearInterval(playBtnPulse); LK.clearInterval(birdFloat); LK.clearInterval(tapInfoBlink); // Add click feedback animation tween(playButton, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100, onFinish: function onFinish() { tween(playButton, { scaleX: 1, scaleY: 1 }, { duration: 100 }); } }); // Hide main menu with animation and start the game directly tween(mainMenuScreen, { alpha: 0 }, { duration: 300, onFinish: function onFinish() { mainMenuScreen.visible = false; // Set default character if not selected selectedCharacter = selectedCharacter || 'bird'; // Initialize game with selected character initializeGameWithCharacter(); // Show instruction text and allow tap to start if (instructionTxt && !instructionTxt.parent) { game.addChild(instructionTxt); instructionTxt.alpha = 1; instructionTxt.scaleX = 1; instructionTxt.scaleY = 1; } gameStarted = false; gameState = 'PLAYING'; } }); }; // (playBtnBg is now part of playButton container, so this block is removed) // Add pulsing animation to play button var playBtnPulse = LK.setInterval(function () { if (playButton && mainMenuScreen.visible) { tween(playButton, { scaleX: 1.1, scaleY: 1.1 }, { duration: 600, onFinish: function onFinish() { tween(playButton, { scaleX: 1, scaleY: 1 }, { duration: 600 }); } }); } }, 1200); var tapToPlayInfo = new Text2('TAP TO BEGIN YOUR ADVENTURE!', { size: 45, fill: 0x00cfff, shadow: { color: 0x003366, blur: 8, angle: Math.PI / 2, distance: 4 } }); tapToPlayInfo.anchor.set(0.5, 0.5); tapToPlayInfo.x = 1024; tapToPlayInfo.y = 1700; // keep as is for now, but move language button further down mainMenuScreen.addChild(tapToPlayInfo); // Add blinking animation to tap instruction var tapInfoBlink = LK.setInterval(function () { if (tapToPlayInfo && mainMenuScreen.visible) { tween(tapToPlayInfo, { alpha: 0.4 }, { duration: 700, onFinish: function onFinish() { tween(tapToPlayInfo, { alpha: 1 }, { duration: 700 }); } }); } }, 1400); // --- Daily Reward Button and Popup --- // Button var dailyRewardBtn = new Container(); var dailyRewardBtnBg = LK.getAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.2, scaleY: 1.1, alpha: 0.7, color: 0xFFD700 }); dailyRewardBtnBg.x = 0; dailyRewardBtnBg.y = 0; dailyRewardBtn.addChild(dailyRewardBtnBg); var dailyRewardBtnText = new Text2('DAILY REWARD', { size: 60, fill: 0x333300, shadow: { color: 0xFFD700, blur: 8, angle: Math.PI / 2, distance: 4 } }); dailyRewardBtnText.anchor.set(0.5, 0.5); dailyRewardBtn.addChild(dailyRewardBtnText); dailyRewardBtn.x = 1024; dailyRewardBtn.y = 1200; // Above character select // Add to main menu mainMenuScreen.addChild(dailyRewardBtn); // Daily reward popup var dailyRewardPopup = new Container(); dailyRewardPopup.visible = false; var dailyRewardPopupBg = LK.getAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, scaleX: 7, scaleY: 4, alpha: 0.95, color: 0xFFF8DC }); dailyRewardPopupBg.x = 0; dailyRewardPopupBg.y = 0; dailyRewardPopup.addChild(dailyRewardPopupBg); var dailyRewardTitle = new Text2('DAILY REWARD!', { size: 90, fill: 0xFFD700 }); dailyRewardTitle.anchor.set(0.5, 0.5); dailyRewardTitle.x = 0; dailyRewardTitle.y = -200; dailyRewardPopup.addChild(dailyRewardTitle); var dailyRewardInfo = new Text2('Come back every day for free coins!', { size: 48, fill: 0x333300 }); dailyRewardInfo.anchor.set(0.5, 0.5); dailyRewardInfo.x = 0; dailyRewardInfo.y = -80; dailyRewardPopup.addChild(dailyRewardInfo); var dailyRewardCoinText = new Text2('+50', { size: 120, fill: 0xFFD700 }); dailyRewardCoinText.anchor.set(0.5, 0.5); dailyRewardCoinText.x = 0; dailyRewardCoinText.y = 80; dailyRewardPopup.addChild(dailyRewardCoinText); var dailyRewardOkBtn = new Text2('OK', { size: 70, fill: 0x00cfff }); dailyRewardOkBtn.anchor.set(0.5, 0.5); dailyRewardOkBtn.x = 0; dailyRewardOkBtn.y = 220; dailyRewardPopup.addChild(dailyRewardOkBtn); dailyRewardPopup.x = 1024; dailyRewardPopup.y = 1366; game.addChild(dailyRewardPopup); // Helper: get today's date as string function getTodayString() { var d = new Date(); return d.getFullYear() + '-' + (d.getMonth() + 1) + '-' + d.getDate(); } // Show popup and give reward if not already claimed today dailyRewardBtn.down = function (x, y, obj) { // Animate button tween(dailyRewardBtn, { scaleX: 0.92, scaleY: 0.92 }, { duration: 100, onFinish: function onFinish() { tween(dailyRewardBtn, { scaleX: 1, scaleY: 1 }, { duration: 100 }); } }); // Check if already claimed today var today = getTodayString(); if (storage.lastDailyReward !== today) { // Give reward coins = (typeof coins === "number" ? coins : 0) + 50; storage.coins = coins; coinTxt.setText('' + coins); storage.lastDailyReward = today; dailyRewardCoinText.setText('+50'); dailyRewardInfo.setText('You received 50 coins!'); } else { dailyRewardCoinText.setText('✓'); dailyRewardInfo.setText('Already claimed today!'); } dailyRewardPopup.visible = true; dailyRewardPopup.alpha = 0; tween(dailyRewardPopup, { alpha: 1 }, { duration: 200 }); }; // OK button closes popup dailyRewardOkBtn.down = function (x, y, obj) { tween(dailyRewardPopup, { alpha: 0 }, { duration: 200, onFinish: function onFinish() { dailyRewardPopup.visible = false; } }); }; game.addChild(mainMenuScreen); // Language Selection Button (Main Menu) var mainMenuLanguageBtn = new Text2(currentLanguage.toUpperCase(), { size: 48, fill: 0xffffff }); mainMenuLanguageBtn.anchor.set(0.5, 0.5); mainMenuLanguageBtn.x = 220; // right of center in container mainMenuLanguageBtn.y = 0; bottomButtonsContainer.addChild(mainMenuLanguageBtn); // Add the bottom buttons container to the main menu mainMenuScreen.addChild(bottomButtonsContainer); mainMenuLanguageBtn.down = function (x, y, obj) { // Cycle through languages (e.g., EN, ES, FR, TR) if (currentLanguage === 'en') { currentLanguage = 'es'; } else if (currentLanguage === 'es') { currentLanguage = 'fr'; } else if (currentLanguage === 'fr') { currentLanguage = 'tr'; } else { currentLanguage = 'en'; } mainMenuLanguageBtn.setText(currentLanguage.toUpperCase()); updateLocalizedText(); // Update all text elements // Add click feedback tween(mainMenuLanguageBtn, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100, onFinish: function onFinish() { tween(mainMenuLanguageBtn, { scaleX: 1, scaleY: 1 }, { duration: 100 }); } }); }; // Function to show character selection function showCharacterSelection() { characterSelectionScreen.visible = true; characterSelectionScreen.alpha = 0; tween(characterSelectionScreen, { alpha: 1 }, { duration: 300 }); // Hide main menu while character selection is visible mainMenuScreen.visible = false; } // Function to hide character selection and show main menu function backToMainMenuFromCharacterSelection() { tween(characterSelectionScreen, { alpha: 0 }, { duration: 300, onFinish: function onFinish() { characterSelectionScreen.visible = false; showMainMenu(); gameState = 'MAIN_MENU'; } }); } // Add a back button to character selection screen if not already present if (typeof characterSelectionBackBtn === "undefined") { var characterSelectionBackBtn = new Text2(localizedText[currentLanguage].backBtn, { size: 60, fill: 0xff6600 }); characterSelectionBackBtn.anchor.set(0.5, 0.5); characterSelectionBackBtn.x = 1024; characterSelectionBackBtn.y = 2400; characterSelectionScreen.addChild(characterSelectionBackBtn); characterSelectionBackBtn.down = function (x, y, obj) { // Animate button press tween(characterSelectionBackBtn, { scaleX: 0.92, scaleY: 0.92 }, { duration: 100, onFinish: function onFinish() { tween(characterSelectionBackBtn, { scaleX: 1, scaleY: 1 }, { duration: 100 }); } }); backToMainMenuFromCharacterSelection(); }; } // Function to show main menu function showMainMenu() { mainMenuScreen.visible = true; mainMenuScreen.alpha = 0; tween(mainMenuScreen, { alpha: 1 }, { duration: 300 }); } // Character Selection Screen var selectionBackground = LK.getAsset('centerCircle', { width: 2048, height: 2732, anchorX: 0, anchorY: 0, alpha: 0.85, scaleX: 20, scaleY: 27, color: 0xeaf6fb }); characterSelectionScreen.addChild(selectionBackground); var selectionTitle = new Text2(localizedText[currentLanguage].selectionTitle, { size: 100, fill: 0xFFFFFF }); selectionTitle.anchor.set(0.5, 0.5); selectionTitle.x = 1024; selectionTitle.y = 500; characterSelectionScreen.addChild(selectionTitle); // Character selection buttons var characterButtons = []; for (var i = 0; i < characterTypes.length; i++) { var buttonContainer = new Container(); // Character preview var charPreview = LK.getAsset(characterTypes[i], { anchorX: 0.5, anchorY: 0.5, scaleX: 2.2, scaleY: 2.2 }); charPreview.x = 0; charPreview.y = 0; buttonContainer.addChild(charPreview); // Character name var charName = new Text2(localizedText[currentLanguage].characterNames[i], { size: 48, fill: 0xFFFFFF }); charName.anchor.set(0.5, 0.5); charName.y = 120; buttonContainer.addChild(charName); // Add selection border (initially hidden, behind preview) var selectionBorder = LK.getAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.7, scaleY: 2.7, alpha: 0.25, color: 0x00cfff }); selectionBorder.visible = false; selectionBorder.x = 0; selectionBorder.y = 0; buttonContainer.addChild(selectionBorder); buttonContainer.selectionBorder = selectionBorder; // Position buttons in a grid (2 columns) var col = i % 2; var row = Math.floor(i / 2); buttonContainer.x = 724 + col * 600; buttonContainer.y = 1000 + row * 400; // Store character type for click handling buttonContainer.characterType = characterTypes[i]; buttonContainer.characterIndex = i; // Click handler for character selection buttonContainer.down = function (x, y, obj) { // Remove selection from all buttons for (var j = 0; j < characterButtons.length; j++) { characterButtons[j].selectionBorder.visible = false; } // Show selection on clicked button this.selectionBorder.visible = true; selectedCharacter = this.characterType; // Add selection feedback animation tween(this, { scaleX: 1.1, scaleY: 1.1 }, { duration: 100, onFinish: function onFinish() { tween(this, { scaleX: 1, scaleY: 1 }, { duration: 100 }); } }); }; characterButtons.push(buttonContainer); characterSelectionScreen.addChild(buttonContainer); } // Show selection on first character by default if (characterButtons.length > 0) { characterButtons[0].selectionBorder.visible = true; } // Confirm selection button var confirmBtn = new Text2(localizedText[currentLanguage].confirmBtn, { size: 70, fill: 0x00ff00 }); confirmBtn.anchor.set(0.5, 0.5); confirmBtn.x = 1024; confirmBtn.y = 2200; characterSelectionScreen.addChild(confirmBtn); confirmBtn.down = function (x, y, obj) { gameState = 'START_SCREEN'; // Hide character selection characterSelectionScreen.visible = false; // Show start screen with animation showStartScreen(); }; characterSelectionScreen.visible = false; // Start Game Screen var startGameScreen = new Container(); // Define start game screen startGameScreen.visible = false; // Initialize start game screen as hidden var startGameScreen = new Container(); var startBackground = LK.getAsset('centerCircle', { width: 2048, height: 2732, anchorX: 0, anchorY: 0, alpha: 0.85, scaleX: 20, scaleY: 27, color: 0xeaf6fb }); startGameScreen.addChild(startBackground); var gameTitle = new Text2(localizedText[currentLanguage].gameTitle, { size: 120, fill: 0xFFD700 }); gameTitle.anchor.set(0.5, 0.5); gameTitle.x = 1024; gameTitle.y = 600; startGameScreen.addChild(gameTitle); // Show selected character preview var selectedCharacterPreview = LK.getAsset('bird', { anchorX: 0.5, anchorY: 0.5, scaleX: 3, scaleY: 3 }); selectedCharacterPreview.x = 1024; selectedCharacterPreview.y = 1000; startGameScreen.addChild(selectedCharacterPreview); var characterLabel = new Text2(localizedText[currentLanguage].characterLabel, { size: 60, fill: 0xFFFFFF }); characterLabel.anchor.set(0.5, 0.5); characterLabel.x = 1024; characterLabel.y = 1200; startGameScreen.addChild(characterLabel); var startBtn = new Text2(localizedText[currentLanguage].startBtn, { size: 100, fill: 0xffffff, shadow: { color: 0x00cfff, blur: 12, angle: Math.PI / 2, distance: 8 } }); startBtn.anchor.set(0.5, 0.5); startBtn.x = 1024; startBtn.y = 1600; startGameScreen.addChild(startBtn); // Add pulsing animation to start button var startBtnPulse = LK.setInterval(function () { if (startBtn && startGameScreen.visible) { tween(startBtn, { scaleX: 1.1, scaleY: 1.1 }, { duration: 500, onFinish: function onFinish() { tween(startBtn, { scaleX: 1, scaleY: 1 }, { duration: 500 }); } }); } }, 1000); var tapToPlayText = new Text2(localizedText[currentLanguage].tapToPlayText, { size: 45, fill: 0xFFD700 }); tapToPlayText.anchor.set(0.5, 0.5); tapToPlayText.x = 1024; tapToPlayText.y = 1750; startGameScreen.addChild(tapToPlayText); // Add blinking animation to tap instruction var tapTextBlink = LK.setInterval(function () { if (tapToPlayText && startGameScreen.visible) { tween(tapToPlayText, { alpha: 0.4 }, { duration: 600, onFinish: function onFinish() { tween(tapToPlayText, { alpha: 1 }, { duration: 600 }); } }); } }, 1200); var backBtn = new Text2(localizedText[currentLanguage].backBtn, { size: 50, fill: 0xff6600 }); backBtn.anchor.set(0.5, 0.5); backBtn.x = 1024; backBtn.y = 1900; startGameScreen.addChild(backBtn); // Add start button background for better visibility var startBtnBg = LK.getAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, scaleX: 4, scaleY: 1.5, alpha: 0.7, color: 0x00cfff }); startBtnBg.x = 1024; startBtnBg.y = 1600; startGameScreen.addChild(startBtnBg); // Ensure start button is on top of background startGameScreen.removeChild(startBtnBg); startGameScreen.addChild(startBtnBg); startGameScreen.addChild(startBtn); // Language Selection Button (Start Game) var startLanguageBtn = new Text2(currentLanguage.toUpperCase(), { size: 50, fill: 0xffffff }); startLanguageBtn.anchor.set(0.5, 0.5); startLanguageBtn.x = 1024; startLanguageBtn.y = 2050; startGameScreen.addChild(startLanguageBtn); startLanguageBtn.down = function (x, y, obj) { // Cycle through languages (e.g., EN, ES, FR, TR) if (currentLanguage === 'en') { currentLanguage = 'es'; } else if (currentLanguage === 'es') { currentLanguage = 'fr'; } else if (currentLanguage === 'fr') { currentLanguage = 'tr'; } else { currentLanguage = 'en'; } startLanguageBtn.setText(currentLanguage.toUpperCase()); updateLocalizedText(); // Update all text elements // Add click feedback tween(startLanguageBtn, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100, onFinish: function onFinish() { tween(startLanguageBtn, { scaleX: 1, scaleY: 1 }, { duration: 100 }); } }); }; startBtn.down = function (x, y, obj) { // Clear all animations LK.clearInterval(startBtnPulse); LK.clearInterval(tapTextBlink); // Add click feedback animation tween(startBtn, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100, onFinish: function onFinish() { tween(startBtn, { scaleX: 1, scaleY: 1 }, { duration: 100 }); } }); // Hide start screen with animation tween(startGameScreen, { alpha: 0 }, { duration: 300, onFinish: function onFinish() { startGameScreen.visible = false; // Initialize game with selected character initializeGameWithCharacter(); // Show instruction text and allow tap to start if (instructionTxt && !instructionTxt.parent) { game.addChild(instructionTxt); instructionTxt.alpha = 1; instructionTxt.scaleX = 1; instructionTxt.scaleY = 1; } gameStarted = false; gameState = 'PLAYING'; } }); }; backBtn.down = function (x, y, obj) { // Clear animations LK.clearInterval(startBtnPulse); LK.clearInterval(tapTextBlink); // Add click feedback for back button tween(backBtn, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100, onFinish: function onFinish() { tween(backBtn, { scaleX: 1, scaleY: 1 }, { duration: 100 }); } }); gameState = 'CHARACTER_SELECT'; // Hide start screen and show character selection tween(startGameScreen, { alpha: 0 }, { duration: 300, onFinish: function onFinish() { startGameScreen.visible = false; // Show character selection screen showCharacterSelection(); } }); }; startGameScreen.visible = false; game.addChild(startGameScreen); // Function to show start screen function showStartScreen() { // Update selected character preview startGameScreen.removeChild(selectedCharacterPreview); selectedCharacterPreview = LK.getAsset(selectedCharacter, { anchorX: 0.5, anchorY: 0.5, scaleX: 3, scaleY: 3 }); selectedCharacterPreview.x = 1024; selectedCharacterPreview.y = 1000; startGameScreen.addChild(selectedCharacterPreview); startGameScreen.visible = true; startGameScreen.alpha = 0; tween(startGameScreen, { alpha: 1 }, { duration: 300 }); // Enable tap to start after showing start screen gameStarted = false; gameState = 'PLAYING'; // Allow tap to start if (instructionTxt && !instructionTxt.parent) { game.addChild(instructionTxt); instructionTxt.alpha = 1; instructionTxt.scaleX = 1; instructionTxt.scaleY = 1; } } // Call updateLocalizedText initially to set the correct language updateLocalizedText(); // Show the main menu initially showMainMenu(); // Game start instruction var instructionTxt = new Text2(localizedText[currentLanguage].instructionTxt, { size: 80, fill: 0xFFFFFF }); // Declare instructionTxt here, initialize later when needed instructionTxt.anchor.set(0.5, 0.5); instructionTxt.x = 1024; instructionTxt.y = 1000; game.addChild(instructionTxt); // Add blinking animation var instructionBlink = LK.setInterval(function () { if (instructionTxt && instructionTxt.parent) { tween(instructionTxt, { alpha: 0.3 }, { duration: 500, onFinish: function onFinish() { if (instructionTxt && instructionTxt.parent) { tween(instructionTxt, { alpha: 1 }, { duration: 500 }); } } }); } }, 1000); // Function to initialize game with selected character function initializeGameWithCharacter() { // Initialize bird with selected character bird = game.addChild(new Bird(selectedCharacter)); bird.x = 400; bird.y = 1366; // Center of screen vertically bird.lastY = bird.y; // Initialize tracking property // Initialize particle system particleSystem = game.addChild(new ParticleSystem({ maxParticles: 100, color: 0xFFD700 })); // Reset modern game variables comboCount = 0; comboTimer = 0; maxCombo = 0; coins = storage.coins || 0; coinTxt.setText('💰 ' + coins); difficulty = 1; difficultyTimer = 0; shieldActive = false; shieldTimer = 0; } // Don't initialize bird immediately - wait for character selection var bird; // Initialize ground ground1 = game.addChild(new Ground()); ground1.x = 0; ground1.y = 2400; // Position ground lower for better gameplay ground1.lastX = ground1.x; // Initialize tracking property ground2 = game.addChild(new Ground()); ground2.x = 2048; ground2.y = 2400; // Position ground lower for better gameplay ground2.lastX = ground2.x; // Initialize tracking property // Add pause button click handler pauseBtn.down = function (x, y, obj) { if (gameStarted && !gamePaused) { gamePaused = true; pauseOverlay.visible = true; // Add fade in animation for pause overlay pauseOverlay.alpha = 0; tween(pauseOverlay, { alpha: 1 }, { duration: 200 }); } }; // Add pause overlay click handler for resume pauseOverlay.down = function (x, y, obj) { if (gamePaused) { // Add fade out animation tween(pauseOverlay, { alpha: 0 }, { duration: 200, onFinish: function onFinish() { pauseOverlay.visible = false; gamePaused = false; } }); } }; // Tap to flap game.down = function (x, y, obj) { // Only allow interaction if game is not paused and gameState is PLAYING if (gamePaused || gameState !== 'PLAYING') { return; } if (!gameStarted) { gameStarted = true; // Hide instruction text with animation if (instructionTxt && instructionTxt.parent) { LK.clearInterval(instructionBlink); tween(instructionTxt, { alpha: 0, scaleX: 0.5, scaleY: 0.5 }, { duration: 300, onFinish: function onFinish() { instructionTxt.destroy(); instructionTxt = null; } }); } return; // Don't flap on first tap, only start the game } if (bird) { bird.flap(); } }; // Collision detection helper function function checkCollision(birdBounds, pipeBounds) { return birdBounds.x < pipeBounds.x + pipeBounds.width && birdBounds.x + birdBounds.width > pipeBounds.x && birdBounds.y < pipeBounds.y + pipeBounds.height && birdBounds.y + birdBounds.height > pipeBounds.y; } // Main game update game.update = function () { if (gameState !== 'PLAYING' || !gameStarted || gamePaused || !bird) { return; } // --- Wind system update --- windTimer++; if (windTimer >= windChangeInterval) { windTimer = 0; // Pick a new wind target between -2 and +2 (stronger at higher difficulty) var maxWind = 2 + Math.min(difficulty, 5) * 0.3; windTarget = (Math.random() - 0.5) * 2 * maxWind; windChangeInterval = 480 + Math.floor(Math.random() * 480); // 8-16s } // Smoothly approach windTarget wind += (windTarget - wind) * 0.01; // Show wind text if (Math.abs(wind) > 0.2) { windTxt.setText((wind > 0 ? '→' : '←') + ' WIND: ' + (wind > 0 ? '+' : '') + wind.toFixed(1)); windTxt.visible = true; } else { windTxt.visible = false; } // Apply wind to bird and pipes if (!shieldActive) { bird.x += wind * 0.5; // Bird is affected less if shield is active } else { bird.x += wind * 0.2; } // Clamp bird x to screen bird.x = Math.max(100, Math.min(1948, bird.x)); // Update difficulty over time difficultyTimer++; if (difficultyTimer >= 1800) { // Every 30 seconds at 60fps difficulty++; difficultyTimer = 0; difficultyTxt.setText(localizedText[currentLanguage].level + difficulty); // Increase game speed slightly pipeSpacing = Math.max(600, pipeSpacing - 20); // Visual feedback for difficulty increase tween(difficultyTxt, { scaleX: 1.3, scaleY: 1.3 }, { duration: 200, onFinish: function onFinish() { tween(difficultyTxt, { scaleX: 1, scaleY: 1 }, { duration: 200 }); } }); } // Update shield timer if (shieldActive) { shieldTimer--; if (shieldTimer <= 0) { shieldActive = false; shieldTxt.visible = false; } } // Update combo timer if (comboTimer > 0) { comboTimer--; if (comboTimer <= 0) { comboCount = 0; comboTxt.visible = false; } } // Spawn pipes pipeTimer++; if (pipeTimer >= pipeSpacing / 4) { // Adjust timing based on speed and difficulty var newPipe = new Pipe(); newPipe.x = 2200; // Start off-screen right newPipe.lastX = newPipe.x; // Initialize tracking property // Random gap position (avoid top and bottom areas) var gapCenter = 500 + Math.random() * 1200; // Between 500 and 1700 for better gameplay // Adjust gap size based on difficulty newPipe.gapSize = Math.max(250, 300 - (difficulty - 1) * 10); newPipe.setGapPosition(gapCenter); // Add entrance animation newPipe.alpha = 0; tween(newPipe, { alpha: 1 }, { duration: 300 }); pipes.push(newPipe); game.addChild(newPipe); pipeTimer = 0; // Spawn power-ups occasionally if (Math.random() < 0.3) { // 30% chance var powerUpType = Math.random() < 0.7 ? 'coin' : 'shield'; var powerUp = new PowerUp(powerUpType); powerUp.x = 2200; powerUp.y = gapCenter + (Math.random() - 0.5) * 100; powerUps.push(powerUp); game.addChild(powerUp); } } // Update pipes and check collisions/scoring for (var i = pipes.length - 1; i >= 0; i--) { var pipe = pipes[i]; // Apply wind to pipe pipe.x += wind * 0.7; // Initialize tracking properties if (pipe.lastX === undefined) { pipe.lastX = pipe.x; } // Check if pipe passed bird for scoring if (!pipe.passed && pipe.lastX > bird.x && pipe.x <= bird.x) { pipe.passed = true; comboCount++; comboTimer = 180; // 3 seconds at 60fps maxCombo = Math.max(maxCombo, comboCount); // Calculate score with combo multiplier var scoreGain = 1; if (comboCount >= 3) { scoreGain = Math.min(comboCount, 10); // Max 10x multiplier } LK.setScore(LK.getScore() + scoreGain); scoreTxt.setText(LK.getScore()); // Show combo text if (comboCount >= 3) { comboTxt.setText(localizedText[currentLanguage].combo + comboCount + '!'); comboTxt.visible = true; tween(comboTxt, { scaleX: 1.2, scaleY: 1.2 }, { duration: 200, onFinish: function onFinish() { tween(comboTxt, { scaleX: 1, scaleY: 1 }, { duration: 200 }); } }); } // Particle effect at bird position particleSystem.emit(bird.x, bird.y, 8); // Play score sound LK.getSound('score').play(); // Check and update best score var currentScore = LK.getScore(); if (currentScore > bestScore) { bestScore = currentScore; storage.bestScore = bestScore; bestScoreTxt.setText(localizedText[currentLanguage].bestScore + bestScore); // Add special animation for new best score tween(bestScoreTxt, { scaleX: 1.4, scaleY: 1.4, alpha: 0.8 }, { duration: 200, onFinish: function onFinish() { tween(bestScoreTxt, { scaleX: 1, scaleY: 1, alpha: 1 }, { duration: 200 }); } }); // Flash screen gold for new best score LK.effects.flashScreen(0xFFD700, 300); } // Add score animation tween(scoreTxt, { scaleX: 1.3, scaleY: 1.3 }, { duration: 150, onFinish: function onFinish() { tween(scoreTxt, { scaleX: 1, scaleY: 1 }, { duration: 150 }); } }); // Flash screen green for successful pass LK.effects.flashScreen(0x00ff00, 200); } // Remove pipes that are off screen if (pipe.x < -200) { pipe.destroy(); pipes.splice(i, 1); continue; } // Check collision with pipes var birdBounds = { x: bird.x - 70, y: bird.y - 70, width: 140, height: 140 }; var topBounds = pipe.getTopBounds(); var bottomBounds = pipe.getBottomBounds(); if (checkCollision(birdBounds, topBounds) || checkCollision(birdBounds, bottomBounds)) { // Check if shield is active if (shieldActive) { // Shield protects from one hit shieldActive = false; shieldTimer = 0; shieldTxt.visible = false; // Visual feedback for shield use LK.effects.flashScreen(0x00FFFF, 400); particleSystem.emit(bird.x, bird.y, 20); // Reset combo but don't end game comboCount = 0; comboTimer = 0; comboTxt.visible = false; // Skip to next iteration, don't end game continue; } // Play hit sound LK.getSound('hit').play(); // Reset combo on collision comboCount = 0; comboTimer = 0; comboTxt.visible = false; // Stop the game immediately gameStarted = false; // Add dramatic bird rotation and fall effect tween(bird, { rotation: Math.PI * 2, y: bird.y + 200 }, { duration: 800 }); // Add bird shake effect before game over tween(bird, { x: bird.x - 15 }, { duration: 75, onFinish: function onFinish() { tween(bird, { x: bird.x + 30 }, { duration: 75, onFinish: function onFinish() { tween(bird, { x: bird.x - 15 }, { duration: 75 }); } }); } }); // Flash screen red for longer duration LK.effects.flashScreen(0xff0000, 800); // Show dramatic "GAME OVER" text before official game over var gameOverTxt = new Text2(localizedText[currentLanguage].gameOver, { size: 120, fill: 0xff0000 }); gameOverTxt.anchor.set(0.5, 0.5); gameOverTxt.x = 1024; gameOverTxt.y = 1366; gameOverTxt.alpha = 0; game.addChild(gameOverTxt); // Animate game over text appearance tween(gameOverTxt, { alpha: 1, scaleX: 1.2, scaleY: 1.2 }, { duration: 400, onFinish: function onFinish() { // Wait a moment then show official game over LK.setTimeout(function () { LK.getSound('gameover').play(); LK.showGameOver(); }, 800); } }); return; } // Update last position pipe.lastX = pipe.x; } // Update and check power-ups for (var j = powerUps.length - 1; j >= 0; j--) { var powerUp = powerUps[j]; // Apply wind to powerup powerUp.x += wind * 0.7; // Remove off-screen power-ups if (powerUp.x < -100) { powerUp.destroy(); powerUps.splice(j, 1); continue; } // Check collision with bird if (!powerUp.collected) { var powerUpBounds = { x: powerUp.x - 40, y: powerUp.y - 40, width: 80, height: 80 }; if (checkCollision(birdBounds, powerUpBounds)) { powerUp.collected = true; if (powerUp.type === 'coin') { coins++; storage.coins = coins; coinTxt.setText('💰 ' + coins); // Coin collection particle effect particleSystem.emit(powerUp.x, powerUp.y, 15); tween(coinTxt, { scaleX: 1.3, scaleY: 1.3 }, { duration: 150, onFinish: function onFinish() { tween(coinTxt, { scaleX: 1, scaleY: 1 }, { duration: 150 }); } }); } else if (powerUp.type === 'shield') { shieldActive = true; shieldTimer = 600; // 10 seconds at 60fps shieldTxt.visible = true; // Shield activation effect LK.effects.flashScreen(0x00FFFF, 300); tween(shieldTxt, { scaleX: 1.2, scaleY: 1.2 }, { duration: 200, onFinish: function onFinish() { tween(shieldTxt, { scaleX: 1, scaleY: 1 }, { duration: 200 }); } }); } // Remove collected power-up with animation tween(powerUp, { alpha: 0, scaleX: 2, scaleY: 2 }, { duration: 200, onFinish: function onFinish() { powerUp.destroy(); powerUps.splice(j, 1); } }); } } } // Check collision with ground if (bird.y >= 2330) { // Ground collision (ground at 2400, bird radius 70) if (shieldActive) { // Shield protects from ground collision too shieldActive = false; shieldTimer = 0; shieldTxt.visible = false; bird.y = 2320; // Move bird up slightly bird.velocity = -8; // Give upward momentum LK.effects.flashScreen(0x00FFFF, 400); particleSystem.emit(bird.x, bird.y, 20); comboCount = 0; comboTimer = 0; comboTxt.visible = false; return; // Don't end game } // Play hit sound LK.getSound('hit').play(); // Save game statistics storage.maxCombo = Math.max(storage.maxCombo || 0, maxCombo); storage.totalGames = (storage.totalGames || 0) + 1; storage.totalCoins = coins; comboCount = 0; comboTimer = 0; comboTxt.visible = false; gameStarted = false; // Make bird bounce slightly on ground impact tween(bird, { y: 2320, rotation: Math.PI / 4 }, { duration: 200, onFinish: function onFinish() { tween(bird, { y: 2330 }, { duration: 100 }); } }); LK.effects.flashScreen(0xff0000, 800); // Show impact text var impactTxt = new Text2(localizedText[currentLanguage].crashed, { size: 100, fill: 0xff4500 }); impactTxt.anchor.set(0.5, 0.5); impactTxt.x = 1024; impactTxt.y = 1200; impactTxt.alpha = 0; game.addChild(impactTxt); tween(impactTxt, { alpha: 1, y: 1100 }, { duration: 300, onFinish: function onFinish() { LK.setTimeout(function () { LK.getSound('gameover').play(); LK.showGameOver(); }, 600); } }); return; } // Check collision with ceiling if (bird.y <= 70) { if (shieldActive) { // Shield protects from ceiling collision shieldActive = false; shieldTimer = 0; shieldTxt.visible = false; bird.y = 80; // Move bird down slightly bird.velocity = 5; // Give downward momentum LK.effects.flashScreen(0x00FFFF, 400); particleSystem.emit(bird.x, bird.y, 20); comboCount = 0; comboTimer = 0; comboTxt.visible = false; return; // Don't end game } // Play hit sound LK.getSound('hit').play(); comboCount = 0; comboTimer = 0; comboTxt.visible = false; gameStarted = false; // Make bird fall dramatically from ceiling tween(bird, { y: 200, rotation: -Math.PI / 2 }, { duration: 300 }); LK.effects.flashScreen(0xffffff, 300); // Show ceiling hit text var ceilingTxt = new Text2(localizedText[currentLanguage].hitCeiling, { size: 80, fill: 0xff6600 }); ceilingTxt.anchor.set(0.5, 0.5); ceilingTxt.x = 1024; ceilingTxt.y = 400; ceilingTxt.alpha = 0; game.addChild(ceilingTxt); tween(ceilingTxt, { alpha: 1, scaleX: 1.1, scaleY: 1.1 }, { duration: 250, onFinish: function onFinish() { LK.setTimeout(function () { LK.getSound('gameover').play(); LK.showGameOver(); }, 500); } }); return; } // Update ground position if (ground1) { ground1.update(); } if (ground2) { ground2.update(); } // Update last position };
===================================================================
--- original.js
+++ change.js
@@ -742,9 +742,9 @@
});
playButtonText.anchor.set(0.5, 0.5);
playButton.addChild(playButtonText);
playButton.x = 1024;
-playButton.y = 1550; // moved down, below character select button
+playButton.y = 2000; // moved further down, well below character select and daily reward
mainMenuScreen.addChild(playButton);
// --- BOTTOM BUTTONS CONTAINER ---
// Create a container to hold both language and character select buttons side by side
var bottomButtonsContainer = new Container();