在我的游戏循环中框架抽搐

时间:2014-09-29 12:57:10

标签: html5 canvas 2d-games game-loop

我希望有人能够指出我的代码出了什么问题,因为我已经看了很长时间才发疯。我正在使用HTML5实现一个横向滚动的自动运行器,并遇到帧速率抖动的一些问题。它在我的Macbook Air上完美运行,在我的Nexus 4上几乎同样出色,但是当我部署到我的iPhone 4时,我注意到帧速率有些烦人的抽搐。请记住,我正在使用CocoonJS,因此Canvas性能应该没有问题。

我花了很多年时间调查可能出现的性能问题,但是当我退后一步时,它似乎比那些更基本的东西。似乎问题可能在于我的游戏循环本身。我创建了一个更基本的例子来重现我遇到的同样问题。这是快速而肮脏的代码,所以为此道歉,但它证明了我的问题。

通过查看http://www.koonsolo.com/news/dewitters-gameloop/comment-page-2/#comment-3877中的一个示例,我实现了一个游戏循环。我没有实现插值,因为我不认为这是基本的东西是必要的。为了更接近低端设备,我已经向控制台写了一个for循环写入(脏,我知道),所以打开web调试器我的Macbook Air上有30 UPS和~60FPS。

有时候,当帧速率下降时,我会经历这个帧抖动,屏幕上的移动块跳跃显着的数量。我的理解是,只要我的FPS保持在UPS之上,那么我就不应该注意到这种行为。要查看我的意思,只需取消注释for循环。

有人可以指出这里的问题是什么吗?或者如果这甚至是有效的测试?任何帮助非常感谢!

HTML

<!DOCTYPE html>

<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>setInterval Example</title>
<script type="text/javascript" charset="utf-8" src="./test.js"></script>
</head>
<body>
<canvas id="viewport" height="480" width="640"></canvas>

<script type="text/javascript" charset="utf-8">

  Game.initialize();

  Game.run = (function() {
    var loops = 0, skipTicks = 1000 / Game.ups,
        maxFrameSkip = 20,
        nextGameTick = (new Date).getTime();

    return function() {
      loops = 0;

      while ((new Date).getTime() > nextGameTick && loops < maxFrameSkip) {
        //for(var i = 0; i <= 250; i++) { console.log('test') }
        Game.update(); 
        nextGameTick += skipTicks;
        loops++;
        Game.logUpdate();

      }

      Game.draw();
      Game.drawFrames();
      Game.logFrame();
    };
  })();

  window.setInterval(Game.run, 0);
</script>
</body>
</html>

JS

////// GAME //////////
var Game = {};
Game.ups = 30;

Game.initialize = function() {
  this.frames = 0;  
  this.updates = 0;
  this.updatesPerSecond=0;

  this.blockA = new Rect(50, 50);
  this.blockB = new Rect(250, 50);
  this.blockC = new Rect(500, 50);

  this.context = document.getElementById("viewport").getContext("2d");
  this.context.font = "bold 18px Arial";

  this.previousUpdateTime = 0;
  this.previousTime = 0;
};

Game.draw = function() {
  this.context.clearRect(0, 0, 640, 480);
  this.blockA.draw(this.context);
  this.blockB.draw(this.context);
  this.blockC.draw(this.context);
};

Game.update = function() {
  this.blockA.update();
  this.blockB.update();
  this.blockC.update();
};

Game.logUpdate = function() {
    this.updates++;                    
    this.currentUpdateTime = new Date().getTime();

    if((this.currentUpdateTime - this.previousUpdateTime) >= 1000) {
        this.updatesPerSecond = this.updates;
        this.previousUpdateTime = this.currentUpdateTime;
        this.currentUpdateTime = 0;
        this.updates = 0;   
    }
};

Game.logFrame = function(){
  this.frames++;                
  this.currentTime = new Date().getTime();

  if((this.currentTime - this.previousTime) >= 1000) {
    this.fps = this.frames;
    this.previousTime = this.currentTime;
    this.currentTime = 0;
    this.frames = 0;        
  }
};

Game.drawFrames = function() {
  this.context.fillText("UPS: " + this.ups, 20, 180);
  this.context.fillText("FPS: " + this.fps, 20, 150);
};
//////// RECT ///////////
function Rect(x, y) {
  this.x = x;
  this.y = y;
  this.velocity = -4;
};

Rect.prototype.draw = function(context) {
  context.fillRect(this.x, this.y, 30, 30);
};

Rect.prototype.update = function() {
  if (this.x < -30) {
    this.x = 640;
  } 

  this.x += this.velocity;
};

0 个答案:

没有答案