User prompt
bu yerleri biraz daha sıkı tut
User prompt
uçağın geçebileceği şekilde düzenle
User prompt
place towers in random places
User prompt
more a little bit
User prompt
enlarge the plane
User prompt
geri al
User prompt
yerlerini bozmadan
User prompt
yukarıdaki kuleler aşşağı baksın
User prompt
ve dondürdüğün kuleleri eskisi gibi yerleştir
User prompt
yukarıdaki kuleleri aşşağıya dondur
User prompt
zoom the plane
User prompt
a little bit more
User prompt
and zoom more
User prompt
Extend the towers pictures to the border
User prompt
Extend the towers to the border
User prompt
Zoom in on the screen
User prompt
bigger towers and random sizes
User prompt
Hey buddy, to make this like the ''Flappy Bird'' game, place the towers at certain intervals so that they are equal at the top and bottom, and when the plane passes between the towers, give it 1 point, and the plane's speed will increase by 1 for every 15 points.
User prompt
Hey dostum bunun ''Flappy Bird'' oyununa benzemesi için belirli aralılarla üste ve alta eşit olacak şekilde kuleleri koy ve uçak kulelerin arasından geçtiğindeyse ona 1 puan ver uçağın hızı her 15 puanda 1 artsın
User prompt
binaları altta ve üstte eşit olacak şekilde yerleştir
User prompt
dostum bunu flappy bird oyununa benzetmen lazım
Code edit (1 edits merged)
Please save this source code
User prompt
Sky Scraper Flight
Initial prompt
hocam bana flappy birds yap fakar kuş yerine uçak koy ve borularda gökdelen olsun
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
highScore: 0,
gamesPlayed: 0,
globalScores: []
});
/****
* Classes
****/
var Airplane = Container.expand(function () {
var self = Container.call(this);
var airplaneGraphics = self.attachAsset('airplane', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.2,
scaleY: 2.2
});
self.velocity = 0;
self.gravity = 0.6;
self.jumpPower = -10;
self.maxVelocity = 12;
self.update = function () {
// Apply gravity
self.velocity += self.gravity;
// Limit velocity
if (self.velocity > self.maxVelocity) {
self.velocity = self.maxVelocity;
}
if (self.velocity < -self.maxVelocity) {
self.velocity = -self.maxVelocity;
}
// Update position
self.y += self.velocity;
// Rotate airplane based on velocity for visual effect
airplaneGraphics.rotation = Math.max(-0.5, Math.min(0.5, self.velocity * 0.05));
// Allow airplane to go off screen (will be caught by game over logic)
};
self.jump = function () {
self.velocity = self.jumpPower;
LK.getSound('fly').play();
};
return self;
});
var Building = Container.expand(function (topHeight, bottomHeight, gapY) {
var self = Container.call(this);
var gapSize = 320;
// Top building
var topBuilding = self.attachAsset('building', {
anchorX: 0,
anchorY: 1,
scaleY: (gapY - gapSize / 2) / 100,
rotation: 0 // Revert the rotation of the top building to its original orientation
});
topBuilding.y = gapY - gapSize / 2; // Position top building at gap start
// Bottom building
var bottomBuilding = self.attachAsset('building', {
anchorX: 0,
anchorY: 0,
scaleY: (2732 - (gapY + gapSize / 2)) / 100
});
bottomBuilding.y = gapY + gapSize / 2; // Position bottom building at gap end
self.speed = -4;
self.passed = false;
self.update = function () {
self.x += self.speed;
};
self.checkCollision = function (airplane) {
// Get airplane's actual scaled dimensions with reduced hitbox for better gameplay
var airplaneScaledWidth = 120 * 2.2 * 0.7; // Reduce hitbox by 30%
var airplaneScaledHeight = 60 * 2.2 * 0.7; // Reduce hitbox by 30%
var airplaneLeft = airplane.x - airplaneScaledWidth / 2;
var airplaneRight = airplane.x + airplaneScaledWidth / 2;
var airplaneTop = airplane.y - airplaneScaledHeight / 2;
var airplaneBottom = airplane.y + airplaneScaledHeight / 2;
// Get building dimensions (no scaling applied to buildings, so use original width)
var buildingWidth = 175;
var buildingLeft = self.x + 10; // Add small margin to building hitbox
var buildingRight = self.x + buildingWidth - 10; // Reduce building hitbox width
// Check if airplane is within building's x range
if (airplaneRight > buildingLeft && airplaneLeft < buildingRight) {
// Check collision with top building (add small margin)
if (airplaneTop < topBuilding.y - 5) {
return true;
}
// Check collision with bottom building (add small margin)
if (airplaneBottom > bottomBuilding.y + 5) {
return true;
}
}
return false;
};
return self;
});
var Coin = Container.expand(function () {
var self = Container.call(this);
var coinGraphics = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -4;
self.update = function () {
self.x += self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB,
scale: 2.0 // Reduce the scale to make the screen appear smaller
});
/****
* Game Code
****/
// Add sea background
var seaBg = game.addChild(LK.getAsset('seaBackground', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
}));
// Add fish shadows in the sea
var fishShadows = [];
for (var i = 0; i < 12; i++) {
var shadowType = 'fishShadow' + (Math.floor(Math.random() * 3) + 1);
var fishShadow = game.addChild(LK.getAsset(shadowType, {
anchorX: 0.5,
anchorY: 0.5,
x: Math.random() * 2200,
y: 1200 + Math.random() * 1000,
alpha: 0.15 + Math.random() * 0.25,
scaleX: 0.8 + Math.random() * 0.4,
scaleY: 0.8 + Math.random() * 0.4
}));
fishShadow.speedX = -0.5 - Math.random() * 1.5;
fishShadow.speedY = (Math.random() - 0.5) * 0.3;
fishShadow.originalX = fishShadow.x;
fishShadow.originalY = fishShadow.y;
fishShadows.push(fishShadow);
}
// Add clouds in the sky
var clouds = [];
for (var i = 0; i < 6; i++) {
var cloud = game.addChild(LK.getAsset('cloud', {
anchorX: 0.5,
anchorY: 0.5,
x: Math.random() * 2400,
y: 200 + Math.random() * 400,
alpha: 0.6 + Math.random() * 0.3,
scaleX: 1.2 + Math.random() * 0.8,
scaleY: 0.8 + Math.random() * 0.6
}));
cloud.speedX = -0.2 - Math.random() * 0.3;
clouds.push(cloud);
}
// Game variables
var airplane;
var buildings = [];
var gameSpeed = 4;
var buildingSpawnTimer = 0;
var buildingSpawnInterval = 220; // frames between buildings
var gameStarted = false;
var lastTapTime = 0;
var tapCooldown = 50; // milliseconds between taps (20 taps per second max)
// Menu state variables
var gameState = 'menu'; // 'menu', 'playing', 'leaderboard'
var menuButtons = [];
// UI Elements
var scoreTxt = new Text2('0', {
size: 120,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Menu UI elements
var titleTxt = new Text2('9/11', {
size: 120,
fill: 0xFFFFFF
});
titleTxt.anchor.set(0.5, 0.5);
titleTxt.x = 1024;
titleTxt.y = 800;
game.addChild(titleTxt);
var playBtn = new Text2('PLAY', {
size: 80,
fill: 0x00FF00
});
playBtn.anchor.set(0.5, 0.5);
playBtn.x = 1024;
playBtn.y = 1200;
game.addChild(playBtn);
var leaderboardBtn = new Text2('LEADERBOARD', {
size: 60,
fill: 0x0080FF
});
leaderboardBtn.anchor.set(0.5, 0.5);
leaderboardBtn.x = 1024;
leaderboardBtn.y = 1350;
game.addChild(leaderboardBtn);
var highScoreTxt = new Text2('HIGH SCORE: ' + storage.highScore, {
size: 60,
fill: 0xFFD700
});
highScoreTxt.anchor.set(0.5, 0.5);
highScoreTxt.x = 1024;
highScoreTxt.y = 1050;
game.addChild(highScoreTxt);
// Leaderboard UI elements (initially hidden)
var leaderboardTitleTxt = new Text2('LEADERBOARD', {
size: 100,
fill: 0xFFFFFF
});
leaderboardTitleTxt.anchor.set(0.5, 0.5);
leaderboardTitleTxt.x = 1024;
leaderboardTitleTxt.y = 600;
leaderboardTitleTxt.visible = false;
game.addChild(leaderboardTitleTxt);
var backBtn = new Text2('BACK TO MENU', {
size: 60,
fill: 0xFF8000
});
backBtn.anchor.set(0.5, 0.5);
backBtn.x = 1024;
backBtn.y = 2000;
backBtn.visible = false;
game.addChild(backBtn);
var highScoreDetailTxt = new Text2('Best Score: ' + storage.highScore + '\nGames Played: ' + (storage.gamesPlayed || 0), {
size: 70,
fill: 0xFFFFFF
});
highScoreDetailTxt.anchor.set(0.5, 0.5);
highScoreDetailTxt.x = 1024;
highScoreDetailTxt.y = 1200;
highScoreDetailTxt.visible = false;
game.addChild(highScoreDetailTxt);
// Add sand elements at the bottom with realistic variation
var sandElements = [];
for (var i = 0; i < 15; i++) {
// Increased number for better coverage
// Create variation in sand height and positioning
var heightVariation = 0.4 + Math.random() * 0.5; // Height between 0.4x and 0.9x
var sandType = 'sand'; // Default sand type
var randomValue = Math.random();
if (randomValue < 0.3) {
sandType = 'sandLight'; // 30% chance for lighter sand
} else if (randomValue < 0.5) {
sandType = 'sandDark'; // 20% chance for darker sand
}
var sand = game.addChild(LK.getAsset(sandType, {
anchorX: 0,
anchorY: 1,
x: i * 140 + (Math.random() - 0.5) * 60,
// More horizontal variation for sandy texture
y: 2732 + Math.random() * 10 - 5,
// Less vertical variation for smoother sand
scaleY: heightVariation,
scaleX: 0.8 + Math.random() * 0.6,
// Width variation between 0.8x and 1.4x
rotation: (Math.random() - 0.5) * 0.1 // Minimal rotation for natural sand look
}));
sandElements.push(sand);
}
// Initialize airplane
airplane = game.addChild(new Airplane());
airplane.x = 400;
airplane.y = 1366;
// Update score display
function updateScore() {
scoreTxt.setText(LK.getScore());
if (LK.getScore() % 15 === 0) {
gameSpeed += 1;
buildingSpawnInterval = Math.max(150, buildingSpawnInterval - 5);
}
}
// Show/hide menu elements
function showMenu() {
gameState = 'menu';
titleTxt.visible = true;
playBtn.visible = true;
leaderboardBtn.visible = true;
highScoreTxt.visible = true;
leaderboardTitleTxt.visible = false;
backBtn.visible = false;
highScoreDetailTxt.visible = false;
scoreTxt.visible = false;
airplane.visible = false;
}
// Show/hide leaderboard elements
function showLeaderboard() {
gameState = 'leaderboard';
titleTxt.visible = false;
playBtn.visible = false;
leaderboardBtn.visible = false;
highScoreTxt.visible = false;
leaderboardTitleTxt.visible = true;
backBtn.visible = true;
highScoreDetailTxt.visible = true;
scoreTxt.visible = false;
airplane.visible = false;
// Update leaderboard text with top 3 scores
var globalScores = storage.globalScores || [];
globalScores.sort(function (a, b) {
return b - a;
});
var leaderboardText = 'TOP SCORES:\n\n';
if (globalScores.length >= 1) {
leaderboardText += '1st: ' + globalScores[0] + '\n';
}
if (globalScores.length >= 2) {
leaderboardText += '2nd: ' + globalScores[1] + '\n';
}
if (globalScores.length >= 3) {
leaderboardText += '3rd: ' + globalScores[2] + '\n';
}
if (globalScores.length === 0) {
leaderboardText += 'No scores yet!\nPlay to set a record!';
}
leaderboardText += '\n\nYour Best: ' + storage.highScore;
leaderboardText += '\nGames Played: ' + (storage.gamesPlayed || 0);
highScoreDetailTxt.setText(leaderboardText);
}
// Start game
function startGame() {
gameState = 'playing';
gameStarted = true;
titleTxt.visible = false;
playBtn.visible = false;
leaderboardBtn.visible = false;
highScoreTxt.visible = false;
leaderboardTitleTxt.visible = false;
backBtn.visible = false;
highScoreDetailTxt.visible = false;
scoreTxt.visible = true;
airplane.visible = true;
// Reset game variables
LK.setScore(0);
updateScore();
gameSpeed = 4;
buildingSpawnInterval = 220;
buildingSpawnTimer = 0;
// Clear any existing buildings
for (var i = buildings.length - 1; i >= 0; i--) {
buildings[i].destroy();
buildings.splice(i, 1);
}
// Reset airplane position
airplane.x = 400;
airplane.y = 1366;
airplane.velocity = 0;
// Spawn first building
spawnBuilding();
}
// Spawn new building
function spawnBuilding() {
var gapSize = 320; // Match the gap size used in Building class
var gapY = Math.floor(Math.random() * (2732 - gapSize - 600)) + 300; // Better gap positioning with margins
var building = new Building(0, 0, gapY);
building.x = 2048 + 100; // Start off-screen to the right
buildings.push(building);
game.addChild(building);
// Randomly decide whether to spawn a coin
if (Math.random() < 0.5) {
// 50% chance to spawn a coin
var coin = new Coin();
coin.x = building.x + 100; // Position coin in the middle of the gap
coin.y = gapY; // Align coin vertically with the gap
game.addChild(coin);
}
}
// Game input handling
game.down = function (x, y, obj) {
var currentTime = Date.now();
if (currentTime - lastTapTime < tapCooldown) {
return; // Too soon, ignore this tap
}
lastTapTime = currentTime;
if (gameState === 'menu') {
// Check if play button was tapped
if (x >= playBtn.x - 100 && x <= playBtn.x + 100 && y >= playBtn.y - 40 && y <= playBtn.y + 40) {
startGame();
return;
}
// Check if leaderboard button was tapped
if (x >= leaderboardBtn.x - 150 && x <= leaderboardBtn.x + 150 && y >= leaderboardBtn.y - 30 && y <= leaderboardBtn.y + 30) {
showLeaderboard();
return;
}
} else if (gameState === 'leaderboard') {
// Check if back button was tapped
if (x >= backBtn.x - 120 && x <= backBtn.x + 120 && y >= backBtn.y - 30 && y <= backBtn.y + 30) {
showMenu();
return;
}
} else if (gameState === 'playing') {
airplane.jump();
}
};
// Main game loop
game.update = function () {
if (gameState !== 'playing' || !gameStarted) return;
// Update building spawn timer
buildingSpawnTimer++;
if (buildingSpawnTimer >= buildingSpawnInterval) {
buildingSpawnTimer = 0;
spawnBuilding();
// Gradually increase difficulty
if (buildingSpawnInterval > 150) {
buildingSpawnInterval -= 0.1;
}
}
// Check collisions and update buildings
for (var i = buildings.length - 1; i >= 0; i--) {
var building = buildings[i];
// Check collision
if (building.checkCollision(airplane)) {
// Save high score and update statistics
if (LK.getScore() > storage.highScore) {
storage.highScore = LK.getScore();
}
// Add score to global leaderboard
var globalScores = storage.globalScores || [];
globalScores.push(LK.getScore());
storage.globalScores = globalScores;
storage.gamesPlayed = (storage.gamesPlayed || 0) + 1;
highScoreTxt.setText('HIGH SCORE: ' + storage.highScore);
LK.getSound('crash').play();
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
// Reset to menu after game over
gameStarted = false;
showMenu();
return;
}
// Check if airplane passed building (score)
if (!building.passed && building.x + 200 < airplane.x) {
building.passed = true;
LK.setScore(LK.getScore() + 1);
updateScore();
}
// Remove buildings that are off-screen
if (building.x < -400) {
building.destroy();
buildings.splice(i, 1);
}
// Check for collisions with coins
var coins = game.children.filter(function (child) {
return child instanceof Coin;
});
for (var j = coins.length - 1; j >= 0; j--) {
var coin = coins[j];
// Manual collision detection for coins using proper airplane dimensions
var airplaneScaledWidth = 120 * 2.2;
var airplaneScaledHeight = 60 * 2.2;
var airplaneLeft = airplane.x - airplaneScaledWidth / 2;
var airplaneRight = airplane.x + airplaneScaledWidth / 2;
var airplaneTop = airplane.y - airplaneScaledHeight / 2;
var airplaneBottom = airplane.y + airplaneScaledHeight / 2;
var coinLeft = coin.x - 25; // coin width/2 = 50/2 = 25
var coinRight = coin.x + 25;
var coinTop = coin.y - 25; // coin height/2 = 50/2 = 25
var coinBottom = coin.y + 25;
// Check if rectangles overlap
if (airplaneRight > coinLeft && airplaneLeft < coinRight && airplaneBottom > coinTop && airplaneTop < coinBottom) {
LK.setScore(LK.getScore() + 2); // Increase score by 2 for collecting a coin
updateScore();
coin.destroy();
coins.splice(j, 1);
}
}
}
// Check ground and ceiling collision
if (airplane.y <= 30 || airplane.y >= 2702) {
// Save high score and update statistics
if (LK.getScore() > storage.highScore) {
storage.highScore = LK.getScore();
}
// Add score to global leaderboard
var globalScores = storage.globalScores || [];
globalScores.push(LK.getScore());
storage.globalScores = globalScores;
storage.gamesPlayed = (storage.gamesPlayed || 0) + 1;
highScoreTxt.setText('HIGH SCORE: ' + storage.highScore);
LK.getSound('crash').play();
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
// Reset to menu after game over
gameStarted = false;
showMenu();
return;
}
// Animate fish shadows
for (var k = 0; k < fishShadows.length; k++) {
var shadow = fishShadows[k];
shadow.x += shadow.speedX;
shadow.y += shadow.speedY;
// Add subtle vertical oscillation for realistic swimming motion
shadow.y += Math.sin(LK.ticks * 0.02 + k) * 0.5;
// Reset fish position when it goes off screen
if (shadow.x < -100) {
shadow.x = 2200 + Math.random() * 100;
shadow.y = 1200 + Math.random() * 1000;
shadow.speedX = -0.5 - Math.random() * 1.5;
shadow.speedY = (Math.random() - 0.5) * 0.3;
}
// Keep fish shadows within reasonable depth bounds
if (shadow.y < 1100) shadow.y = 1100;
if (shadow.y > 2400) shadow.y = 2400;
}
// Animate clouds
for (var c = 0; c < clouds.length; c++) {
var cloud = clouds[c];
cloud.x += cloud.speedX;
// Reset cloud position when it goes off screen
if (cloud.x < -200) {
cloud.x = 2400 + Math.random() * 200;
cloud.y = 200 + Math.random() * 400;
}
}
};
// Initialize score display
updateScore();
// Initialize game in menu state
showMenu();
// Add pause message text (initially hidden)
var pauseWarningTxt = new Text2('YOU CANT STOP IN MY GAME', {
size: 80,
fill: 0xFF0000
});
pauseWarningTxt.anchor.set(0.5, 0);
pauseWarningTxt.x = 1024;
pauseWarningTxt.y = 50;
pauseWarningTxt.visible = false;
game.addChild(pauseWarningTxt);
// Override pause event to prevent pausing and show warning
LK.on('pause', function () {
// Show red warning message
pauseWarningTxt.visible = true;
// Hide message after 2 seconds
LK.setTimeout(function () {
pauseWarningTxt.visible = false;
}, 2000);
// Prevent default pause behavior by returning false
return false;
});
// Start background music
LK.playMusic('arkaplan');
; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
highScore: 0,
gamesPlayed: 0,
globalScores: []
});
/****
* Classes
****/
var Airplane = Container.expand(function () {
var self = Container.call(this);
var airplaneGraphics = self.attachAsset('airplane', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.2,
scaleY: 2.2
});
self.velocity = 0;
self.gravity = 0.6;
self.jumpPower = -10;
self.maxVelocity = 12;
self.update = function () {
// Apply gravity
self.velocity += self.gravity;
// Limit velocity
if (self.velocity > self.maxVelocity) {
self.velocity = self.maxVelocity;
}
if (self.velocity < -self.maxVelocity) {
self.velocity = -self.maxVelocity;
}
// Update position
self.y += self.velocity;
// Rotate airplane based on velocity for visual effect
airplaneGraphics.rotation = Math.max(-0.5, Math.min(0.5, self.velocity * 0.05));
// Allow airplane to go off screen (will be caught by game over logic)
};
self.jump = function () {
self.velocity = self.jumpPower;
LK.getSound('fly').play();
};
return self;
});
var Building = Container.expand(function (topHeight, bottomHeight, gapY) {
var self = Container.call(this);
var gapSize = 320;
// Top building
var topBuilding = self.attachAsset('building', {
anchorX: 0,
anchorY: 1,
scaleY: (gapY - gapSize / 2) / 100,
rotation: 0 // Revert the rotation of the top building to its original orientation
});
topBuilding.y = gapY - gapSize / 2; // Position top building at gap start
// Bottom building
var bottomBuilding = self.attachAsset('building', {
anchorX: 0,
anchorY: 0,
scaleY: (2732 - (gapY + gapSize / 2)) / 100
});
bottomBuilding.y = gapY + gapSize / 2; // Position bottom building at gap end
self.speed = -4;
self.passed = false;
self.update = function () {
self.x += self.speed;
};
self.checkCollision = function (airplane) {
// Get airplane's actual scaled dimensions with reduced hitbox for better gameplay
var airplaneScaledWidth = 120 * 2.2 * 0.7; // Reduce hitbox by 30%
var airplaneScaledHeight = 60 * 2.2 * 0.7; // Reduce hitbox by 30%
var airplaneLeft = airplane.x - airplaneScaledWidth / 2;
var airplaneRight = airplane.x + airplaneScaledWidth / 2;
var airplaneTop = airplane.y - airplaneScaledHeight / 2;
var airplaneBottom = airplane.y + airplaneScaledHeight / 2;
// Get building dimensions (no scaling applied to buildings, so use original width)
var buildingWidth = 175;
var buildingLeft = self.x + 10; // Add small margin to building hitbox
var buildingRight = self.x + buildingWidth - 10; // Reduce building hitbox width
// Check if airplane is within building's x range
if (airplaneRight > buildingLeft && airplaneLeft < buildingRight) {
// Check collision with top building (add small margin)
if (airplaneTop < topBuilding.y - 5) {
return true;
}
// Check collision with bottom building (add small margin)
if (airplaneBottom > bottomBuilding.y + 5) {
return true;
}
}
return false;
};
return self;
});
var Coin = Container.expand(function () {
var self = Container.call(this);
var coinGraphics = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -4;
self.update = function () {
self.x += self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB,
scale: 2.0 // Reduce the scale to make the screen appear smaller
});
/****
* Game Code
****/
// Add sea background
var seaBg = game.addChild(LK.getAsset('seaBackground', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
}));
// Add fish shadows in the sea
var fishShadows = [];
for (var i = 0; i < 12; i++) {
var shadowType = 'fishShadow' + (Math.floor(Math.random() * 3) + 1);
var fishShadow = game.addChild(LK.getAsset(shadowType, {
anchorX: 0.5,
anchorY: 0.5,
x: Math.random() * 2200,
y: 1200 + Math.random() * 1000,
alpha: 0.15 + Math.random() * 0.25,
scaleX: 0.8 + Math.random() * 0.4,
scaleY: 0.8 + Math.random() * 0.4
}));
fishShadow.speedX = -0.5 - Math.random() * 1.5;
fishShadow.speedY = (Math.random() - 0.5) * 0.3;
fishShadow.originalX = fishShadow.x;
fishShadow.originalY = fishShadow.y;
fishShadows.push(fishShadow);
}
// Add clouds in the sky
var clouds = [];
for (var i = 0; i < 6; i++) {
var cloud = game.addChild(LK.getAsset('cloud', {
anchorX: 0.5,
anchorY: 0.5,
x: Math.random() * 2400,
y: 200 + Math.random() * 400,
alpha: 0.6 + Math.random() * 0.3,
scaleX: 1.2 + Math.random() * 0.8,
scaleY: 0.8 + Math.random() * 0.6
}));
cloud.speedX = -0.2 - Math.random() * 0.3;
clouds.push(cloud);
}
// Game variables
var airplane;
var buildings = [];
var gameSpeed = 4;
var buildingSpawnTimer = 0;
var buildingSpawnInterval = 220; // frames between buildings
var gameStarted = false;
var lastTapTime = 0;
var tapCooldown = 50; // milliseconds between taps (20 taps per second max)
// Menu state variables
var gameState = 'menu'; // 'menu', 'playing', 'leaderboard'
var menuButtons = [];
// UI Elements
var scoreTxt = new Text2('0', {
size: 120,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Menu UI elements
var titleTxt = new Text2('9/11', {
size: 120,
fill: 0xFFFFFF
});
titleTxt.anchor.set(0.5, 0.5);
titleTxt.x = 1024;
titleTxt.y = 800;
game.addChild(titleTxt);
var playBtn = new Text2('PLAY', {
size: 80,
fill: 0x00FF00
});
playBtn.anchor.set(0.5, 0.5);
playBtn.x = 1024;
playBtn.y = 1200;
game.addChild(playBtn);
var leaderboardBtn = new Text2('LEADERBOARD', {
size: 60,
fill: 0x0080FF
});
leaderboardBtn.anchor.set(0.5, 0.5);
leaderboardBtn.x = 1024;
leaderboardBtn.y = 1350;
game.addChild(leaderboardBtn);
var highScoreTxt = new Text2('HIGH SCORE: ' + storage.highScore, {
size: 60,
fill: 0xFFD700
});
highScoreTxt.anchor.set(0.5, 0.5);
highScoreTxt.x = 1024;
highScoreTxt.y = 1050;
game.addChild(highScoreTxt);
// Leaderboard UI elements (initially hidden)
var leaderboardTitleTxt = new Text2('LEADERBOARD', {
size: 100,
fill: 0xFFFFFF
});
leaderboardTitleTxt.anchor.set(0.5, 0.5);
leaderboardTitleTxt.x = 1024;
leaderboardTitleTxt.y = 600;
leaderboardTitleTxt.visible = false;
game.addChild(leaderboardTitleTxt);
var backBtn = new Text2('BACK TO MENU', {
size: 60,
fill: 0xFF8000
});
backBtn.anchor.set(0.5, 0.5);
backBtn.x = 1024;
backBtn.y = 2000;
backBtn.visible = false;
game.addChild(backBtn);
var highScoreDetailTxt = new Text2('Best Score: ' + storage.highScore + '\nGames Played: ' + (storage.gamesPlayed || 0), {
size: 70,
fill: 0xFFFFFF
});
highScoreDetailTxt.anchor.set(0.5, 0.5);
highScoreDetailTxt.x = 1024;
highScoreDetailTxt.y = 1200;
highScoreDetailTxt.visible = false;
game.addChild(highScoreDetailTxt);
// Add sand elements at the bottom with realistic variation
var sandElements = [];
for (var i = 0; i < 15; i++) {
// Increased number for better coverage
// Create variation in sand height and positioning
var heightVariation = 0.4 + Math.random() * 0.5; // Height between 0.4x and 0.9x
var sandType = 'sand'; // Default sand type
var randomValue = Math.random();
if (randomValue < 0.3) {
sandType = 'sandLight'; // 30% chance for lighter sand
} else if (randomValue < 0.5) {
sandType = 'sandDark'; // 20% chance for darker sand
}
var sand = game.addChild(LK.getAsset(sandType, {
anchorX: 0,
anchorY: 1,
x: i * 140 + (Math.random() - 0.5) * 60,
// More horizontal variation for sandy texture
y: 2732 + Math.random() * 10 - 5,
// Less vertical variation for smoother sand
scaleY: heightVariation,
scaleX: 0.8 + Math.random() * 0.6,
// Width variation between 0.8x and 1.4x
rotation: (Math.random() - 0.5) * 0.1 // Minimal rotation for natural sand look
}));
sandElements.push(sand);
}
// Initialize airplane
airplane = game.addChild(new Airplane());
airplane.x = 400;
airplane.y = 1366;
// Update score display
function updateScore() {
scoreTxt.setText(LK.getScore());
if (LK.getScore() % 15 === 0) {
gameSpeed += 1;
buildingSpawnInterval = Math.max(150, buildingSpawnInterval - 5);
}
}
// Show/hide menu elements
function showMenu() {
gameState = 'menu';
titleTxt.visible = true;
playBtn.visible = true;
leaderboardBtn.visible = true;
highScoreTxt.visible = true;
leaderboardTitleTxt.visible = false;
backBtn.visible = false;
highScoreDetailTxt.visible = false;
scoreTxt.visible = false;
airplane.visible = false;
}
// Show/hide leaderboard elements
function showLeaderboard() {
gameState = 'leaderboard';
titleTxt.visible = false;
playBtn.visible = false;
leaderboardBtn.visible = false;
highScoreTxt.visible = false;
leaderboardTitleTxt.visible = true;
backBtn.visible = true;
highScoreDetailTxt.visible = true;
scoreTxt.visible = false;
airplane.visible = false;
// Update leaderboard text with top 3 scores
var globalScores = storage.globalScores || [];
globalScores.sort(function (a, b) {
return b - a;
});
var leaderboardText = 'TOP SCORES:\n\n';
if (globalScores.length >= 1) {
leaderboardText += '1st: ' + globalScores[0] + '\n';
}
if (globalScores.length >= 2) {
leaderboardText += '2nd: ' + globalScores[1] + '\n';
}
if (globalScores.length >= 3) {
leaderboardText += '3rd: ' + globalScores[2] + '\n';
}
if (globalScores.length === 0) {
leaderboardText += 'No scores yet!\nPlay to set a record!';
}
leaderboardText += '\n\nYour Best: ' + storage.highScore;
leaderboardText += '\nGames Played: ' + (storage.gamesPlayed || 0);
highScoreDetailTxt.setText(leaderboardText);
}
// Start game
function startGame() {
gameState = 'playing';
gameStarted = true;
titleTxt.visible = false;
playBtn.visible = false;
leaderboardBtn.visible = false;
highScoreTxt.visible = false;
leaderboardTitleTxt.visible = false;
backBtn.visible = false;
highScoreDetailTxt.visible = false;
scoreTxt.visible = true;
airplane.visible = true;
// Reset game variables
LK.setScore(0);
updateScore();
gameSpeed = 4;
buildingSpawnInterval = 220;
buildingSpawnTimer = 0;
// Clear any existing buildings
for (var i = buildings.length - 1; i >= 0; i--) {
buildings[i].destroy();
buildings.splice(i, 1);
}
// Reset airplane position
airplane.x = 400;
airplane.y = 1366;
airplane.velocity = 0;
// Spawn first building
spawnBuilding();
}
// Spawn new building
function spawnBuilding() {
var gapSize = 320; // Match the gap size used in Building class
var gapY = Math.floor(Math.random() * (2732 - gapSize - 600)) + 300; // Better gap positioning with margins
var building = new Building(0, 0, gapY);
building.x = 2048 + 100; // Start off-screen to the right
buildings.push(building);
game.addChild(building);
// Randomly decide whether to spawn a coin
if (Math.random() < 0.5) {
// 50% chance to spawn a coin
var coin = new Coin();
coin.x = building.x + 100; // Position coin in the middle of the gap
coin.y = gapY; // Align coin vertically with the gap
game.addChild(coin);
}
}
// Game input handling
game.down = function (x, y, obj) {
var currentTime = Date.now();
if (currentTime - lastTapTime < tapCooldown) {
return; // Too soon, ignore this tap
}
lastTapTime = currentTime;
if (gameState === 'menu') {
// Check if play button was tapped
if (x >= playBtn.x - 100 && x <= playBtn.x + 100 && y >= playBtn.y - 40 && y <= playBtn.y + 40) {
startGame();
return;
}
// Check if leaderboard button was tapped
if (x >= leaderboardBtn.x - 150 && x <= leaderboardBtn.x + 150 && y >= leaderboardBtn.y - 30 && y <= leaderboardBtn.y + 30) {
showLeaderboard();
return;
}
} else if (gameState === 'leaderboard') {
// Check if back button was tapped
if (x >= backBtn.x - 120 && x <= backBtn.x + 120 && y >= backBtn.y - 30 && y <= backBtn.y + 30) {
showMenu();
return;
}
} else if (gameState === 'playing') {
airplane.jump();
}
};
// Main game loop
game.update = function () {
if (gameState !== 'playing' || !gameStarted) return;
// Update building spawn timer
buildingSpawnTimer++;
if (buildingSpawnTimer >= buildingSpawnInterval) {
buildingSpawnTimer = 0;
spawnBuilding();
// Gradually increase difficulty
if (buildingSpawnInterval > 150) {
buildingSpawnInterval -= 0.1;
}
}
// Check collisions and update buildings
for (var i = buildings.length - 1; i >= 0; i--) {
var building = buildings[i];
// Check collision
if (building.checkCollision(airplane)) {
// Save high score and update statistics
if (LK.getScore() > storage.highScore) {
storage.highScore = LK.getScore();
}
// Add score to global leaderboard
var globalScores = storage.globalScores || [];
globalScores.push(LK.getScore());
storage.globalScores = globalScores;
storage.gamesPlayed = (storage.gamesPlayed || 0) + 1;
highScoreTxt.setText('HIGH SCORE: ' + storage.highScore);
LK.getSound('crash').play();
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
// Reset to menu after game over
gameStarted = false;
showMenu();
return;
}
// Check if airplane passed building (score)
if (!building.passed && building.x + 200 < airplane.x) {
building.passed = true;
LK.setScore(LK.getScore() + 1);
updateScore();
}
// Remove buildings that are off-screen
if (building.x < -400) {
building.destroy();
buildings.splice(i, 1);
}
// Check for collisions with coins
var coins = game.children.filter(function (child) {
return child instanceof Coin;
});
for (var j = coins.length - 1; j >= 0; j--) {
var coin = coins[j];
// Manual collision detection for coins using proper airplane dimensions
var airplaneScaledWidth = 120 * 2.2;
var airplaneScaledHeight = 60 * 2.2;
var airplaneLeft = airplane.x - airplaneScaledWidth / 2;
var airplaneRight = airplane.x + airplaneScaledWidth / 2;
var airplaneTop = airplane.y - airplaneScaledHeight / 2;
var airplaneBottom = airplane.y + airplaneScaledHeight / 2;
var coinLeft = coin.x - 25; // coin width/2 = 50/2 = 25
var coinRight = coin.x + 25;
var coinTop = coin.y - 25; // coin height/2 = 50/2 = 25
var coinBottom = coin.y + 25;
// Check if rectangles overlap
if (airplaneRight > coinLeft && airplaneLeft < coinRight && airplaneBottom > coinTop && airplaneTop < coinBottom) {
LK.setScore(LK.getScore() + 2); // Increase score by 2 for collecting a coin
updateScore();
coin.destroy();
coins.splice(j, 1);
}
}
}
// Check ground and ceiling collision
if (airplane.y <= 30 || airplane.y >= 2702) {
// Save high score and update statistics
if (LK.getScore() > storage.highScore) {
storage.highScore = LK.getScore();
}
// Add score to global leaderboard
var globalScores = storage.globalScores || [];
globalScores.push(LK.getScore());
storage.globalScores = globalScores;
storage.gamesPlayed = (storage.gamesPlayed || 0) + 1;
highScoreTxt.setText('HIGH SCORE: ' + storage.highScore);
LK.getSound('crash').play();
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
// Reset to menu after game over
gameStarted = false;
showMenu();
return;
}
// Animate fish shadows
for (var k = 0; k < fishShadows.length; k++) {
var shadow = fishShadows[k];
shadow.x += shadow.speedX;
shadow.y += shadow.speedY;
// Add subtle vertical oscillation for realistic swimming motion
shadow.y += Math.sin(LK.ticks * 0.02 + k) * 0.5;
// Reset fish position when it goes off screen
if (shadow.x < -100) {
shadow.x = 2200 + Math.random() * 100;
shadow.y = 1200 + Math.random() * 1000;
shadow.speedX = -0.5 - Math.random() * 1.5;
shadow.speedY = (Math.random() - 0.5) * 0.3;
}
// Keep fish shadows within reasonable depth bounds
if (shadow.y < 1100) shadow.y = 1100;
if (shadow.y > 2400) shadow.y = 2400;
}
// Animate clouds
for (var c = 0; c < clouds.length; c++) {
var cloud = clouds[c];
cloud.x += cloud.speedX;
// Reset cloud position when it goes off screen
if (cloud.x < -200) {
cloud.x = 2400 + Math.random() * 200;
cloud.y = 200 + Math.random() * 400;
}
}
};
// Initialize score display
updateScore();
// Initialize game in menu state
showMenu();
// Add pause message text (initially hidden)
var pauseWarningTxt = new Text2('YOU CANT STOP IN MY GAME', {
size: 80,
fill: 0xFF0000
});
pauseWarningTxt.anchor.set(0.5, 0);
pauseWarningTxt.x = 1024;
pauseWarningTxt.y = 50;
pauseWarningTxt.visible = false;
game.addChild(pauseWarningTxt);
// Override pause event to prevent pausing and show warning
LK.on('pause', function () {
// Show red warning message
pauseWarningTxt.visible = true;
// Hide message after 2 seconds
LK.setTimeout(function () {
pauseWarningTxt.visible = false;
}, 2000);
// Prevent default pause behavior by returning false
return false;
});
// Start background music
LK.playMusic('arkaplan');
;