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");
var storage = LK.import("@upit/storage.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 = storage.flyingChickenBestScore || 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('');
}
// Start 8-bit background music
LK.playMusic('8-bit');
}
// 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;
// Stop music on game over
LK.stopMusic();
// Update best score
if (score > bestScore) {
bestScore = score;
storage.flyingChickenBestScore = bestScore;
}
// Flash screen
LK.effects.flashScreen(0xff0000, 800);
// Show game over (auto resets)
LK.setTimeout(function () {
// Show best score in the bestScoreTxt (bottom center) before game over popup
if (bestScore > 0) {
bestScoreTxt.setText('Best: ' + bestScore);
} else {
bestScoreTxt.setText('');
}
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
@@ -344,9 +344,14 @@
// Flash screen
LK.effects.flashScreen(0xff0000, 800);
// Show game over (auto resets)
LK.setTimeout(function () {
- LK.setGameOverText('Best: ' + bestScore);
+ // Show best score in the bestScoreTxt (bottom center) before game over popup
+ if (bestScore > 0) {
+ bestScoreTxt.setText('Best: ' + bestScore);
+ } else {
+ bestScoreTxt.setText('');
+ }
LK.showGameOver();
}, 600);
}
};