当我尝试在HTML5 Canvas中移动时,PNG图像不稳定

时间:2016-08-24 18:42:37

标签: javascript html5-canvas png

因此,当我来到时,我正在使用HTML5 Canvas和纯Javascript进行游戏 在一个恼人的问题。当我尝试使用setInterval移动我的图片移动时,它可以工作,但图片会像它的波动一样抽搐。我的猜测是它与图像需要每10毫秒加载的事实有关。请帮我解决这个问题。

以下示例代码:

<!DOCTYPE html>
<html>
    <head>
        <title></title>
        <meta charset = "UTF-8" />
    </head>
    <body>
        <canvas id = "myCanvas" width = "1000" height = "500" style="border:1px solid #000000;">
        </canvas>
        <script type = "text/javascript">
            var canvas = document.getElementById("myCanvas");
            var ctx = canvas.getContext("2d");
            var x = 0;
            var image = new Image();
            image.src = 'spaceship.png';

            function draw(){
                ctx.clearRect(0, 0, canvas.width, canvas.height);
                image.src = 'spaceship.png';
                image.onload = function(){
                    ctx.drawImage(image, x, 0);
                }
                x += 2;
            }
            setInterval(draw,10);
        </script>
    </body>
</html> 

1 个答案:

答案 0 :(得分:4)

首先,10ms的间隔太短了。即使使用60fps,你的间隔也会达到~16.67ms。

此外,如果可用,您在制作动画时不应使用setInterval,而应使用requestAnimationFrame。这应该会在支持它的浏览器上产生更平滑的动画。

最后应该优化的是你每帧移动图像2px的事实。您无法确定在相同的时间间隔后调用每个帧。像这样你可以在快速计算机上使用更快的动画,在慢速计算机上使用慢动画。您应该使用自上次动画帧以来经过的当前时间和时间增量(例如使用Date.now()

最后要注意的是,图像的onload回调应该只调用一次。并且在执行任何动画或绘图之前。因此,只有在加载图像后,动画才会开始。

移动球的示例:

&#13;
&#13;
var canvas = document.getElementById("canvas"),
    ctx = canvas.getContext("2d"),
    lastTimestamp,
    imageX = 0;

canvas.width = 300;
canvas.height = 300;

var image = new Image();
image.onload = function () {
  requestAnimationFrame(draw);
};
image.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAMAAADzapwJAAAAolBMVEUAAAARqu4YrO4bre4aq+wbrOocrOocq+sbreobquocrOkcrOobq+oaqugdresir+sosewus+w0te01tu06t+0+ue4/ue5GvO5Ov+9cxPBfxfFoyPFwy/J0zPJ4zvN6z/OA0fSE0vSG0/SJ1PSQ1vWR1/WT1/WV2PWY2faZ2vad2/ai3fej3fel3ven3/ev4vix4/i45vm65vm85/m+6PnA6fpEpw5TAAAADnRSTlMADx8vX29/j5+vv8/f79ErPTAAAADdSURBVBgZBcELThsxFADAef5sQkAVEr3/JcsSNrafOxNAKT2wRyYIiFsPwB7XRqC+FY9Smpnjks9FEO/l7c8BOP+NPLfKe/34qgDHx5VtqI7j9hcQrdV9/917lbj5BGhHa618ukVp8TgAGpr7I1rpDgAbyaGXagMYyxpstYUyOmAtuIpouFavAOYr0XZkmbO2FthzJGm31ebBWhcA0yrDAgBYRlmuBADmr1XytU8AkKdXVqvvbAFgnplPldVz9gDM79zPVNmjuUTBvH6sMwmIewdwvTYCqL0H9msk+A8oZ3I4nbdKXwAAAABJRU5ErkJggg==";

function draw() {
  var now = Date.now(),
      timeDelta = (now - (lastTimestamp || now)) / 1000; // in seconds
  imageX += timeDelta * 30; // meaning: 30px per second
  
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.drawImage(image, imageX, 0);
  
  lastTimestamp = now;
  requestAnimationFrame(draw);
}
&#13;
<canvas id="canvas" />
&#13;
&#13;
&#13;