User prompt
arasından geçtiğimiz duvarların kalitesi için baya bir uğraş ekstradan bloklar ve üzerinde uğraş ve daha düzgün daha gerçekçi hale getir oyundaki gibi olsun
User prompt
ayarlar kısmında menüler arası bariyer koy birbirlerini algılamasınlar birbirlerini hata vermesinler diye
User prompt
ayarlar kısmında dil seçeneği ve hız seçenekleri evet görünüm olarak birbirlerinde gözükmeseler bile tıklanırken birbirlerini algılıyorlar yani bir menüde diğeri algılanıyor böyle hataları düzelt
User prompt
oyun bitti tekrar dene ana menü gibi seçenekler ingilizce menü olsa bile türkçe kalıyor böyle hataları düzelt
User prompt
Diller Arası Karışım Oldu Türkçe Ve İngilizce Birbirine Girdi İngilizce Seçtiğimizde Tamamen İngilizce Menü Türkçe Seçtiğimizde Tamamen Türkçe Şey Olsun Hiç Birbirine Girmesin
User prompt
En Yüksek Skor Gibi Ve Başka Dillere Çevirdiğimizde Yazıların Tabelalardan Açtığını Görüyoruz. Her Dile Özgü Açmaması İçin Dikkat Et.
User prompt
en yüksek yaptığımız skoru gösteren tabela her zaman en yüksek yaptığımız skoru göstersin oyundan çık gir yapsak bile silinmesin ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
düğmeleri daha çok sade hale getir ve düğmeler daha düzgün daha şık dursun
User prompt
Arka planda yaşanan ama bizim görmediğimiz hataları düzeltin.
User prompt
Aslında hız seçenekleri yeşil duvarın arkasında kalmış olabilir. Öne getir ve bu ayarları diğer seçeneklerine göre düzgün hale getir. Diğer seçenekleri bozuyor olabilir.
User prompt
hız ayarları düğmeleri gözükmüyor baştan yap eskilerini sil
User prompt
düğmeleri aslında duvarın arkasına koymuş olabilirsin. gözükmüyor çünkü
User prompt
ayarlar kısmında hız seçenekleri gözükmüyor
User prompt
Ayarlar kısmında düğmeler birbirine girmiş öyle hataları düzelt ve düğmeleri daha düzgün hale getir.
User prompt
ayarlar kısmında geri tuşu kayboldu
User prompt
Hız kısmında ve dil kısmında hatalar oluştu.
User prompt
Ayarlar kısmında dil veya hızı seçince arkası gözükmesin.
User prompt
Kız veya dil seçeneğini seçince arkası gözüktüğü için kötü oluyor.
User prompt
dil ve ayarlar kısmında hız ve dil birbirine girdi ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Dilleri seçince menüler arası şeyler değişmiyor, Türkçe kalıyor. ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Oyunu ilk açtığımızda Türkçe değil İngilizce başlasın. ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Ayarlar kısmının arka planın rengini arkası gözükmeyecek şekilde ayarla
User prompt
ayarlar kısmına dil seçeneği ekle ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
oyundaki hiç birşey değiştirme ama tüm hataları düzelt
User prompt
en iyi skoru gösteren tabelanın hatalarını düzelt en yüksek yaptığımız skoru her zaman göstersin ↪💡 Consider importing and using the following plugins: @upit/storage.v1
/****
* Classes
****/
var Bird = Container.expand(function () {
var self = Container.call(this);
var birdGraphics = self.attachAsset('bird', {
anchorX: 0.5,
anchorY: 0.5
});
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.flap = function () {
self.velocity = baseJumpStrength * gameSpeed;
try {
var flapSound = LK.getSound('flap');
if (flapSound && flapSound.play) {
flapSound.play();
}
} catch (e) {
console.log("Flap sound error:", e);
}
};
self.update = function () {
if (!gameStarted) {
// Don't apply physics before game starts - keep bird completely still
self.velocity = 0;
self.y = 1366; // Keep bird at starting position
birdGraphics.rotation = 0; // Keep bird level
return;
}
// Update dynamic values based on current game speed
var gravity = baseGravity * gameSpeed;
var jumpStrength = baseJumpStrength * gameSpeed;
self.velocity += gravity;
self.y += self.velocity;
// Rotate bird based on velocity
birdGraphics.rotation = Math.max(-0.5, Math.min(1.5, self.velocity * 0.1));
// Limit bird movement to screen bounds with proper collision detection
var birdRadius = 40; // Half of bird height for collision detection
if (self.y - birdRadius < 0) {
self.y = birdRadius;
self.velocity = 0;
}
if (self.y + birdRadius > 2732 - 150) {
self.y = 2732 - 150 - birdRadius;
self.velocity = 0;
}
};
return self;
});
var Pipe = Container.expand(function (gapCenterY) {
var self = Container.call(this);
self.gapSize = 600;
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) {
// Don't create joints too close to top
// 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;
}
}
// Create rivets for industrial look
var rivetCount = Math.floor(topPipeHeight / 80);
for (var r = 0; r < rivetCount; r++) {
var rivetY = gapCenterY - self.gapSize / 2 + (r + 1) * 80;
if (rivetY > 30) {
// Left rivet
var leftRivet = self.attachAsset('pipeHighlight', {
anchorX: 0.5,
anchorY: 0.5
});
leftRivet.y = rivetY;
leftRivet.x = -45;
leftRivet.width = 8;
leftRivet.height = 8;
leftRivet.tint = 0x455A64; // Dark rivet
leftRivet.alpha = 0.9;
// Right rivet
var rightRivet = self.attachAsset('pipeHighlight', {
anchorX: 0.5,
anchorY: 0.5
});
rightRivet.y = rivetY;
rightRivet.x = 45;
rightRivet.width = 8;
rightRivet.height = 8;
rightRivet.tint = 0x455A64; // Dark rivet
rightRivet.alpha = 0.9;
}
}
// 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;
}
}
// Create rivets for industrial look
var bottomRivetCount = Math.floor(bottomPipeHeight / 80);
for (var r = 0; r < bottomRivetCount; r++) {
var rivetY = gapCenterY + self.gapSize / 2 + (r + 1) * 80;
if (rivetY < 2732 - 180) {
// Left rivet
var leftRivet = self.attachAsset('pipeHighlight', {
anchorX: 0.5,
anchorY: 0.5
});
leftRivet.y = rivetY;
leftRivet.x = -45;
leftRivet.width = 8;
leftRivet.height = 8;
leftRivet.tint = 0x455A64; // Dark rivet
leftRivet.alpha = 0.9;
// Right rivet
var rightRivet = self.attachAsset('pipeHighlight', {
anchorX: 0.5,
anchorY: 0.5
});
rightRivet.y = rivetY;
rightRivet.x = 45;
rightRivet.width = 8;
rightRivet.height = 8;
rightRivet.tint = 0x455A64; // Dark rivet
rightRivet.alpha = 0.9;
}
}
// 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
****/
// Game variables
// Initialize plugins with proper error handling
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; // Increased spacing between pipes to make them further apart
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.8; // Base gravity for bird
var baseJumpStrength = -12; // Base jump strength for bird
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: 100,
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 = -200;
}
} catch (e) {
console.log("Main menu title error:", e);
}
// Create play button with oval shape
var playButton = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 280,
height: 80,
alpha: 1.0
});
playButton.tint = 0x4A90E2;
LK.gui.center.addChild(playButton);
playButton.y = 50;
var playButtonText = new Text2('OYNA', {
size: 42,
fill: 0xFFFFFF
});
playButtonText.anchor.set(0.5, 0.5);
playButtonText.stroke = 0x2C5F8C;
playButtonText.strokeThickness = 2;
LK.gui.center.addChild(playButtonText);
playButtonText.y = 50;
// Create instruction text
var instructionTxt = new Text2('TIKLA VE OYNA!', {
size: 60,
fill: 0xFFFFFF
});
instructionTxt.anchor.set(0.5, 0.5);
instructionTxt.stroke = 0x000000;
instructionTxt.strokeThickness = 3;
instructionTxt.visible = false;
// Add background shape for instruction text
var instructionBg = LK.getAsset('barrier', {
anchorX: 0.5,
anchorY: 0.5,
width: 400,
height: 100,
alpha: 0.8
});
instructionBg.tint = 0x8B0000;
instructionBg.visible = false;
LK.gui.center.addChild(instructionBg);
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
var retryButton = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 320,
height: 90,
alpha: 1.0
});
retryButton.tint = 0x27AE60;
retryButton.visible = false;
LK.gui.center.addChild(retryButton);
retryButton.y = 100;
var retryButtonText = new Text2('TEKRAR DENE', {
size: 38,
fill: 0xFFFFFF
});
retryButtonText.anchor.set(0.5, 0.5);
retryButtonText.stroke = 0x1E8449;
retryButtonText.strokeThickness = 2;
retryButtonText.visible = false;
LK.gui.center.addChild(retryButtonText);
retryButtonText.y = 100;
// Create menu button
var menuButton = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 320,
height: 90,
alpha: 1.0
});
menuButton.tint = 0xE74C3C;
menuButton.visible = false;
LK.gui.center.addChild(menuButton);
menuButton.y = 250;
var menuButtonText = new Text2('ANA MENÜ', {
size: 38,
fill: 0xFFFFFF
});
menuButtonText.anchor.set(0.5, 0.5);
menuButtonText.stroke = 0xC0392B;
menuButtonText.strokeThickness = 2;
menuButtonText.visible = false;
LK.gui.center.addChild(menuButtonText);
menuButtonText.y = 250;
// Create settings button for top right corner
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 settings icon text (gear symbol)
var settingsIcon = new Text2('⚙', {
size: 60,
fill: 0xFFFFFF
});
settingsIcon.anchor.set(0.5, 0.5);
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
var closeSettingsButton = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 240,
height: 80,
alpha: 1.0
});
closeSettingsButton.tint = 0x95A5A6;
closeSettingsButton.visible = false;
LK.gui.center.addChild(closeSettingsButton);
closeSettingsButton.y = 150;
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
var speedMenuButton = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 320,
height: 80,
alpha: 1.0
});
speedMenuButton.tint = 0x3498DB;
speedMenuButton.visible = false;
LK.gui.center.addChild(speedMenuButton);
speedMenuButton.y = -150;
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
var languageMenuButton = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 320,
height: 80,
alpha: 1.0
});
languageMenuButton.tint = 0x9B59B6;
languageMenuButton.visible = false;
LK.gui.center.addChild(languageMenuButton);
languageMenuButton.y = -20;
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
var normalSpeedButton = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 160,
height: 70,
alpha: 1.0
});
normalSpeedButton.tint = 0x27AE60;
normalSpeedButton.visible = false;
LK.gui.center.addChild(normalSpeedButton);
normalSpeedButton.y = -80;
normalSpeedButton.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('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 160,
height: 70,
alpha: 1.0
});
speed15xButton.tint = 0xF39C12;
speed15xButton.visible = false;
LK.gui.center.addChild(speed15xButton);
speed15xButton.y = -80;
speed15xButton.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('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 160,
height: 70,
alpha: 1.0
});
speed2xButton.tint = 0xE74C3C;
speed2xButton.visible = false;
LK.gui.center.addChild(speed2xButton);
speed2xButton.y = -80;
speed2xButton.x = 280;
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 = 280;
// 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
var speedBackButton = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 200,
height: 70,
alpha: 1.0
});
speedBackButton.tint = 0x7F8C8D;
speedBackButton.visible = false;
LK.gui.center.addChild(speedBackButton);
speedBackButton.y = 150;
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 = 400;
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 = 400;
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 = 400;
bird.y = 1366;
// Initialize bird properly
bird.velocity = 0;
// Create pipe function
function createPipe() {
// Define safe boundaries for gap center to ensure both pipes have reasonable heights
var minGapY = 800; // Minimum gap center position (ensures top pipe has decent height)
var maxGapY = 1800; // Maximum gap center position (ensures bottom pipe has decent height)
var gapCenterY = minGapY + Math.random() * (maxGapY - minGapY);
var pipe = new Pipe(gapCenterY);
// Calculate position based on last pipe position + consistent spacing
if (pipes.length === 0) {
pipe.x = 2048 + 100; // First pipe position - brought closer
} else {
pipe.x = pipes[pipes.length - 1].x + pipeSpacing; // Consistent spacing from last pipe
}
;
pipes.push(pipe);
game.addChild(pipe);
}
// Reset game function
function resetGame() {
// Reset bird
bird.x = 400;
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;
playButton.visible = true;
playButtonText.visible = true;
// Show settings button and icon
settingsButton.visible = true;
settingsIcon.visible = true;
// Show cup shape (high score indicator)
if (cupShape) cupShape.visible = true;
// Hide instruction
instructionTxt.visible = false;
instructionBg.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 = 400;
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 = 400;
bottomBarrier.y = 1416; // 50 pixels below bird
bottomBarrier.alpha = 0; // Make invisible
// Create initial pipes
createPipe();
createPipe();
}
// Function to start game from main menu
function startGameFromMenu() {
showMainMenu = false;
// Hide main menu elements
mainMenuTitle.visible = false;
playButton.visible = false;
playButtonText.visible = false;
// Hide settings button and icon
settingsButton.visible = false;
settingsIcon.visible = false;
// Hide cup shape (high score indicator)
if (cupShape) cupShape.visible = false;
// Show instruction
instructionTxt.visible = true;
instructionBg.visible = true;
}
// Function to show game over screen
function showGameOverScreen(finalScore) {
showGameOver = true;
gameStarted = false;
showMainMenu = false;
// Hide instruction
instructionTxt.visible = false;
instructionBg.visible = false;
// Show game over elements
gameOverBg.visible = true;
gameOverTitle.visible = true;
finalScoreText.visible = true;
bestScoreText.visible = true;
retryButton.visible = true;
retryButtonText.visible = true;
menuButton.visible = true;
menuButtonText.visible = true;
// Update score displays
finalScoreText.setText(getText('score') + ': ' + finalScore);
// Ensure final score text fits properly
if (finalScoreText.width > 600) {
finalScoreText.style.fontSize = Math.max(50, 80 * 600 / finalScoreText.width);
}
// Always show the current high score from storage
var currentHighScore = _storage.highScore || 0;
bestScoreText.setText(getText('bestScore') + ': ' + currentHighScore);
// Ensure best score text fits properly
if (bestScoreText.width > 600) {
bestScoreText.style.fontSize = Math.max(40, 60 * 600 / bestScoreText.width);
}
}
// 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;
menuButton.visible = false;
menuButtonText.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
var turkishButton = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 240,
height: 70,
alpha: 1.0
});
turkishButton.tint = 0x27AE60;
turkishButton.visible = false;
LK.gui.center.addChild(turkishButton);
turkishButton.y = -80;
turkishButton.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('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 240,
height: 70,
alpha: 1.0
});
englishButton.tint = 0x3498DB;
englishButton.visible = false;
LK.gui.center.addChild(englishButton);
englishButton.y = -80;
englishButton.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
var languageBackButton = LK.getAsset('playButtonOval', {
anchorX: 0.5,
anchorY: 0.5,
width: 200,
height: 70,
alpha: 1.0
});
languageBackButton.tint = 0x7F8C8D;
languageBackButton.visible = false;
LK.gui.center.addChild(languageBackButton);
languageBackButton.y = 150;
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;
closeSettingsText.visible = true;
speedMenuButton.visible = true;
speedMenuText.visible = true;
languageMenuButton.visible = true;
languageMenuText.visible = true;
}
// Function to hide settings menu
function hideSettingsMenu() {
settingsOverlay.visible = false;
settingsTitle.visible = false;
closeSettingsButton.visible = false;
closeSettingsText.visible = false;
speedMenuButton.visible = false;
speedMenuText.visible = false;
languageMenuButton.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;
turkishText.visible = true;
englishButton.visible = true;
englishText.visible = true;
currentLanguageText.visible = true;
languageBackButton.visible = true;
languageBackText.visible = true;
updateLanguageDisplay();
}
// Function to hide language controls
function hideLanguageControls() {
languageOverlay.visible = false;
languageTitle.visible = false;
turkishButton.visible = false;
turkishText.visible = false;
englishButton.visible = false;
englishText.visible = false;
currentLanguageText.visible = false;
languageBackButton.visible = false;
languageBackText.visible = false;
// Show language menu button again if settings overlay is visible
if (settingsOverlay.visible) {
languageMenuButton.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 (playButtonText && playButtonText.setText) {
playButtonText.setText(getText('playButton'));
// Ensure text fits in button by adjusting size if needed
var buttonWidth = 280;
if (playButtonText.width > buttonWidth - 20) {
playButtonText.style.fontSize = Math.max(32, 42 * (buttonWidth - 20) / playButtonText.width);
}
}
if (instructionTxt && instructionTxt.setText) {
instructionTxt.setText(getText('instruction'));
// Ensure instruction text fits in background
var bgWidth = 400;
if (instructionTxt.width > bgWidth - 20) {
instructionTxt.style.fontSize = Math.max(40, 60 * (bgWidth - 20) / instructionTxt.width);
}
}
// 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'));
// Ensure retry button text fits
var retryButtonWidth = 320;
if (retryButtonText.width > retryButtonWidth - 20) {
retryButtonText.style.fontSize = Math.max(30, 38 * (retryButtonWidth - 20) / retryButtonText.width);
}
}
if (menuButtonText && menuButtonText.setText) {
menuButtonText.setText(getText('mainMenu'));
// Ensure menu button text fits
var menuButtonWidth = 320;
if (menuButtonText.width > menuButtonWidth - 20) {
menuButtonText.style.fontSize = Math.max(30, 38 * (menuButtonWidth - 20) / menuButtonText.width);
}
}
// Settings texts
if (settingsTitle && settingsTitle.setText) settingsTitle.setText(getText('settings'));
if (closeSettingsText && closeSettingsText.setText) {
closeSettingsText.setText(getText('close'));
// Ensure close button text fits
var closeButtonWidth = 240;
if (closeSettingsText.width > closeButtonWidth - 20) {
closeSettingsText.style.fontSize = Math.max(28, 36 * (closeButtonWidth - 20) / closeSettingsText.width);
}
}
if (speedMenuText && speedMenuText.setText) {
speedMenuText.setText(getText('speed'));
// Ensure speed menu text fits
var speedMenuWidth = 320;
if (speedMenuText.width > speedMenuWidth - 20) {
speedMenuText.style.fontSize = Math.max(32, 42 * (speedMenuWidth - 20) / speedMenuText.width);
}
}
if (languageMenuText && languageMenuText.setText) {
languageMenuText.setText(getText('language'));
// Ensure language menu text fits
var languageMenuWidth = 320;
if (languageMenuText.width > languageMenuWidth - 20) {
languageMenuText.style.fontSize = Math.max(32, 42 * (languageMenuWidth - 20) / languageMenuText.width);
}
}
if (speedTitle && speedTitle.setText) speedTitle.setText(getText('speedTitle'));
if (languageTitle && languageTitle.setText) languageTitle.setText(getText('languageTitle'));
if (normalSpeedText && normalSpeedText.setText) {
normalSpeedText.setText(getText('normal'));
// Ensure normal speed text fits
var normalSpeedWidth = 160;
if (normalSpeedText.width > normalSpeedWidth - 20) {
normalSpeedText.style.fontSize = Math.max(24, 32 * (normalSpeedWidth - 20) / normalSpeedText.width);
}
}
if (speedBackText && speedBackText.setText) {
speedBackText.setText(getText('back'));
// Ensure back button text fits
var backButtonWidth = 200;
if (speedBackText.width > backButtonWidth - 20) {
speedBackText.style.fontSize = Math.max(28, 36 * (backButtonWidth - 20) / speedBackText.width);
}
}
if (languageBackText && languageBackText.setText) {
languageBackText.setText(getText('back'));
// Ensure language back button text fits
var langBackButtonWidth = 200;
if (languageBackText.width > langBackButtonWidth - 20) {
languageBackText.style.fontSize = Math.max(28, 36 * (langBackButtonWidth - 20) / languageBackText.width);
}
}
// Update current speed text with proper language
var speedText = getText('normal');
if (gameSpeed === 2) speedText = '2X';else if (gameSpeed === 1.5) speedText = '1.5X';
if (currentSpeedText && currentSpeedText.setText) {
currentSpeedText.setText(getText('current') + ': ' + speedText);
// Ensure current speed text fits in display area
if (currentSpeedText.width > 600) {
currentSpeedText.style.fontSize = Math.max(35, 50 * 600 / currentSpeedText.width);
}
}
// 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) {
finalScoreText.style.fontSize = Math.max(50, 80 * 600 / finalScoreText.width);
}
}
if (bestScoreText && bestScoreText.setText) {
var currentHighScore = _storage.highScore || 0;
bestScoreText.setText(getText('bestScore') + ': ' + currentHighScore);
if (bestScoreText.width > 600) {
bestScoreText.style.fontSize = Math.max(40, 60 * 600 / bestScoreText.width);
}
}
} 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);
// Ensure current language text fits in display area
if (currentLanguageText.width > 600) {
currentLanguageText.style.fontSize = Math.max(35, 50 * 600 / currentLanguageText.width);
}
// 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) {
turkishText.style.fontSize = Math.max(24, 32 * (turkishButtonWidth - 20) / turkishText.width);
}
}
if (englishText && englishText.setText) {
englishText.setText('ENGLISH');
var englishButtonWidth = 240;
if (englishText.width > englishButtonWidth - 20) {
englishText.style.fontSize = Math.max(24, 32 * (englishButtonWidth - 20) / englishText.width);
}
}
}
// 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(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;
normalSpeedText.visible = true;
speed15xButton.visible = true;
speed15xText.visible = true;
speed2xButton.visible = true;
speed2xText.visible = true;
currentSpeedText.visible = true;
speedBackButton.visible = true;
speedBackText.visible = true;
updateSpeedDisplay();
}
// Function to hide speed controls
function hideSpeedControls() {
speedOverlay.visible = false;
speedTitle.visible = false;
normalSpeedButton.visible = false;
normalSpeedText.visible = false;
speed2xButton.visible = false;
speed2xText.visible = false;
speed15xButton.visible = false;
speed15xText.visible = false;
currentSpeedText.visible = false;
speedBackButton.visible = false;
speedBackText.visible = false;
// Show speed menu button again if settings overlay is visible
if (settingsOverlay.visible) {
speedMenuButton.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';
currentSpeedText.setText(getText('current') + ': ' + speedText);
// Ensure current speed text fits in display area
if (currentSpeedText.width > 600) {
currentSpeedText.style.fontSize = Math.max(35, 50 * 600 / currentSpeedText.width);
}
// Update button colors to show selected speed
normalSpeedButton.tint = gameSpeed === 1 ? 0x2ECC71 : 0x27AE60;
speed2xButton.tint = gameSpeed === 2 ? 0xEC7063 : 0xE74C3C;
speed15xButton.tint = gameSpeed === 1.5 ? 0xF7DC6F : 0xF39C12;
// 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) {
normalSpeedText.style.fontSize = Math.max(24, 32 * (normalButtonWidth - 20) / normalSpeedText.width);
}
}
}
// Function to set game speed
function setGameSpeed(newSpeed) {
gameSpeed = newSpeed;
updateSpeedDisplay();
// Update existing pipes if they exist
for (var i = 0; i < pipes.length; i++) {
if (pipes[i]) {
pipes[i].speed = basePipeSpeed * gameSpeed;
}
}
}
// 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;
if (!_storage.globalLeaderboardNames) _storage.globalLeaderboardNames = [];
if (!_storage.globalLeaderboardScores) _storage.globalLeaderboardScores = [];
if (!_storage.highScore) _storage.highScore = 0;
if (!_storage.lastScore) _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;
}
// 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
tween(settingsButton, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 100,
onFinish: function onFinish() {
tween(settingsButton, {
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
});
}
});
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
});
}
});
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-1204)
if (x >= 1124 && x <= 1204 && y >= 1246 && y <= 1326) {
return; // Block clicks in barrier zone
}
// 2X speed button with isolated click area
if (speed2xButton.visible && x >= 1204 && x <= 1404 && 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;
}
}
// 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
});
}
});
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 400x120
if (x >= 824 && x <= 1224 && y >= 1406 && y <= 1526) {
// 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(retryButton, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 100,
onFinish: function onFinish() {
tween(retryButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100
});
}
});
hideGameOverScreen();
resetGame();
// Show instruction screen instead of starting game directly
startGameFromMenu();
return;
}
// Check menu button (ANA MENÜ) - centered at 1024x1616, button is 400x120
if (x >= 824 && x <= 1224 && y >= 1556 && y <= 1676) {
// 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(menuButton, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 100,
onFinish: function onFinish() {
tween(menuButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100
});
}
});
hideGameOverScreen();
resetGame();
return;
}
return;
}
if (showMainMenu) {
// Check play button (OYNA) - centered at 1024x1366, button is 300x80
if (x >= 874 && x <= 1174 && y >= 1326 && y <= 1406) {
// Prevent rapid clicks
var currentTime = Date.now();
if (currentTime - lastButtonClickTime < 300) {
return; // Ignore click if too recent
}
lastButtonClickTime = currentTime;
// Clear any existing timeout
if (buttonClickTimeout) {
LK.clearTimeout(buttonClickTimeout);
buttonClickTimeout = null;
}
// Add visual feedback with tween
tween(playButton, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 100,
onFinish: function onFinish() {
tween(playButton, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100
});
}
});
// Add small delay to prevent double clicks
buttonClickTimeout = LK.setTimeout(function () {
buttonClickTimeout = null;
startGameFromMenu();
}, 150);
return;
}
return;
}
if (!gameStarted) {
gameStarted = true;
instructionTxt.visible = false;
instructionBg.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
if (!pipe.passed && pipe.x + 50 < 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
@@ -56,122 +56,259 @@
self.passed = false;
self.gapCenterY = gapCenterY;
// Store pipe width for consistent collision detection
self.pipeWidth = 120;
- // Create top pipe body
+ // 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;
- // Set reasonable height for top pipe (minimum 200px, maximum based on gap position)
- var topPipeHeight = Math.max(200, gapCenterY - self.gapSize / 2);
topPipe.height = topPipeHeight;
topPipe.width = self.pipeWidth;
- // Create enhanced top pipe highlight with metallic shine
- var topPipeHighlight = self.attachAsset('pipeHighlight', {
+ topPipe.tint = 0x1B5E20; // Dark forest green base
+ // Create pipe shadow for depth
+ var topPipeShadow = self.attachAsset('topPipe', {
anchorX: 0.5,
anchorY: 1
});
- topPipeHighlight.y = gapCenterY - self.gapSize / 2;
- topPipeHighlight.height = topPipeHeight;
- topPipeHighlight.width = 35;
- topPipeHighlight.x = -30;
- topPipeHighlight.tint = 0xE6E6FA; // Lavender metallic shine
- // Add secondary highlight for depth
- var topPipeShine = self.attachAsset('pipeHighlight', {
+ 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
});
- topPipeShine.y = gapCenterY - self.gapSize / 2;
- topPipeShine.height = topPipeHeight;
- topPipeShine.width = 15;
- topPipeShine.x = -35;
- topPipeShine.tint = 0xF5F5F5; // Bright metallic shine
- topPipeShine.alpha = 0.8;
- // Create decorative top pipe cap with metallic rim
- var topPipeCap = self.attachAsset('pipeTop', {
+ 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
});
- topPipeCap.y = gapCenterY - self.gapSize / 2;
- topPipeCap.width = self.pipeWidth + 30; // More prominent cap
- topPipeCap.tint = 0x4169E1; // Royal blue metallic color
- // Add metallic rim effect on top cap
- var topCapRim = self.attachAsset('pipeTop', {
+ 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) {
+ // Don't create joints too close to top
+ // 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;
+ }
+ }
+ // Create rivets for industrial look
+ var rivetCount = Math.floor(topPipeHeight / 80);
+ for (var r = 0; r < rivetCount; r++) {
+ var rivetY = gapCenterY - self.gapSize / 2 + (r + 1) * 80;
+ if (rivetY > 30) {
+ // Left rivet
+ var leftRivet = self.attachAsset('pipeHighlight', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ leftRivet.y = rivetY;
+ leftRivet.x = -45;
+ leftRivet.width = 8;
+ leftRivet.height = 8;
+ leftRivet.tint = 0x455A64; // Dark rivet
+ leftRivet.alpha = 0.9;
+ // Right rivet
+ var rightRivet = self.attachAsset('pipeHighlight', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ rightRivet.y = rivetY;
+ rightRivet.x = 45;
+ rightRivet.width = 8;
+ rightRivet.height = 8;
+ rightRivet.tint = 0x455A64; // Dark rivet
+ rightRivet.alpha = 0.9;
+ }
+ }
+ // Enhanced top pipe cap with multiple layers
+ var topPipeCapBase = self.attachAsset('pipeTop', {
anchorX: 0.5,
anchorY: 1
});
- topCapRim.y = gapCenterY - self.gapSize / 2;
- topCapRim.width = self.pipeWidth + 40;
- topCapRim.height = 25;
- topCapRim.tint = 0x708090; // Slate gray metallic rim
- // Add golden accent stripe
- var topCapAccent = self.attachAsset('pipeTop', {
+ 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
});
- topCapAccent.y = gapCenterY - self.gapSize / 2 + 15;
- topCapAccent.width = self.pipeWidth + 25;
- topCapAccent.height = 15;
- topCapAccent.tint = 0xFFD700; // Gold accent
- // Create bottom pipe body
+ 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;
- // Set reasonable height for bottom pipe (minimum 200px, maximum based on available space)
- var bottomPipeHeight = Math.max(200, 2732 - 150 - (gapCenterY + self.gapSize / 2));
bottomPipe.height = bottomPipeHeight;
bottomPipe.width = self.pipeWidth;
- // Create enhanced bottom pipe highlight with metallic shine
- var bottomPipeHighlight = self.attachAsset('pipeHighlight', {
+ bottomPipe.tint = 0x1B5E20; // Dark forest green base
+ // Create pipe shadow for depth
+ var bottomPipeShadow = self.attachAsset('bottomPipe', {
anchorX: 0.5,
anchorY: 0
});
- bottomPipeHighlight.y = gapCenterY + self.gapSize / 2;
- bottomPipeHighlight.height = bottomPipeHeight;
- bottomPipeHighlight.width = 35;
- bottomPipeHighlight.x = -30;
- bottomPipeHighlight.tint = 0xE6E6FA; // Lavender metallic shine
- // Add secondary highlight for depth
- var bottomPipeShine = self.attachAsset('pipeHighlight', {
+ 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
});
- bottomPipeShine.y = gapCenterY + self.gapSize / 2;
- bottomPipeShine.height = bottomPipeHeight;
- bottomPipeShine.width = 15;
- bottomPipeShine.x = -35;
- bottomPipeShine.tint = 0xF5F5F5; // Bright metallic shine
- bottomPipeShine.alpha = 0.8;
- // Create decorative bottom pipe cap with metallic rim
- var bottomPipeCap = self.attachAsset('pipeBottom', {
+ 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
});
- bottomPipeCap.y = gapCenterY + self.gapSize / 2;
- bottomPipeCap.width = self.pipeWidth + 30; // More prominent cap
- bottomPipeCap.tint = 0x4169E1; // Royal blue metallic color
- // Add metallic rim effect on bottom cap
- var bottomCapRim = self.attachAsset('pipeBottom', {
+ 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;
+ }
+ }
+ // Create rivets for industrial look
+ var bottomRivetCount = Math.floor(bottomPipeHeight / 80);
+ for (var r = 0; r < bottomRivetCount; r++) {
+ var rivetY = gapCenterY + self.gapSize / 2 + (r + 1) * 80;
+ if (rivetY < 2732 - 180) {
+ // Left rivet
+ var leftRivet = self.attachAsset('pipeHighlight', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ leftRivet.y = rivetY;
+ leftRivet.x = -45;
+ leftRivet.width = 8;
+ leftRivet.height = 8;
+ leftRivet.tint = 0x455A64; // Dark rivet
+ leftRivet.alpha = 0.9;
+ // Right rivet
+ var rightRivet = self.attachAsset('pipeHighlight', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ rightRivet.y = rivetY;
+ rightRivet.x = 45;
+ rightRivet.width = 8;
+ rightRivet.height = 8;
+ rightRivet.tint = 0x455A64; // Dark rivet
+ rightRivet.alpha = 0.9;
+ }
+ }
+ // Enhanced bottom pipe cap with multiple layers
+ var bottomPipeCapBase = self.attachAsset('pipeBottom', {
anchorX: 0.5,
anchorY: 0
});
- bottomCapRim.y = gapCenterY + self.gapSize / 2;
- bottomCapRim.width = self.pipeWidth + 40;
- bottomCapRim.height = 25;
- bottomCapRim.tint = 0x708090; // Slate gray metallic rim
- // Add golden accent stripe
- var bottomCapAccent = self.attachAsset('pipeBottom', {
+ 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
});
- bottomCapAccent.y = gapCenterY + self.gapSize / 2 - 15;
- bottomCapAccent.width = self.pipeWidth + 25;
- bottomCapAccent.height = 15;
- bottomCapAccent.tint = 0xFFD700; // Gold accent
+ 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;