/****
* 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 = -12;
self.rotation = 0;
self.isMonster = false;
self.monsterEndTime = 0;
// Transform into monster
self.transformToMonster = function () {
if (!self.isMonster) {
self.isMonster = true;
self.monsterEndTime = LK.ticks + 600; // 10 seconds at 60fps
// Remove current bird graphics
self.removeChild(birdGraphics);
// Add monster graphics
self.monsterGraphics = self.attachAsset('monster', {
anchorX: 0.5,
anchorY: 0.5
});
// Enhanced abilities
self.flapPower = -4; // Monster jump power
self.gravity = 0.1; // Less gravity
// Visual effect
tween(self.monsterGraphics, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 500,
easing: tween.elasticOut
});
}
};
// Transform back to normal bird
self.transformToNormal = function () {
if (self.isMonster) {
self.isMonster = false;
// Remove monster graphics
if (self.monsterGraphics) {
self.removeChild(self.monsterGraphics);
}
// Add back bird graphics
birdGraphics = self.attachAsset('bird', {
anchorX: 0.5,
anchorY: 0.5
});
// Reset normal abilities
self.flapPower = -12;
self.gravity = 0.3;
// Restart wing animation
self.startWingAnimation();
}
};
// Start continuous wing flapping animation
self.startWingAnimation = function () {
// Create a continuous flapping animation by scaling the bird
function flapUp() {
tween(birdGraphics, {
scaleY: 1.2
}, {
duration: 150,
easing: tween.easeOut,
onFinish: flapDown
});
}
function flapDown() {
tween(birdGraphics, {
scaleY: 0.8
}, {
duration: 150,
easing: tween.easeOut,
onFinish: flapUp
});
}
// Start the animation cycle
flapUp();
};
// Start wing animation immediately
self.startWingAnimation();
self.flap = function () {
self.velocity = self.flapPower;
LK.getSound('flap').play();
};
self.update = function () {
// Check if monster time is up
if (self.isMonster && LK.ticks >= self.monsterEndTime) {
self.transformToNormal();
}
self.velocity += self.gravity;
self.y += self.velocity;
// Monster can fly through boundaries without dying
if (!self.isMonster) {
// Check ground collision
if (self.y > 2732 - 150) {
self.y = 2732 - 150;
gameOver = true;
}
// Check ceiling collision
if (self.y < 50) {
self.y = 50;
gameOver = true;
}
} else {
// Monster just bounces off boundaries
if (self.y > 2732 - 150) {
self.y = 2732 - 150;
self.velocity = -Math.abs(self.velocity);
}
if (self.y < 50) {
self.y = 50;
self.velocity = Math.abs(self.velocity);
}
}
};
return self;
});
var Crown = Container.expand(function () {
var self = Container.call(this);
var crownGraphics = self.attachAsset('crown', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var Dragon = Container.expand(function () {
var self = Container.call(this);
var dragonGraphics = self.attachAsset('dragon', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocity = 0;
self.gravity = 0.2;
self.speed = -12; // Triple speed of pipes
self.jumpPower = 5;
self.dodgeTimer = 0;
self.isDodging = false;
self.targetY = 2732 / 2;
self.jump = function () {
self.velocity = -self.jumpPower;
};
self.update = function () {
// Move horizontally with triple speed
self.x += self.speed;
// Dodge poles by finding safe gaps
if (!self.isDodging) {
// Check for incoming pipes and find safe path
for (var i = 0; i < pipes.length; i++) {
var pipe = pipes[i];
// If pipe is ahead and close enough to dodge (increased detection range)
if (pipe.x > self.x && pipe.x < self.x + 600) {
// Calculate safe Y position (middle of gap between top and bottom pipes)
var gapCenterY = pipe.topPipe.y + (pipe.bottomPipe.y - pipe.topPipe.y) / 2;
self.targetY = gapCenterY;
self.isDodging = true;
self.dodgeTimer = 90; // Dodge for 1.5 seconds
break;
}
}
}
// Move toward target Y position when dodging
if (self.isDodging) {
var yDiff = self.targetY - self.y;
self.y += yDiff * 0.15; // Faster, smoother movement
self.dodgeTimer--;
if (self.dodgeTimer <= 0) {
self.isDodging = false;
}
} else {
// Normal flight behavior when not dodging
self.velocity += self.gravity;
self.y += self.velocity;
// Keep dragon within screen bounds
if (self.y > 2732 - 200) {
self.y = 2732 - 200;
self.velocity = -Math.abs(self.velocity);
}
if (self.y < 100) {
self.y = 100;
self.velocity = Math.abs(self.velocity);
}
}
};
return self;
});
var Pipe = Container.expand(function () {
var self = Container.call(this);
self.gapSize = 1200; // Increased gap size for easier navigation
self.speed = -8;
self.scored = false;
// 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.setGapPosition = function (gapY) {
self.topPipe.y = gapY - self.gapSize / 2;
self.bottomPipe.y = gapY + self.gapSize / 2;
};
self.update = function () {
self.x += self.speed;
// Check if bird passed through pipe
if (!self.scored && self.x < bird.x) {
self.scored = true;
LK.setScore(LK.getScore() + 1);
scoreTxt.setText(LK.getScore());
LK.getSound('score').play();
}
};
return self;
});
var ReplayButton = Container.expand(function () {
var self = Container.call(this);
// Main button background
var buttonGraphics = self.attachAsset('replayButton', {
anchorX: 0.5,
anchorY: 0.5
});
// Crown decoration in corner
var crownDecoration = self.attachAsset('crown', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.6,
scaleY: 0.6
});
// Position crown in top-right corner of button
crownDecoration.x = 70;
crownDecoration.y = -25;
// Replay text
var replayText = new Text2('REPLAY', {
size: 32,
fill: 0xFFFFFF,
align: 'center'
});
replayText.anchor.set(0.5, 0.5);
self.addChild(replayText);
// Button click handler
self.down = function (x, y, obj) {
// Restart the game by reloading
location.reload();
};
return self;
});
var Snow = Container.expand(function () {
var self = Container.call(this);
var snowGraphics = self.attachAsset('snow', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = Math.random() * 2 + 1;
self.sway = Math.random() * 0.02 - 0.01;
self.update = function () {
self.y += self.speed;
self.x += Math.sin(LK.ticks * self.sway) * 0.5;
};
return self;
});
var Star = Container.expand(function () {
var self = Container.call(this);
var starGraphics = self.attachAsset('star', {
anchorX: 0.5,
anchorY: 0.5
});
// Start blinking animation immediately
self.startBlinking = function () {
function fadeOut() {
tween(starGraphics, {
alpha: 0.2
}, {
duration: 1000 + Math.random() * 2000,
easing: tween.easeInOut,
onFinish: fadeIn
});
}
function fadeIn() {
tween(starGraphics, {
alpha: 1.0
}, {
duration: 1000 + Math.random() * 2000,
easing: tween.easeInOut,
onFinish: fadeOut
});
}
// Start with random delay
LK.setTimeout(function () {
fadeOut();
}, Math.random() * 3000);
};
// Start blinking when created
self.startBlinking();
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x5555FF
});
/****
* Game Code
****/
var bird;
var pipes = [];
var ground;
var scoreTxt;
var gameOver = false;
var gameStarted = false;
var pipeSpawnTimer = 0;
var pipeSpawnInterval = 240; // frames between pipe spawns - increased gap
var hasTransformedToMonster = false;
var isWinter = false;
var snowParticles = [];
var snowSpawnTimer = 0;
var stars = [];
var starsSpawned = false;
var endingAnimationStarted = false;
var mario = null;
var crown = null;
function cleanupSnowParticles() {
for (var i = snowParticles.length - 1; i >= 0; i--) {
var snow = snowParticles[i];
snow.destroy();
snowParticles.splice(i, 1);
}
}
function spawnStars() {
// Create 30-50 stars scattered across the sky
var numStars = 30 + Math.floor(Math.random() * 20);
for (var i = 0; i < numStars; i++) {
var star = new Star();
star.x = Math.random() * 2048;
star.y = 100 + Math.random() * 800; // Upper portion of screen
stars.push(star);
game.addChild(star);
}
}
function cleanupStars() {
for (var i = stars.length - 1; i >= 0; i--) {
var star = stars[i];
star.destroy();
stars.splice(i, 1);
}
starsSpawned = false;
}
var everest;
var dragon;
var dragonSpawned = false;
var dragonEndTime = 0;
// Create ground
ground = game.addChild(LK.getAsset('ground', {
anchorX: 0,
anchorY: 1,
x: 0,
y: 2732
}));
// Create bird
bird = game.addChild(new Bird());
bird.x = 300;
bird.y = 2732 / 2;
// Create score text
scoreTxt = new Text2('0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
scoreTxt.y = 100;
// Create instruction text
var instructionTxt = new Text2('TAP TO START', {
size: 60,
fill: 0xFFFFFF
});
instructionTxt.anchor.set(0.5, 0.5);
LK.gui.center.addChild(instructionTxt);
var pipePatternIndex = 0;
var pipePositions = [800, 1000, 1200, 1400, 1600, 1800, 1600, 1400, 1200, 1000]; // Connected systematic pattern
function spawnPipe() {
var pipe = new Pipe();
pipe.x = 2048 + 60;
// Use systematic pattern with smooth transitions
var gapY = pipePositions[pipePatternIndex % pipePositions.length];
pipePatternIndex++;
pipe.setGapPosition(gapY);
pipes.push(pipe);
game.addChild(pipe);
}
function checkCollisions() {
// Monster is invincible and can fly through pipes
if (bird.isMonster) {
return;
}
for (var i = 0; i < pipes.length; i++) {
var pipe = pipes[i];
// Check collision with top pipe
if (bird.intersects(pipe.topPipe)) {
gameOver = true;
LK.getSound('hit').play();
return;
}
// Check collision with bottom pipe
if (bird.intersects(pipe.bottomPipe)) {
gameOver = true;
LK.getSound('hit').play();
return;
}
}
}
function checkSeasonChange() {
// Transform bird into dragon at 85 points
if (LK.getScore() >= 85 && !dragonSpawned) {
dragonSpawned = true;
// Remove current bird graphics (whether bird or monster)
if (bird.isMonster && bird.monsterGraphics) {
bird.removeChild(bird.monsterGraphics);
} else {
// Remove normal bird graphics
var children = bird.children.slice();
for (var i = 0; i < children.length; i++) {
bird.removeChild(children[i]);
}
}
// Add dragon graphics to the bird
bird.dragonGraphics = bird.attachAsset('dragon', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.7,
scaleY: 0.7
});
// Transform bird properties to dragon
bird.flapPower = -8;
bird.gravity = 0.15;
bird.isDragon = true;
// Visual transformation effect
tween(bird.dragonGraphics, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 1000,
easing: tween.elasticOut
});
}
// Day season at 50 points
if (LK.getScore() >= 50) {
game.setBackgroundColor(0xFFD700); // Bright day yellow
// Clean up stars when entering day season
if (starsSpawned) {
cleanupStars();
}
} else if (LK.getScore() >= 25) {
// Winter season at 25 points
game.setBackgroundColor(0xF0F8FF); // Winter white/light blue
// Clean up stars when entering winter season
if (starsSpawned) {
cleanupStars();
}
if (!isWinter) {
isWinter = true;
}
} else if (LK.getScore() >= 5) {
// Change to night theme when score reaches 5
game.setBackgroundColor(0x1a1a2e); // Dark night blue
// Transform bird to monster once when reaching night time
if (!hasTransformedToMonster) {
hasTransformedToMonster = true;
bird.transformToMonster();
}
// Spawn stars for night effect only
if (!starsSpawned) {
starsSpawned = true;
spawnStars();
}
} else {
game.setBackgroundColor(0x5555FF); // 85 blue background
}
}
function cleanupPipes() {
for (var i = pipes.length - 1; i >= 0; i--) {
var pipe = pipes[i];
if (pipe.x < -100) {
pipe.destroy();
pipes.splice(i, 1);
}
}
}
game.down = function (x, y, obj) {
if (gameOver) {
return;
}
if (!gameStarted) {
gameStarted = true;
instructionTxt.visible = false;
}
bird.flap();
};
game.update = function () {
if (gameOver) {
LK.showGameOver();
return;
}
// Check winning condition at 100 points and start ending animation
if (LK.getScore() >= 100 && !endingAnimationStarted) {
endingAnimationStarted = true;
// Create Mario (using dragon asset as Mario)
mario = game.addChild(LK.getAsset('dragon', {
anchorX: 0.5,
anchorY: 0.5,
x: -200,
y: 2732 / 2,
scaleX: 0.6,
scaleY: 0.6
}));
// Create crown
crown = game.addChild(new Crown());
crown.x = -150;
crown.y = 2732 / 2 - 100;
crown.alpha = 0;
// Animation sequence: Mario enters from left
tween(mario, {
x: 800
}, {
duration: 2000,
easing: tween.easeOut,
onFinish: function onFinish() {
// Show crown with fade in
tween(crown, {
alpha: 1,
x: 850
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
// Mario gives crown to bird - move crown to bird
tween(crown, {
x: bird.x,
y: bird.y - 80
}, {
duration: 1500,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Crown ceremony complete - show thank you message
var thankYouText = new Text2('Thank you for playing my game\nI know it is not good very much\nbut I tried my best to provide this ending', {
size: 60,
fill: 0xFFFFFF,
align: 'center'
});
thankYouText.anchor.set(0.5, 0.5);
thankYouText.x = 1024;
thankYouText.y = 1366;
thankYouText.alpha = 0;
LK.gui.center.addChild(thankYouText);
// Fade in thank you message
tween(thankYouText, {
alpha: 1
}, {
duration: 1500,
easing: tween.easeIn,
onFinish: function onFinish() {
// Show message for 3 seconds then show like message
LK.setTimeout(function () {
// Fade out thank you message
tween(thankYouText, {
alpha: 0
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
// Show like message
var likeText = new Text2('Like the game if you really love it', {
size: 60,
fill: 0xFFFFFF,
align: 'center'
});
likeText.anchor.set(0.5, 0.5);
likeText.x = 1024;
likeText.y = 1366;
likeText.alpha = 0;
LK.gui.center.addChild(likeText);
// Fade in like message
tween(likeText, {
alpha: 1
}, {
duration: 1500,
easing: tween.easeIn,
onFinish: function onFinish() {
// Show like message for 3 seconds then show replay button
LK.setTimeout(function () {
// Create and show replay button
var replayButton = new ReplayButton();
replayButton.x = 1024;
replayButton.y = 1600;
replayButton.alpha = 0;
LK.gui.center.addChild(replayButton);
// Fade in replay button
tween(replayButton, {
alpha: 1
}, {
duration: 1000,
easing: tween.easeIn
});
}, 3000);
}
});
}
});
}, 3000);
}
});
}
});
}
});
}
});
return;
}
if (!gameStarted) {
return;
}
// Update bird
// Spawn pipes
pipeSpawnTimer++;
if (pipeSpawnTimer >= pipeSpawnInterval) {
spawnPipe();
pipeSpawnTimer = 0;
}
// Check collisions
checkCollisions();
// Check for season changes
checkSeasonChange();
// Bird is now permanently transformed into dragon at 85 points
// No need for separate dragon lifecycle management
// 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 = -12;
self.rotation = 0;
self.isMonster = false;
self.monsterEndTime = 0;
// Transform into monster
self.transformToMonster = function () {
if (!self.isMonster) {
self.isMonster = true;
self.monsterEndTime = LK.ticks + 600; // 10 seconds at 60fps
// Remove current bird graphics
self.removeChild(birdGraphics);
// Add monster graphics
self.monsterGraphics = self.attachAsset('monster', {
anchorX: 0.5,
anchorY: 0.5
});
// Enhanced abilities
self.flapPower = -4; // Monster jump power
self.gravity = 0.1; // Less gravity
// Visual effect
tween(self.monsterGraphics, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 500,
easing: tween.elasticOut
});
}
};
// Transform back to normal bird
self.transformToNormal = function () {
if (self.isMonster) {
self.isMonster = false;
// Remove monster graphics
if (self.monsterGraphics) {
self.removeChild(self.monsterGraphics);
}
// Add back bird graphics
birdGraphics = self.attachAsset('bird', {
anchorX: 0.5,
anchorY: 0.5
});
// Reset normal abilities
self.flapPower = -12;
self.gravity = 0.3;
// Restart wing animation
self.startWingAnimation();
}
};
// Start continuous wing flapping animation
self.startWingAnimation = function () {
// Create a continuous flapping animation by scaling the bird
function flapUp() {
tween(birdGraphics, {
scaleY: 1.2
}, {
duration: 150,
easing: tween.easeOut,
onFinish: flapDown
});
}
function flapDown() {
tween(birdGraphics, {
scaleY: 0.8
}, {
duration: 150,
easing: tween.easeOut,
onFinish: flapUp
});
}
// Start the animation cycle
flapUp();
};
// Start wing animation immediately
self.startWingAnimation();
self.flap = function () {
self.velocity = self.flapPower;
LK.getSound('flap').play();
};
self.update = function () {
// Check if monster time is up
if (self.isMonster && LK.ticks >= self.monsterEndTime) {
self.transformToNormal();
}
self.velocity += self.gravity;
self.y += self.velocity;
// Monster can fly through boundaries without dying
if (!self.isMonster) {
// Check ground collision
if (self.y > 2732 - 150) {
self.y = 2732 - 150;
gameOver = true;
}
// Check ceiling collision
if (self.y < 50) {
self.y = 50;
gameOver = true;
}
} else {
// Monster just bounces off boundaries
if (self.y > 2732 - 150) {
self.y = 2732 - 150;
self.velocity = -Math.abs(self.velocity);
}
if (self.y < 50) {
self.y = 50;
self.velocity = Math.abs(self.velocity);
}
}
};
return self;
});
var Crown = Container.expand(function () {
var self = Container.call(this);
var crownGraphics = self.attachAsset('crown', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var Dragon = Container.expand(function () {
var self = Container.call(this);
var dragonGraphics = self.attachAsset('dragon', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocity = 0;
self.gravity = 0.2;
self.speed = -12; // Triple speed of pipes
self.jumpPower = 5;
self.dodgeTimer = 0;
self.isDodging = false;
self.targetY = 2732 / 2;
self.jump = function () {
self.velocity = -self.jumpPower;
};
self.update = function () {
// Move horizontally with triple speed
self.x += self.speed;
// Dodge poles by finding safe gaps
if (!self.isDodging) {
// Check for incoming pipes and find safe path
for (var i = 0; i < pipes.length; i++) {
var pipe = pipes[i];
// If pipe is ahead and close enough to dodge (increased detection range)
if (pipe.x > self.x && pipe.x < self.x + 600) {
// Calculate safe Y position (middle of gap between top and bottom pipes)
var gapCenterY = pipe.topPipe.y + (pipe.bottomPipe.y - pipe.topPipe.y) / 2;
self.targetY = gapCenterY;
self.isDodging = true;
self.dodgeTimer = 90; // Dodge for 1.5 seconds
break;
}
}
}
// Move toward target Y position when dodging
if (self.isDodging) {
var yDiff = self.targetY - self.y;
self.y += yDiff * 0.15; // Faster, smoother movement
self.dodgeTimer--;
if (self.dodgeTimer <= 0) {
self.isDodging = false;
}
} else {
// Normal flight behavior when not dodging
self.velocity += self.gravity;
self.y += self.velocity;
// Keep dragon within screen bounds
if (self.y > 2732 - 200) {
self.y = 2732 - 200;
self.velocity = -Math.abs(self.velocity);
}
if (self.y < 100) {
self.y = 100;
self.velocity = Math.abs(self.velocity);
}
}
};
return self;
});
var Pipe = Container.expand(function () {
var self = Container.call(this);
self.gapSize = 1200; // Increased gap size for easier navigation
self.speed = -8;
self.scored = false;
// 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.setGapPosition = function (gapY) {
self.topPipe.y = gapY - self.gapSize / 2;
self.bottomPipe.y = gapY + self.gapSize / 2;
};
self.update = function () {
self.x += self.speed;
// Check if bird passed through pipe
if (!self.scored && self.x < bird.x) {
self.scored = true;
LK.setScore(LK.getScore() + 1);
scoreTxt.setText(LK.getScore());
LK.getSound('score').play();
}
};
return self;
});
var ReplayButton = Container.expand(function () {
var self = Container.call(this);
// Main button background
var buttonGraphics = self.attachAsset('replayButton', {
anchorX: 0.5,
anchorY: 0.5
});
// Crown decoration in corner
var crownDecoration = self.attachAsset('crown', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.6,
scaleY: 0.6
});
// Position crown in top-right corner of button
crownDecoration.x = 70;
crownDecoration.y = -25;
// Replay text
var replayText = new Text2('REPLAY', {
size: 32,
fill: 0xFFFFFF,
align: 'center'
});
replayText.anchor.set(0.5, 0.5);
self.addChild(replayText);
// Button click handler
self.down = function (x, y, obj) {
// Restart the game by reloading
location.reload();
};
return self;
});
var Snow = Container.expand(function () {
var self = Container.call(this);
var snowGraphics = self.attachAsset('snow', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = Math.random() * 2 + 1;
self.sway = Math.random() * 0.02 - 0.01;
self.update = function () {
self.y += self.speed;
self.x += Math.sin(LK.ticks * self.sway) * 0.5;
};
return self;
});
var Star = Container.expand(function () {
var self = Container.call(this);
var starGraphics = self.attachAsset('star', {
anchorX: 0.5,
anchorY: 0.5
});
// Start blinking animation immediately
self.startBlinking = function () {
function fadeOut() {
tween(starGraphics, {
alpha: 0.2
}, {
duration: 1000 + Math.random() * 2000,
easing: tween.easeInOut,
onFinish: fadeIn
});
}
function fadeIn() {
tween(starGraphics, {
alpha: 1.0
}, {
duration: 1000 + Math.random() * 2000,
easing: tween.easeInOut,
onFinish: fadeOut
});
}
// Start with random delay
LK.setTimeout(function () {
fadeOut();
}, Math.random() * 3000);
};
// Start blinking when created
self.startBlinking();
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x5555FF
});
/****
* Game Code
****/
var bird;
var pipes = [];
var ground;
var scoreTxt;
var gameOver = false;
var gameStarted = false;
var pipeSpawnTimer = 0;
var pipeSpawnInterval = 240; // frames between pipe spawns - increased gap
var hasTransformedToMonster = false;
var isWinter = false;
var snowParticles = [];
var snowSpawnTimer = 0;
var stars = [];
var starsSpawned = false;
var endingAnimationStarted = false;
var mario = null;
var crown = null;
function cleanupSnowParticles() {
for (var i = snowParticles.length - 1; i >= 0; i--) {
var snow = snowParticles[i];
snow.destroy();
snowParticles.splice(i, 1);
}
}
function spawnStars() {
// Create 30-50 stars scattered across the sky
var numStars = 30 + Math.floor(Math.random() * 20);
for (var i = 0; i < numStars; i++) {
var star = new Star();
star.x = Math.random() * 2048;
star.y = 100 + Math.random() * 800; // Upper portion of screen
stars.push(star);
game.addChild(star);
}
}
function cleanupStars() {
for (var i = stars.length - 1; i >= 0; i--) {
var star = stars[i];
star.destroy();
stars.splice(i, 1);
}
starsSpawned = false;
}
var everest;
var dragon;
var dragonSpawned = false;
var dragonEndTime = 0;
// Create ground
ground = game.addChild(LK.getAsset('ground', {
anchorX: 0,
anchorY: 1,
x: 0,
y: 2732
}));
// Create bird
bird = game.addChild(new Bird());
bird.x = 300;
bird.y = 2732 / 2;
// Create score text
scoreTxt = new Text2('0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
scoreTxt.y = 100;
// Create instruction text
var instructionTxt = new Text2('TAP TO START', {
size: 60,
fill: 0xFFFFFF
});
instructionTxt.anchor.set(0.5, 0.5);
LK.gui.center.addChild(instructionTxt);
var pipePatternIndex = 0;
var pipePositions = [800, 1000, 1200, 1400, 1600, 1800, 1600, 1400, 1200, 1000]; // Connected systematic pattern
function spawnPipe() {
var pipe = new Pipe();
pipe.x = 2048 + 60;
// Use systematic pattern with smooth transitions
var gapY = pipePositions[pipePatternIndex % pipePositions.length];
pipePatternIndex++;
pipe.setGapPosition(gapY);
pipes.push(pipe);
game.addChild(pipe);
}
function checkCollisions() {
// Monster is invincible and can fly through pipes
if (bird.isMonster) {
return;
}
for (var i = 0; i < pipes.length; i++) {
var pipe = pipes[i];
// Check collision with top pipe
if (bird.intersects(pipe.topPipe)) {
gameOver = true;
LK.getSound('hit').play();
return;
}
// Check collision with bottom pipe
if (bird.intersects(pipe.bottomPipe)) {
gameOver = true;
LK.getSound('hit').play();
return;
}
}
}
function checkSeasonChange() {
// Transform bird into dragon at 85 points
if (LK.getScore() >= 85 && !dragonSpawned) {
dragonSpawned = true;
// Remove current bird graphics (whether bird or monster)
if (bird.isMonster && bird.monsterGraphics) {
bird.removeChild(bird.monsterGraphics);
} else {
// Remove normal bird graphics
var children = bird.children.slice();
for (var i = 0; i < children.length; i++) {
bird.removeChild(children[i]);
}
}
// Add dragon graphics to the bird
bird.dragonGraphics = bird.attachAsset('dragon', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.7,
scaleY: 0.7
});
// Transform bird properties to dragon
bird.flapPower = -8;
bird.gravity = 0.15;
bird.isDragon = true;
// Visual transformation effect
tween(bird.dragonGraphics, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 1000,
easing: tween.elasticOut
});
}
// Day season at 50 points
if (LK.getScore() >= 50) {
game.setBackgroundColor(0xFFD700); // Bright day yellow
// Clean up stars when entering day season
if (starsSpawned) {
cleanupStars();
}
} else if (LK.getScore() >= 25) {
// Winter season at 25 points
game.setBackgroundColor(0xF0F8FF); // Winter white/light blue
// Clean up stars when entering winter season
if (starsSpawned) {
cleanupStars();
}
if (!isWinter) {
isWinter = true;
}
} else if (LK.getScore() >= 5) {
// Change to night theme when score reaches 5
game.setBackgroundColor(0x1a1a2e); // Dark night blue
// Transform bird to monster once when reaching night time
if (!hasTransformedToMonster) {
hasTransformedToMonster = true;
bird.transformToMonster();
}
// Spawn stars for night effect only
if (!starsSpawned) {
starsSpawned = true;
spawnStars();
}
} else {
game.setBackgroundColor(0x5555FF); // 85 blue background
}
}
function cleanupPipes() {
for (var i = pipes.length - 1; i >= 0; i--) {
var pipe = pipes[i];
if (pipe.x < -100) {
pipe.destroy();
pipes.splice(i, 1);
}
}
}
game.down = function (x, y, obj) {
if (gameOver) {
return;
}
if (!gameStarted) {
gameStarted = true;
instructionTxt.visible = false;
}
bird.flap();
};
game.update = function () {
if (gameOver) {
LK.showGameOver();
return;
}
// Check winning condition at 100 points and start ending animation
if (LK.getScore() >= 100 && !endingAnimationStarted) {
endingAnimationStarted = true;
// Create Mario (using dragon asset as Mario)
mario = game.addChild(LK.getAsset('dragon', {
anchorX: 0.5,
anchorY: 0.5,
x: -200,
y: 2732 / 2,
scaleX: 0.6,
scaleY: 0.6
}));
// Create crown
crown = game.addChild(new Crown());
crown.x = -150;
crown.y = 2732 / 2 - 100;
crown.alpha = 0;
// Animation sequence: Mario enters from left
tween(mario, {
x: 800
}, {
duration: 2000,
easing: tween.easeOut,
onFinish: function onFinish() {
// Show crown with fade in
tween(crown, {
alpha: 1,
x: 850
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
// Mario gives crown to bird - move crown to bird
tween(crown, {
x: bird.x,
y: bird.y - 80
}, {
duration: 1500,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Crown ceremony complete - show thank you message
var thankYouText = new Text2('Thank you for playing my game\nI know it is not good very much\nbut I tried my best to provide this ending', {
size: 60,
fill: 0xFFFFFF,
align: 'center'
});
thankYouText.anchor.set(0.5, 0.5);
thankYouText.x = 1024;
thankYouText.y = 1366;
thankYouText.alpha = 0;
LK.gui.center.addChild(thankYouText);
// Fade in thank you message
tween(thankYouText, {
alpha: 1
}, {
duration: 1500,
easing: tween.easeIn,
onFinish: function onFinish() {
// Show message for 3 seconds then show like message
LK.setTimeout(function () {
// Fade out thank you message
tween(thankYouText, {
alpha: 0
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
// Show like message
var likeText = new Text2('Like the game if you really love it', {
size: 60,
fill: 0xFFFFFF,
align: 'center'
});
likeText.anchor.set(0.5, 0.5);
likeText.x = 1024;
likeText.y = 1366;
likeText.alpha = 0;
LK.gui.center.addChild(likeText);
// Fade in like message
tween(likeText, {
alpha: 1
}, {
duration: 1500,
easing: tween.easeIn,
onFinish: function onFinish() {
// Show like message for 3 seconds then show replay button
LK.setTimeout(function () {
// Create and show replay button
var replayButton = new ReplayButton();
replayButton.x = 1024;
replayButton.y = 1600;
replayButton.alpha = 0;
LK.gui.center.addChild(replayButton);
// Fade in replay button
tween(replayButton, {
alpha: 1
}, {
duration: 1000,
easing: tween.easeIn
});
}, 3000);
}
});
}
});
}, 3000);
}
});
}
});
}
});
}
});
return;
}
if (!gameStarted) {
return;
}
// Update bird
// Spawn pipes
pipeSpawnTimer++;
if (pipeSpawnTimer >= pipeSpawnInterval) {
spawnPipe();
pipeSpawnTimer = 0;
}
// Check collisions
checkCollisions();
// Check for season changes
checkSeasonChange();
// Bird is now permanently transformed into dragon at 85 points
// No need for separate dragon lifecycle management
// Cleanup off-screen pipes
cleanupPipes();
};
single pole flappy bird. In-Game asset. 2d. High contrast. No shadows
ground have mincraft ground trxture. In-Game asset. 2d. High contrast. No shadows
long dragon. In-Game asset. 2d. High contrast. No shadows
yeti cartoon image. In-Game asset. 2d. High contrast. No shadows
speed dragon. In-Game asset. 2d. High contrast. No shadows
mount everest. In-Game asset. 2d. High contrast. No shadows
crown. In-Game asset. 2d. High contrast. No shadows
replay button. In-Game asset. 2d. High contrast. No shadows