/****
* Plugins
****/
var tween = LK.import("@upit/tween.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;
self.gravity = 0.3;
self.flapPower = -8;
self.flap = function () {
// Calculate speed multiplier based on score (every 10 points)
var speedMultiplier = 1 + Math.floor(LK.getScore() / 10) * 0.2;
var adjustedFlapPower = self.flapPower * speedMultiplier;
self.velocity = adjustedFlapPower;
LK.getSound('flap').play();
// Add flap animation
tween(birdGraphics, {
rotation: -0.3
}, {
duration: 100
});
tween(birdGraphics, {
rotation: 0
}, {
duration: 200
});
};
self.update = function () {
// Calculate speed multiplier based on score (every 10 points)
var speedMultiplier = 1 + Math.floor(LK.getScore() / 10) * 0.2;
var adjustedGravity = self.gravity * speedMultiplier;
var adjustedFlapPower = self.flapPower * speedMultiplier;
self.velocity += adjustedGravity;
// Add velocity damping to make bird more stable
self.velocity *= 0.95;
// Limit maximum fall speed (also increased with speed)
self.velocity = Math.min(self.velocity, 8 * speedMultiplier);
self.y += self.velocity;
// Rotate bird based on velocity
if (self.velocity > 0) {
birdGraphics.rotation = Math.min(self.velocity * 0.05, 1.5);
}
};
return self;
});
var Pipe = Container.expand(function () {
var self = Container.call(this);
self.speed = -4;
self.gapSize = 300;
self.scored = false;
// Top pipe
var topPipe = self.attachAsset('pipe', {
anchorX: 0.5,
anchorY: 1
});
// Bottom pipe
var bottomPipe = self.attachAsset('pipe', {
anchorX: 0.5,
anchorY: 0
});
self.setupPipes = function (gapY) {
topPipe.y = gapY - self.gapSize / 2;
bottomPipe.y = gapY + self.gapSize / 2;
// Extend top pipe to ceiling level
topPipe.height = gapY - self.gapSize / 2;
// Extend bottom pipe to ground level
bottomPipe.height = 2632 - (gapY + self.gapSize / 2);
};
self.update = function () {
// Calculate speed multiplier based on score (every 10 points)
var speedMultiplier = 1 + Math.floor(LK.getScore() / 10) * 0.2;
var adjustedSpeed = self.speed * speedMultiplier;
self.x += adjustedSpeed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
var bird;
var pipes = [];
var ground;
var gameStarted = false;
var gameActive = true;
var pipeSpawnTimer = 0;
var pipeSpawnInterval = 120; // 2 seconds at 60fps
// Create score display
var scoreTxt = new Text2('0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Create instruction text
var instructionTxt = new Text2('TAP TO FLY', {
size: 60,
fill: 0xFFFFFF
});
instructionTxt.anchor.set(0.5, 0.5);
instructionTxt.x = 1024;
instructionTxt.y = 1000;
game.addChild(instructionTxt);
// Initialize bird
bird = game.addChild(new Bird());
bird.x = 400;
bird.y = 1366; // Center of screen
// Create ground
ground = game.addChild(LK.getAsset('ground', {
anchorX: 0,
anchorY: 0
}));
ground.x = 0;
ground.y = 2632; // Bottom of screen
function spawnPipe() {
var pipe = new Pipe();
var gapY = 600 + Math.random() * 800; // Adjusted range to ensure bottom pipe reaches ground
pipe.setupPipes(gapY);
pipe.x = 2200; // Start off-screen right
pipes.push(pipe);
game.addChild(pipe);
}
function checkCollisions() {
// Check ground collision
if (bird.y + 50 >= ground.y) {
return true;
}
// Check ceiling collision
if (bird.y - 50 <= 0) {
return true;
}
// Check pipe collisions
for (var i = 0; i < pipes.length; i++) {
var pipe = pipes[i];
// Check if bird is within pipe x range
if (bird.x + 50 > pipe.x - 60 && bird.x - 50 < pipe.x + 60) {
// Check collision with top or bottom pipe
if (bird.y - 50 < pipe.children[0].y || bird.y + 50 > pipe.children[1].y) {
return true;
}
}
}
return false;
}
function updateScore() {
for (var i = 0; i < pipes.length; i++) {
var pipe = pipes[i];
if (!pipe.scored && bird.x > pipe.x + 50) {
pipe.scored = true;
LK.setScore(LK.getScore() + 1);
scoreTxt.setText(LK.getScore());
LK.getSound('score').play();
}
}
}
function cleanupPipes() {
for (var i = pipes.length - 1; i >= 0; i--) {
var pipe = pipes[i];
if (pipe.x < -200) {
pipe.destroy();
pipes.splice(i, 1);
}
}
}
game.down = function (x, y, obj) {
if (!gameActive) return;
if (!gameStarted) {
gameStarted = true;
instructionTxt.visible = false;
}
bird.flap();
};
game.update = function () {
if (!gameActive) return;
if (gameStarted) {
// Update bird
bird.update();
// Spawn pipes
pipeSpawnTimer++;
if (pipeSpawnTimer >= pipeSpawnInterval) {
spawnPipe();
pipeSpawnTimer = 0;
}
// Update pipes
for (var i = 0; i < pipes.length; i++) {
pipes[i].update();
}
// Check collisions
if (checkCollisions()) {
gameActive = false;
LK.showGameOver();
}
// Update score
updateScore();
// Cleanup off-screen pipes
cleanupPipes();
}
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.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;
self.gravity = 0.3;
self.flapPower = -8;
self.flap = function () {
// Calculate speed multiplier based on score (every 10 points)
var speedMultiplier = 1 + Math.floor(LK.getScore() / 10) * 0.2;
var adjustedFlapPower = self.flapPower * speedMultiplier;
self.velocity = adjustedFlapPower;
LK.getSound('flap').play();
// Add flap animation
tween(birdGraphics, {
rotation: -0.3
}, {
duration: 100
});
tween(birdGraphics, {
rotation: 0
}, {
duration: 200
});
};
self.update = function () {
// Calculate speed multiplier based on score (every 10 points)
var speedMultiplier = 1 + Math.floor(LK.getScore() / 10) * 0.2;
var adjustedGravity = self.gravity * speedMultiplier;
var adjustedFlapPower = self.flapPower * speedMultiplier;
self.velocity += adjustedGravity;
// Add velocity damping to make bird more stable
self.velocity *= 0.95;
// Limit maximum fall speed (also increased with speed)
self.velocity = Math.min(self.velocity, 8 * speedMultiplier);
self.y += self.velocity;
// Rotate bird based on velocity
if (self.velocity > 0) {
birdGraphics.rotation = Math.min(self.velocity * 0.05, 1.5);
}
};
return self;
});
var Pipe = Container.expand(function () {
var self = Container.call(this);
self.speed = -4;
self.gapSize = 300;
self.scored = false;
// Top pipe
var topPipe = self.attachAsset('pipe', {
anchorX: 0.5,
anchorY: 1
});
// Bottom pipe
var bottomPipe = self.attachAsset('pipe', {
anchorX: 0.5,
anchorY: 0
});
self.setupPipes = function (gapY) {
topPipe.y = gapY - self.gapSize / 2;
bottomPipe.y = gapY + self.gapSize / 2;
// Extend top pipe to ceiling level
topPipe.height = gapY - self.gapSize / 2;
// Extend bottom pipe to ground level
bottomPipe.height = 2632 - (gapY + self.gapSize / 2);
};
self.update = function () {
// Calculate speed multiplier based on score (every 10 points)
var speedMultiplier = 1 + Math.floor(LK.getScore() / 10) * 0.2;
var adjustedSpeed = self.speed * speedMultiplier;
self.x += adjustedSpeed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
var bird;
var pipes = [];
var ground;
var gameStarted = false;
var gameActive = true;
var pipeSpawnTimer = 0;
var pipeSpawnInterval = 120; // 2 seconds at 60fps
// Create score display
var scoreTxt = new Text2('0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Create instruction text
var instructionTxt = new Text2('TAP TO FLY', {
size: 60,
fill: 0xFFFFFF
});
instructionTxt.anchor.set(0.5, 0.5);
instructionTxt.x = 1024;
instructionTxt.y = 1000;
game.addChild(instructionTxt);
// Initialize bird
bird = game.addChild(new Bird());
bird.x = 400;
bird.y = 1366; // Center of screen
// Create ground
ground = game.addChild(LK.getAsset('ground', {
anchorX: 0,
anchorY: 0
}));
ground.x = 0;
ground.y = 2632; // Bottom of screen
function spawnPipe() {
var pipe = new Pipe();
var gapY = 600 + Math.random() * 800; // Adjusted range to ensure bottom pipe reaches ground
pipe.setupPipes(gapY);
pipe.x = 2200; // Start off-screen right
pipes.push(pipe);
game.addChild(pipe);
}
function checkCollisions() {
// Check ground collision
if (bird.y + 50 >= ground.y) {
return true;
}
// Check ceiling collision
if (bird.y - 50 <= 0) {
return true;
}
// Check pipe collisions
for (var i = 0; i < pipes.length; i++) {
var pipe = pipes[i];
// Check if bird is within pipe x range
if (bird.x + 50 > pipe.x - 60 && bird.x - 50 < pipe.x + 60) {
// Check collision with top or bottom pipe
if (bird.y - 50 < pipe.children[0].y || bird.y + 50 > pipe.children[1].y) {
return true;
}
}
}
return false;
}
function updateScore() {
for (var i = 0; i < pipes.length; i++) {
var pipe = pipes[i];
if (!pipe.scored && bird.x > pipe.x + 50) {
pipe.scored = true;
LK.setScore(LK.getScore() + 1);
scoreTxt.setText(LK.getScore());
LK.getSound('score').play();
}
}
}
function cleanupPipes() {
for (var i = pipes.length - 1; i >= 0; i--) {
var pipe = pipes[i];
if (pipe.x < -200) {
pipe.destroy();
pipes.splice(i, 1);
}
}
}
game.down = function (x, y, obj) {
if (!gameActive) return;
if (!gameStarted) {
gameStarted = true;
instructionTxt.visible = false;
}
bird.flap();
};
game.update = function () {
if (!gameActive) return;
if (gameStarted) {
// Update bird
bird.update();
// Spawn pipes
pipeSpawnTimer++;
if (pipeSpawnTimer >= pipeSpawnInterval) {
spawnPipe();
pipeSpawnTimer = 0;
}
// Update pipes
for (var i = 0; i < pipes.length; i++) {
pipes[i].update();
}
// Check collisions
if (checkCollisions()) {
gameActive = false;
LK.showGameOver();
}
// Update score
updateScore();
// Cleanup off-screen pipes
cleanupPipes();
}
};