/****
* Plugins
****/
var storage = LK.import("@upit/storage.v1");
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Bird = Container.expand(function () {
var self = Container.call(this);
// Create bird graphics with proper anchoring
var birdGraphics = self.attachAsset('bird', {
anchorX: 0.5,
anchorY: 0.5
});
// Initialize bird properties
self.velocity = 0;
self.flapCooldown = 0;
// Optimized flap function
self.flap = function () {
// Prevent rapid flapping
if (self.flapCooldown > 0) return;
if (gameOver) return;
self.flapCooldown = 8; // Frames to wait before next flap
// Set velocity with improved scaling for better responsiveness
self.velocity = jumpStrength;
// Play flap sound with minimal error handling
if (LK.getSound('flap')) {
LK.getSound('flap').play();
}
};
// Optimized update method
self.update = function () {
// Update cooldowns
if (self.flapCooldown > 0) self.flapCooldown--;
if (!gameStarted) {
// Pre-game idle state
self.y = 1366;
self.x = 300;
return;
}
// Simple physics with improved scaling
if (!gameOver) {
// Only update position if game is not over
self.velocity += gravity;
self.y += self.velocity;
}
// Update rotation only when velocity changes significantly
if (Math.abs(self.velocity - (self.lastVelocity || 0)) > 2) {
birdGraphics.rotation = self.velocity > 0 ? 0.8 : -0.4;
self.lastVelocity = self.velocity;
}
// Screen bounds collision
if (self.y < 40) {
self.y = 40;
self.velocity = 0;
}
if (self.y > 2582) {
self.y = 2582;
self.velocity = 0;
if (!gameOver) {
gameOver = true; // Trigger game over
showGameOverScreen(LK.getScore()); // Show game over screen with score
}
}
};
return self;
});
var Pipe = Container.expand(function (gapCenterY) {
var self = Container.call(this);
// Fixed gap size for consistent gameplay
self.gapSize = 850; // Normal gap - increased for easier passage
self.speed = pipeSpeed;
self.passed = false;
self.gapCenterY = gapCenterY;
self.pipeWidth = 120;
// Calculate pipe heights
var topPipeHeight = Math.max(200, gapCenterY - self.gapSize / 2);
var bottomPipeHeight = Math.max(200, 2732 - 150 - (gapCenterY + self.gapSize / 2));
// --- Flappy Bird style: dark base, highlight, and shadow for realism ---
// Top pipe main body (dark green)
var topPipe = self.attachAsset('topPipe', {
anchorX: 0.5,
anchorY: 1
});
topPipe.y = gapCenterY - self.gapSize / 2;
topPipe.height = topPipeHeight;
topPipe.width = self.pipeWidth;
topPipe.tint = 0x1a3c1a; // dark green
// Top pipe highlight (lighter green, left side)
var topPipeHighlight = self.attachAsset('pipeHighlight', {
anchorX: 0.5,
anchorY: 1
});
topPipeHighlight.y = gapCenterY - self.gapSize / 2;
topPipeHighlight.height = topPipeHeight;
topPipeHighlight.width = 32;
topPipeHighlight.x = -self.pipeWidth / 2 + 16;
topPipeHighlight.tint = 0x3be24d; // bright highlight
// Top pipe shadow (darker, right side)
var topPipeShadow = self.attachAsset('pipeHighlight', {
anchorX: 0.5,
anchorY: 1
});
topPipeShadow.y = gapCenterY - self.gapSize / 2;
topPipeShadow.height = topPipeHeight;
topPipeShadow.width = 32;
topPipeShadow.x = self.pipeWidth / 2 - 16;
topPipeShadow.tint = 0x0d1a0d; // very dark green
// Bottom pipe main body (dark green)
var bottomPipe = self.attachAsset('bottomPipe', {
anchorX: 0.5,
anchorY: 0
});
bottomPipe.y = gapCenterY + self.gapSize / 2;
bottomPipe.height = bottomPipeHeight;
bottomPipe.width = self.pipeWidth;
bottomPipe.tint = 0x1a3c1a; // dark green
// Bottom pipe highlight (lighter green, left side)
var bottomPipeHighlight = self.attachAsset('pipeHighlight', {
anchorX: 0.5,
anchorY: 0
});
bottomPipeHighlight.y = gapCenterY + self.gapSize / 2;
bottomPipeHighlight.height = bottomPipeHeight;
bottomPipeHighlight.width = 32;
bottomPipeHighlight.x = -self.pipeWidth / 2 + 16;
bottomPipeHighlight.tint = 0x3be24d; // bright highlight
// Bottom pipe shadow (darker, right side)
var bottomPipeShadow = self.attachAsset('pipeHighlight', {
anchorX: 0.5,
anchorY: 0
});
bottomPipeShadow.y = gapCenterY + self.gapSize / 2;
bottomPipeShadow.height = bottomPipeHeight;
bottomPipeShadow.width = 32;
bottomPipeShadow.x = self.pipeWidth / 2 - 16;
bottomPipeShadow.tint = 0x0d1a0d; // very dark green
// Pipe caps (yellowish, like Flappy Bird)
var topPipeCap = self.attachAsset('pipeTop', {
anchorX: 0.5,
anchorY: 1
});
topPipeCap.y = gapCenterY - self.gapSize / 2;
topPipeCap.width = self.pipeWidth + 20;
topPipeCap.height = 25;
topPipeCap.tint = 0xfaf4a0; // yellowish
var bottomPipeCap = self.attachAsset('pipeBottom', {
anchorX: 0.5,
anchorY: 0
});
bottomPipeCap.y = gapCenterY + self.gapSize / 2;
bottomPipeCap.width = self.pipeWidth + 20;
bottomPipeCap.height = 25;
bottomPipeCap.tint = 0xfaf4a0; // yellowish
self.update = function () {
if (!gameStarted) {
return;
}
// Move pipes to the left (negative speed) so bird appears to move forward
self.x += self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game();
/****
* Game Code
****/
// Initialize persistent storage using storage plugin
var currentLanguage = storage.language || 'tr';
var gameHighScore = storage.highScore || 0;
// Smooth visual feedback function using tween
function simpleColorTint(target, color, duration, callback) {
var originalTint = target.tint;
target.tint = color;
// Smooth transition back to original color
tween(target, {
tint: originalTint
}, {
duration: duration || 150,
easing: tween.easeOut,
onFinish: callback
});
}
var bird;
var pipes = [];
var ground;
var gameStarted = false;
var gameOver = false;
var showMainMenu = true;
var showGameOver = false;
// Button click time tracking removed to eliminate delays
var gravity = 0.55; // Gravity for bird - fine-tuned for better control
var jumpStrength = -9.5; // Jump strength for bird - fine-tuned for better balance
var pipeSpeed = -3.5; // Pipe movement speed - increased for better challenge
// Score display
var scoreText = new Text2('0', {
size: 120,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
scoreText.stroke = 0x000000;
scoreText.strokeThickness = 6;
scoreText.visible = false; // Initially hidden, shown when game starts
LK.gui.top.addChild(scoreText);
scoreText.y = 100; // Position below the top menu area
// Create cup shape for score
var cupShape = LK.getAsset('cup', {
anchorX: 0.5,
anchorY: 0
});
cupShape.tint = 0xFFD700;
LK.gui.bottomRight.addChild(cupShape);
cupShape.y = -230;
cupShape.x = -100;
// Create main menu elements
var mainMenuTitle = new Text2('FLAPPY BIRD', {
size: 90,
fill: 0xFFD700
});
mainMenuTitle.anchor.set(0.5, 0.5);
mainMenuTitle.stroke = 0x000000;
mainMenuTitle.strokeThickness = 5;
LK.gui.center.addChild(mainMenuTitle);
mainMenuTitle.y = -280;
// Create instruction text
var instructionTxt = new Text2('TIKLA VE OYNA!', {
size: 50,
fill: 0xFFFFFF
});
instructionTxt.anchor.set(0.5, 0.5);
instructionTxt.stroke = 0x000000;
instructionTxt.strokeThickness = 3;
instructionTxt.visible = false;
instructionTxt.y = -50;
// Remove background shape for instruction text - no longer needed
LK.gui.center.addChild(instructionTxt);
// Create game over screen elements
var gameOverBg = LK.getAsset('topPipe', {
anchorX: 0.5,
anchorY: 0.5,
width: 1600,
height: 1200,
alpha: 0.95
});
gameOverBg.tint = 0x2F4F4F;
gameOverBg.visible = false;
LK.gui.center.addChild(gameOverBg);
// Create high score screen elements
var highScoreBg = LK.getAsset('topPipe', {
anchorX: 0.5,
anchorY: 0.5,
width: 1400,
height: 800,
alpha: 0.95
});
highScoreBg.tint = 0x2F4F4F;
highScoreBg.visible = false;
LK.gui.center.addChild(highScoreBg);
var highScoreTitle = new Text2('EN YÜKSEK SKOR', {
size: 100,
fill: 0xFFD700
});
highScoreTitle.anchor.set(0.5, 0.5);
highScoreTitle.stroke = 0x000000;
highScoreTitle.strokeThickness = 5;
highScoreTitle.visible = false;
LK.gui.center.addChild(highScoreTitle);
highScoreTitle.y = -200;
var highScoreValue = new Text2('0', {
size: 150,
fill: 0xFFFFFF
});
highScoreValue.anchor.set(0.5, 0.5);
highScoreValue.stroke = 0x000000;
highScoreValue.strokeThickness = 6;
highScoreValue.visible = false;
LK.gui.center.addChild(highScoreValue);
highScoreValue.y = 0;
var highScoreCloseButton = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 300,
height: 80,
alpha: 1.0
});
highScoreCloseButton.tint = 0x7F8C8D;
highScoreCloseButton.visible = false;
LK.gui.center.addChild(highScoreCloseButton);
highScoreCloseButton.y = 200;
var highScoreCloseText = new Text2('KAPAT', {
size: 40,
fill: 0xFFFFFF
});
highScoreCloseText.anchor.set(0.5, 0.5);
highScoreCloseText.stroke = 0x566573;
highScoreCloseText.strokeThickness = 3;
highScoreCloseText.visible = false;
LK.gui.center.addChild(highScoreCloseText);
highScoreCloseText.y = 200;
var gameOverTitle = new Text2('OYUN BİTTİ', {
size: 120,
fill: 0xFFFFFF
});
gameOverTitle.anchor.set(0.5, 0.5);
gameOverTitle.stroke = 0x000000;
gameOverTitle.strokeThickness = 6;
gameOverTitle.visible = false;
LK.gui.center.addChild(gameOverTitle);
gameOverTitle.y = -300;
var finalScoreText = new Text2('SKOR: 0', {
size: 80,
fill: 0xFFFFFF
});
finalScoreText.anchor.set(0.5, 0.5);
finalScoreText.stroke = 0x000000;
finalScoreText.strokeThickness = 4;
finalScoreText.visible = false;
LK.gui.center.addChild(finalScoreText);
finalScoreText.y = -150;
var bestScoreText = new Text2('EN İYİ: 0', {
size: 60,
fill: 0xFFD700
});
bestScoreText.anchor.set(0.5, 0.5);
bestScoreText.stroke = 0x000000;
bestScoreText.strokeThickness = 3;
bestScoreText.visible = false;
LK.gui.center.addChild(bestScoreText);
bestScoreText.y = -50;
// Create retry button with enhanced styling
var retryButton = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 380,
height: 110,
alpha: 1.0
});
retryButton.tint = 0xFF9800; // Orange like original Flappy Bird
retryButton.visible = false;
LK.gui.center.addChild(retryButton);
retryButton.y = 100;
// Add retry button shadow for depth
var retryButtonShadow = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 380,
height: 110,
alpha: 0.3
});
retryButtonShadow.tint = 0xE65100; // Darker orange shadow
retryButtonShadow.visible = false;
LK.gui.center.addChild(retryButtonShadow);
retryButtonShadow.y = 108; // Offset shadow slightly down
retryButtonShadow.x = 4; // Offset shadow slightly right
// Add retry button highlight
var retryButtonHighlight = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 350,
height: 85,
alpha: 0.4
});
retryButtonHighlight.tint = 0xFFB74D; // Lighter orange highlight
retryButtonHighlight.visible = false;
LK.gui.center.addChild(retryButtonHighlight);
retryButtonHighlight.y = 92; // Offset highlight slightly up
var retryButtonText = new Text2('TEKRAR DENE', {
size: 44,
fill: 0xFFFFFF
});
retryButtonText.anchor.set(0.5, 0.5);
retryButtonText.stroke = 0xE65100;
retryButtonText.strokeThickness = 3;
retryButtonText.visible = false;
LK.gui.center.addChild(retryButtonText);
retryButtonText.y = 100;
// Create menu button with enhanced styling
var menuButton = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 380,
height: 110,
alpha: 1.0
});
menuButton.tint = 0xF44336; // Red like original Flappy Bird
menuButton.visible = false;
LK.gui.center.addChild(menuButton);
menuButton.y = 250;
// Add menu button shadow for depth
var menuButtonShadow = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 380,
height: 110,
alpha: 0.3
});
menuButtonShadow.tint = 0xD32F2F; // Darker red shadow
menuButtonShadow.visible = false;
LK.gui.center.addChild(menuButtonShadow);
menuButtonShadow.y = 258; // Offset shadow slightly down
menuButtonShadow.x = 4; // Offset shadow slightly right
// Add menu button highlight
var menuButtonHighlight = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 350,
height: 85,
alpha: 0.4
});
menuButtonHighlight.tint = 0xEF5350; // Lighter red highlight
menuButtonHighlight.visible = false;
LK.gui.center.addChild(menuButtonHighlight);
menuButtonHighlight.y = 242; // Offset highlight slightly up
var menuButtonText = new Text2('ANA MENÜ', {
size: 44,
fill: 0xFFFFFF
});
menuButtonText.anchor.set(0.5, 0.5);
menuButtonText.stroke = 0xD32F2F;
menuButtonText.strokeThickness = 3;
menuButtonText.visible = false;
LK.gui.center.addChild(menuButtonText);
menuButtonText.y = 250;
// Simple background setup
var background = game.addChild(LK.getAsset('background', {
anchorX: 0,
anchorY: 0
}));
background.x = 0;
background.y = 0;
background.scaleX = 2;
background.scaleY = 2;
// Create ground
ground = game.addChild(LK.getAsset('ground', {
anchorX: 0,
anchorY: 1
}));
ground.x = 0;
ground.y = 2732;
ground.tint = 0x654321;
// Create bird
bird = game.addChild(new Bird());
bird.x = 300;
bird.y = 1366;
// Pre-generate initial pipes function with better performance
function generateAllPipes() {
// Define safe boundaries for gap center to ensure both pipes have reasonable heights
var minGapY = 700; // Minimum gap center position for better clearance
var maxGapY = 1900; // Maximum gap center position for better clearance
// Generate initial set of pipes only - generate more as needed during gameplay
var initialPipesNeeded = 10; // Start with fewer pipes for better performance
var currentX = 2500; // Starting position to the right of screen since pipes move left
var pipeSpacing = 600; // Spacing between pipes
// Clear existing pipes first
for (var i = pipes.length - 1; i >= 0; i--) {
if (pipes[i] && typeof pipes[i].destroy === "function") {
pipes[i].destroy();
}
}
pipes = [];
for (var pipeIndex = 0; pipeIndex < initialPipesNeeded; pipeIndex++) {
var gapCenterY;
// Create varied random patterns with better distribution
var randomPattern = Math.random();
if (randomPattern < 0.4) {
// 40% chance for high gaps (easier to navigate)
gapCenterY = minGapY + Math.random() * 300;
} else if (randomPattern < 0.7) {
// 30% chance for middle gaps (moderate difficulty)
gapCenterY = 1000 + Math.random() * 500;
} else {
// 30% chance for low gaps (more challenging but still passable)
gapCenterY = maxGapY - Math.random() * 300;
}
// Ensure the gap stays within safe boundaries
gapCenterY = Math.max(minGapY, Math.min(maxGapY, gapCenterY));
var pipe = new Pipe(gapCenterY);
pipe.x = currentX;
pipe.passed = false;
pipes.push(pipe);
game.addChild(pipe);
// Move to next pipe position
currentX += pipeSpacing;
}
}
// Function to generate new pipes as needed during gameplay
function generateNewPipe() {
var minGapY = 700;
var maxGapY = 1900;
var pipeSpacing = 600;
// Find rightmost pipe position
var rightmostX = 2500;
for (var i = 0; i < pipes.length; i++) {
if (pipes[i] && pipes[i].x > rightmostX) {
rightmostX = pipes[i].x;
}
}
// Create new pipe to the right of the rightmost pipe
var newX = rightmostX + pipeSpacing;
var randomPattern = Math.random();
var gapCenterY;
if (randomPattern < 0.4) {
gapCenterY = minGapY + Math.random() * 300;
} else if (randomPattern < 0.7) {
gapCenterY = 1000 + Math.random() * 500;
} else {
gapCenterY = maxGapY - Math.random() * 300;
}
gapCenterY = Math.max(minGapY, Math.min(maxGapY, gapCenterY));
var pipe = new Pipe(gapCenterY);
pipe.x = newX;
pipe.passed = false;
pipes.push(pipe);
game.addChild(pipe);
}
// Reset game function
function resetGame() {
// Reset bird position
bird.x = 300;
bird.y = 1366;
bird.velocity = 0;
// Clear pipes
for (var i = pipes.length - 1; i >= 0; i--) {
if (pipes[i] && typeof pipes[i].destroy === "function") {
pipes[i].destroy();
}
}
pipes = [];
// Reset variables
gameStarted = false;
gameOver = false;
showGameOver = false;
// Hide game over screen
hideGameOverScreen();
LK.setScore(0);
// Reset score display
if (scoreText) {
scoreText.setText('0');
}
// Show main menu with smooth fade in
showMainMenu = true;
var menuElements = [{
element: mainMenuTitle,
targetAlpha: 1,
delay: 0
}, {
element: playButton,
targetAlpha: 1,
delay: 100
}, {
element: playButtonShadow,
targetAlpha: 0.4,
delay: 100
}, {
element: playButtonHighlight,
targetAlpha: 0.5,
delay: 100
}, {
element: playButtonText,
targetAlpha: 1,
delay: 100
}, {
element: cupShape,
targetAlpha: 1,
delay: 200
}, {
element: mainLanguageButton,
targetAlpha: 1,
delay: 300
}, {
element: mainLanguageButtonShadow,
targetAlpha: 0.3,
delay: 300
}, {
element: mainLanguageButtonHighlight,
targetAlpha: 0.4,
delay: 300
}, {
element: mainLanguageButtonText,
targetAlpha: 1,
delay: 300
}];
menuElements.forEach(function (item) {
if (item.element) {
item.element.alpha = 0;
item.element.visible = true;
LK.setTimeout(function () {
tween(item.element, {
alpha: item.targetAlpha
}, {
duration: 400,
easing: tween.easeOut
});
}, item.delay);
}
});
// Hide instruction
instructionTxt.visible = false;
// Hide score display
scoreText.visible = false;
generateAllPipes();
}
// Function to start game from main menu
function startGameFromMenu() {
showMainMenu = false;
// Fade out main menu elements smoothly
tween(mainMenuTitle, {
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
mainMenuTitle.visible = false;
mainMenuTitle.alpha = 1;
}
});
// Hide play button elements with fade
if (playButton) {
tween(playButton, {
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
playButton.visible = false;
playButton.alpha = 1;
}
});
}
if (playButtonShadow) {
tween(playButtonShadow, {
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
playButtonShadow.visible = false;
playButtonShadow.alpha = 0.4;
}
});
}
if (playButtonHighlight) {
tween(playButtonHighlight, {
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
playButtonHighlight.visible = false;
playButtonHighlight.alpha = 0.5;
}
});
}
if (playButtonText) {
tween(playButtonText, {
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
playButtonText.visible = false;
playButtonText.alpha = 1;
}
});
}
// Hide cup shape (high score indicator)
if (cupShape) {
tween(cupShape, {
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
cupShape.visible = false;
cupShape.alpha = 1;
}
});
}
// Hide main language button elements
if (mainLanguageButton) {
tween(mainLanguageButton, {
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
mainLanguageButton.visible = false;
mainLanguageButton.alpha = 1;
}
});
}
if (mainLanguageButtonShadow) {
tween(mainLanguageButtonShadow, {
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
mainLanguageButtonShadow.visible = false;
mainLanguageButtonShadow.alpha = 0.3;
}
});
}
if (mainLanguageButtonHighlight) {
tween(mainLanguageButtonHighlight, {
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
mainLanguageButtonHighlight.visible = false;
mainLanguageButtonHighlight.alpha = 0.4;
}
});
}
if (mainLanguageButtonText) {
tween(mainLanguageButtonText, {
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
mainLanguageButtonText.visible = false;
mainLanguageButtonText.alpha = 1;
}
});
}
// Show instruction and score with fade in
instructionTxt.alpha = 0;
instructionTxt.visible = true;
tween(instructionTxt, {
alpha: 1
}, {
duration: 400,
easing: tween.easeOut
});
scoreText.alpha = 0;
scoreText.visible = true;
scoreText.setText('0');
tween(scoreText, {
alpha: 1
}, {
duration: 400,
easing: tween.easeOut
});
}
// Function to show game over screen
function showGameOverScreen(finalScore) {
if (showGameOver) return;
showGameOver = true;
gameStarted = false;
// Hide all other menus first to prevent overlap
hideLanguageControls();
hideHighScoreScreen();
// Hide instruction and score with fade
tween(instructionTxt, {
alpha: 0
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
instructionTxt.visible = false;
instructionTxt.alpha = 1;
}
});
tween(scoreText, {
alpha: 0
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
scoreText.visible = false;
scoreText.alpha = 1;
}
});
// Show game over elements with smooth fade in
gameOverBg.alpha = 0;
gameOverBg.visible = true;
tween(gameOverBg, {
alpha: 0.95
}, {
duration: 400,
easing: tween.easeOut
});
gameOverTitle.alpha = 0;
gameOverTitle.visible = true;
tween(gameOverTitle, {
alpha: 1
}, {
duration: 500,
easing: tween.easeOut
});
finalScoreText.alpha = 0;
finalScoreText.visible = true;
// Update final score text
var currentScore = LK.getScore();
finalScoreText.setText(getText('score') + ': ' + currentScore);
tween(finalScoreText, {
alpha: 1
}, {
duration: 600,
easing: tween.easeOut
});
bestScoreText.alpha = 0;
bestScoreText.visible = true;
// Show buttons with staggered animation
retryButton.alpha = 0;
retryButton.visible = true;
retryButtonText.alpha = 0;
retryButtonText.visible = true;
retryButtonShadow.alpha = 0;
retryButtonShadow.visible = true;
retryButtonHighlight.alpha = 0;
retryButtonHighlight.visible = true;
menuButton.alpha = 0;
menuButton.visible = true;
menuButtonText.alpha = 0;
menuButtonText.visible = true;
menuButtonShadow.alpha = 0;
menuButtonShadow.visible = true;
menuButtonHighlight.alpha = 0;
menuButtonHighlight.visible = true;
// Remove score display - do not show final score
// Always show the current high score from persistent storage
var currentHighScore = storage.highScore || 0;
// Update high score if current score is higher
if (finalScore > currentHighScore) {
storage.highScore = finalScore;
currentHighScore = finalScore;
// Smooth visual feedback for new high score
if (bestScoreText && bestScoreText.visible) {
tween(bestScoreText, {
tint: 0xFF0000
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(bestScoreText, {
tint: 0xFFD700
}, {
duration: 300,
easing: tween.easeOut
});
}
});
}
}
bestScoreText.setText(getText('bestScore') + ': ' + currentHighScore);
tween(bestScoreText, {
alpha: 1
}, {
duration: 700,
easing: tween.easeOut
});
// Use proper text sizing
if (bestScoreText.width > 600) {
var newSize = Math.max(40, Math.floor(60 * 600 / bestScoreText.width));
bestScoreText.style = {
size: newSize,
fill: bestScoreText.style.fill
};
}
// Animate buttons in with delay
LK.setTimeout(function () {
tween(retryButton, {
alpha: 1
}, {
duration: 300,
easing: tween.easeOut
});
tween(retryButtonShadow, {
alpha: 0.3
}, {
duration: 300,
easing: tween.easeOut
});
tween(retryButtonHighlight, {
alpha: 0.4
}, {
duration: 300,
easing: tween.easeOut
});
tween(retryButtonText, {
alpha: 1
}, {
duration: 300,
easing: tween.easeOut
});
}, 400);
LK.setTimeout(function () {
tween(menuButton, {
alpha: 1
}, {
duration: 300,
easing: tween.easeOut
});
tween(menuButtonShadow, {
alpha: 0.3
}, {
duration: 300,
easing: tween.easeOut
});
tween(menuButtonHighlight, {
alpha: 0.4
}, {
duration: 300,
easing: tween.easeOut
});
tween(menuButtonText, {
alpha: 1
}, {
duration: 300,
easing: tween.easeOut
});
}, 600);
}
// Function to hide game over screen
function hideGameOverScreen() {
showGameOver = false;
// Fade out game over elements smoothly
var elementsToHide = [gameOverBg, gameOverTitle, finalScoreText, bestScoreText, retryButton, retryButtonText, retryButtonShadow, retryButtonHighlight, menuButton, menuButtonText, menuButtonShadow, menuButtonHighlight];
elementsToHide.forEach(function (element) {
if (element && element.visible) {
tween(element, {
alpha: 0
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
element.visible = false;
element.alpha = element === gameOverBg ? 0.95 : element === retryButtonShadow || element === menuButtonShadow ? 0.3 : element === retryButtonHighlight || element === menuButtonHighlight ? 0.4 : 1;
}
});
}
});
}
// Function to show high score screen
function showHighScoreScreen() {
// Hide any other screens to prevent overlap
hideGameOverScreen();
hideLanguageControls();
// Hide main menu elements first to prevent overlap
if (showMainMenu) {
tween(mainMenuTitle, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
mainMenuTitle.visible = false;
mainMenuTitle.alpha = 1;
}
});
if (playButton) {
tween(playButton, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
playButton.visible = false;
playButton.alpha = 1;
}
});
}
if (playButtonShadow) {
tween(playButtonShadow, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
playButtonShadow.visible = false;
playButtonShadow.alpha = 0.4;
}
});
}
if (playButtonHighlight) {
tween(playButtonHighlight, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
playButtonHighlight.visible = false;
playButtonHighlight.alpha = 0.5;
}
});
}
if (playButtonText) {
tween(playButtonText, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
playButtonText.visible = false;
playButtonText.alpha = 1;
}
});
}
if (mainLanguageButton) {
tween(mainLanguageButton, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
mainLanguageButton.visible = false;
mainLanguageButton.alpha = 1;
}
});
}
if (mainLanguageButtonShadow) {
tween(mainLanguageButtonShadow, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
mainLanguageButtonShadow.visible = false;
mainLanguageButtonShadow.alpha = 0.3;
}
});
}
if (mainLanguageButtonHighlight) {
tween(mainLanguageButtonHighlight, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
mainLanguageButtonHighlight.visible = false;
mainLanguageButtonHighlight.alpha = 0.4;
}
});
}
if (mainLanguageButtonText) {
tween(mainLanguageButtonText, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
mainLanguageButtonText.visible = false;
mainLanguageButtonText.alpha = 1;
}
});
}
}
// Update high score value
var currentHighScore = storage.highScore || 0;
highScoreValue.setText(currentHighScore.toString());
highScoreTitle.setText(getText('highestScore'));
highScoreCloseText.setText(getText('close') || 'KAPAT');
// Show high score elements with fade in
var highScoreElements = [{
element: highScoreBg,
targetAlpha: 0.95,
delay: 0
}, {
element: highScoreTitle,
targetAlpha: 1,
delay: 100
}, {
element: highScoreValue,
targetAlpha: 1,
delay: 200
}, {
element: highScoreCloseButton,
targetAlpha: 1,
delay: 300
}, {
element: highScoreCloseText,
targetAlpha: 1,
delay: 300
}];
highScoreElements.forEach(function (item) {
if (item.element) {
item.element.alpha = 0;
item.element.visible = true;
LK.setTimeout(function () {
tween(item.element, {
alpha: item.targetAlpha
}, {
duration: 300,
easing: tween.easeOut
});
}, item.delay);
}
});
}
// Function to hide high score screen
function hideHighScoreScreen() {
// Fade out high score elements
var highScoreElements = [highScoreBg, highScoreTitle, highScoreValue, highScoreCloseButton, highScoreCloseText];
var fadeOutCompleted = 0;
highScoreElements.forEach(function (element) {
if (element && element.visible) {
tween(element, {
alpha: 0
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
element.visible = false;
element.alpha = element === highScoreBg ? 0.95 : 1;
fadeOutCompleted++;
// Show main menu after all high score elements have faded out
if (fadeOutCompleted === highScoreElements.length && showMainMenu && !showGameOver && !gameOverBg.visible && !languageOverlay.visible) {
// Fade in main menu elements
var menuElements = [mainMenuTitle, playButton, playButtonShadow, playButtonHighlight, playButtonText, mainLanguageButton, mainLanguageButtonShadow, mainLanguageButtonHighlight, mainLanguageButtonText];
menuElements.forEach(function (menuElement, index) {
if (menuElement) {
menuElement.alpha = 0;
menuElement.visible = true;
tween(menuElement, {
alpha: menuElement === playButtonShadow ? 0.4 : menuElement === playButtonHighlight ? 0.5 : menuElement === mainLanguageButtonShadow ? 0.3 : menuElement === mainLanguageButtonHighlight ? 0.4 : 1
}, {
duration: 300,
delay: index * 30,
easing: tween.easeOut
});
}
});
}
}
});
}
});
}
// Create language overlay background
var languageOverlay = LK.getAsset('topPipe', {
anchorX: 0.5,
anchorY: 0.5,
width: 2048,
height: 2732,
alpha: 1.0
});
languageOverlay.tint = 0x2F4F4F;
languageOverlay.visible = false;
LK.gui.center.addChild(languageOverlay);
// Create language control title
var languageTitle = new Text2('DİL SEÇENEKLERİ', {
size: 80,
fill: 0xFFFFFF
});
languageTitle.anchor.set(0.5, 0.5);
languageTitle.stroke = 0x000000;
languageTitle.strokeThickness = 4;
languageTitle.visible = false;
LK.gui.center.addChild(languageTitle);
languageTitle.y = -200;
// Create language option buttons with modern rectangular design
var turkishButton = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 260,
height: 65,
alpha: 1.0
});
turkishButton.tint = 0x27AE60;
turkishButton.visible = false;
LK.gui.center.addChild(turkishButton);
turkishButton.y = -80;
turkishButton.x = -220;
// Add Turkish button shadow
var turkishButtonShadow = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 260,
height: 65,
alpha: 0.3
});
turkishButtonShadow.tint = 0x1E8449;
turkishButtonShadow.visible = false;
LK.gui.center.addChild(turkishButtonShadow);
turkishButtonShadow.y = -75;
turkishButtonShadow.x = -217;
// Add Turkish button highlight
var turkishButtonHighlight = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 240,
height: 50,
alpha: 0.4
});
turkishButtonHighlight.tint = 0x58D68D;
turkishButtonHighlight.visible = false;
LK.gui.center.addChild(turkishButtonHighlight);
turkishButtonHighlight.y = -85;
turkishButtonHighlight.x = -220;
var turkishText = new Text2('TÜRKÇE', {
size: 32,
fill: 0xFFFFFF
});
turkishText.anchor.set(0.5, 0.5);
turkishText.stroke = 0x1E8449;
turkishText.strokeThickness = 2;
turkishText.visible = false;
LK.gui.center.addChild(turkishText);
turkishText.y = -80;
turkishText.x = -220;
var englishButton = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 260,
height: 65,
alpha: 1.0
});
englishButton.tint = 0x3498DB;
englishButton.visible = false;
LK.gui.center.addChild(englishButton);
englishButton.y = -80;
englishButton.x = 220;
// Add English button shadow
var englishButtonShadow = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 260,
height: 65,
alpha: 0.3
});
englishButtonShadow.tint = 0x2980B9;
englishButtonShadow.visible = false;
LK.gui.center.addChild(englishButtonShadow);
englishButtonShadow.y = -75;
englishButtonShadow.x = 223;
// Add English button highlight
var englishButtonHighlight = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 240,
height: 50,
alpha: 0.4
});
englishButtonHighlight.tint = 0x85C1E9;
englishButtonHighlight.visible = false;
LK.gui.center.addChild(englishButtonHighlight);
englishButtonHighlight.y = -85;
englishButtonHighlight.x = 220;
var englishText = new Text2('ENGLISH', {
size: 32,
fill: 0xFFFFFF
});
englishText.anchor.set(0.5, 0.5);
englishText.stroke = 0x2980B9;
englishText.strokeThickness = 2;
englishText.visible = false;
LK.gui.center.addChild(englishText);
englishText.y = -80;
englishText.x = 220;
// Current language indicator
var currentLanguageText = new Text2('MEVCUT: TÜRKÇE', {
size: 50,
fill: 0xFFD700
});
currentLanguageText.anchor.set(0.5, 0.5);
currentLanguageText.stroke = 0x000000;
currentLanguageText.strokeThickness = 3;
currentLanguageText.visible = false;
LK.gui.center.addChild(currentLanguageText);
currentLanguageText.y = 30;
// Create back button for language controls with modern rectangular design
var languageBackButton = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 220,
height: 65,
alpha: 1.0
});
languageBackButton.tint = 0x7F8C8D;
languageBackButton.visible = false;
LK.gui.center.addChild(languageBackButton);
languageBackButton.y = 150;
// Add language back button shadow
var languageBackButtonShadow = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 220,
height: 65,
alpha: 0.3
});
languageBackButtonShadow.tint = 0x566573;
languageBackButtonShadow.visible = false;
LK.gui.center.addChild(languageBackButtonShadow);
languageBackButtonShadow.y = 155;
languageBackButtonShadow.x = 3;
// Add language back button highlight
var languageBackButtonHighlight = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 200,
height: 50,
alpha: 0.4
});
languageBackButtonHighlight.tint = 0xABB2B9;
languageBackButtonHighlight.visible = false;
LK.gui.center.addChild(languageBackButtonHighlight);
languageBackButtonHighlight.y = 145;
var languageBackText = new Text2('GERİ', {
size: 36,
fill: 0xFFFFFF
});
languageBackText.anchor.set(0.5, 0.5);
languageBackText.stroke = 0x566573;
languageBackText.strokeThickness = 2;
languageBackText.visible = false;
LK.gui.center.addChild(languageBackText);
languageBackText.y = 150;
// Function to show language controls
function showLanguageControls() {
// Hide all other menus first to prevent overlap
hideGameOverScreen();
hideHighScoreScreen();
// Hide main menu elements with fade
tween(mainMenuTitle, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
mainMenuTitle.visible = false;
mainMenuTitle.alpha = 1;
}
});
if (playButton) {
tween(playButton, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
playButton.visible = false;
playButton.alpha = 1;
}
});
}
if (playButtonShadow) {
tween(playButtonShadow, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
playButtonShadow.visible = false;
playButtonShadow.alpha = 0.4;
}
});
}
if (playButtonHighlight) {
tween(playButtonHighlight, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
playButtonHighlight.visible = false;
playButtonHighlight.alpha = 0.5;
}
});
}
if (playButtonText) {
tween(playButtonText, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
playButtonText.visible = false;
playButtonText.alpha = 1;
}
});
}
if (cupShape) {
tween(cupShape, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
cupShape.visible = false;
cupShape.alpha = 1;
}
});
}
// Hide main language button elements
if (mainLanguageButton) {
tween(mainLanguageButton, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
mainLanguageButton.visible = false;
mainLanguageButton.alpha = 1;
}
});
}
if (mainLanguageButtonShadow) {
tween(mainLanguageButtonShadow, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
mainLanguageButtonShadow.visible = false;
mainLanguageButtonShadow.alpha = 0.3;
}
});
}
if (mainLanguageButtonHighlight) {
tween(mainLanguageButtonHighlight, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
mainLanguageButtonHighlight.visible = false;
mainLanguageButtonHighlight.alpha = 0.4;
}
});
}
if (mainLanguageButtonText) {
tween(mainLanguageButtonText, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
mainLanguageButtonText.visible = false;
mainLanguageButtonText.alpha = 1;
}
});
}
// Show language controls with smooth fade in
languageOverlay.alpha = 0;
languageOverlay.visible = true;
tween(languageOverlay, {
alpha: 1
}, {
duration: 350,
easing: tween.easeOut
});
languageTitle.alpha = 0;
languageTitle.visible = true;
tween(languageTitle, {
alpha: 1
}, {
duration: 400,
easing: tween.easeOut
});
// Show language buttons with staggered animation
turkishButton.alpha = 0;
turkishButton.visible = true;
turkishButtonShadow.alpha = 0;
turkishButtonShadow.visible = true;
turkishButtonHighlight.alpha = 0;
turkishButtonHighlight.visible = true;
turkishText.alpha = 0;
turkishText.visible = true;
englishButton.alpha = 0;
englishButton.visible = true;
englishButtonShadow.alpha = 0;
englishButtonShadow.visible = true;
englishButtonHighlight.alpha = 0;
englishButtonHighlight.visible = true;
englishText.alpha = 0;
englishText.visible = true;
currentLanguageText.alpha = 0;
currentLanguageText.visible = true;
languageBackButton.alpha = 0;
languageBackButton.visible = true;
languageBackButtonShadow.alpha = 0;
languageBackButtonShadow.visible = true;
languageBackButtonHighlight.alpha = 0;
languageBackButtonHighlight.visible = true;
languageBackText.alpha = 0;
languageBackText.visible = true;
// Animate language buttons in with delays
LK.setTimeout(function () {
tween(turkishButton, {
alpha: 1
}, {
duration: 300,
easing: tween.easeOut
});
tween(turkishButtonShadow, {
alpha: 0.3
}, {
duration: 300,
easing: tween.easeOut
});
tween(turkishButtonHighlight, {
alpha: 0.4
}, {
duration: 300,
easing: tween.easeOut
});
tween(turkishText, {
alpha: 1
}, {
duration: 300,
easing: tween.easeOut
});
}, 200);
LK.setTimeout(function () {
tween(englishButton, {
alpha: 1
}, {
duration: 300,
easing: tween.easeOut
});
tween(englishButtonShadow, {
alpha: 0.3
}, {
duration: 300,
easing: tween.easeOut
});
tween(englishButtonHighlight, {
alpha: 0.4
}, {
duration: 300,
easing: tween.easeOut
});
tween(englishText, {
alpha: 1
}, {
duration: 300,
easing: tween.easeOut
});
}, 350);
LK.setTimeout(function () {
tween(currentLanguageText, {
alpha: 1
}, {
duration: 300,
easing: tween.easeOut
});
}, 500);
LK.setTimeout(function () {
tween(languageBackButton, {
alpha: 1
}, {
duration: 300,
easing: tween.easeOut
});
tween(languageBackButtonShadow, {
alpha: 0.3
}, {
duration: 300,
easing: tween.easeOut
});
tween(languageBackButtonHighlight, {
alpha: 0.4
}, {
duration: 300,
easing: tween.easeOut
});
tween(languageBackText, {
alpha: 1
}, {
duration: 300,
easing: tween.easeOut
});
}, 650);
updateLanguageDisplay();
}
// Function to hide language controls
function hideLanguageControls() {
// Fade out all language control elements
var languageElements = [languageOverlay, languageTitle, turkishButton, turkishButtonShadow, turkishButtonHighlight, turkishText, englishButton, englishButtonShadow, englishButtonHighlight, englishText, currentLanguageText, languageBackButton, languageBackButtonShadow, languageBackButtonHighlight, languageBackText];
var fadeOutDuration = 250;
var fadeOutCompleted = 0;
languageElements.forEach(function (element) {
if (element && element.visible) {
tween(element, {
alpha: 0
}, {
duration: fadeOutDuration,
easing: tween.easeOut,
onFinish: function onFinish() {
element.visible = false;
element.alpha = element === languageOverlay ? 1 : element === turkishButtonShadow || element === englishButtonShadow || element === languageBackButtonShadow ? 0.3 : element === turkishButtonHighlight || element === englishButtonHighlight || element === languageBackButtonHighlight ? 0.4 : 1;
fadeOutCompleted++;
// Show main menu after all elements have faded out
if (fadeOutCompleted === languageElements.length && showMainMenu && !showGameOver && !gameOverBg.visible && !highScoreBg.visible) {
// Fade in main menu elements
var menuElements = [mainMenuTitle, playButton, playButtonShadow, playButtonHighlight, playButtonText, cupShape, mainLanguageButton, mainLanguageButtonShadow, mainLanguageButtonHighlight, mainLanguageButtonText];
menuElements.forEach(function (menuElement, index) {
if (menuElement) {
menuElement.alpha = 0;
menuElement.visible = true;
tween(menuElement, {
alpha: menuElement === playButtonShadow ? 0.4 : menuElement === playButtonHighlight ? 0.5 : menuElement === mainLanguageButtonShadow ? 0.3 : menuElement === mainLanguageButtonHighlight ? 0.4 : 1
}, {
duration: 300,
delay: index * 30,
easing: tween.easeOut
});
}
});
}
}
});
}
});
}
// Language text objects
var languageTexts = {
tr: {
mainTitle: 'FLAPPY BIRD',
playButton: 'OYNA',
instruction: 'TIKLA VE OYNA!',
gameOver: 'OYUN BİTTİ',
score: 'SKOR',
bestScore: 'EN İYİ',
retry: 'TEKRAR DENE',
mainMenu: 'ANA MENÜ',
language: 'DİL',
languageTitle: 'DİL SEÇENEKLERİ',
current: 'MEVCUT',
highestScore: 'EN YÜKSEK SKOR',
back: 'GERİ',
close: 'KAPAT'
},
en: {
mainTitle: 'FLAPPY BIRD',
playButton: 'PLAY',
instruction: 'CLICK TO PLAY!',
gameOver: 'GAME OVER',
score: 'SCORE',
bestScore: 'BEST',
retry: 'RETRY',
mainMenu: 'MAIN MENU',
language: 'LANGUAGE',
languageTitle: 'LANGUAGE OPTIONS',
current: 'CURRENT',
highestScore: 'HIGHEST SCORE',
back: 'BACK',
close: 'CLOSE'
}
};
// Function to get text for current language
function getText(key) {
return languageTexts[currentLanguage][key] || languageTexts['en'][key];
}
// Function to update all text elements to current language
function updateAllTexts() {
if (instructionTxt) {
instructionTxt.setText(getText('instruction'));
}
if (playButtonText) {
playButtonText.setText(getText('playButton'));
}
if (gameOverTitle) {
gameOverTitle.setText(getText('gameOver'));
}
if (retryButtonText) {
retryButtonText.setText(getText('retry'));
}
if (menuButtonText) {
menuButtonText.setText(getText('mainMenu'));
}
if (languageTitle) {
languageTitle.setText(getText('languageTitle'));
}
if (languageBackText) {
languageBackText.setText(getText('back'));
}
if (mainLanguageButtonText) {
mainLanguageButtonText.setText(getText('language'));
}
// Update final and best score texts
if (finalScoreText) {
var currentScore = LK.getScore();
finalScoreText.setText(getText('score') + ': ' + currentScore);
}
if (bestScoreText) {
var currentHighScore = storage.highScore || 0;
bestScoreText.setText(getText('bestScore') + ': ' + currentHighScore);
}
}
// Function to update language display
function updateLanguageDisplay() {
var langText = currentLanguage === 'tr' ? 'TÜRKÇE' : 'ENGLISH';
var currentText = currentLanguage === 'tr' ? 'MEVCUT' : 'CURRENT';
if (currentLanguageText) {
currentLanguageText.setText(currentText + ': ' + langText);
}
// Update button colors to show selected language
if (turkishButton) {
turkishButton.tint = currentLanguage === 'tr' ? 0x2ECC71 : 0x27AE60;
}
if (englishButton) {
englishButton.tint = currentLanguage === 'en' ? 0x5DADE2 : 0x3498DB;
}
}
// Function to set language
function setLanguage(lang) {
currentLanguage = lang;
// Save to persistent storage
storage.language = lang;
// Update all text elements immediately
updateAllTexts();
// Update language display
updateLanguageDisplay();
}
// Initialize persistent storage with defaults if values don't exist
if (typeof storage.highScore === 'undefined') storage.highScore = 0;
if (typeof storage.lastScore === 'undefined') storage.lastScore = 0;
if (!storage.language) storage.language = 'tr';
// Update current language from persistent storage
currentLanguage = storage.language || 'tr';
// Create animated play button for main menu
var playButton = LK.getAsset('playButtonMain', {
anchorX: 0.5,
anchorY: 0.5,
width: 400,
height: 120,
alpha: 1.0
});
playButton.tint = 0xFF9800; // Flappy Bird orange
LK.gui.center.addChild(playButton);
playButton.y = -100;
// Create language button for direct access from main menu
var mainLanguageButton = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 300,
height: 80,
alpha: 1.0
});
mainLanguageButton.tint = 0x9B59B6;
LK.gui.center.addChild(mainLanguageButton);
mainLanguageButton.y = 50;
// Create language button shadow
var mainLanguageButtonShadow = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 300,
height: 80,
alpha: 0.3
});
mainLanguageButtonShadow.tint = 0x8E44AD;
LK.gui.center.addChild(mainLanguageButtonShadow);
mainLanguageButtonShadow.y = 55;
mainLanguageButtonShadow.x = 3;
// Create language button highlight
var mainLanguageButtonHighlight = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 280,
height: 65,
alpha: 0.4
});
mainLanguageButtonHighlight.tint = 0xBB8FCE;
LK.gui.center.addChild(mainLanguageButtonHighlight);
mainLanguageButtonHighlight.y = 45;
// Create language button text
var mainLanguageButtonText = new Text2('DİL', {
size: 36,
fill: 0xFFFFFF
});
mainLanguageButtonText.anchor.set(0.5, 0.5);
mainLanguageButtonText.stroke = 0x8E44AD;
mainLanguageButtonText.strokeThickness = 2;
LK.gui.center.addChild(mainLanguageButtonText);
mainLanguageButtonText.y = 50;
// Create separate play button shadow element
var playButtonShadow = LK.getAsset('playButtonShadow', {
anchorX: 0.5,
anchorY: 0.5,
width: 400,
height: 120,
alpha: 0.4
});
playButtonShadow.tint = 0xE65100; // Darker orange shadow
LK.gui.center.addChild(playButtonShadow);
playButtonShadow.y = -92; // Offset shadow slightly up
playButtonShadow.x = 4; // Offset shadow slightly right
// Create separate play button highlight element
var playButtonHighlight = LK.getAsset('playButtonHighlight', {
anchorX: 0.5,
anchorY: 0.5,
width: 370,
height: 95,
alpha: 0.5
});
playButtonHighlight.tint = 0xFFB74D; // Lighter orange highlight
LK.gui.center.addChild(playButtonHighlight);
playButtonHighlight.y = -108; // Offset highlight slightly down
// Create separate play button text element
var playButtonText = new Text2('OYNA', {
size: 50,
fill: 0xFFFFFF
});
playButtonText.anchor.set(0.5, 0.5);
playButtonText.stroke = 0xE65100;
playButtonText.strokeThickness = 4;
LK.gui.center.addChild(playButtonText);
playButtonText.y = -100;
// Initialize game
resetGame(); // Use resetGame to properly initialize all states
// Update all texts to current language
updateAllTexts();
// Update language display to show current selection
updateLanguageDisplay();
// Touch/click handler
game.down = function (x, y, obj) {
// Check if high score screen is visible
if (highScoreBg.visible) {
// Check close button click - centered at 1024x1566 (center.y = 1366 + 200), button is 300x80
if (x >= 874 && x <= 1174 && y >= 1526 && y <= 1606) {
// Simple visual feedback
simpleColorTint(highScoreCloseButton, 0xABB2B9, 0);
hideHighScoreScreen();
return;
}
return; // Don't process other clicks when high score screen is open
}
// Check if language overlay is visible and handle language controls
if (languageOverlay.visible) {
// Turkish language button with isolated click area
if (turkishButton.visible && x >= 654 && x <= 954 && y >= 1246 && y <= 1326) {
// Simple visual feedback with color change
simpleColorTint(turkishButton, 0x58D68D, 0);
setLanguage('tr');
return;
}
// Barrier zone between Turkish and English buttons (x: 954-1094)
if (x >= 954 && x <= 1094 && y >= 1246 && y <= 1326) {
return; // Block clicks in barrier zone
}
// English language button with isolated click area
if (englishButton.visible && x >= 1094 && x <= 1394 && y >= 1246 && y <= 1326) {
// Simple visual feedback with color change
simpleColorTint(englishButton, 0x85C1E9, 0);
setLanguage('en');
return;
}
// Check language back button at x = 1024, y = 1516, size 300x100
if (languageBackButton.visible && x >= 874 && x <= 1174 && y >= 1466 && y <= 1566) {
// Simple visual feedback with color change
simpleColorTint(languageBackButton, 0xABB2B9, 0);
hideLanguageControls();
return;
}
return; // Don't process other clicks when language overlay is open
}
// Check cup click - cup is positioned at bottomRight with offset
var cupX = 2048 - 100; // bottomRight.x + cupShape.x offset
var cupY = 2732 - 230; // bottomRight.y + cupShape.y offset
var cupSize = 120; // Cup asset size
if (x >= cupX - cupSize / 2 && x <= cupX + cupSize / 2 && y >= cupY && y <= cupY + cupSize) {
// Show high score screen
showHighScoreScreen();
// Simple visual feedback without animation
if (cupShape) {
cupShape.tint = 0xFFFFFF;
cupShape.tint = 0xFFD700;
}
return;
}
if (gameOver || showGameOver) {
// Check retry button (TEKRAR DENE) - centered at 1024x1466, button is 380x110
if (x >= 834 && x <= 1214 && y >= 1411 && y <= 1521) {
// Simple visual feedback with color change
simpleColorTint(retryButton, 0xFFB74D, 150, function () {
// Fade out game over screen first
hideGameOverScreen();
// Wait for fade out to complete before resetting
LK.setTimeout(function () {
resetGame();
// Show instruction screen instead of starting game directly
startGameFromMenu();
}, 250);
});
return;
}
// Check menu button (ANA MENÜ) - centered at 1024x1616, button is 380x110
if (x >= 834 && x <= 1214 && y >= 1561 && y <= 1671) {
// Simple visual feedback with color change
simpleColorTint(menuButton, 0xF1948A, 150, function () {
// Fade out game over screen first
hideGameOverScreen();
// Wait for fade out to complete before resetting
LK.setTimeout(function () {
resetGame();
}, 250);
});
return;
}
return;
}
if (showMainMenu) {
// Check play button click - centered at 1024x1266 (center.y = 1366 + playButton.y = -100), button is 400x120
if (playButton && playButton.visible && x >= 824 && x <= 1224 && y >= 1206 && y <= 1326) {
// Simple visual feedback with color change
simpleColorTint(playButton, 0xFFB74D, 0);
startGameFromMenu();
return;
}
// Check main language button click - centered at 1024x1416 (center.y = 1366 + mainLanguageButton.y = 50), button is 300x80
if (mainLanguageButton && mainLanguageButton.visible && x >= 874 && x <= 1174 && y >= 1376 && y <= 1456) {
// Simple visual feedback with color change
simpleColorTint(mainLanguageButton, 0xBB8FCE, 0);
showLanguageControls();
return;
}
return;
}
if (!gameStarted) {
gameStarted = true;
instructionTxt.visible = false;
}
bird.flap();
};
// Main game loop with optimized performance
game.update = function () {
if (gameOver || showMainMenu || showGameOver) return;
// Only run game logic if game has started
if (gameStarted) {
// Check ground and ceiling collision with proper bird size (bird is 80px tall, 120px wide)
var birdRadius = 40; // Half of bird height for collision detection
if (bird.y + birdRadius >= ground.y || bird.y - birdRadius <= 0) {
gameOver = true;
var currentScore = LK.getScore();
// Save score to persistent storage
if (currentScore > (storage.highScore || 0)) {
storage.highScore = currentScore;
}
storage.lastScore = currentScore;
// Add smooth transition to game over
tween(instructionTxt, {
alpha: 0
}, {
duration: 200,
easing: tween.easeOut
});
tween(scoreText, {
alpha: 0
}, {
duration: 200,
easing: tween.easeOut
});
LK.setTimeout(function () {
showGameOverScreen(LK.getScore());
}, 200);
return;
}
// Dynamic pipe generation - generate new pipes as old ones are removed
var rightmostPipeX = -1000;
for (var i = 0; i < pipes.length; i++) {
if (pipes[i] && pipes[i].x > rightmostPipeX) {
rightmostPipeX = pipes[i].x;
}
}
// Generate new pipe if the rightmost pipe is getting close to the screen
if (rightmostPipeX < 3000) {
generateNewPipe();
}
// Optimized pipe cleanup - remove pipes that are far behind only
for (var i = pipes.length - 1; i >= 0; i--) {
var pipe = pipes[i];
// Only remove pipes that are far behind the bird
if (pipe && pipe.x < bird.x - 800) {
pipe.destroy();
pipes.splice(i, 1);
}
}
// Find closest pipe for collision and scoring
var closestPipe = null;
var closestDistance = 99999;
for (var i = 0; i < pipes.length; i++) {
var pipe = pipes[i];
// Check pipes that are close to the bird
if (pipe && pipe.x > bird.x - 100 && pipe.x < bird.x + 200) {
var distance = Math.abs(pipe.x - bird.x);
if (distance < closestDistance) {
closestDistance = distance;
closestPipe = pipe;
}
}
}
if (closestPipe) {
// Initialize lastX tracking
if (typeof closestPipe.lastX === 'undefined') {
closestPipe.lastX = closestPipe.x;
}
// Scoring check - detect when bird passes through the pipe center
// Since pipes move from right to left and bird stays at x=300, check when pipe center passes bird
var pipeCenter = closestPipe.x;
var birdPosition = bird.x;
// Check if pipe center just passed the bird position (was on right, now on left)
if (!closestPipe.passed && closestPipe.lastX > birdPosition && pipeCenter <= birdPosition) {
// Check if bird is within the gap when pipe passes
var gapTop = closestPipe.gapCenterY - closestPipe.gapSize / 2;
var gapBottom = closestPipe.gapCenterY + closestPipe.gapSize / 2;
// Mark pipe as passed
if (bird.y > gapTop && bird.y < gapBottom) {
closestPipe.passed = true;
// Increment score
LK.setScore(LK.getScore() + 1);
var currentScore = LK.getScore();
// Update score display with smooth animation
if (scoreText && scoreText.visible) {
scoreText.setText(currentScore.toString());
// Smooth score flash animation
tween(scoreText, {
tint: 0xFFD700
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(scoreText, {
tint: 0xFFFFFF
}, {
duration: 200,
easing: tween.easeOut
});
}
});
}
// Save high score if current score is higher
if (currentScore > (storage.highScore || 0)) {
storage.highScore = currentScore;
}
// Check win condition - game ends at 100 points for better gameplay
if (currentScore >= 100) {
gameOver = true;
storage.lastScore = currentScore;
LK.showYouWin(); // Show win screen when reaching 100 points
return;
}
if (LK.getSound('score')) {
LK.getSound('score').play();
}
}
}
// Update last position
closestPipe.lastX = closestPipe.x;
// Collision check - only if very close with better collision detection
if (closestPipe.x > bird.x - 80 && closestPipe.x < bird.x + 80) {
var gapTop = closestPipe.gapCenterY - closestPipe.gapSize / 2;
var gapBottom = closestPipe.gapCenterY + closestPipe.gapSize / 2;
// More forgiving collision detection
if (bird.y < gapTop + 60 || bird.y > gapBottom - 60) {
gameOver = true;
// Add smooth transition before showing game over
tween(instructionTxt, {
alpha: 0
}, {
duration: 200,
easing: tween.easeOut
});
tween(scoreText, {
alpha: 0
}, {
duration: 200,
easing: tween.easeOut
});
LK.setTimeout(function () {
showGameOverScreen(LK.getScore());
}, 200);
return;
}
}
}
}
}; /****
* Plugins
****/
var storage = LK.import("@upit/storage.v1");
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Bird = Container.expand(function () {
var self = Container.call(this);
// Create bird graphics with proper anchoring
var birdGraphics = self.attachAsset('bird', {
anchorX: 0.5,
anchorY: 0.5
});
// Initialize bird properties
self.velocity = 0;
self.flapCooldown = 0;
// Optimized flap function
self.flap = function () {
// Prevent rapid flapping
if (self.flapCooldown > 0) return;
if (gameOver) return;
self.flapCooldown = 8; // Frames to wait before next flap
// Set velocity with improved scaling for better responsiveness
self.velocity = jumpStrength;
// Play flap sound with minimal error handling
if (LK.getSound('flap')) {
LK.getSound('flap').play();
}
};
// Optimized update method
self.update = function () {
// Update cooldowns
if (self.flapCooldown > 0) self.flapCooldown--;
if (!gameStarted) {
// Pre-game idle state
self.y = 1366;
self.x = 300;
return;
}
// Simple physics with improved scaling
if (!gameOver) {
// Only update position if game is not over
self.velocity += gravity;
self.y += self.velocity;
}
// Update rotation only when velocity changes significantly
if (Math.abs(self.velocity - (self.lastVelocity || 0)) > 2) {
birdGraphics.rotation = self.velocity > 0 ? 0.8 : -0.4;
self.lastVelocity = self.velocity;
}
// Screen bounds collision
if (self.y < 40) {
self.y = 40;
self.velocity = 0;
}
if (self.y > 2582) {
self.y = 2582;
self.velocity = 0;
if (!gameOver) {
gameOver = true; // Trigger game over
showGameOverScreen(LK.getScore()); // Show game over screen with score
}
}
};
return self;
});
var Pipe = Container.expand(function (gapCenterY) {
var self = Container.call(this);
// Fixed gap size for consistent gameplay
self.gapSize = 850; // Normal gap - increased for easier passage
self.speed = pipeSpeed;
self.passed = false;
self.gapCenterY = gapCenterY;
self.pipeWidth = 120;
// Calculate pipe heights
var topPipeHeight = Math.max(200, gapCenterY - self.gapSize / 2);
var bottomPipeHeight = Math.max(200, 2732 - 150 - (gapCenterY + self.gapSize / 2));
// --- Flappy Bird style: dark base, highlight, and shadow for realism ---
// Top pipe main body (dark green)
var topPipe = self.attachAsset('topPipe', {
anchorX: 0.5,
anchorY: 1
});
topPipe.y = gapCenterY - self.gapSize / 2;
topPipe.height = topPipeHeight;
topPipe.width = self.pipeWidth;
topPipe.tint = 0x1a3c1a; // dark green
// Top pipe highlight (lighter green, left side)
var topPipeHighlight = self.attachAsset('pipeHighlight', {
anchorX: 0.5,
anchorY: 1
});
topPipeHighlight.y = gapCenterY - self.gapSize / 2;
topPipeHighlight.height = topPipeHeight;
topPipeHighlight.width = 32;
topPipeHighlight.x = -self.pipeWidth / 2 + 16;
topPipeHighlight.tint = 0x3be24d; // bright highlight
// Top pipe shadow (darker, right side)
var topPipeShadow = self.attachAsset('pipeHighlight', {
anchorX: 0.5,
anchorY: 1
});
topPipeShadow.y = gapCenterY - self.gapSize / 2;
topPipeShadow.height = topPipeHeight;
topPipeShadow.width = 32;
topPipeShadow.x = self.pipeWidth / 2 - 16;
topPipeShadow.tint = 0x0d1a0d; // very dark green
// Bottom pipe main body (dark green)
var bottomPipe = self.attachAsset('bottomPipe', {
anchorX: 0.5,
anchorY: 0
});
bottomPipe.y = gapCenterY + self.gapSize / 2;
bottomPipe.height = bottomPipeHeight;
bottomPipe.width = self.pipeWidth;
bottomPipe.tint = 0x1a3c1a; // dark green
// Bottom pipe highlight (lighter green, left side)
var bottomPipeHighlight = self.attachAsset('pipeHighlight', {
anchorX: 0.5,
anchorY: 0
});
bottomPipeHighlight.y = gapCenterY + self.gapSize / 2;
bottomPipeHighlight.height = bottomPipeHeight;
bottomPipeHighlight.width = 32;
bottomPipeHighlight.x = -self.pipeWidth / 2 + 16;
bottomPipeHighlight.tint = 0x3be24d; // bright highlight
// Bottom pipe shadow (darker, right side)
var bottomPipeShadow = self.attachAsset('pipeHighlight', {
anchorX: 0.5,
anchorY: 0
});
bottomPipeShadow.y = gapCenterY + self.gapSize / 2;
bottomPipeShadow.height = bottomPipeHeight;
bottomPipeShadow.width = 32;
bottomPipeShadow.x = self.pipeWidth / 2 - 16;
bottomPipeShadow.tint = 0x0d1a0d; // very dark green
// Pipe caps (yellowish, like Flappy Bird)
var topPipeCap = self.attachAsset('pipeTop', {
anchorX: 0.5,
anchorY: 1
});
topPipeCap.y = gapCenterY - self.gapSize / 2;
topPipeCap.width = self.pipeWidth + 20;
topPipeCap.height = 25;
topPipeCap.tint = 0xfaf4a0; // yellowish
var bottomPipeCap = self.attachAsset('pipeBottom', {
anchorX: 0.5,
anchorY: 0
});
bottomPipeCap.y = gapCenterY + self.gapSize / 2;
bottomPipeCap.width = self.pipeWidth + 20;
bottomPipeCap.height = 25;
bottomPipeCap.tint = 0xfaf4a0; // yellowish
self.update = function () {
if (!gameStarted) {
return;
}
// Move pipes to the left (negative speed) so bird appears to move forward
self.x += self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game();
/****
* Game Code
****/
// Initialize persistent storage using storage plugin
var currentLanguage = storage.language || 'tr';
var gameHighScore = storage.highScore || 0;
// Smooth visual feedback function using tween
function simpleColorTint(target, color, duration, callback) {
var originalTint = target.tint;
target.tint = color;
// Smooth transition back to original color
tween(target, {
tint: originalTint
}, {
duration: duration || 150,
easing: tween.easeOut,
onFinish: callback
});
}
var bird;
var pipes = [];
var ground;
var gameStarted = false;
var gameOver = false;
var showMainMenu = true;
var showGameOver = false;
// Button click time tracking removed to eliminate delays
var gravity = 0.55; // Gravity for bird - fine-tuned for better control
var jumpStrength = -9.5; // Jump strength for bird - fine-tuned for better balance
var pipeSpeed = -3.5; // Pipe movement speed - increased for better challenge
// Score display
var scoreText = new Text2('0', {
size: 120,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
scoreText.stroke = 0x000000;
scoreText.strokeThickness = 6;
scoreText.visible = false; // Initially hidden, shown when game starts
LK.gui.top.addChild(scoreText);
scoreText.y = 100; // Position below the top menu area
// Create cup shape for score
var cupShape = LK.getAsset('cup', {
anchorX: 0.5,
anchorY: 0
});
cupShape.tint = 0xFFD700;
LK.gui.bottomRight.addChild(cupShape);
cupShape.y = -230;
cupShape.x = -100;
// Create main menu elements
var mainMenuTitle = new Text2('FLAPPY BIRD', {
size: 90,
fill: 0xFFD700
});
mainMenuTitle.anchor.set(0.5, 0.5);
mainMenuTitle.stroke = 0x000000;
mainMenuTitle.strokeThickness = 5;
LK.gui.center.addChild(mainMenuTitle);
mainMenuTitle.y = -280;
// Create instruction text
var instructionTxt = new Text2('TIKLA VE OYNA!', {
size: 50,
fill: 0xFFFFFF
});
instructionTxt.anchor.set(0.5, 0.5);
instructionTxt.stroke = 0x000000;
instructionTxt.strokeThickness = 3;
instructionTxt.visible = false;
instructionTxt.y = -50;
// Remove background shape for instruction text - no longer needed
LK.gui.center.addChild(instructionTxt);
// Create game over screen elements
var gameOverBg = LK.getAsset('topPipe', {
anchorX: 0.5,
anchorY: 0.5,
width: 1600,
height: 1200,
alpha: 0.95
});
gameOverBg.tint = 0x2F4F4F;
gameOverBg.visible = false;
LK.gui.center.addChild(gameOverBg);
// Create high score screen elements
var highScoreBg = LK.getAsset('topPipe', {
anchorX: 0.5,
anchorY: 0.5,
width: 1400,
height: 800,
alpha: 0.95
});
highScoreBg.tint = 0x2F4F4F;
highScoreBg.visible = false;
LK.gui.center.addChild(highScoreBg);
var highScoreTitle = new Text2('EN YÜKSEK SKOR', {
size: 100,
fill: 0xFFD700
});
highScoreTitle.anchor.set(0.5, 0.5);
highScoreTitle.stroke = 0x000000;
highScoreTitle.strokeThickness = 5;
highScoreTitle.visible = false;
LK.gui.center.addChild(highScoreTitle);
highScoreTitle.y = -200;
var highScoreValue = new Text2('0', {
size: 150,
fill: 0xFFFFFF
});
highScoreValue.anchor.set(0.5, 0.5);
highScoreValue.stroke = 0x000000;
highScoreValue.strokeThickness = 6;
highScoreValue.visible = false;
LK.gui.center.addChild(highScoreValue);
highScoreValue.y = 0;
var highScoreCloseButton = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 300,
height: 80,
alpha: 1.0
});
highScoreCloseButton.tint = 0x7F8C8D;
highScoreCloseButton.visible = false;
LK.gui.center.addChild(highScoreCloseButton);
highScoreCloseButton.y = 200;
var highScoreCloseText = new Text2('KAPAT', {
size: 40,
fill: 0xFFFFFF
});
highScoreCloseText.anchor.set(0.5, 0.5);
highScoreCloseText.stroke = 0x566573;
highScoreCloseText.strokeThickness = 3;
highScoreCloseText.visible = false;
LK.gui.center.addChild(highScoreCloseText);
highScoreCloseText.y = 200;
var gameOverTitle = new Text2('OYUN BİTTİ', {
size: 120,
fill: 0xFFFFFF
});
gameOverTitle.anchor.set(0.5, 0.5);
gameOverTitle.stroke = 0x000000;
gameOverTitle.strokeThickness = 6;
gameOverTitle.visible = false;
LK.gui.center.addChild(gameOverTitle);
gameOverTitle.y = -300;
var finalScoreText = new Text2('SKOR: 0', {
size: 80,
fill: 0xFFFFFF
});
finalScoreText.anchor.set(0.5, 0.5);
finalScoreText.stroke = 0x000000;
finalScoreText.strokeThickness = 4;
finalScoreText.visible = false;
LK.gui.center.addChild(finalScoreText);
finalScoreText.y = -150;
var bestScoreText = new Text2('EN İYİ: 0', {
size: 60,
fill: 0xFFD700
});
bestScoreText.anchor.set(0.5, 0.5);
bestScoreText.stroke = 0x000000;
bestScoreText.strokeThickness = 3;
bestScoreText.visible = false;
LK.gui.center.addChild(bestScoreText);
bestScoreText.y = -50;
// Create retry button with enhanced styling
var retryButton = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 380,
height: 110,
alpha: 1.0
});
retryButton.tint = 0xFF9800; // Orange like original Flappy Bird
retryButton.visible = false;
LK.gui.center.addChild(retryButton);
retryButton.y = 100;
// Add retry button shadow for depth
var retryButtonShadow = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 380,
height: 110,
alpha: 0.3
});
retryButtonShadow.tint = 0xE65100; // Darker orange shadow
retryButtonShadow.visible = false;
LK.gui.center.addChild(retryButtonShadow);
retryButtonShadow.y = 108; // Offset shadow slightly down
retryButtonShadow.x = 4; // Offset shadow slightly right
// Add retry button highlight
var retryButtonHighlight = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 350,
height: 85,
alpha: 0.4
});
retryButtonHighlight.tint = 0xFFB74D; // Lighter orange highlight
retryButtonHighlight.visible = false;
LK.gui.center.addChild(retryButtonHighlight);
retryButtonHighlight.y = 92; // Offset highlight slightly up
var retryButtonText = new Text2('TEKRAR DENE', {
size: 44,
fill: 0xFFFFFF
});
retryButtonText.anchor.set(0.5, 0.5);
retryButtonText.stroke = 0xE65100;
retryButtonText.strokeThickness = 3;
retryButtonText.visible = false;
LK.gui.center.addChild(retryButtonText);
retryButtonText.y = 100;
// Create menu button with enhanced styling
var menuButton = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 380,
height: 110,
alpha: 1.0
});
menuButton.tint = 0xF44336; // Red like original Flappy Bird
menuButton.visible = false;
LK.gui.center.addChild(menuButton);
menuButton.y = 250;
// Add menu button shadow for depth
var menuButtonShadow = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 380,
height: 110,
alpha: 0.3
});
menuButtonShadow.tint = 0xD32F2F; // Darker red shadow
menuButtonShadow.visible = false;
LK.gui.center.addChild(menuButtonShadow);
menuButtonShadow.y = 258; // Offset shadow slightly down
menuButtonShadow.x = 4; // Offset shadow slightly right
// Add menu button highlight
var menuButtonHighlight = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 350,
height: 85,
alpha: 0.4
});
menuButtonHighlight.tint = 0xEF5350; // Lighter red highlight
menuButtonHighlight.visible = false;
LK.gui.center.addChild(menuButtonHighlight);
menuButtonHighlight.y = 242; // Offset highlight slightly up
var menuButtonText = new Text2('ANA MENÜ', {
size: 44,
fill: 0xFFFFFF
});
menuButtonText.anchor.set(0.5, 0.5);
menuButtonText.stroke = 0xD32F2F;
menuButtonText.strokeThickness = 3;
menuButtonText.visible = false;
LK.gui.center.addChild(menuButtonText);
menuButtonText.y = 250;
// Simple background setup
var background = game.addChild(LK.getAsset('background', {
anchorX: 0,
anchorY: 0
}));
background.x = 0;
background.y = 0;
background.scaleX = 2;
background.scaleY = 2;
// Create ground
ground = game.addChild(LK.getAsset('ground', {
anchorX: 0,
anchorY: 1
}));
ground.x = 0;
ground.y = 2732;
ground.tint = 0x654321;
// Create bird
bird = game.addChild(new Bird());
bird.x = 300;
bird.y = 1366;
// Pre-generate initial pipes function with better performance
function generateAllPipes() {
// Define safe boundaries for gap center to ensure both pipes have reasonable heights
var minGapY = 700; // Minimum gap center position for better clearance
var maxGapY = 1900; // Maximum gap center position for better clearance
// Generate initial set of pipes only - generate more as needed during gameplay
var initialPipesNeeded = 10; // Start with fewer pipes for better performance
var currentX = 2500; // Starting position to the right of screen since pipes move left
var pipeSpacing = 600; // Spacing between pipes
// Clear existing pipes first
for (var i = pipes.length - 1; i >= 0; i--) {
if (pipes[i] && typeof pipes[i].destroy === "function") {
pipes[i].destroy();
}
}
pipes = [];
for (var pipeIndex = 0; pipeIndex < initialPipesNeeded; pipeIndex++) {
var gapCenterY;
// Create varied random patterns with better distribution
var randomPattern = Math.random();
if (randomPattern < 0.4) {
// 40% chance for high gaps (easier to navigate)
gapCenterY = minGapY + Math.random() * 300;
} else if (randomPattern < 0.7) {
// 30% chance for middle gaps (moderate difficulty)
gapCenterY = 1000 + Math.random() * 500;
} else {
// 30% chance for low gaps (more challenging but still passable)
gapCenterY = maxGapY - Math.random() * 300;
}
// Ensure the gap stays within safe boundaries
gapCenterY = Math.max(minGapY, Math.min(maxGapY, gapCenterY));
var pipe = new Pipe(gapCenterY);
pipe.x = currentX;
pipe.passed = false;
pipes.push(pipe);
game.addChild(pipe);
// Move to next pipe position
currentX += pipeSpacing;
}
}
// Function to generate new pipes as needed during gameplay
function generateNewPipe() {
var minGapY = 700;
var maxGapY = 1900;
var pipeSpacing = 600;
// Find rightmost pipe position
var rightmostX = 2500;
for (var i = 0; i < pipes.length; i++) {
if (pipes[i] && pipes[i].x > rightmostX) {
rightmostX = pipes[i].x;
}
}
// Create new pipe to the right of the rightmost pipe
var newX = rightmostX + pipeSpacing;
var randomPattern = Math.random();
var gapCenterY;
if (randomPattern < 0.4) {
gapCenterY = minGapY + Math.random() * 300;
} else if (randomPattern < 0.7) {
gapCenterY = 1000 + Math.random() * 500;
} else {
gapCenterY = maxGapY - Math.random() * 300;
}
gapCenterY = Math.max(minGapY, Math.min(maxGapY, gapCenterY));
var pipe = new Pipe(gapCenterY);
pipe.x = newX;
pipe.passed = false;
pipes.push(pipe);
game.addChild(pipe);
}
// Reset game function
function resetGame() {
// Reset bird position
bird.x = 300;
bird.y = 1366;
bird.velocity = 0;
// Clear pipes
for (var i = pipes.length - 1; i >= 0; i--) {
if (pipes[i] && typeof pipes[i].destroy === "function") {
pipes[i].destroy();
}
}
pipes = [];
// Reset variables
gameStarted = false;
gameOver = false;
showGameOver = false;
// Hide game over screen
hideGameOverScreen();
LK.setScore(0);
// Reset score display
if (scoreText) {
scoreText.setText('0');
}
// Show main menu with smooth fade in
showMainMenu = true;
var menuElements = [{
element: mainMenuTitle,
targetAlpha: 1,
delay: 0
}, {
element: playButton,
targetAlpha: 1,
delay: 100
}, {
element: playButtonShadow,
targetAlpha: 0.4,
delay: 100
}, {
element: playButtonHighlight,
targetAlpha: 0.5,
delay: 100
}, {
element: playButtonText,
targetAlpha: 1,
delay: 100
}, {
element: cupShape,
targetAlpha: 1,
delay: 200
}, {
element: mainLanguageButton,
targetAlpha: 1,
delay: 300
}, {
element: mainLanguageButtonShadow,
targetAlpha: 0.3,
delay: 300
}, {
element: mainLanguageButtonHighlight,
targetAlpha: 0.4,
delay: 300
}, {
element: mainLanguageButtonText,
targetAlpha: 1,
delay: 300
}];
menuElements.forEach(function (item) {
if (item.element) {
item.element.alpha = 0;
item.element.visible = true;
LK.setTimeout(function () {
tween(item.element, {
alpha: item.targetAlpha
}, {
duration: 400,
easing: tween.easeOut
});
}, item.delay);
}
});
// Hide instruction
instructionTxt.visible = false;
// Hide score display
scoreText.visible = false;
generateAllPipes();
}
// Function to start game from main menu
function startGameFromMenu() {
showMainMenu = false;
// Fade out main menu elements smoothly
tween(mainMenuTitle, {
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
mainMenuTitle.visible = false;
mainMenuTitle.alpha = 1;
}
});
// Hide play button elements with fade
if (playButton) {
tween(playButton, {
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
playButton.visible = false;
playButton.alpha = 1;
}
});
}
if (playButtonShadow) {
tween(playButtonShadow, {
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
playButtonShadow.visible = false;
playButtonShadow.alpha = 0.4;
}
});
}
if (playButtonHighlight) {
tween(playButtonHighlight, {
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
playButtonHighlight.visible = false;
playButtonHighlight.alpha = 0.5;
}
});
}
if (playButtonText) {
tween(playButtonText, {
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
playButtonText.visible = false;
playButtonText.alpha = 1;
}
});
}
// Hide cup shape (high score indicator)
if (cupShape) {
tween(cupShape, {
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
cupShape.visible = false;
cupShape.alpha = 1;
}
});
}
// Hide main language button elements
if (mainLanguageButton) {
tween(mainLanguageButton, {
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
mainLanguageButton.visible = false;
mainLanguageButton.alpha = 1;
}
});
}
if (mainLanguageButtonShadow) {
tween(mainLanguageButtonShadow, {
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
mainLanguageButtonShadow.visible = false;
mainLanguageButtonShadow.alpha = 0.3;
}
});
}
if (mainLanguageButtonHighlight) {
tween(mainLanguageButtonHighlight, {
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
mainLanguageButtonHighlight.visible = false;
mainLanguageButtonHighlight.alpha = 0.4;
}
});
}
if (mainLanguageButtonText) {
tween(mainLanguageButtonText, {
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
mainLanguageButtonText.visible = false;
mainLanguageButtonText.alpha = 1;
}
});
}
// Show instruction and score with fade in
instructionTxt.alpha = 0;
instructionTxt.visible = true;
tween(instructionTxt, {
alpha: 1
}, {
duration: 400,
easing: tween.easeOut
});
scoreText.alpha = 0;
scoreText.visible = true;
scoreText.setText('0');
tween(scoreText, {
alpha: 1
}, {
duration: 400,
easing: tween.easeOut
});
}
// Function to show game over screen
function showGameOverScreen(finalScore) {
if (showGameOver) return;
showGameOver = true;
gameStarted = false;
// Hide all other menus first to prevent overlap
hideLanguageControls();
hideHighScoreScreen();
// Hide instruction and score with fade
tween(instructionTxt, {
alpha: 0
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
instructionTxt.visible = false;
instructionTxt.alpha = 1;
}
});
tween(scoreText, {
alpha: 0
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
scoreText.visible = false;
scoreText.alpha = 1;
}
});
// Show game over elements with smooth fade in
gameOverBg.alpha = 0;
gameOverBg.visible = true;
tween(gameOverBg, {
alpha: 0.95
}, {
duration: 400,
easing: tween.easeOut
});
gameOverTitle.alpha = 0;
gameOverTitle.visible = true;
tween(gameOverTitle, {
alpha: 1
}, {
duration: 500,
easing: tween.easeOut
});
finalScoreText.alpha = 0;
finalScoreText.visible = true;
// Update final score text
var currentScore = LK.getScore();
finalScoreText.setText(getText('score') + ': ' + currentScore);
tween(finalScoreText, {
alpha: 1
}, {
duration: 600,
easing: tween.easeOut
});
bestScoreText.alpha = 0;
bestScoreText.visible = true;
// Show buttons with staggered animation
retryButton.alpha = 0;
retryButton.visible = true;
retryButtonText.alpha = 0;
retryButtonText.visible = true;
retryButtonShadow.alpha = 0;
retryButtonShadow.visible = true;
retryButtonHighlight.alpha = 0;
retryButtonHighlight.visible = true;
menuButton.alpha = 0;
menuButton.visible = true;
menuButtonText.alpha = 0;
menuButtonText.visible = true;
menuButtonShadow.alpha = 0;
menuButtonShadow.visible = true;
menuButtonHighlight.alpha = 0;
menuButtonHighlight.visible = true;
// Remove score display - do not show final score
// Always show the current high score from persistent storage
var currentHighScore = storage.highScore || 0;
// Update high score if current score is higher
if (finalScore > currentHighScore) {
storage.highScore = finalScore;
currentHighScore = finalScore;
// Smooth visual feedback for new high score
if (bestScoreText && bestScoreText.visible) {
tween(bestScoreText, {
tint: 0xFF0000
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(bestScoreText, {
tint: 0xFFD700
}, {
duration: 300,
easing: tween.easeOut
});
}
});
}
}
bestScoreText.setText(getText('bestScore') + ': ' + currentHighScore);
tween(bestScoreText, {
alpha: 1
}, {
duration: 700,
easing: tween.easeOut
});
// Use proper text sizing
if (bestScoreText.width > 600) {
var newSize = Math.max(40, Math.floor(60 * 600 / bestScoreText.width));
bestScoreText.style = {
size: newSize,
fill: bestScoreText.style.fill
};
}
// Animate buttons in with delay
LK.setTimeout(function () {
tween(retryButton, {
alpha: 1
}, {
duration: 300,
easing: tween.easeOut
});
tween(retryButtonShadow, {
alpha: 0.3
}, {
duration: 300,
easing: tween.easeOut
});
tween(retryButtonHighlight, {
alpha: 0.4
}, {
duration: 300,
easing: tween.easeOut
});
tween(retryButtonText, {
alpha: 1
}, {
duration: 300,
easing: tween.easeOut
});
}, 400);
LK.setTimeout(function () {
tween(menuButton, {
alpha: 1
}, {
duration: 300,
easing: tween.easeOut
});
tween(menuButtonShadow, {
alpha: 0.3
}, {
duration: 300,
easing: tween.easeOut
});
tween(menuButtonHighlight, {
alpha: 0.4
}, {
duration: 300,
easing: tween.easeOut
});
tween(menuButtonText, {
alpha: 1
}, {
duration: 300,
easing: tween.easeOut
});
}, 600);
}
// Function to hide game over screen
function hideGameOverScreen() {
showGameOver = false;
// Fade out game over elements smoothly
var elementsToHide = [gameOverBg, gameOverTitle, finalScoreText, bestScoreText, retryButton, retryButtonText, retryButtonShadow, retryButtonHighlight, menuButton, menuButtonText, menuButtonShadow, menuButtonHighlight];
elementsToHide.forEach(function (element) {
if (element && element.visible) {
tween(element, {
alpha: 0
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
element.visible = false;
element.alpha = element === gameOverBg ? 0.95 : element === retryButtonShadow || element === menuButtonShadow ? 0.3 : element === retryButtonHighlight || element === menuButtonHighlight ? 0.4 : 1;
}
});
}
});
}
// Function to show high score screen
function showHighScoreScreen() {
// Hide any other screens to prevent overlap
hideGameOverScreen();
hideLanguageControls();
// Hide main menu elements first to prevent overlap
if (showMainMenu) {
tween(mainMenuTitle, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
mainMenuTitle.visible = false;
mainMenuTitle.alpha = 1;
}
});
if (playButton) {
tween(playButton, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
playButton.visible = false;
playButton.alpha = 1;
}
});
}
if (playButtonShadow) {
tween(playButtonShadow, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
playButtonShadow.visible = false;
playButtonShadow.alpha = 0.4;
}
});
}
if (playButtonHighlight) {
tween(playButtonHighlight, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
playButtonHighlight.visible = false;
playButtonHighlight.alpha = 0.5;
}
});
}
if (playButtonText) {
tween(playButtonText, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
playButtonText.visible = false;
playButtonText.alpha = 1;
}
});
}
if (mainLanguageButton) {
tween(mainLanguageButton, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
mainLanguageButton.visible = false;
mainLanguageButton.alpha = 1;
}
});
}
if (mainLanguageButtonShadow) {
tween(mainLanguageButtonShadow, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
mainLanguageButtonShadow.visible = false;
mainLanguageButtonShadow.alpha = 0.3;
}
});
}
if (mainLanguageButtonHighlight) {
tween(mainLanguageButtonHighlight, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
mainLanguageButtonHighlight.visible = false;
mainLanguageButtonHighlight.alpha = 0.4;
}
});
}
if (mainLanguageButtonText) {
tween(mainLanguageButtonText, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
mainLanguageButtonText.visible = false;
mainLanguageButtonText.alpha = 1;
}
});
}
}
// Update high score value
var currentHighScore = storage.highScore || 0;
highScoreValue.setText(currentHighScore.toString());
highScoreTitle.setText(getText('highestScore'));
highScoreCloseText.setText(getText('close') || 'KAPAT');
// Show high score elements with fade in
var highScoreElements = [{
element: highScoreBg,
targetAlpha: 0.95,
delay: 0
}, {
element: highScoreTitle,
targetAlpha: 1,
delay: 100
}, {
element: highScoreValue,
targetAlpha: 1,
delay: 200
}, {
element: highScoreCloseButton,
targetAlpha: 1,
delay: 300
}, {
element: highScoreCloseText,
targetAlpha: 1,
delay: 300
}];
highScoreElements.forEach(function (item) {
if (item.element) {
item.element.alpha = 0;
item.element.visible = true;
LK.setTimeout(function () {
tween(item.element, {
alpha: item.targetAlpha
}, {
duration: 300,
easing: tween.easeOut
});
}, item.delay);
}
});
}
// Function to hide high score screen
function hideHighScoreScreen() {
// Fade out high score elements
var highScoreElements = [highScoreBg, highScoreTitle, highScoreValue, highScoreCloseButton, highScoreCloseText];
var fadeOutCompleted = 0;
highScoreElements.forEach(function (element) {
if (element && element.visible) {
tween(element, {
alpha: 0
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
element.visible = false;
element.alpha = element === highScoreBg ? 0.95 : 1;
fadeOutCompleted++;
// Show main menu after all high score elements have faded out
if (fadeOutCompleted === highScoreElements.length && showMainMenu && !showGameOver && !gameOverBg.visible && !languageOverlay.visible) {
// Fade in main menu elements
var menuElements = [mainMenuTitle, playButton, playButtonShadow, playButtonHighlight, playButtonText, mainLanguageButton, mainLanguageButtonShadow, mainLanguageButtonHighlight, mainLanguageButtonText];
menuElements.forEach(function (menuElement, index) {
if (menuElement) {
menuElement.alpha = 0;
menuElement.visible = true;
tween(menuElement, {
alpha: menuElement === playButtonShadow ? 0.4 : menuElement === playButtonHighlight ? 0.5 : menuElement === mainLanguageButtonShadow ? 0.3 : menuElement === mainLanguageButtonHighlight ? 0.4 : 1
}, {
duration: 300,
delay: index * 30,
easing: tween.easeOut
});
}
});
}
}
});
}
});
}
// Create language overlay background
var languageOverlay = LK.getAsset('topPipe', {
anchorX: 0.5,
anchorY: 0.5,
width: 2048,
height: 2732,
alpha: 1.0
});
languageOverlay.tint = 0x2F4F4F;
languageOverlay.visible = false;
LK.gui.center.addChild(languageOverlay);
// Create language control title
var languageTitle = new Text2('DİL SEÇENEKLERİ', {
size: 80,
fill: 0xFFFFFF
});
languageTitle.anchor.set(0.5, 0.5);
languageTitle.stroke = 0x000000;
languageTitle.strokeThickness = 4;
languageTitle.visible = false;
LK.gui.center.addChild(languageTitle);
languageTitle.y = -200;
// Create language option buttons with modern rectangular design
var turkishButton = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 260,
height: 65,
alpha: 1.0
});
turkishButton.tint = 0x27AE60;
turkishButton.visible = false;
LK.gui.center.addChild(turkishButton);
turkishButton.y = -80;
turkishButton.x = -220;
// Add Turkish button shadow
var turkishButtonShadow = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 260,
height: 65,
alpha: 0.3
});
turkishButtonShadow.tint = 0x1E8449;
turkishButtonShadow.visible = false;
LK.gui.center.addChild(turkishButtonShadow);
turkishButtonShadow.y = -75;
turkishButtonShadow.x = -217;
// Add Turkish button highlight
var turkishButtonHighlight = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 240,
height: 50,
alpha: 0.4
});
turkishButtonHighlight.tint = 0x58D68D;
turkishButtonHighlight.visible = false;
LK.gui.center.addChild(turkishButtonHighlight);
turkishButtonHighlight.y = -85;
turkishButtonHighlight.x = -220;
var turkishText = new Text2('TÜRKÇE', {
size: 32,
fill: 0xFFFFFF
});
turkishText.anchor.set(0.5, 0.5);
turkishText.stroke = 0x1E8449;
turkishText.strokeThickness = 2;
turkishText.visible = false;
LK.gui.center.addChild(turkishText);
turkishText.y = -80;
turkishText.x = -220;
var englishButton = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 260,
height: 65,
alpha: 1.0
});
englishButton.tint = 0x3498DB;
englishButton.visible = false;
LK.gui.center.addChild(englishButton);
englishButton.y = -80;
englishButton.x = 220;
// Add English button shadow
var englishButtonShadow = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 260,
height: 65,
alpha: 0.3
});
englishButtonShadow.tint = 0x2980B9;
englishButtonShadow.visible = false;
LK.gui.center.addChild(englishButtonShadow);
englishButtonShadow.y = -75;
englishButtonShadow.x = 223;
// Add English button highlight
var englishButtonHighlight = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 240,
height: 50,
alpha: 0.4
});
englishButtonHighlight.tint = 0x85C1E9;
englishButtonHighlight.visible = false;
LK.gui.center.addChild(englishButtonHighlight);
englishButtonHighlight.y = -85;
englishButtonHighlight.x = 220;
var englishText = new Text2('ENGLISH', {
size: 32,
fill: 0xFFFFFF
});
englishText.anchor.set(0.5, 0.5);
englishText.stroke = 0x2980B9;
englishText.strokeThickness = 2;
englishText.visible = false;
LK.gui.center.addChild(englishText);
englishText.y = -80;
englishText.x = 220;
// Current language indicator
var currentLanguageText = new Text2('MEVCUT: TÜRKÇE', {
size: 50,
fill: 0xFFD700
});
currentLanguageText.anchor.set(0.5, 0.5);
currentLanguageText.stroke = 0x000000;
currentLanguageText.strokeThickness = 3;
currentLanguageText.visible = false;
LK.gui.center.addChild(currentLanguageText);
currentLanguageText.y = 30;
// Create back button for language controls with modern rectangular design
var languageBackButton = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 220,
height: 65,
alpha: 1.0
});
languageBackButton.tint = 0x7F8C8D;
languageBackButton.visible = false;
LK.gui.center.addChild(languageBackButton);
languageBackButton.y = 150;
// Add language back button shadow
var languageBackButtonShadow = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 220,
height: 65,
alpha: 0.3
});
languageBackButtonShadow.tint = 0x566573;
languageBackButtonShadow.visible = false;
LK.gui.center.addChild(languageBackButtonShadow);
languageBackButtonShadow.y = 155;
languageBackButtonShadow.x = 3;
// Add language back button highlight
var languageBackButtonHighlight = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 200,
height: 50,
alpha: 0.4
});
languageBackButtonHighlight.tint = 0xABB2B9;
languageBackButtonHighlight.visible = false;
LK.gui.center.addChild(languageBackButtonHighlight);
languageBackButtonHighlight.y = 145;
var languageBackText = new Text2('GERİ', {
size: 36,
fill: 0xFFFFFF
});
languageBackText.anchor.set(0.5, 0.5);
languageBackText.stroke = 0x566573;
languageBackText.strokeThickness = 2;
languageBackText.visible = false;
LK.gui.center.addChild(languageBackText);
languageBackText.y = 150;
// Function to show language controls
function showLanguageControls() {
// Hide all other menus first to prevent overlap
hideGameOverScreen();
hideHighScoreScreen();
// Hide main menu elements with fade
tween(mainMenuTitle, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
mainMenuTitle.visible = false;
mainMenuTitle.alpha = 1;
}
});
if (playButton) {
tween(playButton, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
playButton.visible = false;
playButton.alpha = 1;
}
});
}
if (playButtonShadow) {
tween(playButtonShadow, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
playButtonShadow.visible = false;
playButtonShadow.alpha = 0.4;
}
});
}
if (playButtonHighlight) {
tween(playButtonHighlight, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
playButtonHighlight.visible = false;
playButtonHighlight.alpha = 0.5;
}
});
}
if (playButtonText) {
tween(playButtonText, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
playButtonText.visible = false;
playButtonText.alpha = 1;
}
});
}
if (cupShape) {
tween(cupShape, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
cupShape.visible = false;
cupShape.alpha = 1;
}
});
}
// Hide main language button elements
if (mainLanguageButton) {
tween(mainLanguageButton, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
mainLanguageButton.visible = false;
mainLanguageButton.alpha = 1;
}
});
}
if (mainLanguageButtonShadow) {
tween(mainLanguageButtonShadow, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
mainLanguageButtonShadow.visible = false;
mainLanguageButtonShadow.alpha = 0.3;
}
});
}
if (mainLanguageButtonHighlight) {
tween(mainLanguageButtonHighlight, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
mainLanguageButtonHighlight.visible = false;
mainLanguageButtonHighlight.alpha = 0.4;
}
});
}
if (mainLanguageButtonText) {
tween(mainLanguageButtonText, {
alpha: 0
}, {
duration: 250,
easing: tween.easeOut,
onFinish: function onFinish() {
mainLanguageButtonText.visible = false;
mainLanguageButtonText.alpha = 1;
}
});
}
// Show language controls with smooth fade in
languageOverlay.alpha = 0;
languageOverlay.visible = true;
tween(languageOverlay, {
alpha: 1
}, {
duration: 350,
easing: tween.easeOut
});
languageTitle.alpha = 0;
languageTitle.visible = true;
tween(languageTitle, {
alpha: 1
}, {
duration: 400,
easing: tween.easeOut
});
// Show language buttons with staggered animation
turkishButton.alpha = 0;
turkishButton.visible = true;
turkishButtonShadow.alpha = 0;
turkishButtonShadow.visible = true;
turkishButtonHighlight.alpha = 0;
turkishButtonHighlight.visible = true;
turkishText.alpha = 0;
turkishText.visible = true;
englishButton.alpha = 0;
englishButton.visible = true;
englishButtonShadow.alpha = 0;
englishButtonShadow.visible = true;
englishButtonHighlight.alpha = 0;
englishButtonHighlight.visible = true;
englishText.alpha = 0;
englishText.visible = true;
currentLanguageText.alpha = 0;
currentLanguageText.visible = true;
languageBackButton.alpha = 0;
languageBackButton.visible = true;
languageBackButtonShadow.alpha = 0;
languageBackButtonShadow.visible = true;
languageBackButtonHighlight.alpha = 0;
languageBackButtonHighlight.visible = true;
languageBackText.alpha = 0;
languageBackText.visible = true;
// Animate language buttons in with delays
LK.setTimeout(function () {
tween(turkishButton, {
alpha: 1
}, {
duration: 300,
easing: tween.easeOut
});
tween(turkishButtonShadow, {
alpha: 0.3
}, {
duration: 300,
easing: tween.easeOut
});
tween(turkishButtonHighlight, {
alpha: 0.4
}, {
duration: 300,
easing: tween.easeOut
});
tween(turkishText, {
alpha: 1
}, {
duration: 300,
easing: tween.easeOut
});
}, 200);
LK.setTimeout(function () {
tween(englishButton, {
alpha: 1
}, {
duration: 300,
easing: tween.easeOut
});
tween(englishButtonShadow, {
alpha: 0.3
}, {
duration: 300,
easing: tween.easeOut
});
tween(englishButtonHighlight, {
alpha: 0.4
}, {
duration: 300,
easing: tween.easeOut
});
tween(englishText, {
alpha: 1
}, {
duration: 300,
easing: tween.easeOut
});
}, 350);
LK.setTimeout(function () {
tween(currentLanguageText, {
alpha: 1
}, {
duration: 300,
easing: tween.easeOut
});
}, 500);
LK.setTimeout(function () {
tween(languageBackButton, {
alpha: 1
}, {
duration: 300,
easing: tween.easeOut
});
tween(languageBackButtonShadow, {
alpha: 0.3
}, {
duration: 300,
easing: tween.easeOut
});
tween(languageBackButtonHighlight, {
alpha: 0.4
}, {
duration: 300,
easing: tween.easeOut
});
tween(languageBackText, {
alpha: 1
}, {
duration: 300,
easing: tween.easeOut
});
}, 650);
updateLanguageDisplay();
}
// Function to hide language controls
function hideLanguageControls() {
// Fade out all language control elements
var languageElements = [languageOverlay, languageTitle, turkishButton, turkishButtonShadow, turkishButtonHighlight, turkishText, englishButton, englishButtonShadow, englishButtonHighlight, englishText, currentLanguageText, languageBackButton, languageBackButtonShadow, languageBackButtonHighlight, languageBackText];
var fadeOutDuration = 250;
var fadeOutCompleted = 0;
languageElements.forEach(function (element) {
if (element && element.visible) {
tween(element, {
alpha: 0
}, {
duration: fadeOutDuration,
easing: tween.easeOut,
onFinish: function onFinish() {
element.visible = false;
element.alpha = element === languageOverlay ? 1 : element === turkishButtonShadow || element === englishButtonShadow || element === languageBackButtonShadow ? 0.3 : element === turkishButtonHighlight || element === englishButtonHighlight || element === languageBackButtonHighlight ? 0.4 : 1;
fadeOutCompleted++;
// Show main menu after all elements have faded out
if (fadeOutCompleted === languageElements.length && showMainMenu && !showGameOver && !gameOverBg.visible && !highScoreBg.visible) {
// Fade in main menu elements
var menuElements = [mainMenuTitle, playButton, playButtonShadow, playButtonHighlight, playButtonText, cupShape, mainLanguageButton, mainLanguageButtonShadow, mainLanguageButtonHighlight, mainLanguageButtonText];
menuElements.forEach(function (menuElement, index) {
if (menuElement) {
menuElement.alpha = 0;
menuElement.visible = true;
tween(menuElement, {
alpha: menuElement === playButtonShadow ? 0.4 : menuElement === playButtonHighlight ? 0.5 : menuElement === mainLanguageButtonShadow ? 0.3 : menuElement === mainLanguageButtonHighlight ? 0.4 : 1
}, {
duration: 300,
delay: index * 30,
easing: tween.easeOut
});
}
});
}
}
});
}
});
}
// Language text objects
var languageTexts = {
tr: {
mainTitle: 'FLAPPY BIRD',
playButton: 'OYNA',
instruction: 'TIKLA VE OYNA!',
gameOver: 'OYUN BİTTİ',
score: 'SKOR',
bestScore: 'EN İYİ',
retry: 'TEKRAR DENE',
mainMenu: 'ANA MENÜ',
language: 'DİL',
languageTitle: 'DİL SEÇENEKLERİ',
current: 'MEVCUT',
highestScore: 'EN YÜKSEK SKOR',
back: 'GERİ',
close: 'KAPAT'
},
en: {
mainTitle: 'FLAPPY BIRD',
playButton: 'PLAY',
instruction: 'CLICK TO PLAY!',
gameOver: 'GAME OVER',
score: 'SCORE',
bestScore: 'BEST',
retry: 'RETRY',
mainMenu: 'MAIN MENU',
language: 'LANGUAGE',
languageTitle: 'LANGUAGE OPTIONS',
current: 'CURRENT',
highestScore: 'HIGHEST SCORE',
back: 'BACK',
close: 'CLOSE'
}
};
// Function to get text for current language
function getText(key) {
return languageTexts[currentLanguage][key] || languageTexts['en'][key];
}
// Function to update all text elements to current language
function updateAllTexts() {
if (instructionTxt) {
instructionTxt.setText(getText('instruction'));
}
if (playButtonText) {
playButtonText.setText(getText('playButton'));
}
if (gameOverTitle) {
gameOverTitle.setText(getText('gameOver'));
}
if (retryButtonText) {
retryButtonText.setText(getText('retry'));
}
if (menuButtonText) {
menuButtonText.setText(getText('mainMenu'));
}
if (languageTitle) {
languageTitle.setText(getText('languageTitle'));
}
if (languageBackText) {
languageBackText.setText(getText('back'));
}
if (mainLanguageButtonText) {
mainLanguageButtonText.setText(getText('language'));
}
// Update final and best score texts
if (finalScoreText) {
var currentScore = LK.getScore();
finalScoreText.setText(getText('score') + ': ' + currentScore);
}
if (bestScoreText) {
var currentHighScore = storage.highScore || 0;
bestScoreText.setText(getText('bestScore') + ': ' + currentHighScore);
}
}
// Function to update language display
function updateLanguageDisplay() {
var langText = currentLanguage === 'tr' ? 'TÜRKÇE' : 'ENGLISH';
var currentText = currentLanguage === 'tr' ? 'MEVCUT' : 'CURRENT';
if (currentLanguageText) {
currentLanguageText.setText(currentText + ': ' + langText);
}
// Update button colors to show selected language
if (turkishButton) {
turkishButton.tint = currentLanguage === 'tr' ? 0x2ECC71 : 0x27AE60;
}
if (englishButton) {
englishButton.tint = currentLanguage === 'en' ? 0x5DADE2 : 0x3498DB;
}
}
// Function to set language
function setLanguage(lang) {
currentLanguage = lang;
// Save to persistent storage
storage.language = lang;
// Update all text elements immediately
updateAllTexts();
// Update language display
updateLanguageDisplay();
}
// Initialize persistent storage with defaults if values don't exist
if (typeof storage.highScore === 'undefined') storage.highScore = 0;
if (typeof storage.lastScore === 'undefined') storage.lastScore = 0;
if (!storage.language) storage.language = 'tr';
// Update current language from persistent storage
currentLanguage = storage.language || 'tr';
// Create animated play button for main menu
var playButton = LK.getAsset('playButtonMain', {
anchorX: 0.5,
anchorY: 0.5,
width: 400,
height: 120,
alpha: 1.0
});
playButton.tint = 0xFF9800; // Flappy Bird orange
LK.gui.center.addChild(playButton);
playButton.y = -100;
// Create language button for direct access from main menu
var mainLanguageButton = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 300,
height: 80,
alpha: 1.0
});
mainLanguageButton.tint = 0x9B59B6;
LK.gui.center.addChild(mainLanguageButton);
mainLanguageButton.y = 50;
// Create language button shadow
var mainLanguageButtonShadow = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 300,
height: 80,
alpha: 0.3
});
mainLanguageButtonShadow.tint = 0x8E44AD;
LK.gui.center.addChild(mainLanguageButtonShadow);
mainLanguageButtonShadow.y = 55;
mainLanguageButtonShadow.x = 3;
// Create language button highlight
var mainLanguageButtonHighlight = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 280,
height: 65,
alpha: 0.4
});
mainLanguageButtonHighlight.tint = 0xBB8FCE;
LK.gui.center.addChild(mainLanguageButtonHighlight);
mainLanguageButtonHighlight.y = 45;
// Create language button text
var mainLanguageButtonText = new Text2('DİL', {
size: 36,
fill: 0xFFFFFF
});
mainLanguageButtonText.anchor.set(0.5, 0.5);
mainLanguageButtonText.stroke = 0x8E44AD;
mainLanguageButtonText.strokeThickness = 2;
LK.gui.center.addChild(mainLanguageButtonText);
mainLanguageButtonText.y = 50;
// Create separate play button shadow element
var playButtonShadow = LK.getAsset('playButtonShadow', {
anchorX: 0.5,
anchorY: 0.5,
width: 400,
height: 120,
alpha: 0.4
});
playButtonShadow.tint = 0xE65100; // Darker orange shadow
LK.gui.center.addChild(playButtonShadow);
playButtonShadow.y = -92; // Offset shadow slightly up
playButtonShadow.x = 4; // Offset shadow slightly right
// Create separate play button highlight element
var playButtonHighlight = LK.getAsset('playButtonHighlight', {
anchorX: 0.5,
anchorY: 0.5,
width: 370,
height: 95,
alpha: 0.5
});
playButtonHighlight.tint = 0xFFB74D; // Lighter orange highlight
LK.gui.center.addChild(playButtonHighlight);
playButtonHighlight.y = -108; // Offset highlight slightly down
// Create separate play button text element
var playButtonText = new Text2('OYNA', {
size: 50,
fill: 0xFFFFFF
});
playButtonText.anchor.set(0.5, 0.5);
playButtonText.stroke = 0xE65100;
playButtonText.strokeThickness = 4;
LK.gui.center.addChild(playButtonText);
playButtonText.y = -100;
// Initialize game
resetGame(); // Use resetGame to properly initialize all states
// Update all texts to current language
updateAllTexts();
// Update language display to show current selection
updateLanguageDisplay();
// Touch/click handler
game.down = function (x, y, obj) {
// Check if high score screen is visible
if (highScoreBg.visible) {
// Check close button click - centered at 1024x1566 (center.y = 1366 + 200), button is 300x80
if (x >= 874 && x <= 1174 && y >= 1526 && y <= 1606) {
// Simple visual feedback
simpleColorTint(highScoreCloseButton, 0xABB2B9, 0);
hideHighScoreScreen();
return;
}
return; // Don't process other clicks when high score screen is open
}
// Check if language overlay is visible and handle language controls
if (languageOverlay.visible) {
// Turkish language button with isolated click area
if (turkishButton.visible && x >= 654 && x <= 954 && y >= 1246 && y <= 1326) {
// Simple visual feedback with color change
simpleColorTint(turkishButton, 0x58D68D, 0);
setLanguage('tr');
return;
}
// Barrier zone between Turkish and English buttons (x: 954-1094)
if (x >= 954 && x <= 1094 && y >= 1246 && y <= 1326) {
return; // Block clicks in barrier zone
}
// English language button with isolated click area
if (englishButton.visible && x >= 1094 && x <= 1394 && y >= 1246 && y <= 1326) {
// Simple visual feedback with color change
simpleColorTint(englishButton, 0x85C1E9, 0);
setLanguage('en');
return;
}
// Check language back button at x = 1024, y = 1516, size 300x100
if (languageBackButton.visible && x >= 874 && x <= 1174 && y >= 1466 && y <= 1566) {
// Simple visual feedback with color change
simpleColorTint(languageBackButton, 0xABB2B9, 0);
hideLanguageControls();
return;
}
return; // Don't process other clicks when language overlay is open
}
// Check cup click - cup is positioned at bottomRight with offset
var cupX = 2048 - 100; // bottomRight.x + cupShape.x offset
var cupY = 2732 - 230; // bottomRight.y + cupShape.y offset
var cupSize = 120; // Cup asset size
if (x >= cupX - cupSize / 2 && x <= cupX + cupSize / 2 && y >= cupY && y <= cupY + cupSize) {
// Show high score screen
showHighScoreScreen();
// Simple visual feedback without animation
if (cupShape) {
cupShape.tint = 0xFFFFFF;
cupShape.tint = 0xFFD700;
}
return;
}
if (gameOver || showGameOver) {
// Check retry button (TEKRAR DENE) - centered at 1024x1466, button is 380x110
if (x >= 834 && x <= 1214 && y >= 1411 && y <= 1521) {
// Simple visual feedback with color change
simpleColorTint(retryButton, 0xFFB74D, 150, function () {
// Fade out game over screen first
hideGameOverScreen();
// Wait for fade out to complete before resetting
LK.setTimeout(function () {
resetGame();
// Show instruction screen instead of starting game directly
startGameFromMenu();
}, 250);
});
return;
}
// Check menu button (ANA MENÜ) - centered at 1024x1616, button is 380x110
if (x >= 834 && x <= 1214 && y >= 1561 && y <= 1671) {
// Simple visual feedback with color change
simpleColorTint(menuButton, 0xF1948A, 150, function () {
// Fade out game over screen first
hideGameOverScreen();
// Wait for fade out to complete before resetting
LK.setTimeout(function () {
resetGame();
}, 250);
});
return;
}
return;
}
if (showMainMenu) {
// Check play button click - centered at 1024x1266 (center.y = 1366 + playButton.y = -100), button is 400x120
if (playButton && playButton.visible && x >= 824 && x <= 1224 && y >= 1206 && y <= 1326) {
// Simple visual feedback with color change
simpleColorTint(playButton, 0xFFB74D, 0);
startGameFromMenu();
return;
}
// Check main language button click - centered at 1024x1416 (center.y = 1366 + mainLanguageButton.y = 50), button is 300x80
if (mainLanguageButton && mainLanguageButton.visible && x >= 874 && x <= 1174 && y >= 1376 && y <= 1456) {
// Simple visual feedback with color change
simpleColorTint(mainLanguageButton, 0xBB8FCE, 0);
showLanguageControls();
return;
}
return;
}
if (!gameStarted) {
gameStarted = true;
instructionTxt.visible = false;
}
bird.flap();
};
// Main game loop with optimized performance
game.update = function () {
if (gameOver || showMainMenu || showGameOver) return;
// Only run game logic if game has started
if (gameStarted) {
// Check ground and ceiling collision with proper bird size (bird is 80px tall, 120px wide)
var birdRadius = 40; // Half of bird height for collision detection
if (bird.y + birdRadius >= ground.y || bird.y - birdRadius <= 0) {
gameOver = true;
var currentScore = LK.getScore();
// Save score to persistent storage
if (currentScore > (storage.highScore || 0)) {
storage.highScore = currentScore;
}
storage.lastScore = currentScore;
// Add smooth transition to game over
tween(instructionTxt, {
alpha: 0
}, {
duration: 200,
easing: tween.easeOut
});
tween(scoreText, {
alpha: 0
}, {
duration: 200,
easing: tween.easeOut
});
LK.setTimeout(function () {
showGameOverScreen(LK.getScore());
}, 200);
return;
}
// Dynamic pipe generation - generate new pipes as old ones are removed
var rightmostPipeX = -1000;
for (var i = 0; i < pipes.length; i++) {
if (pipes[i] && pipes[i].x > rightmostPipeX) {
rightmostPipeX = pipes[i].x;
}
}
// Generate new pipe if the rightmost pipe is getting close to the screen
if (rightmostPipeX < 3000) {
generateNewPipe();
}
// Optimized pipe cleanup - remove pipes that are far behind only
for (var i = pipes.length - 1; i >= 0; i--) {
var pipe = pipes[i];
// Only remove pipes that are far behind the bird
if (pipe && pipe.x < bird.x - 800) {
pipe.destroy();
pipes.splice(i, 1);
}
}
// Find closest pipe for collision and scoring
var closestPipe = null;
var closestDistance = 99999;
for (var i = 0; i < pipes.length; i++) {
var pipe = pipes[i];
// Check pipes that are close to the bird
if (pipe && pipe.x > bird.x - 100 && pipe.x < bird.x + 200) {
var distance = Math.abs(pipe.x - bird.x);
if (distance < closestDistance) {
closestDistance = distance;
closestPipe = pipe;
}
}
}
if (closestPipe) {
// Initialize lastX tracking
if (typeof closestPipe.lastX === 'undefined') {
closestPipe.lastX = closestPipe.x;
}
// Scoring check - detect when bird passes through the pipe center
// Since pipes move from right to left and bird stays at x=300, check when pipe center passes bird
var pipeCenter = closestPipe.x;
var birdPosition = bird.x;
// Check if pipe center just passed the bird position (was on right, now on left)
if (!closestPipe.passed && closestPipe.lastX > birdPosition && pipeCenter <= birdPosition) {
// Check if bird is within the gap when pipe passes
var gapTop = closestPipe.gapCenterY - closestPipe.gapSize / 2;
var gapBottom = closestPipe.gapCenterY + closestPipe.gapSize / 2;
// Mark pipe as passed
if (bird.y > gapTop && bird.y < gapBottom) {
closestPipe.passed = true;
// Increment score
LK.setScore(LK.getScore() + 1);
var currentScore = LK.getScore();
// Update score display with smooth animation
if (scoreText && scoreText.visible) {
scoreText.setText(currentScore.toString());
// Smooth score flash animation
tween(scoreText, {
tint: 0xFFD700
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(scoreText, {
tint: 0xFFFFFF
}, {
duration: 200,
easing: tween.easeOut
});
}
});
}
// Save high score if current score is higher
if (currentScore > (storage.highScore || 0)) {
storage.highScore = currentScore;
}
// Check win condition - game ends at 100 points for better gameplay
if (currentScore >= 100) {
gameOver = true;
storage.lastScore = currentScore;
LK.showYouWin(); // Show win screen when reaching 100 points
return;
}
if (LK.getSound('score')) {
LK.getSound('score').play();
}
}
}
// Update last position
closestPipe.lastX = closestPipe.x;
// Collision check - only if very close with better collision detection
if (closestPipe.x > bird.x - 80 && closestPipe.x < bird.x + 80) {
var gapTop = closestPipe.gapCenterY - closestPipe.gapSize / 2;
var gapBottom = closestPipe.gapCenterY + closestPipe.gapSize / 2;
// More forgiving collision detection
if (bird.y < gapTop + 60 || bird.y > gapBottom - 60) {
gameOver = true;
// Add smooth transition before showing game over
tween(instructionTxt, {
alpha: 0
}, {
duration: 200,
easing: tween.easeOut
});
tween(scoreText, {
alpha: 0
}, {
duration: 200,
easing: tween.easeOut
});
LK.setTimeout(function () {
showGameOverScreen(LK.getScore());
}, 200);
return;
}
}
}
}
};