User prompt
Kuş doğduğu gibi duvara çarpıyor.
User prompt
Kuşu bariyerin önünde direk başlatma. Kuşu onu önüne al ve bariyerler arası mesafeyi kısalt.
User prompt
Kasmaya sebep olan ne varsa kaldır baştan düzgün hale getir.
User prompt
Kuşun önünde oluşan duvarlar direkt dibinde olmasın. Çok az bir boşluk olsun. Çok az. Yani böyle bir süre havada süzülsün sonra ortaya çıksın.
User prompt
Niye arkasında onu bir duvar takip ediyor? Kaldır!
User prompt
Kuşun yaptığı boş hareketler ve boş animasyonlarını kaldır. Stabil, normal bir hale getir. Arkasındaki onu takip eden duvarı da kaldır.
User prompt
Kuş hareket ederken aşırı donuyor, kasıyor.
User prompt
Oyun kendi kendine puan veriyor, kasıyor, demek ki tüm duvarları ve her şey bir anda algılıyor, bunu düzelt.
User prompt
Oyunun 1000 duvardan sonrasına oluşmasına izin verme. Oyun hani 1000 olunca bitiyor ya. Fazladan tekrar eden kodları da sil.
User prompt
Sən Allah aşqına, kuşun yanına direk bariyer qoysan, duvar, yəni şu arasından geçdiyimiz duvarlar direk kuşun yanında başlasın, aralıqlarını da qısalt, aşırı qısalt.
User prompt
Duvarlar birbirine aşırı uzak.
User prompt
Gereksiz artık kullanmadığımız tüm kodları sil, oyunu bozma, herhangi birşeyi kaldırma.
User prompt
Kuşu daha çok sağ tarafa al ortala tam ortada dursun ve gidebileceğimiz max puan 1000 olsun 1000 den sonra oyun bitsin
User prompt
Bu arada en fazla kazanabileceğimiz puan yani 1000 olsun 1000 yaptıktan sonra oyun bitsin ve kazandınız diye bir kutlama efekti gelsin. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
hani bir boru arasından geçtiğimizde puan kazanıyoruz ya bir puan kazanmak aşırı uzun sürüyor oradaki boşluğu azalt bir boru ile diğer boru arasındaki mesafe 3 zıplama 2 zıplama gibi bir şey olsun yani
User prompt
sen borular arasındaki boşlukları eğer azaltıp çoğaltıyorsan burada sinir krizi geçireceksin. ben sana diyorum ki mesela bir boru ile diğer boru arasındaki boşluk yani gittiğimiz mesafe uzaklık boşluk değil.
User prompt
Borular arası, boşluğu azaltabildiğin kadar azalt, azalt, azalt, azalt.
User prompt
Borular arası boşluq hala çox fazla, yav normal Flappy Bird gibi uzaqlıq yapsana
User prompt
BORULAR ARASI BOŞLUQ HAYLA ÇOX FAZLA
User prompt
Duvarlar arası uzaklık, boşluk demiyorum. Uzaklık aşırı fazla.
User prompt
Oyuna başladığımızda sayının sıfırla değil de ikiyle başlamayla ilgili hatasını düzelt ve bariyerler arası sırayı yani uzaklığı tekrar eski haline getir daha düzgün ve daha stabil uzaklık yap.
User prompt
Oyunu başlattığımız gibi kuşun ölenmesi yani ölmesi ile ilgili hatayı düzelt ve kuşu en arkadaki bariyerden öne koy yani sağ tarafa yani kuşu eski haline getir oyun çalışmıyor. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please fix the bug: 'Uncaught TypeError: tween.stop is not a function' in or related to this line: 'tween.stop(birdGraphics);' Line Number: 55 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Kuşu sil baştan yap ve bu sefer kuşu animasyonlu, daha düzgün, daha gerçekçi ve daha animasyonlu, daha dinamik ve hatalardan uzak şekilde yap. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Kuşu arkadaki bariyerden uzak tut. Başladığı gibi oyun bitiyor.
/****
* 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.isFlapping = false;
self.flapCooldown = 0;
self.idleTime = 0;
self.lastFlapTime = 0;
// Animation state tracking
self.animationState = 'idle'; // 'idle', 'flapping', 'falling', 'gliding'
self.wingPhase = 0; // For continuous wing animation
self.bobPhase = 0; // For idle floating animation
// Enhanced flap function with realistic physics and animations
self.flap = function () {
// Prevent rapid flapping
if (self.flapCooldown > 0) return;
self.flapCooldown = 8; // Frames to wait before next flap
// Set velocity with balanced scaling
self.velocity = baseJumpStrength * Math.pow(gameSpeed, 0.8) * 1.05;
self.isFlapping = true;
self.animationState = 'flapping';
self.lastFlapTime = 0;
// Stop any existing animations to prevent conflicts
tween.stop(birdGraphics);
tween.stop(self);
// Wing flap animation - quick downstroke
tween(birdGraphics, {
scaleX: 1.4,
scaleY: 0.7,
rotation: -0.3
}, {
duration: 60,
easing: tween.easeOut,
onFinish: function onFinish() {
// Wing upstroke - slower recovery
tween(birdGraphics, {
scaleX: 0.9,
scaleY: 1.2,
rotation: -0.1
}, {
duration: 100,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Return to normal with gentle overshoot
tween(birdGraphics, {
scaleX: 1.05,
scaleY: 0.95,
rotation: 0.05
}, {
duration: 80,
easing: tween.easeOut,
onFinish: function onFinish() {
// Final settle
tween(birdGraphics, {
scaleX: 1.0,
scaleY: 1.0,
rotation: 0
}, {
duration: 60,
easing: tween.easeInOut,
onFinish: function onFinish() {
self.isFlapping = false;
self.animationState = 'gliding';
}
});
}
});
}
});
}
});
// Subtle upward movement during flap
tween(self, {
y: self.y - 8
}, {
duration: 120,
easing: tween.easeOut
});
// Play flap sound with error handling
try {
var flapSound = LK.getSound('flap');
if (flapSound && flapSound.play) {
flapSound.play();
}
} catch (e) {
console.log("Flap sound error:", e);
}
};
// Continuous idle animation for floating effect
self.startIdleAnimation = function () {
if (self.animationState !== 'idle') return;
self.bobPhase += 0.05;
var bobOffset = Math.sin(self.bobPhase) * 2;
var scaleVariation = 1 + Math.sin(self.bobPhase * 0.7) * 0.02;
// Gentle floating motion
tween(birdGraphics, {
y: bobOffset,
scaleX: scaleVariation,
scaleY: scaleVariation,
rotation: Math.sin(self.bobPhase * 0.3) * 0.05
}, {
duration: 100,
easing: tween.easeInOut
});
};
// Enhanced update method with better physics and animations
self.update = function () {
// Update cooldowns
if (self.flapCooldown > 0) self.flapCooldown--;
self.lastFlapTime++;
if (!gameStarted) {
// Pre-game idle state
self.velocity = 0;
self.y = 1366;
self.animationState = 'idle';
self.startIdleAnimation();
return;
}
// Update physics with dynamic scaling
var gravity = baseGravity * Math.pow(gameSpeed, 0.7);
self.velocity += gravity;
self.y += self.velocity;
// Determine animation state based on velocity and recent flaps
if (self.isFlapping) {
self.animationState = 'flapping';
} else if (self.velocity > 2) {
self.animationState = 'falling';
} else if (self.velocity < -2) {
self.animationState = 'gliding';
} else {
self.animationState = 'idle';
}
// Dynamic rotation based on velocity and state
var targetRotation = 0;
if (self.animationState === 'falling') {
targetRotation = Math.min(1.2, self.velocity * 0.08);
} else if (self.animationState === 'gliding') {
targetRotation = Math.max(-0.6, self.velocity * 0.1);
} else if (self.animationState === 'flapping') {
targetRotation = -0.2;
}
// Smooth rotation transition
var rotationDiff = targetRotation - birdGraphics.rotation;
if (Math.abs(rotationDiff) > 0.02) {
tween(birdGraphics, {
rotation: targetRotation
}, {
duration: 100,
easing: tween.easeOut
});
}
// Continuous wing animation during flight
if (self.animationState === 'falling' || self.animationState === 'gliding') {
self.wingPhase += 0.12;
var wingFlutter = Math.sin(self.wingPhase) * 0.05;
birdGraphics.scaleY = 1 + wingFlutter;
}
// Idle floating animation
if (self.animationState === 'idle' && !self.isFlapping) {
self.startIdleAnimation();
}
// Screen bounds collision with smooth handling
var birdRadius = 40;
if (self.y - birdRadius < 0) {
self.y = birdRadius;
self.velocity = Math.max(0, self.velocity * 0.3); // Soft bounce
}
if (self.y + birdRadius > 2732 - 150) {
self.y = 2732 - 150 - birdRadius;
self.velocity = Math.min(0, self.velocity * 0.3); // Soft bounce
}
// Add subtle particle trail effect during fast movement
if (Math.abs(self.velocity) > 8) {
// Create subtle glow effect
birdGraphics.alpha = 0.9 + Math.sin(self.wingPhase * 2) * 0.1;
} else {
birdGraphics.alpha = 1.0;
}
};
return self;
});
var Pipe = Container.expand(function (gapCenterY) {
var self = Container.call(this);
self.gapSize = 750 + (gameSpeed - 1) * 50; // Dynamic gap size based on speed for better balance
self.speed = basePipeSpeed * gameSpeed;
self.passed = false;
self.gapCenterY = gapCenterY;
// Store pipe width for consistent collision detection
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));
// =============== TOP PIPE CONSTRUCTION ===============
// Create main top pipe body with darker base color
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 = 0x1B5E20; // Dark forest green base
// Create pipe shadow for depth
var topPipeShadow = self.attachAsset('topPipe', {
anchorX: 0.5,
anchorY: 1
});
topPipeShadow.y = gapCenterY - self.gapSize / 2;
topPipeShadow.height = topPipeHeight;
topPipeShadow.width = self.pipeWidth + 6;
topPipeShadow.x = 3;
topPipeShadow.tint = 0x0D2818; // Very dark shadow
topPipeShadow.alpha = 0.4;
// Create multiple highlight layers for realistic metallic sheen
var topPipeHighlight1 = self.attachAsset('pipeHighlight', {
anchorX: 0.5,
anchorY: 1
});
topPipeHighlight1.y = gapCenterY - self.gapSize / 2;
topPipeHighlight1.height = topPipeHeight;
topPipeHighlight1.width = 25;
topPipeHighlight1.x = -35;
topPipeHighlight1.tint = 0x66BB6A; // Bright green highlight
topPipeHighlight1.alpha = 0.8;
var topPipeHighlight2 = self.attachAsset('pipeHighlight', {
anchorX: 0.5,
anchorY: 1
});
topPipeHighlight2.y = gapCenterY - self.gapSize / 2;
topPipeHighlight2.height = topPipeHeight;
topPipeHighlight2.width = 12;
topPipeHighlight2.x = -42;
topPipeHighlight2.tint = 0xA5D6A7; // Lighter green shine
topPipeHighlight2.alpha = 0.9;
// Create realistic pipe joint rings every 150px
var numJoints = Math.floor(topPipeHeight / 150);
for (var j = 0; j < numJoints; j++) {
var jointY = gapCenterY - self.gapSize / 2 - (j + 1) * 150;
if (jointY > 50 && jointY < gapCenterY - self.gapSize / 2 - 50) {
// Don't create joints too close to top or gap area
// Main joint ring
var topJoint = self.attachAsset('pipeTop', {
anchorX: 0.5,
anchorY: 0.5
});
topJoint.y = jointY;
topJoint.width = self.pipeWidth + 15;
topJoint.height = 20;
topJoint.tint = 0x37474F; // Blue-gray metallic
// Joint highlight
var topJointHighlight = self.attachAsset('pipeTop', {
anchorX: 0.5,
anchorY: 0.5
});
topJointHighlight.y = jointY - 3;
topJointHighlight.width = self.pipeWidth + 12;
topJointHighlight.height = 8;
topJointHighlight.tint = 0x78909C; // Lighter metallic
topJointHighlight.alpha = 0.7;
}
}
// Rivets removed to prevent visual elements in gap area
// Enhanced top pipe cap with multiple layers
var topPipeCapBase = self.attachAsset('pipeTop', {
anchorX: 0.5,
anchorY: 1
});
topPipeCapBase.y = gapCenterY - self.gapSize / 2;
topPipeCapBase.width = self.pipeWidth + 45;
topPipeCapBase.height = 35;
topPipeCapBase.tint = 0x263238; // Very dark base
var topPipeCap = self.attachAsset('pipeTop', {
anchorX: 0.5,
anchorY: 1
});
topPipeCap.y = gapCenterY - self.gapSize / 2;
topPipeCap.width = self.pipeWidth + 35;
topPipeCap.height = 30;
topPipeCap.tint = 0x37474F; // Dark metallic
var topCapHighlight = self.attachAsset('pipeTop', {
anchorX: 0.5,
anchorY: 1
});
topCapHighlight.y = gapCenterY - self.gapSize / 2;
topCapHighlight.width = self.pipeWidth + 30;
topCapHighlight.height = 12;
topCapHighlight.tint = 0x78909C; // Metallic highlight
topCapHighlight.alpha = 0.8;
// =============== BOTTOM PIPE CONSTRUCTION ===============
// Create main bottom pipe body with darker base color
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 = 0x1B5E20; // Dark forest green base
// Create pipe shadow for depth
var bottomPipeShadow = self.attachAsset('bottomPipe', {
anchorX: 0.5,
anchorY: 0
});
bottomPipeShadow.y = gapCenterY + self.gapSize / 2;
bottomPipeShadow.height = bottomPipeHeight;
bottomPipeShadow.width = self.pipeWidth + 6;
bottomPipeShadow.x = 3;
bottomPipeShadow.tint = 0x0D2818; // Very dark shadow
bottomPipeShadow.alpha = 0.4;
// Create multiple highlight layers for realistic metallic sheen
var bottomPipeHighlight1 = self.attachAsset('pipeHighlight', {
anchorX: 0.5,
anchorY: 0
});
bottomPipeHighlight1.y = gapCenterY + self.gapSize / 2;
bottomPipeHighlight1.height = bottomPipeHeight;
bottomPipeHighlight1.width = 25;
bottomPipeHighlight1.x = -35;
bottomPipeHighlight1.tint = 0x66BB6A; // Bright green highlight
bottomPipeHighlight1.alpha = 0.8;
var bottomPipeHighlight2 = self.attachAsset('pipeHighlight', {
anchorX: 0.5,
anchorY: 0
});
bottomPipeHighlight2.y = gapCenterY + self.gapSize / 2;
bottomPipeHighlight2.height = bottomPipeHeight;
bottomPipeHighlight2.width = 12;
bottomPipeHighlight2.x = -42;
bottomPipeHighlight2.tint = 0xA5D6A7; // Lighter green shine
bottomPipeHighlight2.alpha = 0.9;
// Create realistic pipe joint rings every 150px
var numBottomJoints = Math.floor(bottomPipeHeight / 150);
for (var j = 0; j < numBottomJoints; j++) {
var jointY = gapCenterY + self.gapSize / 2 + (j + 1) * 150;
if (jointY < 2732 - 200) {
// Don't create joints too close to ground
// Main joint ring
var bottomJoint = self.attachAsset('pipeBottom', {
anchorX: 0.5,
anchorY: 0.5
});
bottomJoint.y = jointY;
bottomJoint.width = self.pipeWidth + 15;
bottomJoint.height = 20;
bottomJoint.tint = 0x37474F; // Blue-gray metallic
// Joint highlight
var bottomJointHighlight = self.attachAsset('pipeBottom', {
anchorX: 0.5,
anchorY: 0.5
});
bottomJointHighlight.y = jointY + 3;
bottomJointHighlight.width = self.pipeWidth + 12;
bottomJointHighlight.height = 8;
bottomJointHighlight.tint = 0x78909C; // Lighter metallic
bottomJointHighlight.alpha = 0.7;
}
}
// Rivets removed to prevent visual elements in gap area
// Enhanced bottom pipe cap with multiple layers
var bottomPipeCapBase = self.attachAsset('pipeBottom', {
anchorX: 0.5,
anchorY: 0
});
bottomPipeCapBase.y = gapCenterY + self.gapSize / 2;
bottomPipeCapBase.width = self.pipeWidth + 45;
bottomPipeCapBase.height = 35;
bottomPipeCapBase.tint = 0x263238; // Very dark base
var bottomPipeCap = self.attachAsset('pipeBottom', {
anchorX: 0.5,
anchorY: 0
});
bottomPipeCap.y = gapCenterY + self.gapSize / 2;
bottomPipeCap.width = self.pipeWidth + 35;
bottomPipeCap.height = 30;
bottomPipeCap.tint = 0x37474F; // Dark metallic
var bottomCapHighlight = self.attachAsset('pipeBottom', {
anchorX: 0.5,
anchorY: 0
});
bottomCapHighlight.y = gapCenterY + self.gapSize / 2;
bottomCapHighlight.width = self.pipeWidth + 30;
bottomCapHighlight.height = 12;
bottomCapHighlight.tint = 0x78909C; // Metallic highlight
bottomCapHighlight.alpha = 0.8;
self.update = function () {
if (!gameStarted) {
// Don't move pipes before game starts
return;
}
// Update dynamic speed based on current game speed
self.speed = basePipeSpeed * gameSpeed;
self.x += self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game();
/****
* Game Code
****/
// Initialize plugins with proper error handling
// Game variables
var tween;
var storage;
try {
tween = LK.import("@upit/tween.v1");
storage = LK.import("@upit/storage.v1", {
highScore: 0,
language: 'en',
username: 'Player1',
globalLeaderboardNames: [],
globalLeaderboardScores: [],
lastScore: 0
});
} catch (e) {
console.log("Plugin import error:", e);
// Provide comprehensive fallback objects to prevent undefined errors
tween = function tween(target, props, options) {
return {
duration: options ? options.duration || 0 : 0,
onFinish: options && options.onFinish ? options.onFinish : function () {}
};
};
storage = {
highScore: 0,
language: 'en',
username: 'Player1',
globalLeaderboardNames: [],
globalLeaderboardScores: [],
lastScore: 0
};
}
var bird;
var pipes = [];
var ground;
var topBarrier;
var bottomBarrier;
var gameStarted = false;
var gameOver = false;
var showMainMenu = true;
var showGameOver = false;
var pipeSpacing = 500 + gameSpeed * 50; // Dynamic spacing based on speed for better balance
var buttonClickTimeout = null; // Prevent rapid button clicks
var lastButtonClickTime = 0; // Track last button click time
var gameSpeed = 1; // Current game speed multiplier (1 = normal, 2 = 2x, 3 = 3x)
var baseGravity = 0.55; // Base gravity for bird - fine-tuned for better control
var baseJumpStrength = -9.5; // Base jump strength for bird - fine-tuned for better balance
var basePipeSpeed = -3; // Base pipe movement speed
// Initialize game speed properly
gameSpeed = 1;
// Initialize storage with defaults
var _storage = storage;
// Create score text display
var scoreTxt = new Text2('0', {
size: 150,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
scoreTxt.stroke = 0x000000;
scoreTxt.strokeThickness = 5;
try {
if (LK.gui && LK.gui.top) {
LK.gui.top.addChild(scoreTxt);
}
} catch (e) {
console.log("GUI score text error:", e);
}
// Create cup shape for score
var cupShape;
try {
cupShape = LK.getAsset('cup', {
anchorX: 0.5,
anchorY: 0
});
cupShape.tint = 0xFFD700;
if (LK.gui && LK.gui.bottomRight) {
LK.gui.bottomRight.addChild(cupShape);
cupShape.y = -230;
cupShape.x = -100;
}
} catch (e) {
console.log("Cup shape error:", e);
}
// Create main menu elements
var mainMenuTitle = new Text2('FLAPPY BIRD', {
size: 90,
fill: 0xFFD700
});
mainMenuTitle.anchor.set(0.5, 0.5);
mainMenuTitle.stroke = 0x000000;
mainMenuTitle.strokeThickness = 5;
try {
if (LK.gui && LK.gui.center) {
LK.gui.center.addChild(mainMenuTitle);
mainMenuTitle.y = -280;
}
} catch (e) {
console.log("Main menu title error:", e);
}
// Create instruction text
var instructionTxt = new Text2('TIKLA VE OYNA!', {
size: 50,
fill: 0xFFFFFF
});
instructionTxt.anchor.set(0.5, 0.5);
instructionTxt.stroke = 0x000000;
instructionTxt.strokeThickness = 3;
instructionTxt.visible = false;
instructionTxt.y = -50;
// Remove background shape for instruction text - no longer needed
LK.gui.center.addChild(instructionTxt);
// Create game over screen elements
var gameOverBg = LK.getAsset('barrier', {
anchorX: 0.5,
anchorY: 0.5,
width: 1600,
height: 1200,
alpha: 0.95
});
gameOverBg.tint = 0x2F4F4F;
gameOverBg.visible = false;
LK.gui.center.addChild(gameOverBg);
var gameOverTitle = new Text2('OYUN BİTTİ', {
size: 120,
fill: 0xFFFFFF
});
gameOverTitle.anchor.set(0.5, 0.5);
gameOverTitle.stroke = 0x000000;
gameOverTitle.strokeThickness = 6;
gameOverTitle.visible = false;
LK.gui.center.addChild(gameOverTitle);
gameOverTitle.y = -300;
var finalScoreText = new Text2('SKOR: 0', {
size: 80,
fill: 0xFFFFFF
});
finalScoreText.anchor.set(0.5, 0.5);
finalScoreText.stroke = 0x000000;
finalScoreText.strokeThickness = 4;
finalScoreText.visible = false;
LK.gui.center.addChild(finalScoreText);
finalScoreText.y = -150;
var bestScoreText = new Text2('EN İYİ: 0', {
size: 60,
fill: 0xFFD700
});
bestScoreText.anchor.set(0.5, 0.5);
bestScoreText.stroke = 0x000000;
bestScoreText.strokeThickness = 3;
bestScoreText.visible = false;
LK.gui.center.addChild(bestScoreText);
bestScoreText.y = -50;
// Create retry button with enhanced styling
var retryButton = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 380,
height: 110,
alpha: 1.0
});
retryButton.tint = 0xFF9800; // Orange like original Flappy Bird
retryButton.visible = false;
LK.gui.center.addChild(retryButton);
retryButton.y = 100;
// Add retry button shadow for depth
var retryButtonShadow = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 380,
height: 110,
alpha: 0.3
});
retryButtonShadow.tint = 0xE65100; // Darker orange shadow
retryButtonShadow.visible = false;
LK.gui.center.addChild(retryButtonShadow);
retryButtonShadow.y = 108; // Offset shadow slightly down
retryButtonShadow.x = 4; // Offset shadow slightly right
// Add retry button highlight
var retryButtonHighlight = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 350,
height: 85,
alpha: 0.4
});
retryButtonHighlight.tint = 0xFFB74D; // Lighter orange highlight
retryButtonHighlight.visible = false;
LK.gui.center.addChild(retryButtonHighlight);
retryButtonHighlight.y = 92; // Offset highlight slightly up
var retryButtonText = new Text2('TEKRAR DENE', {
size: 44,
fill: 0xFFFFFF
});
retryButtonText.anchor.set(0.5, 0.5);
retryButtonText.stroke = 0xE65100;
retryButtonText.strokeThickness = 3;
retryButtonText.visible = false;
LK.gui.center.addChild(retryButtonText);
retryButtonText.y = 100;
// Create menu button with enhanced styling
var menuButton = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 380,
height: 110,
alpha: 1.0
});
menuButton.tint = 0xF44336; // Red like original Flappy Bird
menuButton.visible = false;
LK.gui.center.addChild(menuButton);
menuButton.y = 250;
// Add menu button shadow for depth
var menuButtonShadow = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 380,
height: 110,
alpha: 0.3
});
menuButtonShadow.tint = 0xD32F2F; // Darker red shadow
menuButtonShadow.visible = false;
LK.gui.center.addChild(menuButtonShadow);
menuButtonShadow.y = 258; // Offset shadow slightly down
menuButtonShadow.x = 4; // Offset shadow slightly right
// Add menu button highlight
var menuButtonHighlight = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 350,
height: 85,
alpha: 0.4
});
menuButtonHighlight.tint = 0xEF5350; // Lighter red highlight
menuButtonHighlight.visible = false;
LK.gui.center.addChild(menuButtonHighlight);
menuButtonHighlight.y = 242; // Offset highlight slightly up
var menuButtonText = new Text2('ANA MENÜ', {
size: 44,
fill: 0xFFFFFF
});
menuButtonText.anchor.set(0.5, 0.5);
menuButtonText.stroke = 0xD32F2F;
menuButtonText.strokeThickness = 3;
menuButtonText.visible = false;
LK.gui.center.addChild(menuButtonText);
menuButtonText.y = 250;
// Create separate settings button element
var settingsButton = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 100,
height: 100,
alpha: 1.0
});
settingsButton.tint = 0x8E44AD;
try {
if (LK.gui && LK.gui.topRight) {
LK.gui.topRight.addChild(settingsButton);
settingsButton.x = -80;
settingsButton.y = 80;
}
} catch (e) {
console.log("Settings button error:", e);
}
// Create separate settings button shadow element
var settingsButtonShadow = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 100,
height: 100,
alpha: 0.3
});
settingsButtonShadow.tint = 0x6B2C91; // Darker purple shadow
try {
if (LK.gui && LK.gui.topRight) {
LK.gui.topRight.addChild(settingsButtonShadow);
settingsButtonShadow.x = -77;
settingsButtonShadow.y = 83;
}
} catch (e) {
console.log("Settings button shadow error:", e);
}
// Create separate settings button highlight element
var settingsButtonHighlight = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 85,
height: 85,
alpha: 0.4
});
settingsButtonHighlight.tint = 0xBB8FCE; // Lighter purple highlight
try {
if (LK.gui && LK.gui.topRight) {
LK.gui.topRight.addChild(settingsButtonHighlight);
settingsButtonHighlight.x = -80;
settingsButtonHighlight.y = 77;
}
} catch (e) {
console.log("Settings button highlight error:", e);
}
// Create separate settings icon text element
var settingsIcon = new Text2('⚙', {
size: 60,
fill: 0xFFFFFF
});
settingsIcon.anchor.set(0.5, 0.5);
settingsIcon.stroke = 0x6B2C91;
settingsIcon.strokeThickness = 2;
try {
if (LK.gui && LK.gui.topRight) {
LK.gui.topRight.addChild(settingsIcon);
settingsIcon.x = -80;
settingsIcon.y = 80;
}
} catch (e) {
console.log("Settings icon error:", e);
}
// Create settings menu overlay (initially hidden)
var settingsOverlay = LK.getAsset('barrier', {
anchorX: 0.5,
anchorY: 0.5,
width: 2048,
height: 2732,
alpha: 1.0
});
settingsOverlay.tint = 0x2F4F4F;
settingsOverlay.visible = false;
LK.gui.center.addChild(settingsOverlay);
var settingsTitle = new Text2('AYARLAR', {
size: 100,
fill: 0xFFFFFF
});
settingsTitle.anchor.set(0.5, 0.5);
settingsTitle.stroke = 0x000000;
settingsTitle.strokeThickness = 5;
settingsTitle.visible = false;
LK.gui.center.addChild(settingsTitle);
settingsTitle.y = -300;
// Create close settings button with modern rectangular design
var closeSettingsButton = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 260,
height: 70,
alpha: 1.0
});
closeSettingsButton.tint = 0x95A5A6;
closeSettingsButton.visible = false;
LK.gui.center.addChild(closeSettingsButton);
closeSettingsButton.y = 150;
// Add close button shadow for depth
var closeSettingsButtonShadow = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 260,
height: 70,
alpha: 0.3
});
closeSettingsButtonShadow.tint = 0x7F8C8D;
closeSettingsButtonShadow.visible = false;
LK.gui.center.addChild(closeSettingsButtonShadow);
closeSettingsButtonShadow.y = 155;
closeSettingsButtonShadow.x = 3;
// Add close button highlight
var closeSettingsButtonHighlight = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 240,
height: 55,
alpha: 0.4
});
closeSettingsButtonHighlight.tint = 0xBDC3C7;
closeSettingsButtonHighlight.visible = false;
LK.gui.center.addChild(closeSettingsButtonHighlight);
closeSettingsButtonHighlight.y = 145;
var closeSettingsText = new Text2('KAPAT', {
size: 36,
fill: 0xFFFFFF
});
closeSettingsText.anchor.set(0.5, 0.5);
closeSettingsText.stroke = 0x7F8C8D;
closeSettingsText.strokeThickness = 2;
closeSettingsText.visible = false;
LK.gui.center.addChild(closeSettingsText);
closeSettingsText.y = 150;
// Create speed menu button with modern rectangular design
var speedMenuButton = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 340,
height: 75,
alpha: 1.0
});
speedMenuButton.tint = 0x3498DB;
speedMenuButton.visible = false;
LK.gui.center.addChild(speedMenuButton);
speedMenuButton.y = -150;
// Add speed button shadow for depth
var speedMenuButtonShadow = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 340,
height: 75,
alpha: 0.3
});
speedMenuButtonShadow.tint = 0x2980B9;
speedMenuButtonShadow.visible = false;
LK.gui.center.addChild(speedMenuButtonShadow);
speedMenuButtonShadow.y = -145;
speedMenuButtonShadow.x = 3;
// Add speed button highlight
var speedMenuButtonHighlight = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 320,
height: 60,
alpha: 0.4
});
speedMenuButtonHighlight.tint = 0x5DADE2;
speedMenuButtonHighlight.visible = false;
LK.gui.center.addChild(speedMenuButtonHighlight);
speedMenuButtonHighlight.y = -155;
var speedMenuText = new Text2('HIZ', {
size: 42,
fill: 0xFFFFFF
});
speedMenuText.anchor.set(0.5, 0.5);
speedMenuText.stroke = 0x2980B9;
speedMenuText.strokeThickness = 2;
speedMenuText.visible = false;
LK.gui.center.addChild(speedMenuText);
speedMenuText.y = -150;
// Create language menu button with modern rectangular design
var languageMenuButton = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 340,
height: 75,
alpha: 1.0
});
languageMenuButton.tint = 0x9B59B6;
languageMenuButton.visible = false;
LK.gui.center.addChild(languageMenuButton);
languageMenuButton.y = -20;
// Add language button shadow for depth
var languageMenuButtonShadow = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 340,
height: 75,
alpha: 0.3
});
languageMenuButtonShadow.tint = 0x8E44AD;
languageMenuButtonShadow.visible = false;
LK.gui.center.addChild(languageMenuButtonShadow);
languageMenuButtonShadow.y = -15;
languageMenuButtonShadow.x = 3;
// Add language button highlight
var languageMenuButtonHighlight = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 320,
height: 60,
alpha: 0.4
});
languageMenuButtonHighlight.tint = 0xBB8FCE;
languageMenuButtonHighlight.visible = false;
LK.gui.center.addChild(languageMenuButtonHighlight);
languageMenuButtonHighlight.y = -25;
var languageMenuText = new Text2('DİL', {
size: 42,
fill: 0xFFFFFF
});
languageMenuText.anchor.set(0.5, 0.5);
languageMenuText.stroke = 0x8E44AD;
languageMenuText.strokeThickness = 2;
languageMenuText.visible = false;
LK.gui.center.addChild(languageMenuText);
languageMenuText.y = -20;
// Create new speed control elements
var speedTitle = new Text2('HIZ AYARI', {
size: 80,
fill: 0xFFFFFF
});
speedTitle.anchor.set(0.5, 0.5);
speedTitle.stroke = 0x000000;
speedTitle.strokeThickness = 4;
speedTitle.visible = false;
LK.gui.center.addChild(speedTitle);
speedTitle.y = -200;
// Create speed option buttons with modern rectangular design
var normalSpeedButton = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 180,
height: 65,
alpha: 1.0
});
normalSpeedButton.tint = 0x27AE60;
normalSpeedButton.visible = false;
LK.gui.center.addChild(normalSpeedButton);
normalSpeedButton.y = -80;
normalSpeedButton.x = -280;
// Add normal speed button shadow
var normalSpeedButtonShadow = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 180,
height: 65,
alpha: 0.3
});
normalSpeedButtonShadow.tint = 0x1E8449;
normalSpeedButtonShadow.visible = false;
LK.gui.center.addChild(normalSpeedButtonShadow);
normalSpeedButtonShadow.y = -75;
normalSpeedButtonShadow.x = -277;
// Add normal speed button highlight
var normalSpeedButtonHighlight = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 160,
height: 50,
alpha: 0.4
});
normalSpeedButtonHighlight.tint = 0x58D68D;
normalSpeedButtonHighlight.visible = false;
LK.gui.center.addChild(normalSpeedButtonHighlight);
normalSpeedButtonHighlight.y = -85;
normalSpeedButtonHighlight.x = -280;
var normalSpeedText = new Text2('NORMAL', {
size: 32,
fill: 0xFFFFFF
});
normalSpeedText.anchor.set(0.5, 0.5);
normalSpeedText.stroke = 0x1E8449;
normalSpeedText.strokeThickness = 2;
normalSpeedText.visible = false;
LK.gui.center.addChild(normalSpeedText);
normalSpeedText.y = -80;
normalSpeedText.x = -280;
var speed15xButton = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 180,
height: 65,
alpha: 1.0
});
speed15xButton.tint = 0xF39C12;
speed15xButton.visible = false;
LK.gui.center.addChild(speed15xButton);
speed15xButton.y = -80;
speed15xButton.x = 0;
// Add 1.5x speed button shadow
var speed15xButtonShadow = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 180,
height: 65,
alpha: 0.3
});
speed15xButtonShadow.tint = 0xD68910;
speed15xButtonShadow.visible = false;
LK.gui.center.addChild(speed15xButtonShadow);
speed15xButtonShadow.y = -75;
speed15xButtonShadow.x = 3;
// Add 1.5x speed button highlight
var speed15xButtonHighlight = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 160,
height: 50,
alpha: 0.4
});
speed15xButtonHighlight.tint = 0xF7DC6F;
speed15xButtonHighlight.visible = false;
LK.gui.center.addChild(speed15xButtonHighlight);
speed15xButtonHighlight.y = -85;
speed15xButtonHighlight.x = 0;
var speed15xText = new Text2('1.5X', {
size: 32,
fill: 0xFFFFFF
});
speed15xText.anchor.set(0.5, 0.5);
speed15xText.stroke = 0xD68910;
speed15xText.strokeThickness = 2;
speed15xText.visible = false;
LK.gui.center.addChild(speed15xText);
speed15xText.y = -80;
speed15xText.x = 0;
var speed2xButton = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 180,
height: 65,
alpha: 1.0
});
speed2xButton.tint = 0xE74C3C;
speed2xButton.visible = false;
LK.gui.center.addChild(speed2xButton);
speed2xButton.y = -80;
speed2xButton.x = 180;
// Add 2x speed button shadow
var speed2xButtonShadow = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 180,
height: 65,
alpha: 0.3
});
speed2xButtonShadow.tint = 0xC0392B;
speed2xButtonShadow.visible = false;
LK.gui.center.addChild(speed2xButtonShadow);
speed2xButtonShadow.y = -75;
speed2xButtonShadow.x = 183;
// Add 2x speed button highlight
var speed2xButtonHighlight = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 160,
height: 50,
alpha: 0.4
});
speed2xButtonHighlight.tint = 0xF1948A;
speed2xButtonHighlight.visible = false;
LK.gui.center.addChild(speed2xButtonHighlight);
speed2xButtonHighlight.y = -85;
speed2xButtonHighlight.x = 180;
var speed2xText = new Text2('2X', {
size: 32,
fill: 0xFFFFFF
});
speed2xText.anchor.set(0.5, 0.5);
speed2xText.stroke = 0xC0392B;
speed2xText.strokeThickness = 2;
speed2xText.visible = false;
LK.gui.center.addChild(speed2xText);
speed2xText.y = -80;
speed2xText.x = 180;
// Create 2.5x speed button
var speed25xButton = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 180,
height: 65,
alpha: 1.0
});
speed25xButton.tint = 0x9C27B0;
speed25xButton.visible = false;
LK.gui.center.addChild(speed25xButton);
speed25xButton.y = -80;
speed25xButton.x = 360;
// Add 2.5x speed button shadow
var speed25xButtonShadow = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 180,
height: 65,
alpha: 0.3
});
speed25xButtonShadow.tint = 0x7B1FA2;
speed25xButtonShadow.visible = false;
LK.gui.center.addChild(speed25xButtonShadow);
speed25xButtonShadow.y = -75;
speed25xButtonShadow.x = 363;
// Add 2.5x speed button highlight
var speed25xButtonHighlight = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 160,
height: 50,
alpha: 0.4
});
speed25xButtonHighlight.tint = 0xBA68C8;
speed25xButtonHighlight.visible = false;
LK.gui.center.addChild(speed25xButtonHighlight);
speed25xButtonHighlight.y = -85;
speed25xButtonHighlight.x = 360;
var speed25xText = new Text2('2.5X', {
size: 32,
fill: 0xFFFFFF
});
speed25xText.anchor.set(0.5, 0.5);
speed25xText.stroke = 0x7B1FA2;
speed25xText.strokeThickness = 2;
speed25xText.visible = false;
LK.gui.center.addChild(speed25xText);
speed25xText.y = -80;
speed25xText.x = 360;
// Current speed indicator
var currentSpeedText = new Text2('MEVCUT: NORMAL', {
size: 50,
fill: 0xFFD700
});
currentSpeedText.anchor.set(0.5, 0.5);
currentSpeedText.stroke = 0x000000;
currentSpeedText.strokeThickness = 3;
currentSpeedText.visible = false;
LK.gui.center.addChild(currentSpeedText);
currentSpeedText.y = 30;
// Create back button for speed controls with modern rectangular design
var speedBackButton = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 220,
height: 65,
alpha: 1.0
});
speedBackButton.tint = 0x7F8C8D;
speedBackButton.visible = false;
LK.gui.center.addChild(speedBackButton);
speedBackButton.y = 150;
// Add speed back button shadow
var speedBackButtonShadow = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 220,
height: 65,
alpha: 0.3
});
speedBackButtonShadow.tint = 0x566573;
speedBackButtonShadow.visible = false;
LK.gui.center.addChild(speedBackButtonShadow);
speedBackButtonShadow.y = 155;
speedBackButtonShadow.x = 3;
// Add speed back button highlight
var speedBackButtonHighlight = LK.getAsset('settingsButtonRect', {
anchorX: 0.5,
anchorY: 0.5,
width: 200,
height: 50,
alpha: 0.4
});
speedBackButtonHighlight.tint = 0xABB2B9;
speedBackButtonHighlight.visible = false;
LK.gui.center.addChild(speedBackButtonHighlight);
speedBackButtonHighlight.y = 145;
var speedBackText = new Text2('GERİ', {
size: 36,
fill: 0xFFFFFF
});
speedBackText.anchor.set(0.5, 0.5);
speedBackText.stroke = 0x566573;
speedBackText.strokeThickness = 2;
speedBackText.visible = false;
LK.gui.center.addChild(speedBackText);
speedBackText.y = 150;
// Create invisible barrier blocks to constrain bird before game starts
var topBarrier = game.addChild(LK.getAsset('barrier', {
anchorX: 0.5,
anchorY: 1
}));
topBarrier.x = -100;
topBarrier.y = 1316; // 50 pixels above bird
topBarrier.alpha = 0; // Make invisible
var bottomBarrier = game.addChild(LK.getAsset('barrier', {
anchorX: 0.5,
anchorY: 0
}));
bottomBarrier.x = -100;
bottomBarrier.y = 1416; // 50 pixels below bird
bottomBarrier.alpha = 0; // Make invisible
// Create and add background image (appears behind barriers but in front of other elements)
var background = game.addChild(LK.getAsset('background', {
anchorX: 0,
anchorY: 0
}));
background.x = 0;
background.y = 0;
// Scale background to fill screen for better performance
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 = -100;
bird.y = 1366;
// Initialize bird properly
bird.velocity = 0;
// Create barrier pipe function - creates a pipe behind the bird to prevent immediate death
function createBarrierPipe() {
// Create a pipe with safe gap at bird's height
var barrierPipe = new Pipe(1366); // Gap centered at bird's starting position
barrierPipe.x = -500; // Position much further behind bird
barrierPipe.passed = true; // Mark as already passed so it doesn't score
barrierPipe.speed = 0; // Make it stationary
pipes.push(barrierPipe);
game.addChild(barrierPipe);
}
// Create pipe function
function createPipe() {
// Define safe boundaries for gap center to ensure both pipes have reasonable heights
var minGapY = 700; // Increased minimum gap center position for better clearance
var maxGapY = 1900; // Adjusted maximum gap center position for better clearance
var gapCenterY;
// Create more varied random patterns with better distribution
var randomPattern = Math.random();
if (randomPattern < 0.4) {
// 40% chance for high gaps (easier to navigate)
gapCenterY = minGapY + Math.random() * 300;
} else if (randomPattern < 0.7) {
// 30% chance for middle gaps (moderate difficulty)
gapCenterY = 1000 + Math.random() * 500;
} else {
// 30% chance for low gaps (more challenging but still passable)
gapCenterY = maxGapY - Math.random() * 300;
}
// Add some variation based on current score for progressive difficulty
var currentScore = LK.getScore();
if (currentScore > 10) {
// After score 10, make gaps slightly more challenging
var difficultyFactor = Math.min(0.8, currentScore / 50); // Max 80% difficulty increase
var centerPull = 1300; // Pull towards center-high area
gapCenterY = gapCenterY + (centerPull - gapCenterY) * difficultyFactor * 0.3;
}
// Ensure the gap stays within safe boundaries
gapCenterY = Math.max(minGapY, Math.min(maxGapY, gapCenterY));
var pipe = new Pipe(gapCenterY);
// Calculate position based on last pipe position + consistent spacing
if (pipes.length === 0) {
// First pipe after barrier - position further right
pipe.x = 2048 + 800; // Even further right so bird must pass it to score
} else {
pipe.x = pipes[pipes.length - 1].x + pipeSpacing; // Consistent spacing from last pipe
}
;
// Ensure pipe is marked as not passed initially
pipe.passed = false;
pipes.push(pipe);
game.addChild(pipe);
}
// Reset game function
function resetGame() {
// Reset bird - position it much further back so it starts behind all pipes
bird.x = -100;
bird.y = 1366;
bird.velocity = 0;
// Clear pipes
for (var i = pipes.length - 1; i >= 0; i--) {
pipes[i].destroy();
}
pipes = [];
// Reset variables
gameStarted = false;
gameOver = false;
showMainMenu = true;
showGameOver = false;
// Hide game over screen
hideGameOverScreen();
LK.setScore(0);
scoreTxt.setText('0');
// Show main menu
mainMenuTitle.visible = true;
// Show play button elements
if (playButton) playButton.visible = true;
if (playButtonShadow) playButtonShadow.visible = true;
if (playButtonHighlight) playButtonHighlight.visible = true;
if (playButtonText) playButtonText.visible = true;
// Start play button animation
startPlayButtonAnimation();
// Show all settings button elements
settingsButton.visible = true;
settingsButtonShadow.visible = true;
settingsButtonHighlight.visible = true;
settingsIcon.visible = true;
// Show cup shape (high score indicator)
if (cupShape) cupShape.visible = true;
// Hide instruction
instructionTxt.visible = false;
// Clear existing barriers if they exist
if (topBarrier) {
topBarrier.destroy();
topBarrier = null;
}
if (bottomBarrier) {
bottomBarrier.destroy();
bottomBarrier = null;
}
// Recreate invisible barriers
topBarrier = game.addChild(LK.getAsset('barrier', {
anchorX: 0.5,
anchorY: 1
}));
topBarrier.x = -100;
topBarrier.y = 1316; // 50 pixels above bird
topBarrier.alpha = 0; // Make invisible
bottomBarrier = game.addChild(LK.getAsset('barrier', {
anchorX: 0.5,
anchorY: 0
}));
bottomBarrier.x = -100;
bottomBarrier.y = 1416; // 50 pixels below bird
bottomBarrier.alpha = 0; // Make invisible
// Create barrier pipe first to prevent immediate death
createBarrierPipe();
// Create initial pipes
createPipe();
createPipe();
}
// Function to start game from main menu
function startGameFromMenu() {
showMainMenu = false;
// Hide main menu elements
mainMenuTitle.visible = false;
// Hide play button elements
if (playButton) playButton.visible = false;
if (playButtonShadow) playButtonShadow.visible = false;
if (playButtonHighlight) playButtonHighlight.visible = false;
if (playButtonText) playButtonText.visible = false;
// Hide all settings button elements
settingsButton.visible = false;
settingsButtonShadow.visible = false;
settingsButtonHighlight.visible = false;
settingsIcon.visible = false;
// Hide cup shape (high score indicator)
if (cupShape) cupShape.visible = false;
// Show instruction
instructionTxt.visible = true;
}
// Function to show game over screen
function showGameOverScreen(finalScore) {
showGameOver = true;
gameStarted = false;
showMainMenu = false;
// Hide instruction
instructionTxt.visible = false;
// Show game over elements
gameOverBg.visible = true;
gameOverTitle.visible = true;
finalScoreText.visible = true;
bestScoreText.visible = true;
retryButton.visible = true;
retryButtonText.visible = true;
retryButtonShadow.visible = true;
retryButtonHighlight.visible = true;
menuButton.visible = true;
menuButtonText.visible = true;
menuButtonShadow.visible = true;
menuButtonHighlight.visible = true;
// Update score displays
finalScoreText.setText(getText('score') + ': ' + finalScore);
// Use proper text sizing
if (finalScoreText.width > 600) {
var newSize = Math.max(50, Math.floor(80 * 600 / finalScoreText.width));
finalScoreText.style = {
size: newSize,
fill: finalScoreText.style.fill
};
}
// Always show the current high score from storage
var currentHighScore = _storage && _storage.highScore ? _storage.highScore : 0;
bestScoreText.setText(getText('bestScore') + ': ' + currentHighScore);
// Use proper text sizing
if (bestScoreText.width > 600) {
var newSize = Math.max(40, Math.floor(60 * 600 / bestScoreText.width));
bestScoreText.style = {
size: newSize,
fill: bestScoreText.style.fill
};
}
// Add entrance animation for buttons
tween(retryButton, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(retryButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 200,
easing: tween.easeInOut
});
}
});
tween(menuButton, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(menuButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 200,
easing: tween.easeInOut
});
}
});
}
// Function to hide game over screen
function hideGameOverScreen() {
showGameOver = false;
// Hide game over elements
gameOverBg.visible = false;
gameOverTitle.visible = false;
finalScoreText.visible = false;
bestScoreText.visible = false;
retryButton.visible = false;
retryButtonText.visible = false;
retryButtonShadow.visible = false;
retryButtonHighlight.visible = false;
menuButton.visible = false;
menuButtonText.visible = false;
menuButtonShadow.visible = false;
menuButtonHighlight.visible = false;
}
// Create speed overlay background - moved to end to ensure it's on top
var speedOverlay = LK.getAsset('barrier', {
anchorX: 0.5,
anchorY: 0.5,
width: 2048,
height: 2732,
alpha: 1.0
});
speedOverlay.tint = 0x2F4F4F;
speedOverlay.visible = false;
// Add to front to ensure visibility above all other elements
LK.gui.center.addChild(speedOverlay);
// Create language overlay background
var languageOverlay = LK.getAsset('barrier', {
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 settings menu
function showSettingsMenu() {
// Remove and re-add settings overlay to bring it to front
LK.gui.center.removeChild(settingsOverlay);
LK.gui.center.addChild(settingsOverlay);
// Remove and re-add all settings elements to bring them to front
LK.gui.center.removeChild(settingsTitle);
LK.gui.center.addChild(settingsTitle);
LK.gui.center.removeChild(closeSettingsButton);
LK.gui.center.addChild(closeSettingsButton);
LK.gui.center.removeChild(closeSettingsText);
LK.gui.center.addChild(closeSettingsText);
LK.gui.center.removeChild(speedMenuButton);
LK.gui.center.addChild(speedMenuButton);
LK.gui.center.removeChild(speedMenuText);
LK.gui.center.addChild(speedMenuText);
LK.gui.center.removeChild(languageMenuButton);
LK.gui.center.addChild(languageMenuButton);
LK.gui.center.removeChild(languageMenuText);
LK.gui.center.addChild(languageMenuText);
settingsOverlay.visible = true;
settingsTitle.visible = true;
closeSettingsButton.visible = true;
closeSettingsButtonShadow.visible = true;
closeSettingsButtonHighlight.visible = true;
closeSettingsText.visible = true;
speedMenuButton.visible = true;
speedMenuButtonShadow.visible = true;
speedMenuButtonHighlight.visible = true;
speedMenuText.visible = true;
languageMenuButton.visible = true;
languageMenuButtonShadow.visible = true;
languageMenuButtonHighlight.visible = true;
languageMenuText.visible = true;
}
// Function to hide settings menu
function hideSettingsMenu() {
settingsOverlay.visible = false;
settingsTitle.visible = false;
closeSettingsButton.visible = false;
closeSettingsButtonShadow.visible = false;
closeSettingsButtonHighlight.visible = false;
closeSettingsText.visible = false;
speedMenuButton.visible = false;
speedMenuButtonShadow.visible = false;
speedMenuButtonHighlight.visible = false;
speedMenuText.visible = false;
languageMenuButton.visible = false;
languageMenuButtonShadow.visible = false;
languageMenuButtonHighlight.visible = false;
languageMenuText.visible = false;
hideSpeedControls();
hideLanguageControls();
}
// Function to show language controls
function showLanguageControls() {
// Hide speed controls first
hideSpeedControls();
// Hide language menu button
languageMenuButton.visible = false;
languageMenuText.visible = false;
// Remove and re-add language overlay to bring it to front
LK.gui.center.removeChild(languageOverlay);
LK.gui.center.addChild(languageOverlay);
// Remove and re-add all language elements to bring them to front
LK.gui.center.removeChild(languageTitle);
LK.gui.center.addChild(languageTitle);
LK.gui.center.removeChild(turkishButton);
LK.gui.center.addChild(turkishButton);
LK.gui.center.removeChild(turkishText);
LK.gui.center.addChild(turkishText);
LK.gui.center.removeChild(englishButton);
LK.gui.center.addChild(englishButton);
LK.gui.center.removeChild(englishText);
LK.gui.center.addChild(englishText);
LK.gui.center.removeChild(currentLanguageText);
LK.gui.center.addChild(currentLanguageText);
LK.gui.center.removeChild(languageBackButton);
LK.gui.center.addChild(languageBackButton);
LK.gui.center.removeChild(languageBackText);
LK.gui.center.addChild(languageBackText);
// Show language overlay and controls
languageOverlay.visible = true;
languageTitle.visible = true;
turkishButton.visible = true;
turkishButtonShadow.visible = true;
turkishButtonHighlight.visible = true;
turkishText.visible = true;
englishButton.visible = true;
englishButtonShadow.visible = true;
englishButtonHighlight.visible = true;
englishText.visible = true;
currentLanguageText.visible = true;
languageBackButton.visible = true;
languageBackButtonShadow.visible = true;
languageBackButtonHighlight.visible = true;
languageBackText.visible = true;
updateLanguageDisplay();
}
// Function to hide language controls
function hideLanguageControls() {
languageOverlay.visible = false;
languageTitle.visible = false;
turkishButton.visible = false;
turkishButtonShadow.visible = false;
turkishButtonHighlight.visible = false;
turkishText.visible = false;
englishButton.visible = false;
englishButtonShadow.visible = false;
englishButtonHighlight.visible = false;
englishText.visible = false;
currentLanguageText.visible = false;
languageBackButton.visible = false;
languageBackButtonShadow.visible = false;
languageBackButtonHighlight.visible = false;
languageBackText.visible = false;
// Show language menu button again if settings overlay is visible
if (settingsOverlay.visible) {
languageMenuButton.visible = true;
languageMenuButtonShadow.visible = true;
languageMenuButtonHighlight.visible = true;
languageMenuText.visible = true;
}
}
// Language text objects
var languageTexts = {
tr: {
mainTitle: 'FLAPPY BIRD',
playButton: 'OYNA',
instruction: 'TIKLA VE OYNA!',
gameOver: 'OYUN BİTTİ',
score: 'SKOR',
bestScore: 'EN İYİ',
retry: 'TEKRAR DENE',
mainMenu: 'ANA MENÜ',
settings: 'AYARLAR',
close: 'KAPAT',
speed: 'HIZ',
language: 'DİL',
speedTitle: 'HIZ AYARI',
languageTitle: 'DİL SEÇENEKLERİ',
normal: 'NORMAL',
current: 'MEVCUT',
highestScore: 'EN YÜKSEK',
back: 'GERİ'
},
en: {
mainTitle: 'FLAPPY BIRD',
playButton: 'PLAY',
instruction: 'CLICK TO PLAY!',
gameOver: 'GAME OVER',
score: 'SCORE',
bestScore: 'BEST',
retry: 'RETRY',
mainMenu: 'MAIN MENU',
settings: 'SETTINGS',
close: 'CLOSE',
speed: 'SPEED',
language: 'LANGUAGE',
speedTitle: 'SPEED SETTINGS',
languageTitle: 'LANGUAGE OPTIONS',
normal: 'NORMAL',
current: 'CURRENT',
highestScore: 'HIGHEST SCORE',
back: 'BACK'
}
};
// Function to get text for current language
function getText(key) {
return languageTexts[currentLanguage][key] || languageTexts['en'][key];
}
// Function to update all text elements to current language
function updateAllTexts() {
try {
// Main menu texts
if (instructionTxt && instructionTxt.setText) {
instructionTxt.setText(getText('instruction'));
// Use proper text sizing
var bgWidth = 400;
if (instructionTxt.width > bgWidth - 20) {
var newSize = Math.max(40, Math.floor(60 * (bgWidth - 20) / instructionTxt.width));
instructionTxt.style = {
size: newSize,
fill: instructionTxt.style.fill
};
}
}
// Update play button text
if (playButtonText && playButtonText.setText) {
playButtonText.setText(getText('playButton'));
// Use proper text sizing for play button
var playButtonWidth = 370;
if (playButtonText.width > playButtonWidth - 20) {
var newSize = Math.max(35, Math.floor(50 * (playButtonWidth - 20) / playButtonText.width));
playButtonText.style = {
size: newSize,
fill: playButtonText.style.fill
};
}
}
// Game over texts - always update these regardless of visibility
if (gameOverTitle && gameOverTitle.setText) gameOverTitle.setText(getText('gameOver'));
if (retryButtonText && retryButtonText.setText) {
retryButtonText.setText(getText('retry'));
// Use proper text sizing
var retryButtonWidth = 320;
if (retryButtonText.width > retryButtonWidth - 20) {
var newSize = Math.max(30, Math.floor(38 * (retryButtonWidth - 20) / retryButtonText.width));
retryButtonText.style = {
size: newSize,
fill: retryButtonText.style.fill
};
}
}
if (menuButtonText && menuButtonText.setText) {
menuButtonText.setText(getText('mainMenu'));
// Use proper text sizing
var menuButtonWidth = 320;
if (menuButtonText.width > menuButtonWidth - 20) {
var newSize = Math.max(30, Math.floor(38 * (menuButtonWidth - 20) / menuButtonText.width));
menuButtonText.style = {
size: newSize,
fill: menuButtonText.style.fill
};
}
}
// Settings texts
if (settingsTitle && settingsTitle.setText) settingsTitle.setText(getText('settings'));
if (closeSettingsText && closeSettingsText.setText) {
closeSettingsText.setText(getText('close'));
// Use proper text sizing
var closeButtonWidth = 240;
if (closeSettingsText.width > closeButtonWidth - 20) {
var newSize = Math.max(28, Math.floor(36 * (closeButtonWidth - 20) / closeSettingsText.width));
closeSettingsText.style = {
size: newSize,
fill: closeSettingsText.style.fill
};
}
}
if (speedMenuText && speedMenuText.setText) {
speedMenuText.setText(getText('speed'));
// Use proper text sizing
var speedMenuWidth = 320;
if (speedMenuText.width > speedMenuWidth - 20) {
var newSize = Math.max(32, Math.floor(42 * (speedMenuWidth - 20) / speedMenuText.width));
speedMenuText.style = {
size: newSize,
fill: speedMenuText.style.fill
};
}
}
if (languageMenuText && languageMenuText.setText) {
languageMenuText.setText(getText('language'));
// Use proper text sizing
var languageMenuWidth = 320;
if (languageMenuText.width > languageMenuWidth - 20) {
var newSize = Math.max(32, Math.floor(42 * (languageMenuWidth - 20) / languageMenuText.width));
languageMenuText.style = {
size: newSize,
fill: languageMenuText.style.fill
};
}
}
if (speedTitle && speedTitle.setText) speedTitle.setText(getText('speedTitle'));
if (languageTitle && languageTitle.setText) languageTitle.setText(getText('languageTitle'));
if (normalSpeedText && normalSpeedText.setText) {
normalSpeedText.setText(getText('normal'));
// Use proper text sizing
var normalSpeedWidth = 160;
if (normalSpeedText.width > normalSpeedWidth - 20) {
var newSize = Math.max(24, Math.floor(32 * (normalSpeedWidth - 20) / normalSpeedText.width));
normalSpeedText.style = {
size: newSize,
fill: normalSpeedText.style.fill
};
}
}
if (speedBackText && speedBackText.setText) {
speedBackText.setText(getText('back'));
// Use proper text sizing
var backButtonWidth = 200;
if (speedBackText.width > backButtonWidth - 20) {
var newSize = Math.max(28, Math.floor(36 * (backButtonWidth - 20) / speedBackText.width));
speedBackText.style = {
size: newSize,
fill: speedBackText.style.fill
};
}
}
if (languageBackText && languageBackText.setText) {
languageBackText.setText(getText('back'));
// Use proper text sizing
var langBackButtonWidth = 200;
if (languageBackText.width > langBackButtonWidth - 20) {
var newSize = Math.max(28, Math.floor(36 * (langBackButtonWidth - 20) / languageBackText.width));
languageBackText.style = {
size: newSize,
fill: languageBackText.style.fill
};
}
}
// Update current speed text with proper language
var speedText = getText('normal');
if (gameSpeed === 2) speedText = '2X';else if (gameSpeed === 1.5) speedText = '1.5X';else if (gameSpeed === 2.5) speedText = '2.5X';
if (currentSpeedText && currentSpeedText.setText) {
currentSpeedText.setText(getText('current') + ': ' + speedText);
// Use proper text sizing
if (currentSpeedText.width > 600) {
var newSize = Math.max(35, Math.floor(50 * 600 / currentSpeedText.width));
currentSpeedText.style = {
size: newSize,
fill: currentSpeedText.style.fill
};
}
}
// Update final and best score texts - always update these regardless of visibility
if (finalScoreText && finalScoreText.setText) {
var currentScore = LK.getScore();
finalScoreText.setText(getText('score') + ': ' + currentScore);
if (finalScoreText.width > 600) {
var newSize = Math.max(50, Math.floor(80 * 600 / finalScoreText.width));
finalScoreText.style = {
size: newSize,
fill: finalScoreText.style.fill
};
}
}
if (bestScoreText && bestScoreText.setText) {
var currentHighScore = _storage.highScore || 0;
bestScoreText.setText(getText('bestScore') + ': ' + currentHighScore);
if (bestScoreText.width > 600) {
var newSize = Math.max(40, Math.floor(60 * 600 / bestScoreText.width));
bestScoreText.style = {
size: newSize,
fill: bestScoreText.style.fill
};
}
}
} catch (e) {
console.log("Text update error:", e);
}
}
// Function to update language display
function updateLanguageDisplay() {
var langText = currentLanguage === 'tr' ? 'TÜRKÇE' : 'ENGLISH';
var currentText = currentLanguage === 'tr' ? 'MEVCUT' : 'CURRENT';
currentLanguageText.setText(currentText + ': ' + langText);
// Use proper text sizing
if (currentLanguageText.width > 600) {
var newSize = Math.max(35, Math.floor(50 * 600 / currentLanguageText.width));
currentLanguageText.style = {
size: newSize,
fill: currentLanguageText.style.fill
};
}
// Update button colors to show selected language
turkishButton.tint = currentLanguage === 'tr' ? 0x2ECC71 : 0x27AE60;
englishButton.tint = currentLanguage === 'en' ? 0x5DADE2 : 0x3498DB;
// Ensure language button texts fit properly
if (turkishText && turkishText.setText) {
turkishText.setText('TÜRKÇE');
var turkishButtonWidth = 240;
if (turkishText.width > turkishButtonWidth - 20) {
var newSize = Math.max(24, Math.floor(32 * (turkishButtonWidth - 20) / turkishText.width));
turkishText.style = {
size: newSize,
fill: turkishText.style.fill
};
}
}
if (englishText && englishText.setText) {
englishText.setText('ENGLISH');
var englishButtonWidth = 240;
if (englishText.width > englishButtonWidth - 20) {
var newSize = Math.max(24, Math.floor(32 * (englishButtonWidth - 20) / englishText.width));
englishText.style = {
size: newSize,
fill: englishText.style.fill
};
}
}
}
// Function to set language
function setLanguage(lang) {
currentLanguage = lang;
_storage.language = lang;
// Update all text elements immediately
updateAllTexts();
// Update language display
updateLanguageDisplay();
// Update speed display to use correct language
updateSpeedDisplay();
}
// Function to show speed controls
function showSpeedControls() {
// Hide language controls first
hideLanguageControls();
// Hide speed menu button
speedMenuButton.visible = false;
speedMenuText.visible = false;
// Remove and re-add speed overlay to bring it to front
LK.gui.center.removeChild(speedOverlay);
LK.gui.center.addChild(speedOverlay);
// Remove and re-add all speed elements to bring them to front
LK.gui.center.removeChild(speedTitle);
LK.gui.center.addChild(speedTitle);
LK.gui.center.removeChild(normalSpeedButton);
LK.gui.center.addChild(normalSpeedButton);
LK.gui.center.removeChild(normalSpeedText);
LK.gui.center.addChild(normalSpeedText);
LK.gui.center.removeChild(speed15xButton);
LK.gui.center.addChild(speed15xButton);
LK.gui.center.removeChild(speed15xText);
LK.gui.center.addChild(speed15xText);
LK.gui.center.removeChild(speed2xButton);
LK.gui.center.addChild(speed2xButton);
LK.gui.center.removeChild(speed2xText);
LK.gui.center.addChild(speed2xText);
LK.gui.center.removeChild(speed25xButton);
LK.gui.center.addChild(speed25xButton);
LK.gui.center.removeChild(speed25xText);
LK.gui.center.addChild(speed25xText);
LK.gui.center.removeChild(currentSpeedText);
LK.gui.center.addChild(currentSpeedText);
LK.gui.center.removeChild(speedBackButton);
LK.gui.center.addChild(speedBackButton);
LK.gui.center.removeChild(speedBackText);
LK.gui.center.addChild(speedBackText);
// Show speed overlay and controls
speedOverlay.visible = true;
speedTitle.visible = true;
normalSpeedButton.visible = true;
normalSpeedButtonShadow.visible = true;
normalSpeedButtonHighlight.visible = true;
normalSpeedText.visible = true;
speed15xButton.visible = true;
speed15xButtonShadow.visible = true;
speed15xButtonHighlight.visible = true;
speed15xText.visible = true;
speed2xButton.visible = true;
speed2xButtonShadow.visible = true;
speed2xButtonHighlight.visible = true;
speed2xText.visible = true;
speed25xButton.visible = true;
speed25xButtonShadow.visible = true;
speed25xButtonHighlight.visible = true;
speed25xText.visible = true;
currentSpeedText.visible = true;
speedBackButton.visible = true;
speedBackButtonShadow.visible = true;
speedBackButtonHighlight.visible = true;
speedBackText.visible = true;
updateSpeedDisplay();
}
// Function to hide speed controls
function hideSpeedControls() {
speedOverlay.visible = false;
speedTitle.visible = false;
normalSpeedButton.visible = false;
normalSpeedButtonShadow.visible = false;
normalSpeedButtonHighlight.visible = false;
normalSpeedText.visible = false;
speed2xButton.visible = false;
speed2xButtonShadow.visible = false;
speed2xButtonHighlight.visible = false;
speed2xText.visible = false;
speed25xButton.visible = false;
speed25xButtonShadow.visible = false;
speed25xButtonHighlight.visible = false;
speed25xText.visible = false;
speed15xButton.visible = false;
speed15xButtonShadow.visible = false;
speed15xButtonHighlight.visible = false;
speed15xText.visible = false;
currentSpeedText.visible = false;
speedBackButton.visible = false;
speedBackButtonShadow.visible = false;
speedBackButtonHighlight.visible = false;
speedBackText.visible = false;
// Show speed menu button again if settings overlay is visible
if (settingsOverlay.visible) {
speedMenuButton.visible = true;
speedMenuButtonShadow.visible = true;
speedMenuButtonHighlight.visible = true;
speedMenuText.visible = true;
}
}
// Function to update speed display
function updateSpeedDisplay() {
var speedText = getText('normal');
if (gameSpeed === 2) speedText = '2X';else if (gameSpeed === 1.5) speedText = '1.5X';else if (gameSpeed === 2.5) speedText = '2.5X';
currentSpeedText.setText(getText('current') + ': ' + speedText);
// Use proper text sizing
if (currentSpeedText.width > 600) {
var newSize = Math.max(35, Math.floor(50 * 600 / currentSpeedText.width));
currentSpeedText.style = {
size: newSize,
fill: currentSpeedText.style.fill
};
}
// Update button colors to show selected speed with more distinct colors
normalSpeedButton.tint = gameSpeed === 1 ? 0x1ABC9C : 0x27AE60; // Brighter teal when selected
speed2xButton.tint = gameSpeed === 2 ? 0xFF6B6B : 0xE74C3C; // Brighter red when selected
speed15xButton.tint = gameSpeed === 1.5 ? 0xFFE066 : 0xF39C12; // Brighter yellow when selected
speed25xButton.tint = gameSpeed === 2.5 ? 0xE91E63 : 0x9C27B0; // Brighter purple when selected
// Add subtle pulse animation to the selected button
if (gameSpeed === 1) {
tween(normalSpeedButton, {
scaleX: 1.05,
scaleY: 1.05
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(normalSpeedButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 500,
easing: tween.easeInOut
});
}
});
} else if (gameSpeed === 1.5) {
tween(speed15xButton, {
scaleX: 1.05,
scaleY: 1.05
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(speed15xButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 500,
easing: tween.easeInOut
});
}
});
} else if (gameSpeed === 2) {
tween(speed2xButton, {
scaleX: 1.05,
scaleY: 1.05
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(speed2xButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 500,
easing: tween.easeInOut
});
}
});
} else if (gameSpeed === 2.5) {
tween(speed25xButton, {
scaleX: 1.05,
scaleY: 1.05
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(speed25xButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 500,
easing: tween.easeInOut
});
}
});
}
// Ensure speed button texts fit properly and use correct language
if (normalSpeedText && normalSpeedText.setText) {
normalSpeedText.setText(getText('normal'));
var normalButtonWidth = 160;
if (normalSpeedText.width > normalButtonWidth - 20) {
var newSize = Math.max(24, Math.floor(32 * (normalButtonWidth - 20) / normalSpeedText.width));
normalSpeedText.style = {
size: newSize,
fill: normalSpeedText.style.fill
};
}
}
}
// Function to set game speed
function setGameSpeed(newSpeed) {
gameSpeed = newSpeed;
// Update dynamic spacing based on new speed
pipeSpacing = 500 + gameSpeed * 50;
updateSpeedDisplay();
// Update existing pipes if they exist
for (var i = 0; i < pipes.length; i++) {
if (pipes[i]) {
pipes[i].speed = basePipeSpeed * gameSpeed;
// Update gap size for existing pipes
pipes[i].gapSize = 750 + (gameSpeed - 1) * 50;
}
}
}
// Current language variable
var currentLanguage = 'tr'; // Default to Turkish
// Initialize local storage arrays if they don't exist
try {
// Use persistent storage directly
_storage = storage;
// Initialize arrays and values if they don't exist, but preserve existing values
if (!_storage.globalLeaderboardNames) _storage.globalLeaderboardNames = [];
if (!_storage.globalLeaderboardScores) _storage.globalLeaderboardScores = [];
if (typeof _storage.highScore === 'undefined') _storage.highScore = 0;
if (typeof _storage.lastScore === 'undefined') _storage.lastScore = 0;
if (!_storage.language) _storage.language = 'tr';
if (!_storage.username) _storage.username = 'Oyuncu1';
currentLanguage = _storage.language;
} catch (e) {
console.log("Storage initialization error:", e);
_storage = {
globalLeaderboardNames: [],
globalLeaderboardScores: [],
highScore: 0,
lastScore: 0,
language: 'tr',
username: 'Oyuncu1'
};
}
// Initialize username if not exists
if (!_storage.username) {
var playerNumber = 1;
while (_storage.globalLeaderboardNames.indexOf('Oyuncu ' + playerNumber) !== -1) {
playerNumber++;
}
_storage.username = 'Oyuncu ' + playerNumber;
}
// Create animated play button for main menu
var playButton = LK.getAsset('playButtonMain', {
anchorX: 0.5,
anchorY: 0.5,
width: 400,
height: 120,
alpha: 1.0
});
playButton.tint = 0xFF9800; // Flappy Bird orange
try {
if (LK.gui && LK.gui.center) {
LK.gui.center.addChild(playButton);
playButton.y = -100;
}
} catch (e) {
console.log("Play button error:", e);
}
// Create separate play button shadow element
var playButtonShadow = LK.getAsset('playButtonShadow', {
anchorX: 0.5,
anchorY: 0.5,
width: 400,
height: 120,
alpha: 0.4
});
playButtonShadow.tint = 0xE65100; // Darker orange shadow
try {
if (LK.gui && LK.gui.center) {
LK.gui.center.addChild(playButtonShadow);
playButtonShadow.y = -92; // Offset shadow slightly up
playButtonShadow.x = 4; // Offset shadow slightly right
}
} catch (e) {
console.log("Play button shadow error:", e);
}
// Create separate play button highlight element
var playButtonHighlight = LK.getAsset('playButtonHighlight', {
anchorX: 0.5,
anchorY: 0.5,
width: 370,
height: 95,
alpha: 0.5
});
playButtonHighlight.tint = 0xFFB74D; // Lighter orange highlight
try {
if (LK.gui && LK.gui.center) {
LK.gui.center.addChild(playButtonHighlight);
playButtonHighlight.y = -108; // Offset highlight slightly down
}
} catch (e) {
console.log("Play button highlight error:", e);
}
// Create separate play button text element
var playButtonText = new Text2('OYNA', {
size: 50,
fill: 0xFFFFFF
});
playButtonText.anchor.set(0.5, 0.5);
playButtonText.stroke = 0xE65100;
playButtonText.strokeThickness = 4;
try {
if (LK.gui && LK.gui.center) {
LK.gui.center.addChild(playButtonText);
playButtonText.y = -100;
}
} catch (e) {
console.log("Play button text error:", e);
}
// Start continuous floating animation for play button
function startPlayButtonAnimation() {
if (playButton && playButton.parent) {
tween(playButton, {
y: -120,
scaleX: 1.05,
scaleY: 1.05
}, {
duration: 1500,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (playButton && playButton.parent) {
tween(playButton, {
y: -80,
scaleX: 0.95,
scaleY: 0.95
}, {
duration: 1500,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (showMainMenu) {
startPlayButtonAnimation(); // Loop animation
}
}
});
}
}
});
}
// Animate shadow with slight delay
if (playButtonShadow && playButtonShadow.parent) {
tween(playButtonShadow, {
y: -112,
scaleX: 1.05,
scaleY: 1.05,
alpha: 0.3
}, {
duration: 1500,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (playButtonShadow && playButtonShadow.parent) {
tween(playButtonShadow, {
y: -72,
scaleX: 0.95,
scaleY: 0.95,
alpha: 0.4
}, {
duration: 1500,
easing: tween.easeInOut
});
}
}
});
}
// Animate highlight with slight delay
if (playButtonHighlight && playButtonHighlight.parent) {
tween(playButtonHighlight, {
y: -128,
scaleX: 1.05,
scaleY: 1.05,
alpha: 0.4
}, {
duration: 1500,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (playButtonHighlight && playButtonHighlight.parent) {
tween(playButtonHighlight, {
y: -88,
scaleX: 0.95,
scaleY: 0.95,
alpha: 0.5
}, {
duration: 1500,
easing: tween.easeInOut
});
}
}
});
}
// Animate text
if (playButtonText && playButtonText.parent) {
tween(playButtonText, {
y: -120,
scaleX: 1.05,
scaleY: 1.05
}, {
duration: 1500,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (playButtonText && playButtonText.parent) {
tween(playButtonText, {
y: -80,
scaleX: 0.95,
scaleY: 0.95
}, {
duration: 1500,
easing: tween.easeInOut
});
}
}
});
}
}
// Initialize game
resetGame(); // Use resetGame to properly initialize all states
// Update all texts to current language
updateAllTexts();
// Touch/click handler
game.down = function (x, y, obj) {
// Check settings button click - settings button is positioned at topRight with offset
var settingsX = 2048 - 80; // topRight.x + settingsButton.x offset
var settingsY = 80; // topRight.y + settingsButton.y offset
var settingsSize = 120; // Settings button size
if (x >= settingsX - settingsSize / 2 && x <= settingsX + settingsSize / 2 && y >= settingsY - settingsSize / 2 && y <= settingsY + settingsSize / 2) {
// Prevent rapid clicks
var currentTime;
try {
currentTime = Date.now ? Date.now() : new Date().getTime();
} catch (e) {
currentTime = 0;
}
if (currentTime - lastButtonClickTime < 500) {
return; // Ignore click if too recent
}
lastButtonClickTime = currentTime;
// Add visual feedback with tween for all settings button elements
tween(settingsButton, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 100,
onFinish: function onFinish() {
tween(settingsButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100
});
}
});
// Animate settings button shadow
tween(settingsButtonShadow, {
scaleX: 1.2,
scaleY: 1.2,
alpha: 0.5
}, {
duration: 100,
onFinish: function onFinish() {
tween(settingsButtonShadow, {
scaleX: 1.0,
scaleY: 1.0,
alpha: 0.3
}, {
duration: 100
});
}
});
// Animate settings button highlight
tween(settingsButtonHighlight, {
scaleX: 1.2,
scaleY: 1.2,
alpha: 0.6
}, {
duration: 100,
onFinish: function onFinish() {
tween(settingsButtonHighlight, {
scaleX: 1.0,
scaleY: 1.0,
alpha: 0.4
}, {
duration: 100
});
}
});
// Animate settings icon
tween(settingsIcon, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 100,
onFinish: function onFinish() {
tween(settingsIcon, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100
});
}
});
showSettingsMenu();
return;
}
// Check close settings button if settings menu is open
if (settingsOverlay.visible) {
// Add invisible barriers between menu sections to prevent overlapping clicks
// Speed menu section barrier (between speed and language menus)
if (speedMenuButton.visible && !speedOverlay.visible && !languageOverlay.visible) {
// Check speed menu button (HIZ) with isolated click area
if (x >= 824 && x <= 1224 && y >= 1166 && y <= 1266) {
var currentTime = Date.now();
if (currentTime - lastButtonClickTime < 300) return;
lastButtonClickTime = currentTime;
tween(speedMenuButton, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 100,
onFinish: function onFinish() {
tween(speedMenuButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100
});
}
});
// Animate shadow and highlight for depth effect
tween(speedMenuButtonShadow, {
scaleX: 1.1,
scaleY: 1.1,
alpha: 0.5
}, {
duration: 100,
onFinish: function onFinish() {
tween(speedMenuButtonShadow, {
scaleX: 1.0,
scaleY: 1.0,
alpha: 0.3
}, {
duration: 100
});
}
});
tween(speedMenuButtonHighlight, {
scaleX: 1.1,
scaleY: 1.1,
alpha: 0.6
}, {
duration: 100,
onFinish: function onFinish() {
tween(speedMenuButtonHighlight, {
scaleX: 1.0,
scaleY: 1.0,
alpha: 0.4
}, {
duration: 100
});
}
});
showSpeedControls();
return;
}
// Barrier zone between speed and language buttons (y: 1266-1296)
if (y >= 1266 && y <= 1296) {
return; // Block clicks in the barrier zone
}
}
// Language menu section barrier
if (languageMenuButton.visible && !speedOverlay.visible && !languageOverlay.visible) {
// Check language menu button (DIL) with isolated click area
if (x >= 824 && x <= 1224 && y >= 1296 && y <= 1396) {
var currentTime = Date.now();
if (currentTime - lastButtonClickTime < 300) return;
lastButtonClickTime = currentTime;
tween(languageMenuButton, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 100,
onFinish: function onFinish() {
tween(languageMenuButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100
});
}
});
// Animate shadow and highlight for depth effect
tween(languageMenuButtonShadow, {
scaleX: 1.1,
scaleY: 1.1,
alpha: 0.5
}, {
duration: 100,
onFinish: function onFinish() {
tween(languageMenuButtonShadow, {
scaleX: 1.0,
scaleY: 1.0,
alpha: 0.3
}, {
duration: 100
});
}
});
tween(languageMenuButtonHighlight, {
scaleX: 1.1,
scaleY: 1.1,
alpha: 0.6
}, {
duration: 100,
onFinish: function onFinish() {
tween(languageMenuButtonHighlight, {
scaleX: 1.0,
scaleY: 1.0,
alpha: 0.4
}, {
duration: 100
});
}
});
showLanguageControls();
return;
}
}
// Language control buttons with barriers - only when language overlay is visible
if (languageOverlay.visible) {
// Turkish language button with isolated click area
if (turkishButton.visible && x >= 654 && x <= 954 && y >= 1246 && y <= 1326) {
var currentTime = Date.now();
if (currentTime - lastButtonClickTime < 300) return;
lastButtonClickTime = currentTime;
tween(turkishButton, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 100,
onFinish: function onFinish() {
tween(turkishButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100
});
}
});
setLanguage('tr');
return;
}
// Barrier zone between Turkish and English buttons (x: 954-1094)
if (x >= 954 && x <= 1094 && y >= 1246 && y <= 1326) {
return; // Block clicks in barrier zone
}
// English language button with isolated click area
if (englishButton.visible && x >= 1094 && x <= 1394 && y >= 1246 && y <= 1326) {
var currentTime = Date.now();
if (currentTime - lastButtonClickTime < 300) return;
lastButtonClickTime = currentTime;
tween(englishButton, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 100,
onFinish: function onFinish() {
tween(englishButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100
});
}
});
setLanguage('en');
return;
}
}
// Speed control buttons with barriers - only when speed overlay is visible
if (speedOverlay.visible) {
// Normal speed button with isolated click area
if (normalSpeedButton.visible && x >= 644 && x <= 844 && y >= 1246 && y <= 1326) {
var currentTime = Date.now();
if (currentTime - lastButtonClickTime < 300) return;
lastButtonClickTime = currentTime;
tween(normalSpeedButton, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 100,
onFinish: function onFinish() {
tween(normalSpeedButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100
});
}
});
setGameSpeed(1);
return;
}
// Barrier zone between normal and 1.5x buttons (x: 844-924)
if (x >= 844 && x <= 924 && y >= 1246 && y <= 1326) {
return; // Block clicks in barrier zone
}
// 1.5X speed button with isolated click area
if (speed15xButton.visible && x >= 924 && x <= 1124 && y >= 1246 && y <= 1326) {
var currentTime = Date.now();
if (currentTime - lastButtonClickTime < 300) return;
lastButtonClickTime = currentTime;
tween(speed15xButton, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 100,
onFinish: function onFinish() {
tween(speed15xButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100
});
}
});
setGameSpeed(1.5);
return;
}
// Barrier zone between 1.5x and 2x buttons (x: 1124-1164)
if (x >= 1124 && x <= 1164 && y >= 1246 && y <= 1326) {
return; // Block clicks in barrier zone
}
// 2X speed button with isolated click area
if (speed2xButton.visible && x >= 1164 && x <= 1344 && y >= 1246 && y <= 1326) {
var currentTime = Date.now();
if (currentTime - lastButtonClickTime < 300) return;
lastButtonClickTime = currentTime;
tween(speed2xButton, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 100,
onFinish: function onFinish() {
tween(speed2xButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100
});
}
});
setGameSpeed(2);
return;
}
// Barrier zone between 2x and 2.5x buttons (x: 1344-1384)
if (x >= 1344 && x <= 1384 && y >= 1246 && y <= 1326) {
return; // Block clicks in barrier zone
}
// 2.5X speed button with isolated click area
if (speed25xButton.visible && x >= 1384 && x <= 1564 && y >= 1246 && y <= 1326) {
var currentTime = Date.now();
if (currentTime - lastButtonClickTime < 300) return;
lastButtonClickTime = currentTime;
tween(speed25xButton, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 100,
onFinish: function onFinish() {
tween(speed25xButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100
});
}
});
setGameSpeed(2.5);
return;
}
}
// Check speed back button at x = 1024, y = 1516, size 300x100
if (speedBackButton.visible && x >= 874 && x <= 1174 && y >= 1466 && y <= 1566) {
var currentTime = Date.now();
if (currentTime - lastButtonClickTime < 300) return;
lastButtonClickTime = currentTime;
tween(speedBackButton, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 100,
onFinish: function onFinish() {
tween(speedBackButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100
});
}
});
hideSpeedControls();
return;
}
// Check language back button at x = 1024, y = 1516, size 300x100
if (languageBackButton.visible && x >= 874 && x <= 1174 && y >= 1466 && y <= 1566) {
var currentTime = Date.now();
if (currentTime - lastButtonClickTime < 300) return;
lastButtonClickTime = currentTime;
tween(languageBackButton, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 100,
onFinish: function onFinish() {
tween(languageBackButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100
});
}
});
hideLanguageControls();
return;
}
// Check close settings button (KAPAT) - centered at 1024x1516, button is 300x100
if (x >= 874 && x <= 1174 && y >= 1466 && y <= 1566) {
// Prevent rapid clicks
var currentTime = Date.now();
if (currentTime - lastButtonClickTime < 300) {
return; // Ignore click if too recent
}
lastButtonClickTime = currentTime;
// Add visual feedback with tween
tween(closeSettingsButton, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 100,
onFinish: function onFinish() {
tween(closeSettingsButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100
});
}
});
// Animate shadow and highlight for depth effect
tween(closeSettingsButtonShadow, {
scaleX: 1.1,
scaleY: 1.1,
alpha: 0.5
}, {
duration: 100,
onFinish: function onFinish() {
tween(closeSettingsButtonShadow, {
scaleX: 1.0,
scaleY: 1.0,
alpha: 0.3
}, {
duration: 100
});
}
});
tween(closeSettingsButtonHighlight, {
scaleX: 1.1,
scaleY: 1.1,
alpha: 0.6
}, {
duration: 100,
onFinish: function onFinish() {
tween(closeSettingsButtonHighlight, {
scaleX: 1.0,
scaleY: 1.0,
alpha: 0.4
}, {
duration: 100
});
}
});
hideSettingsMenu();
return;
}
return; // Don't process other clicks when settings menu 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) {
// Prevent rapid clicks
var currentTime;
try {
currentTime = Date.now ? Date.now() : new Date().getTime();
} catch (e) {
currentTime = 0;
}
if (currentTime - lastButtonClickTime < 500) {
return; // Ignore click if too recent
}
lastButtonClickTime = currentTime;
// Clear any existing high score displays first
var existingDisplays = LK.gui.center.children;
for (var k = existingDisplays.length - 1; k >= 0; k--) {
var child = existingDisplays[k];
if (child && child.getText && child.getText().indexOf('EN YÜKSEK:') !== -1) {
try {
child.destroy();
} catch (e) {
console.log("Error destroying high score display:", e);
}
}
}
// Clear any existing backgrounds
for (var k = existingDisplays.length - 1; k >= 0; k--) {
var child = existingDisplays[k];
if (child && child.tint === 0x000000 && child.width === 700) {
try {
child.destroy();
} catch (e) {
console.log("Error destroying background:", e);
}
}
}
// Show highest score in a temporary display using storage
var highScore = _storage && _storage.highScore || 0;
var highScoreDisplay = new Text2(getText('highestScore') + ': ' + highScore, {
size: 90,
fill: 0xFFFF00
});
highScoreDisplay.anchor.set(0.5, 0.5);
highScoreDisplay.stroke = 0x000000;
highScoreDisplay.strokeThickness = 4;
LK.gui.center.addChild(highScoreDisplay);
highScoreDisplay.y = -100;
// Add background for better visibility
var highScoreBg = LK.getAsset('barrier', {
anchorX: 0.5,
anchorY: 0.5,
width: 700,
height: 160,
alpha: 0.98
});
highScoreBg.tint = 0x000000;
LK.gui.center.addChild(highScoreBg);
highScoreBg.y = -100;
// Move background behind text
LK.gui.center.removeChild(highScoreBg);
LK.gui.center.addChildAt(highScoreBg, LK.gui.center.getChildIndex(highScoreDisplay));
// Auto-hide after 3 seconds
LK.setTimeout(function () {
try {
if (highScoreDisplay && highScoreDisplay.parent) {
highScoreDisplay.destroy();
}
if (highScoreBg && highScoreBg.parent) {
highScoreBg.destroy();
}
} catch (e) {
console.log("Error in timeout cleanup:", e);
}
}, 3000);
return;
}
if (gameOver || showGameOver) {
// Check retry button (TEKRAR DENE) - centered at 1024x1466, button is 380x110
if (x >= 834 && x <= 1214 && y >= 1411 && y <= 1521) {
// Prevent rapid clicks
var currentTime = Date.now();
if (currentTime - lastButtonClickTime < 300) {
return; // Ignore click if too recent
}
lastButtonClickTime = currentTime;
// Add enhanced visual feedback with tween
tween(retryButton, {
scaleX: 1.15,
scaleY: 1.15
}, {
duration: 120,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(retryButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 150,
easing: tween.easeInOut
});
}
});
// Animate shadow and highlight for depth effect
tween(retryButtonShadow, {
scaleX: 1.15,
scaleY: 1.15,
alpha: 0.5
}, {
duration: 120,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(retryButtonShadow, {
scaleX: 1.0,
scaleY: 1.0,
alpha: 0.3
}, {
duration: 150,
easing: tween.easeInOut
});
}
});
tween(retryButtonHighlight, {
scaleX: 1.15,
scaleY: 1.15,
alpha: 0.6
}, {
duration: 120,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(retryButtonHighlight, {
scaleX: 1.0,
scaleY: 1.0,
alpha: 0.4
}, {
duration: 150,
easing: tween.easeInOut
});
}
});
hideGameOverScreen();
resetGame();
// Show instruction screen instead of starting game directly
startGameFromMenu();
return;
}
// Check menu button (ANA MENÜ) - centered at 1024x1616, button is 380x110
if (x >= 834 && x <= 1214 && y >= 1561 && y <= 1671) {
// Prevent rapid clicks
var currentTime = Date.now();
if (currentTime - lastButtonClickTime < 300) {
return; // Ignore click if too recent
}
lastButtonClickTime = currentTime;
// Add enhanced visual feedback with tween
tween(menuButton, {
scaleX: 1.15,
scaleY: 1.15
}, {
duration: 120,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(menuButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 150,
easing: tween.easeInOut
});
}
});
// Animate shadow and highlight for depth effect
tween(menuButtonShadow, {
scaleX: 1.15,
scaleY: 1.15,
alpha: 0.5
}, {
duration: 120,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(menuButtonShadow, {
scaleX: 1.0,
scaleY: 1.0,
alpha: 0.3
}, {
duration: 150,
easing: tween.easeInOut
});
}
});
tween(menuButtonHighlight, {
scaleX: 1.15,
scaleY: 1.15,
alpha: 0.6
}, {
duration: 120,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(menuButtonHighlight, {
scaleX: 1.0,
scaleY: 1.0,
alpha: 0.4
}, {
duration: 150,
easing: tween.easeInOut
});
}
});
hideGameOverScreen();
resetGame();
return;
}
return;
}
if (showMainMenu) {
// Check play button click - centered at 1024x1266 (center.y = 1366 + playButton.y = -100), button is 400x120
if (playButton && playButton.visible && x >= 824 && x <= 1224 && y >= 1206 && y <= 1326) {
// Prevent rapid clicks
var currentTime = Date.now();
if (currentTime - lastButtonClickTime < 300) {
return; // Ignore click if too recent
}
lastButtonClickTime = currentTime;
// Enhanced click animation
tween(playButton, {
scaleX: 1.2,
scaleY: 1.2,
tint: 0xFFB74D
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(playButton, {
scaleX: 1.0,
scaleY: 1.0,
tint: 0xFF9800
}, {
duration: 150,
easing: tween.easeInOut
});
}
});
// Animate shadow
tween(playButtonShadow, {
scaleX: 1.2,
scaleY: 1.2,
alpha: 0.6
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(playButtonShadow, {
scaleX: 1.0,
scaleY: 1.0,
alpha: 0.4
}, {
duration: 150,
easing: tween.easeInOut
});
}
});
// Animate highlight
tween(playButtonHighlight, {
scaleX: 1.2,
scaleY: 1.2,
alpha: 0.8
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(playButtonHighlight, {
scaleX: 1.0,
scaleY: 1.0,
alpha: 0.5
}, {
duration: 150,
easing: tween.easeInOut
});
}
});
// Animate text
tween(playButtonText, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(playButtonText, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 150,
easing: tween.easeInOut
});
}
});
startGameFromMenu();
return;
}
return;
}
if (!gameStarted) {
gameStarted = true;
instructionTxt.visible = false;
// Remove invisible barriers when game starts
if (topBarrier) {
topBarrier.destroy();
topBarrier = null;
}
if (bottomBarrier) {
bottomBarrier.destroy();
bottomBarrier = null;
}
}
bird.flap();
};
// Main game loop
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 >= 2732 - 150 || bird.y - birdRadius <= 0) {
gameOver = true;
var currentScore = LK.getScore();
_storage.lastScore = currentScore;
if (currentScore > (_storage.highScore || 0)) {
_storage.highScore = currentScore;
// High score is automatically saved to persistent storage via _storage reference
}
// Add to leaderboard if score > 0
if (currentScore > 0 && _storage) {
var currentUsername = _storage.username || 'Oyuncu';
var playerExists = false;
var leaderboardNames = _storage.globalLeaderboardNames || [];
for (var i = 0; i < leaderboardNames.length; i++) {
if (_storage.globalLeaderboardNames[i] === currentUsername) {
if (currentScore > _storage.globalLeaderboardScores[i]) {
_storage.globalLeaderboardScores[i] = currentScore;
}
playerExists = true;
break;
}
}
if (!playerExists) {
_storage.globalLeaderboardNames.push(currentUsername);
_storage.globalLeaderboardScores.push(currentScore);
}
}
showGameOverScreen(currentScore);
return;
}
// Check pipe collisions and scoring
for (var i = 0; i < pipes.length; i++) {
var pipe = pipes[i];
if (!pipe || !bird || pipe.destroyed || !pipe.parent) continue;
// Check scoring first - only for pipes that haven't been passed yet
// Only score if bird has actually moved past the pipe center (not just the edge)
if (!pipe.passed && pipe.x < bird.x) {
pipe.passed = true;
LK.setScore(LK.getScore() + 1);
scoreTxt.setText(LK.getScore().toString());
try {
var scoreSound = LK.getSound('score');
if (scoreSound && scoreSound.play) {
scoreSound.play();
}
} catch (e) {
console.log("Sound error:", e);
}
}
// Only check collision for pipes that are close to the bird
if (Math.abs(pipe.x - bird.x) < 150) {
// Check if bird is within pipe horizontally using actual pipe width
var pipeHalfWidth = (pipe.pipeWidth || 120) / 2;
if (bird.x + 40 > pipe.x - pipeHalfWidth && bird.x - 40 < pipe.x + pipeHalfWidth) {
// Check collision with top or bottom pipe - bird is 80px tall, so use 40px radius
var birdTop = bird.y - 40;
var birdBottom = bird.y + 40;
var gapTop = pipe.gapCenterY - pipe.gapSize / 2;
var gapBottom = pipe.gapCenterY + pipe.gapSize / 2;
// Collision occurs if bird overlaps with pipe (outside the gap)
if (birdTop < gapTop || birdBottom > gapBottom) {
gameOver = true;
var currentScore = LK.getScore();
_storage.lastScore = currentScore;
if (currentScore > (_storage.highScore || 0)) {
_storage.highScore = currentScore;
// High score is automatically saved to persistent storage via _storage reference
}
// Add to leaderboard if score > 0
if (currentScore > 0) {
var currentUsername = _storage.username;
var playerExists = false;
for (var j = 0; j < _storage.globalLeaderboardNames.length; j++) {
if (_storage.globalLeaderboardNames[j] === currentUsername) {
if (currentScore > _storage.globalLeaderboardScores[j]) {
_storage.globalLeaderboardScores[j] = currentScore;
}
playerExists = true;
break;
}
}
if (!playerExists) {
_storage.globalLeaderboardNames.push(currentUsername);
_storage.globalLeaderboardScores.push(currentScore);
}
}
showGameOverScreen(currentScore);
return;
}
}
}
}
// Create new pipes - maintain consistent spacing
if (pipes.length === 0 || pipes.length > 0 && pipes[pipes.length - 1].x <= 2048 + 100 - pipeSpacing) {
createPipe();
}
// Remove off-screen pipes periodically using frame counter
if (!game.frameCounter) game.frameCounter = 0;
game.frameCounter++;
if (game.frameCounter % 30 === 0) {
for (var j = pipes.length - 1; j >= 0; j--) {
if (pipes[j].x < -150) {
pipes[j].destroy();
pipes.splice(j, 1);
}
}
}
}
}; ===================================================================
--- original.js
+++ change.js
@@ -2,102 +2,90 @@
* 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;
- // Don't set gravity and jumpStrength here as gameSpeed may not be initialized yet
- // They will be set dynamically in update method
+ self.isFlapping = false;
+ self.flapCooldown = 0;
+ self.idleTime = 0;
+ self.lastFlapTime = 0;
+ // Animation state tracking
+ self.animationState = 'idle'; // 'idle', 'flapping', 'falling', 'gliding'
+ self.wingPhase = 0; // For continuous wing animation
+ self.bobPhase = 0; // For idle floating animation
+ // Enhanced flap function with realistic physics and animations
self.flap = function () {
- // Set velocity with more balanced scaling for consistent control
- self.velocity = baseJumpStrength * Math.pow(gameSpeed, 0.8) * 1.05; // More balanced power scaling
- // Create natural wing flap animation with squash and stretch
+ // Prevent rapid flapping
+ if (self.flapCooldown > 0) return;
+ self.flapCooldown = 8; // Frames to wait before next flap
+ // Set velocity with balanced scaling
+ self.velocity = baseJumpStrength * Math.pow(gameSpeed, 0.8) * 1.05;
+ self.isFlapping = true;
+ self.animationState = 'flapping';
+ self.lastFlapTime = 0;
+ // Stop any existing animations to prevent conflicts
+ tween.stop(birdGraphics);
+ tween.stop(self);
+ // Wing flap animation - quick downstroke
tween(birdGraphics, {
- scaleX: 1.3,
- scaleY: 0.8,
- rotation: -0.4
+ scaleX: 1.4,
+ scaleY: 0.7,
+ rotation: -0.3
}, {
- duration: 80,
+ duration: 60,
easing: tween.easeOut,
onFinish: function onFinish() {
- // Secondary animation for natural wing movement
+ // Wing upstroke - slower recovery
tween(birdGraphics, {
scaleX: 0.9,
- scaleY: 1.1,
- rotation: -0.2
+ scaleY: 1.2,
+ rotation: -0.1
}, {
- duration: 120,
+ duration: 100,
easing: tween.easeInOut,
onFinish: function onFinish() {
- // Return to normal with slight overshoot for natural feel
+ // Return to normal with gentle overshoot
tween(birdGraphics, {
scaleX: 1.05,
scaleY: 0.95,
- rotation: 0.1
+ rotation: 0.05
}, {
- duration: 150,
+ duration: 80,
easing: tween.easeOut,
onFinish: function onFinish() {
+ // Final settle
tween(birdGraphics, {
scaleX: 1.0,
scaleY: 1.0,
rotation: 0
}, {
- duration: 100,
- easing: tween.easeInOut
+ duration: 60,
+ easing: tween.easeInOut,
+ onFinish: function onFinish() {
+ self.isFlapping = false;
+ self.animationState = 'gliding';
+ }
});
}
});
}
});
}
});
- // Create natural arc movement - bird moves slightly forward and up during flap
- var currentX = self.x;
- var currentY = self.y;
- // First part of arc - upward and slightly forward
+ // Subtle upward movement during flap
tween(self, {
- x: currentX + 15,
- y: currentY - 25
+ y: self.y - 8
}, {
- duration: 100,
- easing: tween.easeOut,
- onFinish: function onFinish() {
- // Second part of arc - continue forward motion with natural deceleration
- tween(self, {
- x: currentX + 8
- }, {
- duration: 200,
- easing: tween.easeInOut
- });
- }
- });
- // Add slight horizontal bob for more natural movement
- tween(birdGraphics, {
- x: 3
- }, {
duration: 120,
- easing: tween.easeOut,
- onFinish: function onFinish() {
- tween(birdGraphics, {
- x: -2
- }, {
- duration: 180,
- easing: tween.easeInOut,
- onFinish: function onFinish() {
- tween(birdGraphics, {
- x: 0
- }, {
- duration: 100,
- easing: tween.easeOut
- });
- }
- });
- }
+ easing: tween.easeOut
});
+ // Play flap sound with error handling
try {
var flapSound = LK.getSound('flap');
if (flapSound && flapSound.play) {
flapSound.play();
@@ -105,43 +93,98 @@
} catch (e) {
console.log("Flap sound error:", e);
}
};
+ // Continuous idle animation for floating effect
+ self.startIdleAnimation = function () {
+ if (self.animationState !== 'idle') return;
+ self.bobPhase += 0.05;
+ var bobOffset = Math.sin(self.bobPhase) * 2;
+ var scaleVariation = 1 + Math.sin(self.bobPhase * 0.7) * 0.02;
+ // Gentle floating motion
+ tween(birdGraphics, {
+ y: bobOffset,
+ scaleX: scaleVariation,
+ scaleY: scaleVariation,
+ rotation: Math.sin(self.bobPhase * 0.3) * 0.05
+ }, {
+ duration: 100,
+ easing: tween.easeInOut
+ });
+ };
+ // Enhanced update method with better physics and animations
self.update = function () {
+ // Update cooldowns
+ if (self.flapCooldown > 0) self.flapCooldown--;
+ self.lastFlapTime++;
if (!gameStarted) {
- // Don't apply physics before game starts - keep bird completely still
+ // Pre-game idle state
self.velocity = 0;
- self.y = 1366; // Keep bird at starting position
- birdGraphics.rotation = 0; // Keep bird level
+ self.y = 1366;
+ self.animationState = 'idle';
+ self.startIdleAnimation();
return;
}
- // Update dynamic values based on current game speed with more balanced scaling
- var gravity = baseGravity * Math.pow(gameSpeed, 0.7); // More balanced gravity scaling
- var jumpStrength = baseJumpStrength * Math.pow(gameSpeed, 0.75); // More balanced jump scaling
+ // Update physics with dynamic scaling
+ var gravity = baseGravity * Math.pow(gameSpeed, 0.7);
self.velocity += gravity;
self.y += self.velocity;
- // More responsive rotation based on velocity with better scaling
- var rotationScale = 0.065 + (gameSpeed - 1) * 0.015; // Slightly more responsive at higher speeds
- var targetRotation = Math.max(-0.5, Math.min(1.1, self.velocity * rotationScale));
- // Smooth rotation transition using tween for more natural movement
- if (Math.abs(birdGraphics.rotation - targetRotation) > 0.04) {
+ // Determine animation state based on velocity and recent flaps
+ if (self.isFlapping) {
+ self.animationState = 'flapping';
+ } else if (self.velocity > 2) {
+ self.animationState = 'falling';
+ } else if (self.velocity < -2) {
+ self.animationState = 'gliding';
+ } else {
+ self.animationState = 'idle';
+ }
+ // Dynamic rotation based on velocity and state
+ var targetRotation = 0;
+ if (self.animationState === 'falling') {
+ targetRotation = Math.min(1.2, self.velocity * 0.08);
+ } else if (self.animationState === 'gliding') {
+ targetRotation = Math.max(-0.6, self.velocity * 0.1);
+ } else if (self.animationState === 'flapping') {
+ targetRotation = -0.2;
+ }
+ // Smooth rotation transition
+ var rotationDiff = targetRotation - birdGraphics.rotation;
+ if (Math.abs(rotationDiff) > 0.02) {
tween(birdGraphics, {
rotation: targetRotation
}, {
- duration: 120,
+ duration: 100,
easing: tween.easeOut
});
}
- // Limit bird movement to screen bounds with proper collision detection
- var birdRadius = 40; // Half of bird height for collision detection
+ // Continuous wing animation during flight
+ if (self.animationState === 'falling' || self.animationState === 'gliding') {
+ self.wingPhase += 0.12;
+ var wingFlutter = Math.sin(self.wingPhase) * 0.05;
+ birdGraphics.scaleY = 1 + wingFlutter;
+ }
+ // Idle floating animation
+ if (self.animationState === 'idle' && !self.isFlapping) {
+ self.startIdleAnimation();
+ }
+ // Screen bounds collision with smooth handling
+ var birdRadius = 40;
if (self.y - birdRadius < 0) {
self.y = birdRadius;
- self.velocity = 0;
+ self.velocity = Math.max(0, self.velocity * 0.3); // Soft bounce
}
if (self.y + birdRadius > 2732 - 150) {
self.y = 2732 - 150 - birdRadius;
- self.velocity = 0;
+ self.velocity = Math.min(0, self.velocity * 0.3); // Soft bounce
}
+ // Add subtle particle trail effect during fast movement
+ if (Math.abs(self.velocity) > 8) {
+ // Create subtle glow effect
+ birdGraphics.alpha = 0.9 + Math.sin(self.wingPhase * 2) * 0.1;
+ } else {
+ birdGraphics.alpha = 1.0;
+ }
};
return self;
});
var Pipe = Container.expand(function (gapCenterY) {