Flappy Bird游戏:碰撞管道后小鸟下落过快的解决方案求助
解决Flappy Bird碰撞管道后瞬间坠落的问题
问题根源
你的代码中,当gameover为true时,使用了同步while循环直接将小鸟的Y坐标一次性加到目标位置:
if (gameover == true) { while (bird.Y < canvas.height / 1.2) { console.log(bird.Y) bird.Y += gravity; } // ... 其他渲染 return; }
这个循环会在单帧内执行完成,导致小鸟的位置瞬间跳跃,视觉上表现为“瞬间坠落”,而非逐帧的慢速下落。
解决方案
将同步循环改为逐帧更新,让小鸟在每帧中只移动一小段距离,直到到达目标位置:
修改refresh函数中的gameover分支:
//logic for bird on colliding with pillar if (gameover == true) { // 逐帧更新小鸟位置,而非一次性跳到位 if (bird.Y < canvas.height / 1.2) { bird.Y += gravity; } pipearry.forEach((e) => { context.drawImage(e.img, e.X, e.Y, e.width, e.height); }) context.fillStyle = "white"; // 修正大小写,确保颜色生效 context.font = "45px sans-serif"; context.fillText(score, 5, 45); return; }
额外优化点
- 修复变量声明问题:
gameover变量未使用let/const声明,会成为全局变量,建议改为:
let gameover = false;
- 修复文字颜色不生效问题:
context.fillstyle应为context.fillStyle(JavaScript区分大小写),在所有使用fillstyle的地方修正为fillStyle。 - 移除冗余代码:
refresh函数中keypressed判断分支逻辑重复,可以简化为:
velocityY += gravity; bird.Y += velocityY;
修改后的完整refresh函数示例
function refresh() { window.requestAnimationFrame(refresh); context.clearRect(0, 0, canvas.width, canvas.height); context.drawImage(img_bird, bird.X, bird.Y, 50, 40); //logic for bird on colliding with pillar if (gameover == true) { // 逐帧下落 if (bird.Y < canvas.height / 1.2) { bird.Y += gravity; } pipearry.forEach((e) => { context.drawImage(e.img, e.X, e.Y, e.width, e.height); }) context.fillStyle = "white"; context.font = "45px sans-serif"; context.fillText(score, 5, 45); return; } for (let i = 0; i < pipearry.length; i++) { pipe = pipearry[i]; context.drawImage(pipe.img, pipe.X, pipe.Y, pipe.width, pipe.height); pipe.X += velocityX; if (pipe.passed == false && bird.X > pipe.X + pipe.width) { score += 1; pipe.passed = true; } if (detectcollision(bird, pipe)) { gameover = true; }; } if (bird.Y > boardheight / 1.23) gameover = true; velocityY += gravity; bird.Y += velocityY; context.fillStyle = "white"; context.font = "45px sans-serif"; context.fillText(score, 5, 45); }
内容的提问来源于stack exchange,提问作者Rahan Ajai
相关产品推荐
相关产品推荐

