Canvas实现Goomba行走动画遇问题:值变化但图像静止
问题根源与解决方案
你的代码核心问题是:绘制动作只在图片加载完成时执行了一次,之后number虽然在动画循环里切换,但没有触发重新绘制,所以画面一直停留在第一帧。
具体问题点
img.addEventListener('load', ...)里的绘制代码只运行一次,图片加载完就不会再执行了,后续number变化无法更新画面。- 动画循环
useframes只负责切换number,没有包含绘制逻辑。 - 第二段代码里的
usage判断逻辑有问题——usage >=10时两个if会依次触发,导致number刚切换就立刻切回去,等于没变化。
修复后的代码示例(drawImage方案)
<img src="https://www.spriters-resource.com/resources/sheets/49/52570.png?updated=1635821170" id="sprite" width='0' height='0'> <canvas></canvas> <style> body { margin: 0px !important; } </style> <script> const img = document.getElementById("sprite"); const canvas = document.querySelector("canvas"); const c = canvas.getContext("2d"); canvas.height = innerHeight; canvas.width = innerWidth; let number = 'even'; let usage = 0; let isImgLoaded = false; img.addEventListener('load', () => { isImgLoaded = true; }); function useframes() { requestAnimationFrame(useframes); if (!isImgLoaded) return; // 清空画布,避免旧帧叠加 c.clearRect(0, 0, canvas.width, canvas.height); // 修复帧切换逻辑:用else if避免重复触发 if (usage < 10) { usage += 1; } else if (number === 'even') { number = 'odd'; usage = 0; } else { number = 'even'; usage = 0; } // 根据当前number绘制对应帧 if (number === 'even') { c.drawImage(img, 18, 16, 16, 16, 100, 100, 64, 64); } else { c.drawImage(img, 0, 16, 16, 16, 100, 100, 64, 64); } } useframes(); </script>
关键修复说明
- 把绘制逻辑移到
useframes动画循环内,每次循环都重新绘制画面,确保number变化能同步到视觉上。 - 增加
isImgLoaded标记,保证图片加载完成后再开始绘制,解决移除load事件就无内容的问题。 - 用
clearRect清空画布,防止新帧叠在旧帧上导致画面混乱。 - 调整帧切换的条件判断,避免同一帧内
number来回切换。
内容的提问来源于stack exchange,提问作者Nguyen Tran
相关产品推荐
相关产品推荐

