/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Bird class var Bird = Container.expand(function () { var self = Container.call(this); var birdSprite = self.attachAsset('bird', { anchorX: 0.5, anchorY: 0.5 }); self.vy = 0; // vertical velocity // Bird physics update self.update = function () { self.vy += gravity; self.y += self.vy; // Clamp rotation for visual feedback var maxAngle = Math.PI / 4; var minAngle = -Math.PI / 2.5; var t = Math.max(-1, Math.min(1, self.vy / 30)); birdSprite.rotation = t * maxAngle; if (birdSprite.rotation < minAngle) birdSprite.rotation = minAngle; if (birdSprite.rotation > maxAngle) birdSprite.rotation = maxAngle; }; // Flap (jump) self.flap = function () { self.vy = flapStrength; LK.getSound('flap').play(); }; return self; }); // PipePair class (top and bottom pipes) var PipePair = Container.expand(function () { var self = Container.call(this); // Top pipe self.topPipe = self.attachAsset('pipe', { anchorX: 0, anchorY: 1 }); // Bottom pipe self.bottomPipe = self.attachAsset('pipe', { anchorX: 0, anchorY: 0 }); // Used for scoring self.passed = false; // Set gap and position self.setGap = function (gapY, gapHeight) { // Top pipe: bottom at gapY - gapHeight/2 self.topPipe.height = Math.max(100, gapY - gapHeight / 2); self.topPipe.y = self.topPipe.height; // Bottom pipe: top at gapY + gapHeight/2 self.bottomPipe.y = gapY + gapHeight / 2; self.bottomPipe.height = Math.max(100, 2732 - self.bottomPipe.y - groundHeight); }; // Move pipes left self.update = function () { self.x -= pipeSpeed; }; // Get bounding rectangles for collision self.getTopRect = function () { return new Rectangle(self.x, 0, self.topPipe.width, self.topPipe.height); }; self.getBottomRect = function () { return new Rectangle(self.x, self.bottomPipe.y, self.bottomPipe.width, self.bottomPipe.height); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87ceeb // Sky blue }); /**** * Game Code ****/ // Sound: Hit // Sound: Score // Sound: Flap // Ground: brown box // Pipe: green box // Bird: yellow ellipse // Constants var gravity = 1.6; var flapStrength = -28; var pipeSpeed = 16; var pipeInterval = 110; // frames between pipes var pipeGap = 520; // vertical gap between pipes var groundHeight = 120; var birdStartX = 600; var birdStartY = 1200; // Game state var bird; var pipes = []; var score = 0; var scoreTxt; var ground; var gameStarted = false; var gameOver = false; var lastPipeFrame = 0; // GUI Score scoreTxt = new Text2('0', { size: 180, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Add ground ground = LK.getAsset('ground', { anchorX: 0, anchorY: 0, x: 0, y: 2732 - groundHeight }); game.addChild(ground); // Add bird bird = new Bird(); bird.x = birdStartX; bird.y = birdStartY; game.addChild(bird); // Reset function function resetGame() { // Remove pipes for (var i = 0; i < pipes.length; i++) { pipes[i].destroy(); } pipes = []; // Reset bird bird.x = birdStartX; bird.y = birdStartY; bird.vy = 0; // Reset score score = 0; scoreTxt.setText(score); // Reset state gameStarted = false; gameOver = false; lastPipeFrame = LK.ticks; } // Start game on first tap function startGame() { if (!gameStarted && !gameOver) { gameStarted = true; bird.flap(); } } // Flap on tap game.down = function (x, y, obj) { if (gameOver) return; if (!gameStarted) { startGame(); return; } bird.flap(); }; // Main update loop game.update = function () { if (gameOver) return; // Bird physics if (gameStarted) { bird.update(); } // Pipes if (gameStarted) { // Spawn pipes if (LK.ticks - lastPipeFrame >= pipeInterval) { var gapY = 400 + Math.floor(Math.random() * (2732 - groundHeight - 800)); var pair = new PipePair(); pair.x = 2048; pair.setGap(gapY, pipeGap); pipes.push(pair); game.addChild(pair); lastPipeFrame = LK.ticks; } } // Update pipes and check for collisions for (var i = pipes.length - 1; i >= 0; i--) { var pair = pipes[i]; if (gameStarted) { pair.update(); } // Remove pipes off screen if (pair.x + pair.topPipe.width < 0) { pair.destroy(); pipes.splice(i, 1); continue; } // Score: passed pipe if (!pair.passed && pair.x + pair.topPipe.width < bird.x) { pair.passed = true; score += 1; scoreTxt.setText(score); LK.getSound('score').play(); } // Collision detection if (rectIntersectsCircle(pair.getTopRect(), bird.x, bird.y, birdWidth() / 2) || rectIntersectsCircle(pair.getBottomRect(), bird.x, bird.y, birdWidth() / 2)) { triggerGameOver(); return; } } // Ground collision if (bird.y + birdHeight() / 2 >= 2732 - groundHeight) { bird.y = 2732 - groundHeight - birdHeight() / 2; triggerGameOver(); return; } // Ceiling clamp if (bird.y - birdHeight() / 2 < 0) { bird.y = birdHeight() / 2; bird.vy = 0; } }; // Helper: get bird width/height function birdWidth() { return bird.children[0].width; } function birdHeight() { return bird.children[0].height; } // Rectangle-circle collision function rectIntersectsCircle(rect, cx, cy, cr) { // Find closest point to circle center within the 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)); // Calculate distance var dx = cx - closestX; var dy = cy - closestY; return dx * dx + dy * dy < cr * cr; } // Game over function triggerGameOver() { if (gameOver) return; gameOver = true; LK.getSound('hit').play(); LK.effects.flashScreen(0xff0000, 600); LK.showGameOver(); } // Reset on game over LK.on('gameover', function () { resetGame(); }); // Initial reset resetGame();
===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,250 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+
+/****
+* Classes
+****/
+// Bird class
+var Bird = Container.expand(function () {
+ var self = Container.call(this);
+ var birdSprite = self.attachAsset('bird', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.vy = 0; // vertical velocity
+ // Bird physics update
+ self.update = function () {
+ self.vy += gravity;
+ self.y += self.vy;
+ // Clamp rotation for visual feedback
+ var maxAngle = Math.PI / 4;
+ var minAngle = -Math.PI / 2.5;
+ var t = Math.max(-1, Math.min(1, self.vy / 30));
+ birdSprite.rotation = t * maxAngle;
+ if (birdSprite.rotation < minAngle) birdSprite.rotation = minAngle;
+ if (birdSprite.rotation > maxAngle) birdSprite.rotation = maxAngle;
+ };
+ // Flap (jump)
+ self.flap = function () {
+ self.vy = flapStrength;
+ LK.getSound('flap').play();
+ };
+ return self;
+});
+// PipePair class (top and bottom pipes)
+var PipePair = Container.expand(function () {
+ var self = Container.call(this);
+ // Top pipe
+ self.topPipe = self.attachAsset('pipe', {
+ anchorX: 0,
+ anchorY: 1
+ });
+ // Bottom pipe
+ self.bottomPipe = self.attachAsset('pipe', {
+ anchorX: 0,
+ anchorY: 0
+ });
+ // Used for scoring
+ self.passed = false;
+ // Set gap and position
+ self.setGap = function (gapY, gapHeight) {
+ // Top pipe: bottom at gapY - gapHeight/2
+ self.topPipe.height = Math.max(100, gapY - gapHeight / 2);
+ self.topPipe.y = self.topPipe.height;
+ // Bottom pipe: top at gapY + gapHeight/2
+ self.bottomPipe.y = gapY + gapHeight / 2;
+ self.bottomPipe.height = Math.max(100, 2732 - self.bottomPipe.y - groundHeight);
+ };
+ // Move pipes left
+ self.update = function () {
+ self.x -= pipeSpeed;
+ };
+ // Get bounding rectangles for collision
+ self.getTopRect = function () {
+ return new Rectangle(self.x, 0, self.topPipe.width, self.topPipe.height);
+ };
+ self.getBottomRect = function () {
+ return new Rectangle(self.x, self.bottomPipe.y, self.bottomPipe.width, self.bottomPipe.height);
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x87ceeb // Sky blue
+});
+
+/****
+* Game Code
+****/
+// Sound: Hit
+// Sound: Score
+// Sound: Flap
+// Ground: brown box
+// Pipe: green box
+// Bird: yellow ellipse
+// Constants
+var gravity = 1.6;
+var flapStrength = -28;
+var pipeSpeed = 16;
+var pipeInterval = 110; // frames between pipes
+var pipeGap = 520; // vertical gap between pipes
+var groundHeight = 120;
+var birdStartX = 600;
+var birdStartY = 1200;
+// Game state
+var bird;
+var pipes = [];
+var score = 0;
+var scoreTxt;
+var ground;
+var gameStarted = false;
+var gameOver = false;
+var lastPipeFrame = 0;
+// GUI Score
+scoreTxt = new Text2('0', {
+ size: 180,
+ fill: 0xFFFFFF
+});
+scoreTxt.anchor.set(0.5, 0);
+LK.gui.top.addChild(scoreTxt);
+// Add ground
+ground = LK.getAsset('ground', {
+ anchorX: 0,
+ anchorY: 0,
+ x: 0,
+ y: 2732 - groundHeight
+});
+game.addChild(ground);
+// Add bird
+bird = new Bird();
+bird.x = birdStartX;
+bird.y = birdStartY;
+game.addChild(bird);
+// Reset function
+function resetGame() {
+ // Remove pipes
+ for (var i = 0; i < pipes.length; i++) {
+ pipes[i].destroy();
+ }
+ pipes = [];
+ // Reset bird
+ bird.x = birdStartX;
+ bird.y = birdStartY;
+ bird.vy = 0;
+ // Reset score
+ score = 0;
+ scoreTxt.setText(score);
+ // Reset state
+ gameStarted = false;
+ gameOver = false;
+ lastPipeFrame = LK.ticks;
+}
+// Start game on first tap
+function startGame() {
+ if (!gameStarted && !gameOver) {
+ gameStarted = true;
+ bird.flap();
+ }
+}
+// Flap on tap
+game.down = function (x, y, obj) {
+ if (gameOver) return;
+ if (!gameStarted) {
+ startGame();
+ return;
+ }
+ bird.flap();
+};
+// Main update loop
+game.update = function () {
+ if (gameOver) return;
+ // Bird physics
+ if (gameStarted) {
+ bird.update();
+ }
+ // Pipes
+ if (gameStarted) {
+ // Spawn pipes
+ if (LK.ticks - lastPipeFrame >= pipeInterval) {
+ var gapY = 400 + Math.floor(Math.random() * (2732 - groundHeight - 800));
+ var pair = new PipePair();
+ pair.x = 2048;
+ pair.setGap(gapY, pipeGap);
+ pipes.push(pair);
+ game.addChild(pair);
+ lastPipeFrame = LK.ticks;
+ }
+ }
+ // Update pipes and check for collisions
+ for (var i = pipes.length - 1; i >= 0; i--) {
+ var pair = pipes[i];
+ if (gameStarted) {
+ pair.update();
+ }
+ // Remove pipes off screen
+ if (pair.x + pair.topPipe.width < 0) {
+ pair.destroy();
+ pipes.splice(i, 1);
+ continue;
+ }
+ // Score: passed pipe
+ if (!pair.passed && pair.x + pair.topPipe.width < bird.x) {
+ pair.passed = true;
+ score += 1;
+ scoreTxt.setText(score);
+ LK.getSound('score').play();
+ }
+ // Collision detection
+ if (rectIntersectsCircle(pair.getTopRect(), bird.x, bird.y, birdWidth() / 2) || rectIntersectsCircle(pair.getBottomRect(), bird.x, bird.y, birdWidth() / 2)) {
+ triggerGameOver();
+ return;
+ }
+ }
+ // Ground collision
+ if (bird.y + birdHeight() / 2 >= 2732 - groundHeight) {
+ bird.y = 2732 - groundHeight - birdHeight() / 2;
+ triggerGameOver();
+ return;
+ }
+ // Ceiling clamp
+ if (bird.y - birdHeight() / 2 < 0) {
+ bird.y = birdHeight() / 2;
+ bird.vy = 0;
+ }
+};
+// Helper: get bird width/height
+function birdWidth() {
+ return bird.children[0].width;
+}
+function birdHeight() {
+ return bird.children[0].height;
+}
+// Rectangle-circle collision
+function rectIntersectsCircle(rect, cx, cy, cr) {
+ // Find closest point to circle center within the 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));
+ // Calculate distance
+ var dx = cx - closestX;
+ var dy = cy - closestY;
+ return dx * dx + dy * dy < cr * cr;
+}
+// Game over
+function triggerGameOver() {
+ if (gameOver) return;
+ gameOver = true;
+ LK.getSound('hit').play();
+ LK.effects.flashScreen(0xff0000, 600);
+ LK.showGameOver();
+}
+// Reset on game over
+LK.on('gameover', function () {
+ resetGame();
+});
+// Initial reset
+resetGame();
\ No newline at end of file
Fullscreen modern App Store landscape banner, 16:9, high definition, for a game titled "Flappy Bird: Tap to Fly" and with the description "Tap to keep the bird airborne and navigate through gaps in pipes. Avoid obstacles and see how far you can go!". No text on banner!
wall . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
coin . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat