User prompt
remove the blue around the bird model asset
User prompt
Remove the blue around the bird model. The model of the clouds should not be the same as the bird model.
User prompt
Increase the distance between the pipes. Always let the gap height of the first pipe be close to the middle. The pipe gap height should be the same as the previous pipe at most once, but the distance between them should not be exaggerated. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
background progress without player clicking on the screen
User prompt
Okay, let's say the height that a jump takes us to is the same as before, less. And the game doesn't progress until we make the first jump.
User prompt
Okay, let's say the height that a jump takes us to is the same as before, less. And the game doesn't progress until we make the first jump. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Before starting the game, the bird should not move forward. The distance between the pipes should increase even more. The bird should move forward more slowly and fall down more slowly. One jump should make it jump a little higher. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Let the bird move forward more slowly. Let the gap heights of the 2 pipes not be too far apart, but let them move away over time. Add clouds to the background. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
The bird should not move forward unless we click on the screen. Let there be a longer distance between the bird's starting position and the first pipe. Let the bird fall more slowly. Let the distance between the pipes increase.
Code edit (1 edits merged)
Please save this source code
User prompt
Flappy Birdie: Pipe Dash
Initial prompt
Green ground, blue sky background. A yellow bird is moving forward and the screen jumps a certain distance each time we click, if we don't click it slowly falls. When we touch the floor or ceiling we burn and start the game over. Green pipes with bottoms and tops constantly appear in front of us and in each obstacle pipe there is a randomly heighted gap that we can pass through. When we pass each pipe 1 will be added to the score counter above, the counter will be reset each time we start over. But our record score will be written on the starting screen. If we touch any part of the pipe we burn.
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
bestScore: 0
});
/****
* Classes
****/
// Bird class
var Bird = Container.expand(function () {
var self = Container.call(this);
// Attach yellow ellipse as bird (now a shape, not an image)
var birdAsset = self.attachAsset('bird', {
anchorX: 0.5,
anchorY: 0.5
});
// Physics
self.vy = 0;
self.gravity = 0.45; // px per frame^2 (even slower fall)
self.jumpStrength = -14; // px per frame (even lower jump, less height per tap)
// Bird size for collision
self.radius = birdAsset.width * 0.45;
// Flap animation (squash/stretch)
self.flap = function () {
// Animate scale for a quick squash
tween.stop(birdAsset, {
scaleY: true,
scaleX: true
});
birdAsset.scaleY = 1.0;
birdAsset.scaleX = 1.0;
tween(birdAsset, {
scaleY: 0.7,
scaleX: 1.2
}, {
duration: 60,
easing: tween.cubicOut,
onFinish: function onFinish() {
tween(birdAsset, {
scaleY: 1.0,
scaleX: 1.0
}, {
duration: 120,
easing: tween.cubicIn
});
}
});
};
// Bird physics update
self.update = function () {
self.vy += self.gravity;
self.y += self.vy;
// Only move forward (x) if the player has tapped (i.e. on jump)
if (gameState === 'play' && self._moveForward) {
self.x += 3; // Move forward even more slowly per jump
self._moveForward = false;
}
// Clamp rotation based on vy
var maxAngle = Math.PI / 4;
var minAngle = -Math.PI / 6;
var t = Math.max(-20, Math.min(20, self.vy)) / 20;
birdAsset.rotation = minAngle + (maxAngle - minAngle) * ((t + 1) / 2);
};
// Reset bird state
self.reset = function (x, y) {
self.x = x;
self.y = y;
self.vy = 0;
birdAsset.rotation = 0;
birdAsset.scaleX = 1.0;
birdAsset.scaleY = 1.0;
};
return self;
});
// PipePair class (top and bottom pipes)
var PipePair = Container.expand(function () {
var self = Container.call(this);
// Pipe config
self.pipeWidth = 220;
self.gapHeight = 520;
self.speed = 12; // px per frame
// Top pipe
var topPipe = self.attachAsset('pipe', {
anchorX: 0,
anchorY: 1,
width: self.pipeWidth,
height: 900,
y: 0
});
// Bottom pipe
var bottomPipe = self.attachAsset('pipe', {
anchorX: 0,
anchorY: 0,
width: self.pipeWidth,
height: 900,
y: 0
});
// For collision
self.topRect = new Rectangle();
self.bottomRect = new Rectangle();
// Set vertical gap position
self.setGap = function (gapY) {
// gapY is the center of the gap
var pipeTop = gapY - self.gapHeight / 2;
var pipeBottom = gapY + self.gapHeight / 2;
topPipe.height = Math.max(80, pipeTop);
topPipe.y = pipeTop;
bottomPipe.height = Math.max(80, 2732 - pipeBottom - 220);
bottomPipe.y = pipeBottom;
};
// Update position
self.update = function () {
self.x -= self.speed;
};
// Get rectangles for collision
self.getRects = function () {
// Top pipe
self.topRect.x = self.x;
self.topRect.y = 0;
self.topRect.width = self.pipeWidth;
self.topRect.height = topPipe.height;
// Bottom pipe
self.bottomRect.x = self.x;
self.bottomRect.y = bottomPipe.y;
self.bottomRect.width = self.pipeWidth;
self.bottomRect.height = bottomPipe.height;
return [self.topRect, self.bottomRect];
};
// Reset pipe position and gap
self.reset = function (x, gapY) {
self.x = x;
self.setGap(gapY);
self.gapY = gapY;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x6ec6ff // blue sky
});
/****
* Game Code
****/
// --- Game Variables ---
// --- Asset Initialization ---
var bird;
var pipes = [];
var pipeSpacing = 1500; // px between pipes (increased even more)
var pipeCount = 3;
var pipeMinY = 420;
var pipeMaxY = 2732 - 220 - 420;
var ground;
var score = 0;
var bestScore = storage.bestScore || 0;
var scoreTxt;
var bestScoreTxt;
var gameState = 'start'; // 'start', 'play', 'gameover'
var tapToStartTxt;
var dragNode = null;
// --- GUI Elements ---
scoreTxt = new Text2('0', {
size: 180,
fill: 0xFFF700,
font: "Impact, 'Arial Black', Tahoma"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
bestScoreTxt = new Text2('', {
size: 90,
fill: 0xFFFFFF,
font: "Impact, 'Arial Black', Tahoma"
});
bestScoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(bestScoreTxt);
tapToStartTxt = new Text2('TAP TO START', {
size: 120,
fill: 0xFFFFFF,
font: "Impact, 'Arial Black', Tahoma"
});
tapToStartTxt.anchor.set(0.5, 0.5);
LK.gui.center.addChild(tapToStartTxt);
// --- Background and Ground ---
// Add clouds (simple white ellipses, different sizes, parallax)
var cloudAssets = [];
var cloudCount = 5;
for (var i = 0; i < cloudCount; i++) {
var cloud = LK.getAsset('ellipse', {
// use a white ellipse for cloud, not the bird image
anchorX: 0.5,
anchorY: 0.5,
width: 320 + Math.random() * 220,
height: 120 + Math.random() * 80,
x: Math.random() * 2048,
y: 200 + Math.random() * 600,
color: 0xffffff
});
cloud.alpha = 0.45 + Math.random() * 0.25;
game.addChild(cloud);
cloudAssets.push(cloud);
}
ground = LK.getAsset('ground', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 2732 - 220
});
game.addChild(ground);
// Animate clouds in game.update
var _origUpdate = game.update;
game.update = function () {
// Move clouds slowly for parallax (always, even before first tap)
for (var i = 0; i < cloudAssets.length; i++) {
var c = cloudAssets[i];
c.x -= 0.7 + i * 0.15;
if (c.x < -300) {
c.x = 2048 + 200 * Math.random();
c.y = 200 + Math.random() * 600;
}
}
if (_origUpdate) _origUpdate.apply(this, arguments);
};
// --- Bird ---
bird = new Bird();
game.addChild(bird);
// --- Pipes ---
for (var i = 0; i < pipeCount; i++) {
var pipe = new PipePair();
pipes.push(pipe);
game.addChild(pipe);
}
// --- Helper Functions ---
function resetGame() {
// Reset state
score = 0;
scoreTxt.setText('0');
gameState = 'start';
tapToStartTxt.visible = true;
bestScoreTxt.visible = true;
bestScoreTxt.setText('BEST: ' + bestScore);
// Center bird
bird.reset(600, 1200);
bird._moveForward = false; // Prevent forward movement before first tap
// Reset pipes
var prevGapY = undefined;
for (var i = 0; i < pipes.length; i++) {
// First pipe is much further away from the bird
var px = i === 0 ? 2048 + 900 : 2048 + 900 + i * pipeSpacing * 1.25; // increase spacing even more
var gapY;
if (i === 0) {
// Always start first pipe gap near center
var centerY = Math.floor((pipeMinY + pipeMaxY) / 2);
gapY = centerY + Math.floor((Math.random() - 0.5) * 120); // within ±60px of center
} else {
// For subsequent pipes, gapY should not be exactly the same as previous
var maxGapDelta = 220; // keep initial difference reasonable
var minY = Math.max(pipeMinY, prevGapY - maxGapDelta);
var maxY = Math.min(pipeMaxY, prevGapY + maxGapDelta);
do {
gapY = minY + Math.floor(Math.random() * (maxY - minY));
} while (gapY === prevGapY && maxY > minY); // ensure not exactly the same as previous
}
pipes[i].reset(px, gapY);
pipes[i].gapY = gapY;
pipes[i].passed = false;
prevGapY = gapY;
}
}
function startGame() {
gameState = 'play';
tapToStartTxt.visible = false;
bestScoreTxt.visible = false;
score = 0;
scoreTxt.setText('0');
// Reset bird velocity
bird.vy = 0;
}
function gameOver() {
gameState = 'gameover';
// Flash screen red
LK.effects.flashScreen(0xff0000, 800);
// Update best score
if (score > bestScore) {
bestScore = score;
storage.bestScore = bestScore;
}
// Show game over popup (handled by LK)
LK.showGameOver();
}
// --- Input Handling ---
// Tap to jump or start
game.down = function (x, y, obj) {
if (gameState === 'start') {
startGame();
bird.vy = bird.jumpStrength;
bird.flap();
bird._moveForward = true;
} else if (gameState === 'play') {
bird.vy = bird.jumpStrength;
bird.flap();
bird._moveForward = true;
}
// No input in gameover (wait for LK reset)
};
// --- Main Update Loop ---
game.update = function () {
if (gameState === 'start') {
// Bird idle bobbing
bird.y = 1200 + Math.sin(LK.ticks / 20) * 30;
bird.vy = 0;
// Pipes do not move before first jump
// Prevent pipes from moving before first jump (on start screen)
// But allow clouds to move (background progress)
return;
}
if (gameState !== 'play') return;
// Bird physics
bird.update();
// Pipes
for (var i = 0; i < pipes.length; i++) {
var pipe = pipes[i];
pipe.update();
// Recycle pipe if off screen
if (pipe.x < -pipe.pipeWidth) {
var maxX = 0;
for (var j = 0; j < pipes.length; j++) {
if (pipes[j].x > maxX) maxX = pipes[j].x;
}
var px = maxX + pipeSpacing * 1.25; // increase spacing even more
// --- Gap height logic: keep new gapY close to previous, but never exactly the same as previous ---
var prevIndex = (i - 1 + pipes.length) % pipes.length;
var prevGapY = pipes[prevIndex].gapY !== undefined ? pipes[prevIndex].gapY : pipeMinY + Math.floor(Math.random() * (pipeMaxY - pipeMinY));
var maxGapDelta = 220 + Math.floor(score * 2); // Start with 220px, increase slowly with score
if (maxGapDelta > 600) maxGapDelta = 600; // Cap the max difference
var minY = Math.max(pipeMinY, prevGapY - maxGapDelta);
var maxY = Math.min(pipeMaxY, prevGapY + maxGapDelta);
var gapY;
do {
gapY = minY + Math.floor(Math.random() * (maxY - minY));
} while (gapY === prevGapY && maxY > minY); // ensure not exactly the same as previous
// Store gapY for next pipe logic
pipe.gapY = gapY;
pipe.reset(px, gapY);
pipe.passed = false;
}
// Score: if bird passes pipe
if (!pipe.passed && pipe.x + pipe.pipeWidth < bird.x - bird.radius) {
pipe.passed = true;
score += 1;
scoreTxt.setText(score + '');
}
}
// Collision detection
// 1. Ground
if (bird.y + bird.radius > 2732 - 220) {
bird.y = 2732 - 220 - bird.radius;
gameOver();
return;
}
// 2. Ceiling
if (bird.y - bird.radius < 0) {
bird.y = bird.radius;
gameOver();
return;
}
// 3. Pipes
for (var i = 0; i < pipes.length; i++) {
var rects = pipes[i].getRects();
for (var r = 0; r < rects.length; r++) {
if (circleRectCollide(bird.x, bird.y, bird.radius, rects[r])) {
gameOver();
return;
}
}
}
};
// --- Utility: Circle-Rectangle Collision ---
function circleRectCollide(cx, cy, cr, rect) {
// Find closest point to circle within rectangle
var closestX = Math.max(rect.x, Math.min(cx, rect.x + rect.width));
var closestY = Math.max(rect.y, Math.min(cy, rect.y + rect.height));
var dx = cx - closestX;
var dy = cy - closestY;
return dx * dx + dy * dy < cr * cr;
}
// --- Game Over Handler (reset on LK reset) ---
LK.on('gameover', function () {
resetGame();
});
// --- Initial State ---
resetGame(); ===================================================================
--- original.js
+++ change.js
@@ -11,9 +11,9 @@
****/
// Bird class
var Bird = Container.expand(function () {
var self = Container.call(this);
- // Attach yellow ellipse as bird
+ // Attach yellow ellipse as bird (now a shape, not an image)
var birdAsset = self.attachAsset('bird', {
anchorX: 0.5,
anchorY: 0.5
});
A yellow bird. In pixel art style. The bird should be just like the head part.. In-Game asset. 2d. High contrast. No shadows
white cloud. In-Game asset. 2d. High contrast. No shadows
the soil covering the entire image and extending horizontally and the greenery (short grass) on top of it. In-Game asset. 2d. High contrast. No shadows
green pipe. In-Game asset. 2d. High contrast. No shadows