/****
* 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.velocityY = 0;
self.gravity = 1.2;
self.flapStrength = -24;
self.isAlive = true;
self.flap = function () {
if (self.isAlive) {
self.velocityY = self.flapStrength;
LK.getSound('flap').play();
// Add flap animation
tween(birdGraphics, {
rotation: -0.3
}, {
duration: 150
});
tween(birdGraphics, {
rotation: 0.3
}, {
duration: 300,
onFinish: function onFinish() {
tween(birdGraphics, {
rotation: 0
}, {
duration: 200
});
}
});
}
};
self.update = function () {
if (self.isAlive) {
self.velocityY += self.gravity;
self.y += self.velocityY;
// Rotate bird based on velocity
var targetRotation = Math.max(-0.5, Math.min(0.8, self.velocityY * 0.1));
birdGraphics.rotation = targetRotation;
// Check bounds
if (self.y < 0 || self.y > 2632) {
// 2732 - 100 (ground height)
self.die();
}
}
};
self.die = function () {
if (self.isAlive) {
self.isAlive = false;
LK.showGameOver();
}
};
return self;
});
var Pipe = Container.expand(function () {
var self = Container.call(this);
self.speed = -8;
self.scored = false;
self.gapSize = 520;
// Create top pipe
self.topPipe = self.attachAsset('pipe', {
anchorX: 0.5,
anchorY: 1
});
// Create bottom pipe
self.bottomPipe = self.attachAsset('pipe', {
anchorX: 0.5,
anchorY: 0
});
self.setupPipes = function (gapCenterY) {
self.topPipe.y = gapCenterY - self.gapSize / 2;
self.bottomPipe.y = gapCenterY + self.gapSize / 2;
// Extend top pipe to ceiling
var topPipeTop = gapCenterY - self.gapSize / 2;
var distanceToCeiling = topPipeTop; // Distance from top of screen (0) to top pipe
self.topPipe.height = 800 + distanceToCeiling;
// Extend bottom pipe to ground level
var bottomPipeBottom = gapCenterY + self.gapSize / 2;
var distanceToGround = 2632 - bottomPipeBottom; // 2632 is ground y position
self.bottomPipe.height = 800 + distanceToGround;
};
self.update = function () {
self.x += self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Game variables
var bird;
var pipes = [];
var ground;
var pipeSpawnTimer = 0;
var pipeSpawnInterval = 280; // frames between pipe spawns
var gameStarted = false;
// Create bird
bird = game.addChild(new Bird());
bird.x = 400;
bird.y = 1366; // Center of screen
// Create ground (after bird so it renders on top)
ground = game.addChild(LK.getAsset('ground', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 2632
}));
// Create score display
var scoreTxt = new Text2('0', {
size: 120,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
scoreTxt.y = 150; // Move down from top edge
// Create tap to start text
var instructionTxt = new Text2('TAP TO FLY', {
size: 80,
fill: 0xFFFFFF
});
instructionTxt.anchor.set(0.5, 0.5);
LK.gui.center.addChild(instructionTxt);
function spawnPipe() {
var pipe = new Pipe();
var gapCenterY = 400 + Math.random() * 1800; // Random gap position
pipe.setupPipes(gapCenterY);
pipe.x = 2200; // Start off-screen right
pipes.push(pipe);
game.addChild(pipe);
}
function checkCollisions() {
for (var i = 0; i < pipes.length; i++) {
var pipe = pipes[i];
// Check collision with top and bottom pipes
if (bird.intersects(pipe.topPipe) || bird.intersects(pipe.bottomPipe)) {
bird.die();
return;
}
// Check if bird passed pipe for scoring
if (!pipe.scored && pipe.x + 60 < bird.x) {
pipe.scored = true;
LK.setScore(LK.getScore() + 1);
scoreTxt.setText(LK.getScore());
LK.getSound('score').play();
// Check for win condition
if (LK.getScore() >= 50) {
LK.showYouWin();
}
}
}
// Check collision with ground
if (bird.intersects(ground)) {
bird.die();
}
}
function startGame() {
if (!gameStarted) {
gameStarted = true;
instructionTxt.visible = false;
}
}
// Game input
game.down = function (x, y, obj) {
if (!gameStarted) {
startGame();
}
bird.flap();
};
// Main game loop
game.update = function () {
if (gameStarted) {
// Spawn pipes
pipeSpawnTimer++;
if (pipeSpawnTimer >= pipeSpawnInterval) {
spawnPipe();
pipeSpawnTimer = 0;
}
// Remove off-screen pipes
for (var i = pipes.length - 1; i >= 0; i--) {
var pipe = pipes[i];
if (pipe.x < -200) {
pipe.destroy();
pipes.splice(i, 1);
}
}
// Check collisions
checkCollisions();
}
}; /****
* 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.velocityY = 0;
self.gravity = 1.2;
self.flapStrength = -24;
self.isAlive = true;
self.flap = function () {
if (self.isAlive) {
self.velocityY = self.flapStrength;
LK.getSound('flap').play();
// Add flap animation
tween(birdGraphics, {
rotation: -0.3
}, {
duration: 150
});
tween(birdGraphics, {
rotation: 0.3
}, {
duration: 300,
onFinish: function onFinish() {
tween(birdGraphics, {
rotation: 0
}, {
duration: 200
});
}
});
}
};
self.update = function () {
if (self.isAlive) {
self.velocityY += self.gravity;
self.y += self.velocityY;
// Rotate bird based on velocity
var targetRotation = Math.max(-0.5, Math.min(0.8, self.velocityY * 0.1));
birdGraphics.rotation = targetRotation;
// Check bounds
if (self.y < 0 || self.y > 2632) {
// 2732 - 100 (ground height)
self.die();
}
}
};
self.die = function () {
if (self.isAlive) {
self.isAlive = false;
LK.showGameOver();
}
};
return self;
});
var Pipe = Container.expand(function () {
var self = Container.call(this);
self.speed = -8;
self.scored = false;
self.gapSize = 520;
// Create top pipe
self.topPipe = self.attachAsset('pipe', {
anchorX: 0.5,
anchorY: 1
});
// Create bottom pipe
self.bottomPipe = self.attachAsset('pipe', {
anchorX: 0.5,
anchorY: 0
});
self.setupPipes = function (gapCenterY) {
self.topPipe.y = gapCenterY - self.gapSize / 2;
self.bottomPipe.y = gapCenterY + self.gapSize / 2;
// Extend top pipe to ceiling
var topPipeTop = gapCenterY - self.gapSize / 2;
var distanceToCeiling = topPipeTop; // Distance from top of screen (0) to top pipe
self.topPipe.height = 800 + distanceToCeiling;
// Extend bottom pipe to ground level
var bottomPipeBottom = gapCenterY + self.gapSize / 2;
var distanceToGround = 2632 - bottomPipeBottom; // 2632 is ground y position
self.bottomPipe.height = 800 + distanceToGround;
};
self.update = function () {
self.x += self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Game variables
var bird;
var pipes = [];
var ground;
var pipeSpawnTimer = 0;
var pipeSpawnInterval = 280; // frames between pipe spawns
var gameStarted = false;
// Create bird
bird = game.addChild(new Bird());
bird.x = 400;
bird.y = 1366; // Center of screen
// Create ground (after bird so it renders on top)
ground = game.addChild(LK.getAsset('ground', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 2632
}));
// Create score display
var scoreTxt = new Text2('0', {
size: 120,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
scoreTxt.y = 150; // Move down from top edge
// Create tap to start text
var instructionTxt = new Text2('TAP TO FLY', {
size: 80,
fill: 0xFFFFFF
});
instructionTxt.anchor.set(0.5, 0.5);
LK.gui.center.addChild(instructionTxt);
function spawnPipe() {
var pipe = new Pipe();
var gapCenterY = 400 + Math.random() * 1800; // Random gap position
pipe.setupPipes(gapCenterY);
pipe.x = 2200; // Start off-screen right
pipes.push(pipe);
game.addChild(pipe);
}
function checkCollisions() {
for (var i = 0; i < pipes.length; i++) {
var pipe = pipes[i];
// Check collision with top and bottom pipes
if (bird.intersects(pipe.topPipe) || bird.intersects(pipe.bottomPipe)) {
bird.die();
return;
}
// Check if bird passed pipe for scoring
if (!pipe.scored && pipe.x + 60 < bird.x) {
pipe.scored = true;
LK.setScore(LK.getScore() + 1);
scoreTxt.setText(LK.getScore());
LK.getSound('score').play();
// Check for win condition
if (LK.getScore() >= 50) {
LK.showYouWin();
}
}
}
// Check collision with ground
if (bird.intersects(ground)) {
bird.die();
}
}
function startGame() {
if (!gameStarted) {
gameStarted = true;
instructionTxt.visible = false;
}
}
// Game input
game.down = function (x, y, obj) {
if (!gameStarted) {
startGame();
}
bird.flap();
};
// Main game loop
game.update = function () {
if (gameStarted) {
// Spawn pipes
pipeSpawnTimer++;
if (pipeSpawnTimer >= pipeSpawnInterval) {
spawnPipe();
pipeSpawnTimer = 0;
}
// Remove off-screen pipes
for (var i = pipes.length - 1; i >= 0; i--) {
var pipe = pipes[i];
if (pipe.x < -200) {
pipe.destroy();
pipes.splice(i, 1);
}
}
// Check collisions
checkCollisions();
}
};