User prompt
coins
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'speed')' in or related to this line: 'pipeGaps[i].x -= pipes[i * 2].speed;' Line Number: 231
Code edit (1 edits merged)
Please save this source code
User prompt
Flappy Bird
Initial prompt
flappy bird
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Bird = Container.expand(function () {
var self = Container.call(this);
var birdGraphics = self.attachAsset('bird', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityY = 0;
self.gravity = 0.6;
self.flapStrength = -12;
self.isAlive = true;
self.flap = function () {
self.velocityY = self.flapStrength;
LK.getSound('flap').play();
};
self.update = function () {
if (!self.isAlive) return;
self.velocityY += self.gravity;
self.y += self.velocityY;
// Rotation based on velocity
birdGraphics.rotation = Math.min(Math.max(self.velocityY * 0.1, -0.5), 0.5);
};
return self;
});
var Coin = Container.expand(function () {
var self = Container.call(this);
var coinGraphics = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 6;
self.collected = false;
self.update = function () {
self.x -= self.speed;
};
return self;
});
var Pipe = Container.expand(function () {
var self = Container.call(this);
var topPipeGraphics = self.attachAsset('pipe', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 6;
self.hasScored = false;
self.update = function () {
self.x -= self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
var bird = null;
var pipes = [];
var pipeGaps = [];
var coins = [];
var gameActive = true;
var score = 0;
var baseGapSize = 200;
var gapDecreaseRate = 0.5;
var pipeSpawnTimer = 0;
var pipeSpawnInterval = 100;
var coinSpawnTimer = 0;
var coinSpawnInterval = 150;
var baseSpeed = 6;
var speedIncreaseRate = 0.001;
var scoreTxt = new Text2('0', {
size: 120,
fill: 0x000000
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
function initializeGame() {
bird = game.addChild(new Bird());
bird.x = 400;
bird.y = 1366;
bird.velocityY = 0;
bird.isAlive = true;
pipes = [];
pipeGaps = [];
coins = [];
gameActive = true;
score = 0;
pipeSpawnTimer = 0;
coinSpawnTimer = 0;
baseSpeed = 6;
scoreTxt.setText('0');
updateScore();
}
function updateScore() {
scoreTxt.setText(score);
LK.setScore(score);
}
function getRandomGapPosition() {
var minY = 150;
var maxY = 2732 - 150 - baseGapSize;
return minY + Math.random() * (maxY - minY);
}
function spawnPipe() {
var gapSize = Math.max(120, baseGapSize - score * gapDecreaseRate);
var gapY = getRandomGapPosition();
// Top pipe
var topPipe = new Pipe();
topPipe.x = 2048 + 100;
topPipe.y = gapY - gapSize / 2;
topPipe.speed = baseSpeed + score * speedIncreaseRate;
topPipe.scaleY = (gapY - gapSize / 2) / 800;
topPipe.hasScored = false;
game.addChild(topPipe);
pipes.push(topPipe);
// Bottom pipe
var bottomPipe = new Pipe();
bottomPipe.x = 2048 + 100;
bottomPipe.y = gapY + gapSize / 2;
bottomPipe.speed = baseSpeed + score * speedIncreaseRate;
bottomPipe.scaleY = (2732 - (gapY + gapSize / 2)) / 800;
bottomPipe.hasScored = false;
game.addChild(bottomPipe);
pipes.push(bottomPipe);
pipeGaps.push({
x: 2048 + 100,
y: gapY,
gapSize: gapSize,
scored: false,
speed: baseSpeed + score * speedIncreaseRate
});
}
function spawnCoin() {
var coinY = 200 + Math.random() * (2732 - 400);
var coin = new Coin();
coin.x = 2048 + 100;
coin.y = coinY;
coin.speed = baseSpeed + score * speedIncreaseRate;
coin.collected = false;
game.addChild(coin);
coins.push(coin);
}
function handleGameOver() {
if (!gameActive) return;
gameActive = false;
bird.isAlive = false;
LK.getSound('collision').play();
LK.effects.flashScreen(0xFF0000, 500);
LK.setTimeout(function () {
LK.showGameOver();
}, 500);
}
function checkCollisions() {
if (!gameActive || !bird.isAlive) return;
// Check screen boundaries
if (bird.y - bird.height / 2 <= 0 || bird.y + bird.height / 2 >= 2732) {
handleGameOver();
return;
}
// Check pipe collisions
for (var i = 0; i < pipes.length; i++) {
if (bird.intersects(pipes[i])) {
handleGameOver();
return;
}
}
// Check coin collisions
for (var i = 0; i < coins.length; i++) {
if (!coins[i].collected && bird.intersects(coins[i])) {
coins[i].collected = true;
score += 5;
LK.getSound('coinCollect').play();
updateScore();
}
}
}
function updateScoring() {
if (!gameActive) return;
for (var i = 0; i < pipeGaps.length; i++) {
var gap = pipeGaps[i];
if (!gap.scored && gap.x + 80 < bird.x && bird.lastX >= gap.x + 80) {
gap.scored = true;
score++;
LK.getSound('score').play();
updateScore();
if (score >= 100) {
gameActive = false;
bird.isAlive = false;
LK.setTimeout(function () {
LK.showYouWin();
}, 500);
}
}
}
}
function cleanup() {
// Remove off-screen pipes
for (var i = pipes.length - 1; i >= 0; i--) {
if (pipes[i].x < -200) {
pipes[i].destroy();
pipes.splice(i, 1);
}
}
// Remove off-screen gap trackers
for (var i = pipeGaps.length - 1; i >= 0; i--) {
if (pipeGaps[i].x < -200) {
pipeGaps.splice(i, 1);
}
}
// Remove collected or off-screen coins
for (var i = coins.length - 1; i >= 0; i--) {
if (coins[i].collected || coins[i].x < -200) {
coins[i].destroy();
coins.splice(i, 1);
}
}
}
game.move = function (x, y, obj) {
if (gameActive && bird.isAlive) {
bird.flap();
}
};
game.down = function (x, y, obj) {
if (gameActive && bird.isAlive) {
bird.flap();
}
};
game.update = function () {
if (!bird) {
initializeGame();
return;
}
if (gameActive) {
// Spawn pipes
pipeSpawnTimer++;
if (pipeSpawnTimer >= pipeSpawnInterval) {
spawnPipe();
pipeSpawnTimer = 0;
pipeSpawnInterval = Math.max(60, 100 - score);
}
// Spawn coins
coinSpawnTimer++;
if (coinSpawnTimer >= coinSpawnInterval) {
spawnCoin();
coinSpawnTimer = 0;
}
// Update pipes
for (var i = 0; i < pipes.length; i++) {
pipes[i].speed = baseSpeed + score * speedIncreaseRate;
pipes[i].update();
}
// Update gap trackers
for (var i = 0; i < pipeGaps.length; i++) {
pipeGaps[i].x -= pipeGaps[i].speed;
pipeGaps[i].speed = baseSpeed + score * speedIncreaseRate;
}
// Update coins
for (var i = 0; i < coins.length; i++) {
coins[i].speed = baseSpeed + score * speedIncreaseRate;
coins[i].update();
}
// Update scoring
updateScoring();
// Cleanup
cleanup();
}
// Update bird
if (bird) {
bird.lastX = bird.x;
bird.update();
checkCollisions();
}
}; ===================================================================
--- original.js
+++ change.js
@@ -28,8 +28,21 @@
birdGraphics.rotation = Math.min(Math.max(self.velocityY * 0.1, -0.5), 0.5);
};
return self;
});
+var Coin = Container.expand(function () {
+ var self = Container.call(this);
+ var coinGraphics = self.attachAsset('coin', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 6;
+ self.collected = false;
+ self.update = function () {
+ self.x -= self.speed;
+ };
+ return self;
+});
var Pipe = Container.expand(function () {
var self = Container.call(this);
var topPipeGraphics = self.attachAsset('pipe', {
anchorX: 0.5,
@@ -55,14 +68,17 @@
****/
var bird = null;
var pipes = [];
var pipeGaps = [];
+var coins = [];
var gameActive = true;
var score = 0;
var baseGapSize = 200;
var gapDecreaseRate = 0.5;
var pipeSpawnTimer = 0;
var pipeSpawnInterval = 100;
+var coinSpawnTimer = 0;
+var coinSpawnInterval = 150;
var baseSpeed = 6;
var speedIncreaseRate = 0.001;
var scoreTxt = new Text2('0', {
size: 120,
@@ -77,11 +93,13 @@
bird.velocityY = 0;
bird.isAlive = true;
pipes = [];
pipeGaps = [];
+ coins = [];
gameActive = true;
score = 0;
pipeSpawnTimer = 0;
+ coinSpawnTimer = 0;
baseSpeed = 6;
scoreTxt.setText('0');
updateScore();
}
@@ -122,8 +140,18 @@
scored: false,
speed: baseSpeed + score * speedIncreaseRate
});
}
+function spawnCoin() {
+ var coinY = 200 + Math.random() * (2732 - 400);
+ var coin = new Coin();
+ coin.x = 2048 + 100;
+ coin.y = coinY;
+ coin.speed = baseSpeed + score * speedIncreaseRate;
+ coin.collected = false;
+ game.addChild(coin);
+ coins.push(coin);
+}
function handleGameOver() {
if (!gameActive) return;
gameActive = false;
bird.isAlive = false;
@@ -146,8 +174,17 @@
handleGameOver();
return;
}
}
+ // Check coin collisions
+ for (var i = 0; i < coins.length; i++) {
+ if (!coins[i].collected && bird.intersects(coins[i])) {
+ coins[i].collected = true;
+ score += 5;
+ LK.getSound('coinCollect').play();
+ updateScore();
+ }
+ }
}
function updateScoring() {
if (!gameActive) return;
for (var i = 0; i < pipeGaps.length; i++) {
@@ -180,8 +217,15 @@
if (pipeGaps[i].x < -200) {
pipeGaps.splice(i, 1);
}
}
+ // Remove collected or off-screen coins
+ for (var i = coins.length - 1; i >= 0; i--) {
+ if (coins[i].collected || coins[i].x < -200) {
+ coins[i].destroy();
+ coins.splice(i, 1);
+ }
+ }
}
game.move = function (x, y, obj) {
if (gameActive && bird.isAlive) {
bird.flap();
@@ -204,8 +248,14 @@
spawnPipe();
pipeSpawnTimer = 0;
pipeSpawnInterval = Math.max(60, 100 - score);
}
+ // Spawn coins
+ coinSpawnTimer++;
+ if (coinSpawnTimer >= coinSpawnInterval) {
+ spawnCoin();
+ coinSpawnTimer = 0;
+ }
// Update pipes
for (var i = 0; i < pipes.length; i++) {
pipes[i].speed = baseSpeed + score * speedIncreaseRate;
pipes[i].update();
@@ -214,8 +264,13 @@
for (var i = 0; i < pipeGaps.length; i++) {
pipeGaps[i].x -= pipeGaps[i].speed;
pipeGaps[i].speed = baseSpeed + score * speedIncreaseRate;
}
+ // Update coins
+ for (var i = 0; i < coins.length; i++) {
+ coins[i].speed = baseSpeed + score * speedIncreaseRate;
+ coins[i].update();
+ }
// Update scoring
updateScoring();
// Cleanup
cleanup();