/**** * 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();
}
};