使用JavaScript开发Flappy Bird时Canvas无法显示图片求助
问题原因分析
你的代码中图片无法显示的核心问题在于**bird.onload事件的绑定位置错误**:
- 每次调用
drawBird()都会重新绑定一次onload事件,当图片已经加载完成后,这个事件不会再次触发,导致后续的update循环里无法绘制图片。 - 即使图片加载完成,
drawBird()也只在第一次触发onload时绘制一次,之后的循环不会重复绘制。
修正方案
1. 调整图片加载逻辑,仅绑定一次onload
把onload事件绑定移到全局作用域,标记图片加载状态,确保后续循环可以持续绘制:
var canvas = document.getElementById("myCanvas"); var context = canvas.getContext("2d"); var bird = new Image(); var birdLoaded = false; // 标记图片是否加载完成 bird.src = "https://www.nicepng.com/png/detail/151-1515288_flappy-bird-png-jpg-download-flappy-bird-bird.png"; // 仅绑定一次onload事件,加载完成后标记状态 bird.onload = function() { birdLoaded = true; };
2. 修改drawBird函数,确保每次循环都能绘制图片
drawBird只需判断图片是否加载完成,完成后直接绘制即可(建议用y变量跟随小鸟位置,而非固定坐标):
function drawBird(){ if (birdLoaded) { context.drawImage(bird, 250, y); } }
3. 可选:添加图片加载失败排查
可以增加onerror事件,快速定位图片加载问题:
bird.onerror = function() { console.error("小鸟图片加载失败"); };
修正后的完整核心代码片段
var canvas = document.getElementById("myCanvas"); var context = canvas.getContext("2d"); var bird = new Image(); var birdLoaded = false; var y = 350; // 小鸟初始y坐标 var dy = 0; var gravity = 0.5; var pipes = []; var dx = -2; var xp = 1300; bird.src = "https://www.nicepng.com/png/detail/151-1515288_flappy-bird-png-jpg-download-flappy-bird-bird.png"; bird.onload = function() { birdLoaded = true; }; bird.onerror = function() { console.error("小鸟图片加载失败"); }; function drawBird(){ if (birdLoaded) { context.drawImage(bird, 250, y); } } function drawPipes(){ for (var i = 0; i < pipes.length; i++) { var topPipe = pipes[i].top; var bottomPipe = pipes[i].bottom; context.beginPath(); context.rect(topPipe.xpos, topPipe.ypos, topPipe.width, topPipe.height); context.rect(bottomPipe.xpos, bottomPipe.ypos, bottomPipe.width, bottomPipe.height); context.fillStyle = "green"; context.fill(); context.lineWidth = 2; context.strokeStyle = "black"; context.closePath(); context.stroke(); } } function topPipe() { this.width = 50; this.height = Math.random() * 200 + 50; this.xpos = canvas.width; this.ypos = 0; } function bottomPipe(height) { this.width = 50; this.height = height; this.xpos = canvas.width; this.ypos = canvas.height - height; } function jump() { dy = -8; } function update(){ context.clearRect(0, 0, canvas.width, canvas.height); drawBird(); drawPipes(); if (pipes.length === 0 || pipes[pipes.length - 1].top.xpos <= canvas.width / 2 - pipes[pipes.length - 1].top.width) { var topPipeObj = new topPipe(); var topPipeHeight = topPipeObj.height; var bottomPipeHeight = canvas.height - 200 - topPipeHeight; pipes.push({ top: topPipeObj, bottom: new bottomPipe(bottomPipeHeight), }); } for (var i = 0; i < pipes.length; i++) { pipes[i].top.xpos += dx; pipes[i].bottom.xpos += dx; } if (xp <= canvas.width / 2) { xp = 1300; } xp += dx; y += dy; dy += gravity; requestAnimationFrame(update); } document.addEventListener("click", function(event) { jump(); }); update();
补充说明
- 本地图片加载失败通常是浏览器跨域限制导致,建议用本地服务器(如Live Server插件)运行项目,避免直接用
file://协议打开文件。 - 代码补全了
topPipe、bottomPipe、jump等缺失函数,确保逻辑完整。
内容的提问来源于stack exchange,提问作者Jayson
相关产品推荐
相关产品推荐

