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();
// Add light gray background to pause overlay
var pauseBackground = LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 10,
scaleY: 3,
color: 0xeeeeee,
alpha: 0.95
});
pauseBackground.x = 1024;
pauseBackground.y = 1300;
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();
// Add light gray background to main menu
var menuBackground = LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 12,
scaleY: 8,
color: 0xeeeeee,
alpha: 0.95
});
menuBackground.x = 1024;
menuBackground.y = 1366;
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.5,
color: 0x1e90ff // Brighter blue for a modern look
});
playBtnBg.x = 0;
playBtnBg.y = 0;
playButton.addChild(playBtnBg);
var playButtonText = new Text2('PLAY', {
size: 100,
fill: 0xffffff,
shadow: {
color: 0x1e90ff,
blur: 12,
angle: Math.PI / 2,
distance: 8
}
});
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;
// Place the bottom buttons container above the ground (ground y=2400, ground height=804.72, so ground bottom=3204.72, but screen is 2732px high)
// Place it just above the ground, with a margin
bottomButtonsContainer.y = 2400 - 40; // Move slightly lower (closer to ground) to ensure no overlap with daily reward
// 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.5,
color: 0x4ecdc4 // Modern teal
});
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.5,
color: 0xffc300 // Modern gold
});
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 = 1850; // Move further down, below tapToPlayInfo and above bottom buttons
// Add to main menu
mainMenuScreen.addChild(dailyRewardBtn);
// Daily reward popup
var dailyRewardPopup = new Container();
dailyRewardPopup.visible = false;
// Add light gray background to daily reward popup
var dailyRewardPopupBg = LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 7,
scaleY: 4,
color: 0xfff7cc,
//{9f} // new color (light yellowish)
alpha: 0.97 //{9g} // slightly more opaque for better contrast
});
dailyRewardPopupBg.x = 0;
dailyRewardPopupBg.y = 0;
// Always add background as first child to ensure it is behind all content
if (dailyRewardPopup.children.length > 0) {
dailyRewardPopup.removeChild(dailyRewardPopupBg);
dailyRewardPopup.addChildAt(dailyRewardPopupBg, 0);
} else {
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;
dailyRewardPopup.zIndex = 9999; // Ensure popup is on top
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,
alpha: 0.5
});
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
// Ensure bottomButtonsContainer is added BEFORE the ground visual (if any) so it appears above ground
mainMenuScreen.addChild(bottomButtonsContainer);
// Make sure ground visual is always below UI (if you ever add a ground visual to mainMenuScreen, add it before this line)
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
// Add light gray background to character selection screen
var selectionBackground = LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 10,
scaleY: 7,
color: 0xeeeeee,
alpha: 0.95
});
selectionBackground.x = 1024;
selectionBackground.y = 1366;
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: 0x43d675
});
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: 0x43d675 // Modern green
});
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();
// Add light gray background to start game screen
var startBackground = LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 10,
scaleY: 7,
color: 0xeeeeee,
alpha: 0.95
});
startBackground.x = 1024;
startBackground.y = 1366;
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.9,
color: 0x1e90ff
});
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
@@ -960,9 +960,15 @@
alpha: 0.97 //{9g} // slightly more opaque for better contrast
});
dailyRewardPopupBg.x = 0;
dailyRewardPopupBg.y = 0;
-dailyRewardPopup.addChild(dailyRewardPopupBg);
+// Always add background as first child to ensure it is behind all content
+if (dailyRewardPopup.children.length > 0) {
+ dailyRewardPopup.removeChild(dailyRewardPopupBg);
+ dailyRewardPopup.addChildAt(dailyRewardPopupBg, 0);
+} else {
+ dailyRewardPopup.addChild(dailyRewardPopupBg);
+}
var dailyRewardTitle = new Text2('DAILY REWARD!', {
size: 90,
fill: 0xFFD700
});
@@ -995,8 +1001,9 @@
dailyRewardOkBtn.y = 220;
dailyRewardPopup.addChild(dailyRewardOkBtn);
dailyRewardPopup.x = 1024;
dailyRewardPopup.y = 1366;
+dailyRewardPopup.zIndex = 9999; // Ensure popup is on top
game.addChild(dailyRewardPopup);
// Helper: get today's date as string
function getTodayString() {
var d = new Date();