User prompt
Please fix the bug: 'Timeout.tick error: LK.setGameOverText is not a function' in or related to this line: 'LK.setGameOverText('Best: ' + bestScore);' Line Number: 380
User prompt
Please fix the bug: 'storage.get is not a function' in or related to this line: 'var bestScore = storage.get('flyingChickenBestScore') || 0;' Line Number: 167 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Please fix the bug: 'storage.getItem is not a function' in or related to this line: 'var bestScore = storage.getItem('flyingChickenBestScore') || 0;' Line Number: 167
User prompt
Please fix the bug: 'storage.get is not a function' in or related to this line: 'var bestScore = storage.get('flyingChickenBestScore') || 0;' Line Number: 167
User prompt
add top score in game over screen
User prompt
add 8-bit background music
Code edit (1 edits merged)
Please save this source code
User prompt
Flying Chicken
Initial prompt
📱 Game Name: "Flying Chicken" 🐔 Concept: The player makes a chicken jump between obstacles. The goal is to go as far as possible. A "tap-to-jump" game that seems easy but requires timing. 🎮 Gameplay: Control Mechanics: Just one touch: when you touch the screen, the chicken jumps up, when you release it, it falls down (Flappy Bird style). Obstacles: There are obstacles such as protruding pipes, walls or tractor tires on both sides of the screen (top-bottom or right-left). +1 point is earned for each obstacle passed. Difficulty: The gap between obstacles narrows, moving obstacles may come, environmental factors such as wind/birds may be added.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Chicken class var Chicken = Container.expand(function () { var self = Container.call(this); var chickenSprite = self.attachAsset('chicken', { anchorX: 0.5, anchorY: 0.5 }); self.radius = chickenSprite.width * 0.5; self.vy = 0; self.gravity = 2.2; self.flapStrength = -38; self.maxFall = 38; self.alive = true; // Flap upward self.flap = function () { if (!self.alive) return; self.vy = self.flapStrength; LK.getSound('flap').play(); // Animate chicken (slight scale for feedback) tween.stop(self, { scaleY: true }); self.scaleY = 1.0; tween(self, { scaleY: 0.8 }, { duration: 80, easing: tween.cubicOut, onFinish: function onFinish() { tween(self, { scaleY: 1.0 }, { duration: 120, easing: tween.cubicIn }); } }); }; // Update position self.update = function () { if (!self.alive) return; self.vy += self.gravity; if (self.vy > self.maxFall) self.vy = self.maxFall; self.y += self.vy; // Rotate chicken based on velocity var maxAngle = Math.PI / 3; var minAngle = -Math.PI / 6; var t = (self.vy + 38) / (self.maxFall + 38); chickenSprite.rotation = minAngle + (maxAngle - minAngle) * t; }; // Die self.die = function () { self.alive = false; // Fall fast self.vy = 18; // Flash red LK.effects.flashObject(self, 0xff0000, 400); }; return self; }); // PipePair class (top and bottom pipes) var PipePair = Container.expand(function () { var self = Container.call(this); // Top pipe var topPipe = self.attachAsset('pipe', { anchorX: 0.5, anchorY: 1.0 }); var topCap = self.attachAsset('pipecap', { anchorX: 0.5, anchorY: 1.0, y: -topPipe.height }); // Bottom pipe var bottomPipe = self.attachAsset('pipe', { anchorX: 0.5, anchorY: 0.0, y: 0 }); var bottomCap = self.attachAsset('pipecap', { anchorX: 0.5, anchorY: 0.0, y: bottomPipe.height }); // For collision self.topPipe = topPipe; self.bottomPipe = bottomPipe; // Has the chicken passed this pipe? self.passed = false; // Set gap and position self.setGap = function (gapY, gapHeight) { // Top pipe: bottom at gapY - gapHeight/2 topPipe.height = Math.max(120, gapY - gapHeight / 2); topCap.y = -topPipe.height; // Bottom pipe: top at gapY + gapHeight/2 bottomPipe.y = gapY + gapHeight / 2; bottomPipe.height = Math.max(120, 2732 - bottomPipe.y - 120); bottomCap.y = bottomPipe.y + bottomPipe.height; }; // Move pipes left self.update = function () { self.x -= pipeSpeed; }; // Destroy self.destroyPair = function () { self.destroy(); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87ceeb // Sky blue }); /**** * Game Code ****/ // Sound for hit // Sound for point // Sound for flap // Ground // Obstacle (pipe cap) // Obstacle (pipe) // Chicken (player) // Game constants var GROUND_HEIGHT = 120; var CHICKEN_START_X = 600; var CHICKEN_START_Y = 1200; var PIPE_INTERVAL = 1100; // px between pipes var PIPE_MIN_GAP = 340; var PIPE_MAX_GAP = 520; var PIPE_MIN_Y = 420; var PIPE_MAX_Y = 2732 - GROUND_HEIGHT - 420; var pipeSpeed = 16; var pipePairs = []; var score = 0; var bestScore = 0; var gameStarted = false; var gameOver = false; var dragNode = null; var lastPassedPipe = null; // Score text var scoreTxt = new Text2('0', { size: 180, fill: 0xFFF700 }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Best score text (bottom center) var bestScoreTxt = new Text2('', { size: 70, fill: 0xFFFFFF }); bestScoreTxt.anchor.set(0.5, 1); LK.gui.bottom.addChild(bestScoreTxt); // Ground var ground = LK.getAsset('ground', { anchorX: 0, anchorY: 0, x: 0, y: 2732 - GROUND_HEIGHT }); game.addChild(ground); // Chicken var chicken = new Chicken(); game.addChild(chicken); chicken.x = CHICKEN_START_X; chicken.y = CHICKEN_START_Y; // Helper: reset game state function resetGame() { // Remove pipes for (var i = 0; i < pipePairs.length; i++) { pipePairs[i].destroyPair(); } pipePairs = []; score = 0; scoreTxt.setText('0'); chicken.x = CHICKEN_START_X; chicken.y = CHICKEN_START_Y; chicken.vy = 0; chicken.alive = true; chicken.rotation = 0; gameStarted = false; gameOver = false; pipeSpeed = 16; lastPassedPipe = null; // Show best score if (bestScore > 0) { bestScoreTxt.setText('Best: ' + bestScore); } else { bestScoreTxt.setText(''); } } // Helper: spawn a new pipe pair function spawnPipePair() { // Gap size decreases as score increases var gapHeight = Math.max(PIPE_MIN_GAP, PIPE_MAX_GAP - score * 8); // Gap Y position var gapY = PIPE_MIN_Y + Math.random() * (PIPE_MAX_Y - PIPE_MIN_Y); var pair = new PipePair(); pair.x = 2048 + 200; pair.setGap(gapY, gapHeight); game.addChild(pair); pipePairs.push(pair); } // Helper: check collision between chicken and a pipe function checkPipeCollision(chicken, pipePair) { // Chicken bounding circle var cx = chicken.x; var cy = chicken.y; var r = chicken.radius * 0.92; // Top pipe rect var tp = pipePair.topPipe; var tpx = pipePair.x; var tpy = tp.y + pipePair.y; var tpw = tp.width; var tph = tp.height; // Bottom pipe rect var bp = pipePair.bottomPipe; var bpx = pipePair.x; var bpy = bp.y + pipePair.y; var bpw = bp.width; var bph = bp.height; // Circle-rect collision function circleRectCollide(cx, cy, r, rx, ry, rw, rh) { var closestX = Math.max(rx - rw / 2, Math.min(cx, rx + rw / 2)); var closestY = Math.max(ry, Math.min(cy, ry + rh)); var dx = cx - closestX; var dy = cy - closestY; return dx * dx + dy * dy < r * r; } // Top pipe if (circleRectCollide(cx, cy, r, tpx, tpy - tph, tpw, tph)) return true; // Bottom pipe if (circleRectCollide(cx, cy, r, bpx, bpy, bpw, bph)) return true; return false; } // Helper: check collision with ground or ceiling function checkGroundCeiling(chicken) { if (chicken.y + chicken.radius > 2732 - GROUND_HEIGHT) return true; if (chicken.y - chicken.radius < 0) return true; return false; } // Start game on first tap function startGame() { if (gameStarted) return; resetGame(); gameStarted = true; // Spawn initial pipes for (var i = 0; i < 3; i++) { var pair = new PipePair(); pair.x = 2048 + 600 + i * PIPE_INTERVAL; var gapHeight = Math.max(PIPE_MIN_GAP, PIPE_MAX_GAP - score * 8); var gapY = PIPE_MIN_Y + Math.random() * (PIPE_MAX_Y - PIPE_MIN_Y); pair.setGap(gapY, gapHeight); game.addChild(pair); pipePairs.push(pair); } } // Game tap: chicken flaps game.down = function (x, y, obj) { if (gameOver) return; if (!gameStarted) { startGame(); } chicken.flap(); dragNode = chicken; }; // Release: nothing (but required for dragNode) game.up = function (x, y, obj) { dragNode = null; }; // Move: not used for chicken, but required for dragNode game.move = function (x, y, obj) { // No drag for chicken, but required for completeness }; // Main game loop game.update = function () { if (!gameStarted) return; // Chicken update chicken.update(); // Pipes update for (var i = pipePairs.length - 1; i >= 0; i--) { var pair = pipePairs[i]; pair.update(); // Remove pipes off screen if (pair.x < -300) { pair.destroyPair(); pipePairs.splice(i, 1); continue; } // Check for passing pipe (score) if (!pair.passed && pair.x + 110 < chicken.x) { pair.passed = true; score += 1; scoreTxt.setText(score + ''); LK.getSound('point').play(); // Increase speed every 10 points if (score % 10 === 0) { pipeSpeed += 1.5; } } } // Spawn new pipes if (pipePairs.length === 0 || pipePairs[pipePairs.length - 1].x < 2048 - PIPE_INTERVAL) { spawnPipePair(); } // Collision detection var collided = false; for (var i = 0; i < pipePairs.length; i++) { if (checkPipeCollision(chicken, pipePairs[i])) { collided = true; break; } } if (checkGroundCeiling(chicken)) { collided = true; } if (collided && chicken.alive) { chicken.die(); LK.getSound('hit').play(); gameOver = true; // Update best score if (score > bestScore) bestScore = score; // Flash screen LK.effects.flashScreen(0xff0000, 800); // Show game over (auto resets) LK.setTimeout(function () { LK.showGameOver(); }, 600); } }; // On game over, reset state LK.on('gameover', function () { resetGame(); }); // On you win (not used, but for completeness) LK.on('youwin', function () { resetGame(); }); // Initial state resetGame();
===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,353 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+
+/****
+* Classes
+****/
+// Chicken class
+var Chicken = Container.expand(function () {
+ var self = Container.call(this);
+ var chickenSprite = self.attachAsset('chicken', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.radius = chickenSprite.width * 0.5;
+ self.vy = 0;
+ self.gravity = 2.2;
+ self.flapStrength = -38;
+ self.maxFall = 38;
+ self.alive = true;
+ // Flap upward
+ self.flap = function () {
+ if (!self.alive) return;
+ self.vy = self.flapStrength;
+ LK.getSound('flap').play();
+ // Animate chicken (slight scale for feedback)
+ tween.stop(self, {
+ scaleY: true
+ });
+ self.scaleY = 1.0;
+ tween(self, {
+ scaleY: 0.8
+ }, {
+ duration: 80,
+ easing: tween.cubicOut,
+ onFinish: function onFinish() {
+ tween(self, {
+ scaleY: 1.0
+ }, {
+ duration: 120,
+ easing: tween.cubicIn
+ });
+ }
+ });
+ };
+ // Update position
+ self.update = function () {
+ if (!self.alive) return;
+ self.vy += self.gravity;
+ if (self.vy > self.maxFall) self.vy = self.maxFall;
+ self.y += self.vy;
+ // Rotate chicken based on velocity
+ var maxAngle = Math.PI / 3;
+ var minAngle = -Math.PI / 6;
+ var t = (self.vy + 38) / (self.maxFall + 38);
+ chickenSprite.rotation = minAngle + (maxAngle - minAngle) * t;
+ };
+ // Die
+ self.die = function () {
+ self.alive = false;
+ // Fall fast
+ self.vy = 18;
+ // Flash red
+ LK.effects.flashObject(self, 0xff0000, 400);
+ };
+ return self;
+});
+// PipePair class (top and bottom pipes)
+var PipePair = Container.expand(function () {
+ var self = Container.call(this);
+ // Top pipe
+ var topPipe = self.attachAsset('pipe', {
+ anchorX: 0.5,
+ anchorY: 1.0
+ });
+ var topCap = self.attachAsset('pipecap', {
+ anchorX: 0.5,
+ anchorY: 1.0,
+ y: -topPipe.height
+ });
+ // Bottom pipe
+ var bottomPipe = self.attachAsset('pipe', {
+ anchorX: 0.5,
+ anchorY: 0.0,
+ y: 0
+ });
+ var bottomCap = self.attachAsset('pipecap', {
+ anchorX: 0.5,
+ anchorY: 0.0,
+ y: bottomPipe.height
+ });
+ // For collision
+ self.topPipe = topPipe;
+ self.bottomPipe = bottomPipe;
+ // Has the chicken passed this pipe?
+ self.passed = false;
+ // Set gap and position
+ self.setGap = function (gapY, gapHeight) {
+ // Top pipe: bottom at gapY - gapHeight/2
+ topPipe.height = Math.max(120, gapY - gapHeight / 2);
+ topCap.y = -topPipe.height;
+ // Bottom pipe: top at gapY + gapHeight/2
+ bottomPipe.y = gapY + gapHeight / 2;
+ bottomPipe.height = Math.max(120, 2732 - bottomPipe.y - 120);
+ bottomCap.y = bottomPipe.y + bottomPipe.height;
+ };
+ // Move pipes left
+ self.update = function () {
+ self.x -= pipeSpeed;
+ };
+ // Destroy
+ self.destroyPair = function () {
+ self.destroy();
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x87ceeb // Sky blue
+});
+
+/****
+* Game Code
+****/
+// Sound for hit
+// Sound for point
+// Sound for flap
+// Ground
+// Obstacle (pipe cap)
+// Obstacle (pipe)
+// Chicken (player)
+// Game constants
+var GROUND_HEIGHT = 120;
+var CHICKEN_START_X = 600;
+var CHICKEN_START_Y = 1200;
+var PIPE_INTERVAL = 1100; // px between pipes
+var PIPE_MIN_GAP = 340;
+var PIPE_MAX_GAP = 520;
+var PIPE_MIN_Y = 420;
+var PIPE_MAX_Y = 2732 - GROUND_HEIGHT - 420;
+var pipeSpeed = 16;
+var pipePairs = [];
+var score = 0;
+var bestScore = 0;
+var gameStarted = false;
+var gameOver = false;
+var dragNode = null;
+var lastPassedPipe = null;
+// Score text
+var scoreTxt = new Text2('0', {
+ size: 180,
+ fill: 0xFFF700
+});
+scoreTxt.anchor.set(0.5, 0);
+LK.gui.top.addChild(scoreTxt);
+// Best score text (bottom center)
+var bestScoreTxt = new Text2('', {
+ size: 70,
+ fill: 0xFFFFFF
+});
+bestScoreTxt.anchor.set(0.5, 1);
+LK.gui.bottom.addChild(bestScoreTxt);
+// Ground
+var ground = LK.getAsset('ground', {
+ anchorX: 0,
+ anchorY: 0,
+ x: 0,
+ y: 2732 - GROUND_HEIGHT
+});
+game.addChild(ground);
+// Chicken
+var chicken = new Chicken();
+game.addChild(chicken);
+chicken.x = CHICKEN_START_X;
+chicken.y = CHICKEN_START_Y;
+// Helper: reset game state
+function resetGame() {
+ // Remove pipes
+ for (var i = 0; i < pipePairs.length; i++) {
+ pipePairs[i].destroyPair();
+ }
+ pipePairs = [];
+ score = 0;
+ scoreTxt.setText('0');
+ chicken.x = CHICKEN_START_X;
+ chicken.y = CHICKEN_START_Y;
+ chicken.vy = 0;
+ chicken.alive = true;
+ chicken.rotation = 0;
+ gameStarted = false;
+ gameOver = false;
+ pipeSpeed = 16;
+ lastPassedPipe = null;
+ // Show best score
+ if (bestScore > 0) {
+ bestScoreTxt.setText('Best: ' + bestScore);
+ } else {
+ bestScoreTxt.setText('');
+ }
+}
+// Helper: spawn a new pipe pair
+function spawnPipePair() {
+ // Gap size decreases as score increases
+ var gapHeight = Math.max(PIPE_MIN_GAP, PIPE_MAX_GAP - score * 8);
+ // Gap Y position
+ var gapY = PIPE_MIN_Y + Math.random() * (PIPE_MAX_Y - PIPE_MIN_Y);
+ var pair = new PipePair();
+ pair.x = 2048 + 200;
+ pair.setGap(gapY, gapHeight);
+ game.addChild(pair);
+ pipePairs.push(pair);
+}
+// Helper: check collision between chicken and a pipe
+function checkPipeCollision(chicken, pipePair) {
+ // Chicken bounding circle
+ var cx = chicken.x;
+ var cy = chicken.y;
+ var r = chicken.radius * 0.92;
+ // Top pipe rect
+ var tp = pipePair.topPipe;
+ var tpx = pipePair.x;
+ var tpy = tp.y + pipePair.y;
+ var tpw = tp.width;
+ var tph = tp.height;
+ // Bottom pipe rect
+ var bp = pipePair.bottomPipe;
+ var bpx = pipePair.x;
+ var bpy = bp.y + pipePair.y;
+ var bpw = bp.width;
+ var bph = bp.height;
+ // Circle-rect collision
+ function circleRectCollide(cx, cy, r, rx, ry, rw, rh) {
+ var closestX = Math.max(rx - rw / 2, Math.min(cx, rx + rw / 2));
+ var closestY = Math.max(ry, Math.min(cy, ry + rh));
+ var dx = cx - closestX;
+ var dy = cy - closestY;
+ return dx * dx + dy * dy < r * r;
+ }
+ // Top pipe
+ if (circleRectCollide(cx, cy, r, tpx, tpy - tph, tpw, tph)) return true;
+ // Bottom pipe
+ if (circleRectCollide(cx, cy, r, bpx, bpy, bpw, bph)) return true;
+ return false;
+}
+// Helper: check collision with ground or ceiling
+function checkGroundCeiling(chicken) {
+ if (chicken.y + chicken.radius > 2732 - GROUND_HEIGHT) return true;
+ if (chicken.y - chicken.radius < 0) return true;
+ return false;
+}
+// Start game on first tap
+function startGame() {
+ if (gameStarted) return;
+ resetGame();
+ gameStarted = true;
+ // Spawn initial pipes
+ for (var i = 0; i < 3; i++) {
+ var pair = new PipePair();
+ pair.x = 2048 + 600 + i * PIPE_INTERVAL;
+ var gapHeight = Math.max(PIPE_MIN_GAP, PIPE_MAX_GAP - score * 8);
+ var gapY = PIPE_MIN_Y + Math.random() * (PIPE_MAX_Y - PIPE_MIN_Y);
+ pair.setGap(gapY, gapHeight);
+ game.addChild(pair);
+ pipePairs.push(pair);
+ }
+}
+// Game tap: chicken flaps
+game.down = function (x, y, obj) {
+ if (gameOver) return;
+ if (!gameStarted) {
+ startGame();
+ }
+ chicken.flap();
+ dragNode = chicken;
+};
+// Release: nothing (but required for dragNode)
+game.up = function (x, y, obj) {
+ dragNode = null;
+};
+// Move: not used for chicken, but required for dragNode
+game.move = function (x, y, obj) {
+ // No drag for chicken, but required for completeness
+};
+// Main game loop
+game.update = function () {
+ if (!gameStarted) return;
+ // Chicken update
+ chicken.update();
+ // Pipes update
+ for (var i = pipePairs.length - 1; i >= 0; i--) {
+ var pair = pipePairs[i];
+ pair.update();
+ // Remove pipes off screen
+ if (pair.x < -300) {
+ pair.destroyPair();
+ pipePairs.splice(i, 1);
+ continue;
+ }
+ // Check for passing pipe (score)
+ if (!pair.passed && pair.x + 110 < chicken.x) {
+ pair.passed = true;
+ score += 1;
+ scoreTxt.setText(score + '');
+ LK.getSound('point').play();
+ // Increase speed every 10 points
+ if (score % 10 === 0) {
+ pipeSpeed += 1.5;
+ }
+ }
+ }
+ // Spawn new pipes
+ if (pipePairs.length === 0 || pipePairs[pipePairs.length - 1].x < 2048 - PIPE_INTERVAL) {
+ spawnPipePair();
+ }
+ // Collision detection
+ var collided = false;
+ for (var i = 0; i < pipePairs.length; i++) {
+ if (checkPipeCollision(chicken, pipePairs[i])) {
+ collided = true;
+ break;
+ }
+ }
+ if (checkGroundCeiling(chicken)) {
+ collided = true;
+ }
+ if (collided && chicken.alive) {
+ chicken.die();
+ LK.getSound('hit').play();
+ gameOver = true;
+ // Update best score
+ if (score > bestScore) bestScore = score;
+ // Flash screen
+ LK.effects.flashScreen(0xff0000, 800);
+ // Show game over (auto resets)
+ LK.setTimeout(function () {
+ LK.showGameOver();
+ }, 600);
+ }
+};
+// On game over, reset state
+LK.on('gameover', function () {
+ resetGame();
+});
+// On you win (not used, but for completeness)
+LK.on('youwin', function () {
+ resetGame();
+});
+// Initial state
+resetGame();
\ No newline at end of file