/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var topPipe = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 1
});
var bottomPipe = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0
});
self.speed = gameSpeed;
self.gap = 300;
self.passed = false;
self.setGap = function (centerY) {
topPipe.y = centerY - self.gap / 2;
bottomPipe.y = centerY + self.gap / 2;
};
self.update = function () {
self.x -= self.speed;
// Check if parrot passed this obstacle
if (!self.passed && self.x < parrot.x - 50) {
self.passed = true;
LK.setScore(LK.getScore() + 1);
scoreTxt.setText(LK.getScore());
}
};
return self;
});
var Parrot = Container.expand(function () {
var self = Container.call(this);
var parrotGraphics = self.attachAsset('parrot', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocity = 0;
self.gravity = 0.5;
self.flapPower = -12;
self.maxFallSpeed = 15;
self.flap = function () {
self.velocity = self.flapPower;
LK.getSound('flap').play();
// Wing flap animation
tween(parrotGraphics, {
scaleY: 0.8
}, {
duration: 100,
onFinish: function onFinish() {
tween(parrotGraphics, {
scaleY: 1
}, {
duration: 100
});
}
});
};
self.update = function () {
// Apply gravity
self.velocity += self.gravity;
// Limit fall speed
if (self.velocity > self.maxFallSpeed) {
self.velocity = self.maxFallSpeed;
}
// Update position
self.y += self.velocity;
// Keep parrot on screen
if (self.y < 50) {
self.y = 50;
self.velocity = 0;
}
if (self.y > 2732 - 50) {
self.y = 2732 - 50;
self.velocity = 0;
}
// Subtle rotation based on velocity
parrotGraphics.rotation = Math.max(-0.5, Math.min(0.5, self.velocity * 0.1));
};
return self;
});
var Seed = Container.expand(function () {
var self = Container.call(this);
var seedGraphics = self.attachAsset('seed', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = gameSpeed;
self.collected = false;
self.rotationSpeed = 0.1;
self.update = function () {
self.x -= self.speed;
seedGraphics.rotation += self.rotationSpeed;
// Gentle floating animation
seedGraphics.y = Math.sin(LK.ticks * 0.05 + self.x * 0.01) * 10;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
var gameSpeed = 4;
var speedIncrement = 0.002;
var maxSpeed = 8;
var parrot = game.addChild(new Parrot());
parrot.x = 300;
parrot.y = 2732 / 2;
var obstacles = [];
var seeds = [];
var obstacleSpawnTimer = 0;
var seedSpawnTimer = 0;
// Score display
var scoreTxt = new Text2('0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
scoreTxt.y = 100;
// Distance display
var distanceTxt = new Text2('Distance: 0m', {
size: 50,
fill: 0xFFFFFF
});
distanceTxt.anchor.set(0, 0);
LK.gui.topLeft.addChild(distanceTxt);
distanceTxt.x = 120;
distanceTxt.y = 50;
var distance = 0;
var isGameActive = true;
function spawnObstacle() {
var obstacle = new Obstacle();
obstacle.x = 2048 + 100;
// Random gap position
var minY = 400;
var maxY = 2732 - 400;
var gapCenterY = minY + Math.random() * (maxY - minY);
obstacle.setGap(gapCenterY);
obstacles.push(obstacle);
game.addChild(obstacle);
}
function spawnSeed() {
var seed = new Seed();
seed.x = 2048 + 50;
seed.y = 200 + Math.random() * (2732 - 400);
seeds.push(seed);
game.addChild(seed);
}
function checkCollisions() {
// Check obstacle collisions
for (var i = 0; i < obstacles.length; i++) {
var obstacle = obstacles[i];
if (parrot.intersects(obstacle)) {
gameOver();
return;
}
}
// Check seed collection
for (var j = seeds.length - 1; j >= 0; j--) {
var seed = seeds[j];
if (!seed.collected && parrot.intersects(seed)) {
seed.collected = true;
LK.setScore(LK.getScore() + 5);
scoreTxt.setText(LK.getScore());
LK.getSound('collect').play();
// Collection effect
tween(seed, {
alpha: 0,
scaleX: 2,
scaleY: 2
}, {
duration: 300,
onFinish: function onFinish() {
seed.destroy();
seeds.splice(j, 1);
}
});
}
}
}
function gameOver() {
if (!isGameActive) return;
isGameActive = false;
LK.getSound('hit').play();
LK.effects.flashScreen(0xff0000, 1000);
LK.setTimeout(function () {
LK.showGameOver();
}, 500);
}
function cleanupOffscreenObjects() {
// Clean up obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
if (obstacles[i].x < -200) {
obstacles[i].destroy();
obstacles.splice(i, 1);
}
}
// Clean up seeds
for (var j = seeds.length - 1; j >= 0; j--) {
if (seeds[j].x < -100 && !seeds[j].collected) {
seeds[j].destroy();
seeds.splice(j, 1);
}
}
}
game.down = function (x, y, obj) {
if (isGameActive) {
parrot.flap();
}
};
game.update = function () {
if (!isGameActive) return;
// Increase game speed gradually
if (gameSpeed < maxSpeed) {
gameSpeed += speedIncrement;
}
// Update distance
distance += gameSpeed * 0.1;
distanceTxt.setText('Distance: ' + Math.floor(distance) + 'm');
// Spawn obstacles
obstacleSpawnTimer++;
if (obstacleSpawnTimer >= 120) {
// Every 2 seconds at 60 FPS
spawnObstacle();
obstacleSpawnTimer = 0;
}
// Spawn seeds less frequently
seedSpawnTimer++;
if (seedSpawnTimer >= 180 && Math.random() < 0.7) {
// Every 3 seconds, 70% chance
spawnSeed();
seedSpawnTimer = 0;
}
// Update all obstacles
for (var i = 0; i < obstacles.length; i++) {
obstacles[i].speed = gameSpeed;
}
// Update all seeds
for (var j = 0; j < seeds.length; j++) {
seeds[j].speed = gameSpeed;
}
checkCollisions();
cleanupOffscreenObjects();
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var topPipe = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 1
});
var bottomPipe = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0
});
self.speed = gameSpeed;
self.gap = 300;
self.passed = false;
self.setGap = function (centerY) {
topPipe.y = centerY - self.gap / 2;
bottomPipe.y = centerY + self.gap / 2;
};
self.update = function () {
self.x -= self.speed;
// Check if parrot passed this obstacle
if (!self.passed && self.x < parrot.x - 50) {
self.passed = true;
LK.setScore(LK.getScore() + 1);
scoreTxt.setText(LK.getScore());
}
};
return self;
});
var Parrot = Container.expand(function () {
var self = Container.call(this);
var parrotGraphics = self.attachAsset('parrot', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocity = 0;
self.gravity = 0.5;
self.flapPower = -12;
self.maxFallSpeed = 15;
self.flap = function () {
self.velocity = self.flapPower;
LK.getSound('flap').play();
// Wing flap animation
tween(parrotGraphics, {
scaleY: 0.8
}, {
duration: 100,
onFinish: function onFinish() {
tween(parrotGraphics, {
scaleY: 1
}, {
duration: 100
});
}
});
};
self.update = function () {
// Apply gravity
self.velocity += self.gravity;
// Limit fall speed
if (self.velocity > self.maxFallSpeed) {
self.velocity = self.maxFallSpeed;
}
// Update position
self.y += self.velocity;
// Keep parrot on screen
if (self.y < 50) {
self.y = 50;
self.velocity = 0;
}
if (self.y > 2732 - 50) {
self.y = 2732 - 50;
self.velocity = 0;
}
// Subtle rotation based on velocity
parrotGraphics.rotation = Math.max(-0.5, Math.min(0.5, self.velocity * 0.1));
};
return self;
});
var Seed = Container.expand(function () {
var self = Container.call(this);
var seedGraphics = self.attachAsset('seed', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = gameSpeed;
self.collected = false;
self.rotationSpeed = 0.1;
self.update = function () {
self.x -= self.speed;
seedGraphics.rotation += self.rotationSpeed;
// Gentle floating animation
seedGraphics.y = Math.sin(LK.ticks * 0.05 + self.x * 0.01) * 10;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
var gameSpeed = 4;
var speedIncrement = 0.002;
var maxSpeed = 8;
var parrot = game.addChild(new Parrot());
parrot.x = 300;
parrot.y = 2732 / 2;
var obstacles = [];
var seeds = [];
var obstacleSpawnTimer = 0;
var seedSpawnTimer = 0;
// Score display
var scoreTxt = new Text2('0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
scoreTxt.y = 100;
// Distance display
var distanceTxt = new Text2('Distance: 0m', {
size: 50,
fill: 0xFFFFFF
});
distanceTxt.anchor.set(0, 0);
LK.gui.topLeft.addChild(distanceTxt);
distanceTxt.x = 120;
distanceTxt.y = 50;
var distance = 0;
var isGameActive = true;
function spawnObstacle() {
var obstacle = new Obstacle();
obstacle.x = 2048 + 100;
// Random gap position
var minY = 400;
var maxY = 2732 - 400;
var gapCenterY = minY + Math.random() * (maxY - minY);
obstacle.setGap(gapCenterY);
obstacles.push(obstacle);
game.addChild(obstacle);
}
function spawnSeed() {
var seed = new Seed();
seed.x = 2048 + 50;
seed.y = 200 + Math.random() * (2732 - 400);
seeds.push(seed);
game.addChild(seed);
}
function checkCollisions() {
// Check obstacle collisions
for (var i = 0; i < obstacles.length; i++) {
var obstacle = obstacles[i];
if (parrot.intersects(obstacle)) {
gameOver();
return;
}
}
// Check seed collection
for (var j = seeds.length - 1; j >= 0; j--) {
var seed = seeds[j];
if (!seed.collected && parrot.intersects(seed)) {
seed.collected = true;
LK.setScore(LK.getScore() + 5);
scoreTxt.setText(LK.getScore());
LK.getSound('collect').play();
// Collection effect
tween(seed, {
alpha: 0,
scaleX: 2,
scaleY: 2
}, {
duration: 300,
onFinish: function onFinish() {
seed.destroy();
seeds.splice(j, 1);
}
});
}
}
}
function gameOver() {
if (!isGameActive) return;
isGameActive = false;
LK.getSound('hit').play();
LK.effects.flashScreen(0xff0000, 1000);
LK.setTimeout(function () {
LK.showGameOver();
}, 500);
}
function cleanupOffscreenObjects() {
// Clean up obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
if (obstacles[i].x < -200) {
obstacles[i].destroy();
obstacles.splice(i, 1);
}
}
// Clean up seeds
for (var j = seeds.length - 1; j >= 0; j--) {
if (seeds[j].x < -100 && !seeds[j].collected) {
seeds[j].destroy();
seeds.splice(j, 1);
}
}
}
game.down = function (x, y, obj) {
if (isGameActive) {
parrot.flap();
}
};
game.update = function () {
if (!isGameActive) return;
// Increase game speed gradually
if (gameSpeed < maxSpeed) {
gameSpeed += speedIncrement;
}
// Update distance
distance += gameSpeed * 0.1;
distanceTxt.setText('Distance: ' + Math.floor(distance) + 'm');
// Spawn obstacles
obstacleSpawnTimer++;
if (obstacleSpawnTimer >= 120) {
// Every 2 seconds at 60 FPS
spawnObstacle();
obstacleSpawnTimer = 0;
}
// Spawn seeds less frequently
seedSpawnTimer++;
if (seedSpawnTimer >= 180 && Math.random() < 0.7) {
// Every 3 seconds, 70% chance
spawnSeed();
seedSpawnTimer = 0;
}
// Update all obstacles
for (var i = 0; i < obstacles.length; i++) {
obstacles[i].speed = gameSpeed;
}
// Update all seeds
for (var j = 0; j < seeds.length; j++) {
seeds[j].speed = gameSpeed;
}
checkCollisions();
cleanupOffscreenObjects();
};