You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Canvas实现Goomba行走动画遇问题:值变化但图像静止

问题根源与解决方案

你的代码核心问题是:绘制动作只在图片加载完成时执行了一次,之后number虽然在动画循环里切换,但没有触发重新绘制,所以画面一直停留在第一帧。

具体问题点

  1. img.addEventListener('load', ...)里的绘制代码只运行一次,图片加载完就不会再执行了,后续number变化无法更新画面。
  2. 动画循环useframes只负责切换number,没有包含绘制逻辑。
  3. 第二段代码里的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 12:42:08