3

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

我怀疑图像闪烁是因为屏幕底部的速度很大。

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

调用更新位置

      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);
   },
4

2 回答 2

0

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

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

于 2012-12-30T19:12:19.197 回答
0

这是关于视觉感知的。首先找出浏览器通过 requestanimationframe 调用游戏循环的速率。如果是 Chrome,它的任务管理器会有所帮助。如果没有,请使用时间戳自己计算费率。它应该至少每秒60次。如果浏览器以这个速度运行并且移动仍然不流畅,那么速度对于那个速度来说太高了。

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

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

于 2012-12-29T14:42:10.067 回答