为图像进行平滑运动的最佳方法

时间:2012-12-28 22:55:48

标签: javascript drawing html5-canvas

我写了一个快速程序,在屏幕上反弹一个球。一切正常,但图像容易闪烁而且不平滑。

我怀疑图像闪烁是因为屏幕底部的速度非常明显。

我想知道是否有人对如何插入球的运动以减少闪烁有任何想法。

被要求更新职位

      this.step = function()
      {
        thegame.myface.y = thegame.myface.y + thegame.myface.vSpeed;
        if (thegame.myface.y > thegame.height)
        {
        thegame.myface.vSpeed = -thegame.myface.vSpeed;
        }
        else
        {
        thegame.myface.vSpeed = thegame.myface.vSpeed + 1;
        }
      }
  },

被叫重绘

draw: function()
      {
          //clears the canvas
          thegame.ctx.clearRect(0,0,thegame.width,thegame.height);
          //draw the objects
          thegame.ctx.drawImage(thegame.imgFace,this.x-this.width/2,this.y-this.height/2);
          return;
      },

index.html

中调用框架
<script type="text/javascript">
thegame.init(450,450);
// http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
(function()
 {
 var lastTime = 0;
 var vendors = ['ms', 'moz', 'webkit', 'o'];
 for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x)
 {
 window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
 window.cancelRequestAnimationFrame = window[vendors[x]+'CancelRequestAnimationFrame'];
 }
 if (!window.requestAnimationFrame)
 {
 var f = function(callback, element)
 {
 var currTime = new Date().getTime();
 var timeToCall = Math.max(0, 16-(currTime-lastTime));
 var id = window.setTimeout(function()
     {
     callback(currTime+timeToCall);
     }, timeToCall);
 lastTime = currTime+timeToCall;
 return id;
 };
window.requestAnimationFrame = f;
 }
if (!window.cancelAnimationFrame)
    window.cancelAnimationFrame = function(id)
    {
        clearTimeout(id);
    };
 }());
(function gameloop()
 {
 thegame.update();
 requestAnimationFrame(gameloop);
 thegame.draw();
 })();
</script>

编辑thegame

的定义
   init: function(width, height)
   {
       var canvas = $("<canvas width='"+width+"' height='"+height+"'></canvas>");
       canvas.appendTo("body");
       thegame.ctx = canvas.get(0).getContext("2d");
       thegame.width = width;
       thegame.height = height;
       thegame.imgFace = new Image();
       thegame.imgFace.src = "face.png";
       thegame.myface = new thegame.makeFace(width/2,height/2);
   },

2 个答案:

答案 0 :(得分:0)

这是关于视觉感知。首先要了解浏览器通过requestanimationframe调用游戏循环的速率。如果是Chrome,它的任务管理器会提供帮助。如果不是,请使用时间戳自行计算费率。它应该至少每秒60次。如果浏览器以此速率运行并且移动仍然不平滑,则速度对于该速率来说太高了。

但是,您可以选择欺骗动作。一种是使图像更小(简单),另一种是运动模糊(复杂)。要做到后者,你基本上以双倍速度隐藏游戏并在可见画布上绘制两个混合帧。或者以相同的速度和更简单的方式,跟踪最后两个图像并在画布上以50%alpha绘制。如果你想要更多背景信息,请按照讨论为什么最新的霍比特人电影是以48而不是通常的每秒24帧拍摄的。

如果图像被水平切割/切成两半,则浏览器未正确同步到显示器。在这种情况下,请确保系统或显示选项不会覆盖垂直同步(vsync)。

答案 1 :(得分:0)

你的帆布有多大?不确定它是否能解决您的闪烁问题,但您可以尝试的另一个优化是修改您的clearRect()调用,以便在每次更新之前清除脏区域。

Ex:thegame.ctx.clearRect(this.x-this.width / 2,this.y-this.height / 2,thegame.imgFace.width,thegame.imgFace.height);