User prompt
make the top pipes touch the ceiling
User prompt
make them a little higher
User prompt
make the pipes spawn only in the moddle
User prompt
make the space between the pipes a lot wider
User prompt
make the only top pipes upside down
User prompt
make the pipes THICCER
User prompt
make the speed of the pipes slower
User prompt
Increase the vertical gap between the top and bottom pipes for easier gameplay
User prompt
make the space between the pipes wider
User prompt
reduce the strength of the gravity
User prompt
fix the hitboxes
User prompt
make the bird jump lower
User prompt
reduce the gravity
Code edit (1 edits merged)
Please save this source code
User prompt
Flappy Bird: Tap to Fly
Initial prompt
Flappy Bird
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Bird class var Bird = Container.expand(function () { var self = Container.call(this); // Attach bird asset (yellow ellipse) var birdAsset = self.attachAsset('bird', { anchorX: 0.5, anchorY: 0.5 }); // Set initial properties self.vy = 0; // vertical velocity self.gravity = 1.5; // gravity per frame self.flapStrength = -28; // negative for upward movement // Bird update: apply gravity, move, clamp position self.update = function () { self.vy += self.gravity; self.y += self.vy; // Clamp to top of screen if (self.y < self.height / 2) { self.y = self.height / 2; self.vy = 0; } }; // Flap: set upward velocity self.flap = function () { self.vy = self.flapStrength; }; 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; // Create top pipe (green box) self.topPipe = self.attachAsset('pipe', { anchorX: 0.5, anchorY: 1, width: self.pipeWidth, height: 900 }); // Create bottom pipe (green box) self.bottomPipe = self.attachAsset('pipe', { anchorX: 0.5, anchorY: 0, width: self.pipeWidth, height: 900 }); // Set initial positions (will be set by spawn) self.topPipe.x = 0; self.bottomPipe.x = 0; // Used to track if score was already given for this pipe self.passed = false; // Set pipes' vertical positions based on gapY self.setGap = function (gapY) { self.topPipe.y = gapY - self.gapHeight / 2; self.bottomPipe.y = gapY + self.gapHeight / 2; }; // Move pipes left self.update = function () { self.x -= self.speed; }; // Helper: get bounding rect for collision self.getTopRect = function () { return new Rectangle(self.x - self.pipeWidth / 2, 0, self.pipeWidth, self.topPipe.y); }; self.getBottomRect = function () { return new Rectangle(self.x - self.pipeWidth / 2, self.bottomPipe.y, self.pipeWidth, 2732 - self.bottomPipe.y); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87ceeb // Sky blue }); /**** * Game Code ****/ // --- Game Variables --- // --- Asset Initialization --- var bird; var pipes = []; var ground; var score = 0; var scoreTxt; var gameStarted = false; var gameOver = false; var pipeTimer = null; var lastPipeX = 0; var nextPipeDist = 0; var bestScore = 0; // --- GUI Score Display --- scoreTxt = new Text2('0', { size: 180, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // --- Best Score Display (top right) --- var bestScoreTxt = new Text2('', { size: 60, fill: 0xFFF7B2 }); bestScoreTxt.anchor.set(1, 0); bestScoreTxt.x = -60; bestScoreTxt.y = 30; LK.gui.topRight.addChild(bestScoreTxt); // --- Ground --- ground = LK.getAsset('ground', { anchorX: 0, anchorY: 0, x: 0, y: 2732 - 120 }); game.addChild(ground); // --- Bird --- bird = new Bird(); bird.x = 500; bird.y = 2732 / 2; game.addChild(bird); // --- Reset Game State --- function resetGame() { // Remove pipes for (var i = 0; i < pipes.length; i++) { pipes[i].destroy(); } pipes = []; // Reset bird bird.x = 500; bird.y = 2732 / 2; bird.vy = 0; // Reset score score = 0; scoreTxt.setText(score); // Reset state gameStarted = false; gameOver = false; // Show best score bestScore = bestScore || 0; bestScoreTxt.setText('Best: ' + bestScore); // Remove pipe timer if any if (pipeTimer) { LK.clearInterval(pipeTimer); pipeTimer = null; } } // --- Start Game --- function startGame() { if (gameStarted) return; gameStarted = true; gameOver = false; score = 0; scoreTxt.setText(score); // Remove pipes for (var i = 0; i < pipes.length; i++) { pipes[i].destroy(); } pipes = []; // Reset bird bird.x = 500; bird.y = 2732 / 2; bird.vy = 0; // Start pipe spawning spawnPipe(); if (pipeTimer) LK.clearInterval(pipeTimer); pipeTimer = LK.setInterval(spawnPipe, 1100); } // --- End Game --- function endGame() { if (gameOver) return; gameOver = true; gameStarted = false; // Stop pipe spawning if (pipeTimer) { LK.clearInterval(pipeTimer); pipeTimer = null; } // Flash screen LK.effects.flashScreen(0xff0000, 600); // Update best score if (score > bestScore) { bestScore = score; } bestScoreTxt.setText('Best: ' + bestScore); // Show game over popup (handled by LK) LK.showGameOver(); } // --- Pipe Spawning --- function spawnPipe() { // Gap vertical position: between 400 and (screen height - ground - 400) var minGapY = 400 + 120; var maxGapY = 2732 - 400 - 120 - 120; var gapY = minGapY + Math.floor(Math.random() * (maxGapY - minGapY)); var pipePair = new PipePair(); pipePair.x = 2048 + pipePair.pipeWidth; // Spawn just off right edge pipePair.setGap(gapY); game.addChild(pipePair); pipes.push(pipePair); } // --- Collision Detection --- function rectsIntersect(ax, ay, aw, ah, bx, by, bw, bh) { return ax < bx + bw && ax + aw > bx && ay < by + bh && ay + ah > by; } // --- Game Update Loop --- game.update = function () { if (!gameStarted) return; // Bird update bird.update(); // Ground collision if (bird.y + bird.height / 2 >= 2732 - 120) { bird.y = 2732 - 120 - bird.height / 2; endGame(); return; } // Pipe update and collision for (var i = pipes.length - 1; i >= 0; i--) { var pipe = pipes[i]; pipe.update(); // Remove pipes off screen if (pipe.x < -pipe.pipeWidth) { pipe.destroy(); pipes.splice(i, 1); continue; } // Collision with pipes // Bird bounding box var bx = bird.x - bird.width / 2 + 18; var by = bird.y - bird.height / 2 + 18; var bw = bird.width - 36; var bh = bird.height - 36; // Top pipe var topRect = pipe.getTopRect(); if (rectsIntersect(bx, by, bw, bh, topRect.x, topRect.y, topRect.width, topRect.height)) { endGame(); return; } // Bottom pipe var bottomRect = pipe.getBottomRect(); if (rectsIntersect(bx, by, bw, bh, bottomRect.x, bottomRect.y, bottomRect.width, bottomRect.height)) { endGame(); return; } // Score: if bird passed pipe center and not yet scored if (!pipe.passed && pipe.x + pipe.pipeWidth / 2 < bird.x - bird.width / 2) { pipe.passed = true; score += 1; scoreTxt.setText(score); } } }; // --- Tap/Touch Controls --- game.down = function (x, y, obj) { if (gameOver) { resetGame(); return; } if (!gameStarted) { startGame(); } bird.flap(); }; // --- Reset on Game Over --- LK.on('gameover', function () { resetGame(); }); // --- Initial State --- resetGame();
===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,280 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+
+/****
+* Classes
+****/
+// Bird class
+var Bird = Container.expand(function () {
+ var self = Container.call(this);
+ // Attach bird asset (yellow ellipse)
+ var birdAsset = self.attachAsset('bird', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // Set initial properties
+ self.vy = 0; // vertical velocity
+ self.gravity = 1.5; // gravity per frame
+ self.flapStrength = -28; // negative for upward movement
+ // Bird update: apply gravity, move, clamp position
+ self.update = function () {
+ self.vy += self.gravity;
+ self.y += self.vy;
+ // Clamp to top of screen
+ if (self.y < self.height / 2) {
+ self.y = self.height / 2;
+ self.vy = 0;
+ }
+ };
+ // Flap: set upward velocity
+ self.flap = function () {
+ self.vy = self.flapStrength;
+ };
+ 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;
+ // Create top pipe (green box)
+ self.topPipe = self.attachAsset('pipe', {
+ anchorX: 0.5,
+ anchorY: 1,
+ width: self.pipeWidth,
+ height: 900
+ });
+ // Create bottom pipe (green box)
+ self.bottomPipe = self.attachAsset('pipe', {
+ anchorX: 0.5,
+ anchorY: 0,
+ width: self.pipeWidth,
+ height: 900
+ });
+ // Set initial positions (will be set by spawn)
+ self.topPipe.x = 0;
+ self.bottomPipe.x = 0;
+ // Used to track if score was already given for this pipe
+ self.passed = false;
+ // Set pipes' vertical positions based on gapY
+ self.setGap = function (gapY) {
+ self.topPipe.y = gapY - self.gapHeight / 2;
+ self.bottomPipe.y = gapY + self.gapHeight / 2;
+ };
+ // Move pipes left
+ self.update = function () {
+ self.x -= self.speed;
+ };
+ // Helper: get bounding rect for collision
+ self.getTopRect = function () {
+ return new Rectangle(self.x - self.pipeWidth / 2, 0, self.pipeWidth, self.topPipe.y);
+ };
+ self.getBottomRect = function () {
+ return new Rectangle(self.x - self.pipeWidth / 2, self.bottomPipe.y, self.pipeWidth, 2732 - self.bottomPipe.y);
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x87ceeb // Sky blue
+});
+
+/****
+* Game Code
+****/
+// --- Game Variables ---
+// --- Asset Initialization ---
+var bird;
+var pipes = [];
+var ground;
+var score = 0;
+var scoreTxt;
+var gameStarted = false;
+var gameOver = false;
+var pipeTimer = null;
+var lastPipeX = 0;
+var nextPipeDist = 0;
+var bestScore = 0;
+// --- GUI Score Display ---
+scoreTxt = new Text2('0', {
+ size: 180,
+ fill: 0xFFFFFF
+});
+scoreTxt.anchor.set(0.5, 0);
+LK.gui.top.addChild(scoreTxt);
+// --- Best Score Display (top right) ---
+var bestScoreTxt = new Text2('', {
+ size: 60,
+ fill: 0xFFF7B2
+});
+bestScoreTxt.anchor.set(1, 0);
+bestScoreTxt.x = -60;
+bestScoreTxt.y = 30;
+LK.gui.topRight.addChild(bestScoreTxt);
+// --- Ground ---
+ground = LK.getAsset('ground', {
+ anchorX: 0,
+ anchorY: 0,
+ x: 0,
+ y: 2732 - 120
+});
+game.addChild(ground);
+// --- Bird ---
+bird = new Bird();
+bird.x = 500;
+bird.y = 2732 / 2;
+game.addChild(bird);
+// --- Reset Game State ---
+function resetGame() {
+ // Remove pipes
+ for (var i = 0; i < pipes.length; i++) {
+ pipes[i].destroy();
+ }
+ pipes = [];
+ // Reset bird
+ bird.x = 500;
+ bird.y = 2732 / 2;
+ bird.vy = 0;
+ // Reset score
+ score = 0;
+ scoreTxt.setText(score);
+ // Reset state
+ gameStarted = false;
+ gameOver = false;
+ // Show best score
+ bestScore = bestScore || 0;
+ bestScoreTxt.setText('Best: ' + bestScore);
+ // Remove pipe timer if any
+ if (pipeTimer) {
+ LK.clearInterval(pipeTimer);
+ pipeTimer = null;
+ }
+}
+// --- Start Game ---
+function startGame() {
+ if (gameStarted) return;
+ gameStarted = true;
+ gameOver = false;
+ score = 0;
+ scoreTxt.setText(score);
+ // Remove pipes
+ for (var i = 0; i < pipes.length; i++) {
+ pipes[i].destroy();
+ }
+ pipes = [];
+ // Reset bird
+ bird.x = 500;
+ bird.y = 2732 / 2;
+ bird.vy = 0;
+ // Start pipe spawning
+ spawnPipe();
+ if (pipeTimer) LK.clearInterval(pipeTimer);
+ pipeTimer = LK.setInterval(spawnPipe, 1100);
+}
+// --- End Game ---
+function endGame() {
+ if (gameOver) return;
+ gameOver = true;
+ gameStarted = false;
+ // Stop pipe spawning
+ if (pipeTimer) {
+ LK.clearInterval(pipeTimer);
+ pipeTimer = null;
+ }
+ // Flash screen
+ LK.effects.flashScreen(0xff0000, 600);
+ // Update best score
+ if (score > bestScore) {
+ bestScore = score;
+ }
+ bestScoreTxt.setText('Best: ' + bestScore);
+ // Show game over popup (handled by LK)
+ LK.showGameOver();
+}
+// --- Pipe Spawning ---
+function spawnPipe() {
+ // Gap vertical position: between 400 and (screen height - ground - 400)
+ var minGapY = 400 + 120;
+ var maxGapY = 2732 - 400 - 120 - 120;
+ var gapY = minGapY + Math.floor(Math.random() * (maxGapY - minGapY));
+ var pipePair = new PipePair();
+ pipePair.x = 2048 + pipePair.pipeWidth; // Spawn just off right edge
+ pipePair.setGap(gapY);
+ game.addChild(pipePair);
+ pipes.push(pipePair);
+}
+// --- Collision Detection ---
+function rectsIntersect(ax, ay, aw, ah, bx, by, bw, bh) {
+ return ax < bx + bw && ax + aw > bx && ay < by + bh && ay + ah > by;
+}
+// --- Game Update Loop ---
+game.update = function () {
+ if (!gameStarted) return;
+ // Bird update
+ bird.update();
+ // Ground collision
+ if (bird.y + bird.height / 2 >= 2732 - 120) {
+ bird.y = 2732 - 120 - bird.height / 2;
+ endGame();
+ return;
+ }
+ // Pipe update and collision
+ for (var i = pipes.length - 1; i >= 0; i--) {
+ var pipe = pipes[i];
+ pipe.update();
+ // Remove pipes off screen
+ if (pipe.x < -pipe.pipeWidth) {
+ pipe.destroy();
+ pipes.splice(i, 1);
+ continue;
+ }
+ // Collision with pipes
+ // Bird bounding box
+ var bx = bird.x - bird.width / 2 + 18;
+ var by = bird.y - bird.height / 2 + 18;
+ var bw = bird.width - 36;
+ var bh = bird.height - 36;
+ // Top pipe
+ var topRect = pipe.getTopRect();
+ if (rectsIntersect(bx, by, bw, bh, topRect.x, topRect.y, topRect.width, topRect.height)) {
+ endGame();
+ return;
+ }
+ // Bottom pipe
+ var bottomRect = pipe.getBottomRect();
+ if (rectsIntersect(bx, by, bw, bh, bottomRect.x, bottomRect.y, bottomRect.width, bottomRect.height)) {
+ endGame();
+ return;
+ }
+ // Score: if bird passed pipe center and not yet scored
+ if (!pipe.passed && pipe.x + pipe.pipeWidth / 2 < bird.x - bird.width / 2) {
+ pipe.passed = true;
+ score += 1;
+ scoreTxt.setText(score);
+ }
+ }
+};
+// --- Tap/Touch Controls ---
+game.down = function (x, y, obj) {
+ if (gameOver) {
+ resetGame();
+ return;
+ }
+ if (!gameStarted) {
+ startGame();
+ }
+ bird.flap();
+};
+// --- Reset on Game Over ---
+LK.on('gameover', function () {
+ resetGame();
+});
+// --- Initial State ---
+resetGame();
\ No newline at end of file