User prompt
Keep the money between the two pipes
User prompt
Let the coins give 5 points
User prompt
Box the score next to High Score
User prompt
Put the top score in a box
User prompt
Make the pipes facing up and down
User prompt
Make the pipes normal pipes
User prompt
No bird hovering on the start screen
User prompt
On the game start screen, keep the bird in the air until the game starts ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
make the game easy
User prompt
Make sure the bird stays in the air on the game start screen
User prompt
Leave some space between the upward and downward facing pipes
User prompt
High Score on the top right
User prompt
Increase the thickness of the pipes a little
User prompt
Also, the length of the pipes should be such that they touch up and touch down.
User prompt
Put coins between the pipes and they become points
Code edit (1 edits merged)
Please save this source code
User prompt
Flappy Wings
Initial prompt
Make me Flappy Bird
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
highScore: 0
});
/****
* Classes
****/
var Bird = Container.expand(function () {
var self = Container.call(this);
var birdSprite = self.attachAsset('bird', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocity = 0;
self.gravity = 0.25;
self.jumpPower = -8;
self.rotation = 0;
self.dead = false;
self.flap = function () {
if (self.dead) return;
self.velocity = self.jumpPower;
LK.getSound('flap').play();
tween(self, {
rotation: -0.5
}, {
duration: 100,
easing: tween.easeOut
});
};
self.update = function () {
if (self.dead) return;
self.velocity += self.gravity;
self.y += self.velocity;
// Rotate bird based on velocity
if (self.velocity > 0) {
var targetRotation = Math.min(Math.PI / 2, self.velocity * 0.05);
tween.stop(self, {
rotation: true
});
tween(self, {
rotation: targetRotation
}, {
duration: 100,
easing: tween.linear
});
}
};
self.die = function () {
if (self.dead) return;
self.dead = true;
LK.getSound('hit').play();
tween.stop(self);
};
return self;
});
var Coin = Container.expand(function () {
var self = Container.call(this);
self.coinSprite = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 4;
self.collected = false;
self.update = function () {
self.x -= self.speed;
};
self.checkCollection = function (bird) {
if (self.collected || bird.dead) return false;
// Simple circular collision detection
var birdBounds = {
x: bird.x,
y: bird.y,
radius: 25 // Half of bird width
};
var coinBounds = {
x: self.x,
y: self.y,
radius: 25 // Half of coin width
};
var dx = birdBounds.x - coinBounds.x;
var dy = birdBounds.y - coinBounds.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < birdBounds.radius + coinBounds.radius) {
self.collected = true;
return true;
}
return false;
};
return self;
});
var Pipe = Container.expand(function () {
var self = Container.call(this);
self.topPipe = self.attachAsset('pipe', {
anchorX: 0.5,
anchorY: 1.0
});
self.bottomPipe = self.attachAsset('pipe', {
anchorX: 0.5,
anchorY: 0.0
});
self.speed = 2.5;
self.scored = false;
self.gapHeight = 600;
self.setGapPosition = function (yPos) {
// Make top pipe extend from top of screen to gap
self.topPipe.y = yPos - self.gapHeight / 2;
self.topPipe.height = yPos - self.gapHeight / 2;
// Make bottom pipe extend from gap to ground
self.bottomPipe.y = yPos + self.gapHeight / 2;
self.bottomPipe.height = 2732 - (yPos + self.gapHeight / 2) - 100; // Account for ground height
};
self.update = function () {
self.x -= self.speed;
};
self.checkCollision = function (bird) {
if (bird.dead) return false;
// Convert positions to global space for collision check
var birdBounds = {
x: bird.x - 15,
y: bird.y - 12.5,
width: 30,
height: 25
};
var topPipeBounds = {
x: self.x - 75,
y: self.topPipe.y - self.topPipe.height,
width: 150,
height: self.topPipe.height
};
var bottomPipeBounds = {
x: self.x - 75,
y: self.bottomPipe.y,
width: 150,
height: self.bottomPipe.height
};
// Check if bird collides with either pipe
if (birdBounds.x + birdBounds.width > topPipeBounds.x && birdBounds.x < topPipeBounds.x + topPipeBounds.width && birdBounds.y < topPipeBounds.y + topPipeBounds.height && birdBounds.y + birdBounds.height > topPipeBounds.y) {
return true;
}
if (birdBounds.x + birdBounds.width > bottomPipeBounds.x && birdBounds.x < bottomPipeBounds.x + bottomPipeBounds.width && birdBounds.y < bottomPipeBounds.y + bottomPipeBounds.height && birdBounds.y + birdBounds.height > bottomPipeBounds.y) {
return true;
}
return false;
};
self.checkPassed = function (bird) {
if (self.scored || bird.dead) return false;
if (self.x + 50 < bird.x - 25) {
self.scored = true;
return true;
}
return false;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Game variables
var bird;
var pipes = [];
var coins = [];
var ground;
var background;
var gameStarted = false;
var gameOver = false;
var score = 0;
var highScore = storage.highScore || 0;
var pipeSpawnTimer = 0;
var pipeSpawnInterval = 180; // frames (3 seconds at 60fps)
// Setup UI
var scoreTxt = new Text2('0', {
size: 100,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
scoreTxt.y = 50;
var instructionsTxt = new Text2('Tap to flap!', {
size: 70,
fill: 0xFFFFFF
});
instructionsTxt.anchor.set(0.5, 0.5);
LK.gui.center.addChild(instructionsTxt);
// Create a box for the high score
var highScoreBox = LK.getAsset('ground', {
width: 420,
height: 90,
color: 0x222222,
anchorX: 1,
anchorY: 0,
x: 0,
y: 0
});
highScoreBox.alpha = 0.7;
LK.gui.topRight.addChild(highScoreBox);
highScoreBox.x = -10;
highScoreBox.y = 10;
var highScoreTxt = new Text2('High Score: ' + highScore, {
size: 50,
fill: 0xFFFFFF
});
highScoreTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(highScoreTxt);
highScoreTxt.x = -30;
highScoreTxt.y = 30;
// Create background
background = LK.getAsset('background', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
});
game.addChild(background);
// Create ground
ground = LK.getAsset('ground', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 2732 - 100
});
game.addChild(ground);
// Create bird
bird = new Bird();
bird.x = 400;
bird.y = 2732 / 2;
game.addChild(bird);
// Define floating animation but don't use it
function floatBird() {
tween(bird, {
y: bird.y - 50
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(bird, {
y: bird.y + 50
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: floatBird
});
}
});
}
// Don't call floatBird() to prevent hovering animation
// Function to start the game
function startGame() {
if (gameStarted || gameOver) return;
gameStarted = true;
LK.gui.center.removeChild(instructionsTxt);
bird.flap();
// Play background music
LK.playMusic('gameMusic');
}
// Function to reset the game
function resetGame() {
// Clear pipes
for (var i = 0; i < pipes.length; i++) {
game.removeChild(pipes[i]);
}
pipes = [];
// Clear coins
for (var i = 0; i < coins.length; i++) {
game.removeChild(coins[i]);
}
coins = [];
// Reset bird
game.removeChild(bird);
bird = new Bird();
bird.x = 400;
bird.y = 2732 / 2;
game.addChild(bird);
// Reset game state
gameStarted = false;
gameOver = false;
score = 0;
pipeSpawnTimer = 0;
scoreTxt.setText("0");
// Show instructions again
LK.gui.center.addChild(instructionsTxt);
}
// Function to spawn a new pipe
function spawnPipe() {
var pipe = new Pipe();
pipe.x = 2048 + 100; // Start off-screen to the right
// Random gap position between 20% and 80% of screen height
var minY = 2732 * 0.2;
var maxY = 2732 * 0.8 - 100; // Account for ground
var gapY = minY + Math.random() * (maxY - minY);
pipe.setGapPosition(gapY);
pipes.push(pipe);
game.addChild(pipe);
// Add a coin in the middle of the gap
var coin = new Coin();
coin.x = pipe.x; // Same x position as pipe
coin.y = gapY; // In the middle of the gap
coin.lastX = coin.x; // Initialize lastX for tracking
coins.push(coin);
game.addChild(coin);
}
// Input events
game.down = function (x, y, obj) {
if (!gameStarted) {
startGame();
} else if (!gameOver) {
bird.flap();
} else {
resetGame();
}
};
// Game update logic
game.update = function () {
if (!gameStarted) return;
// Update bird
bird.update();
// Check if bird hits the ground or flies too high
if (bird.y > 2732 - 100 - 17.5 || bird.y < 0) {
if (!gameOver) {
gameOver = true;
bird.die();
// Update high score if needed
if (score > highScore) {
highScore = score;
storage.highScore = highScore;
highScoreTxt.setText('High Score: ' + highScore);
}
LK.showGameOver();
}
// Keep bird above ground
if (bird.y > 2732 - 100 - 17.5) {
bird.y = 2732 - 100 - 17.5;
bird.velocity = 0;
}
return;
}
// Spawn pipes
if (gameStarted && !gameOver) {
pipeSpawnTimer++;
if (pipeSpawnTimer >= pipeSpawnInterval) {
spawnPipe();
pipeSpawnTimer = 0;
}
}
// Update pipes and check collisions
for (var i = pipes.length - 1; i >= 0; i--) {
var pipe = pipes[i];
pipe.update();
// Remove pipes that have gone off screen
if (pipe.x < -100) {
game.removeChild(pipe);
pipes.splice(i, 1);
continue;
}
// Check if bird passed pipe for scoring
if (pipe.checkPassed(bird)) {
score++;
scoreTxt.setText(score.toString());
LK.setScore(score);
LK.getSound('score').play();
}
// Check for collision with pipes
if (pipe.checkCollision(bird)) {
if (!gameOver) {
gameOver = true;
bird.die();
// Update high score if needed
if (score > highScore) {
highScore = score;
storage.highScore = highScore;
highScoreTxt.setText('High Score: ' + highScore);
}
LK.showGameOver();
}
}
}
// Update coins and check collections
for (var i = coins.length - 1; i >= 0; i--) {
var coin = coins[i];
coin.update();
// Remove coins that have gone off screen
if (coin.x < -50) {
game.removeChild(coin);
coins.splice(i, 1);
continue;
}
// Check if bird collected the coin
if (coin.checkCollection(bird)) {
// Add points for collecting the coin
score += 3;
scoreTxt.setText(score.toString());
LK.setScore(score);
LK.getSound('coin').play();
// Visually remove the coin
game.removeChild(coin);
coins.splice(i, 1);
}
}
}; ===================================================================
--- original.js
+++ change.js
@@ -192,16 +192,30 @@
fill: 0xFFFFFF
});
instructionsTxt.anchor.set(0.5, 0.5);
LK.gui.center.addChild(instructionsTxt);
+// Create a box for the high score
+var highScoreBox = LK.getAsset('ground', {
+ width: 420,
+ height: 90,
+ color: 0x222222,
+ anchorX: 1,
+ anchorY: 0,
+ x: 0,
+ y: 0
+});
+highScoreBox.alpha = 0.7;
+LK.gui.topRight.addChild(highScoreBox);
+highScoreBox.x = -10;
+highScoreBox.y = 10;
var highScoreTxt = new Text2('High Score: ' + highScore, {
size: 50,
fill: 0xFFFFFF
});
highScoreTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(highScoreTxt);
-highScoreTxt.x = -20;
-highScoreTxt.y = 20;
+highScoreTxt.x = -30;
+highScoreTxt.y = 30;
// Create background
background = LK.getAsset('background', {
anchorX: 0,
anchorY: 0,