不同计算机上的游戏循环速度不同

时间:2017-11-29 20:42:01

标签: javascript

所以我正在制作一个javascript游戏。我有这个基本的游戏循环引擎。

var left = 0,
    speed = documentHeight/300;

var keyState = {};
window.addEventListener('keydown',function(e){
    keyState[e.keyCode || e.which] = true;
},true);    
window.addEventListener('keyup',function(e){
    keyState[e.keyCode || e.which] = false;
},true);

function gameLoop() {
  if (keyState[39]) {
     left -= speed;
     move();
  }
  if (keyState[37]){
     left += speed;
     move();
  }

  function move() {
     element.style.left = left + 'px';
  }

  setTimeout(gameLoop, 20);
}
gameLoop();

我拥有100%高度的全部因此我相对于文档高度设置了速度。它在我的电脑上运行得很好,即使在调整大小时它也是一致的。但是当我在iMac上测试它时,元素移动得慢得多。我也尝试过window.requestAnimationFrame(gameLoop),但同样的事情发生了。

这是否与处理更多fps的某些屏幕有关?在所有计算机/屏幕上实现一致速度的最佳方法是什么?

1 个答案:

答案 0 :(得分:2)

每帧20毫秒,即50 fps。这不是超高,但它可以在较慢的计算机上放慢速度(因为它无法跟上)。

更安全的方法是仍以所需的帧速率运行它,然后检查帧之间的时间差值,并根据经过的实际时间进行移动,而不是假设一个恒定的FPS。

这样做的简单方法就是记录每个循环的最后一次,然后从当前时间中减去并根据时间量按某种因素缩放,例如:

所以我正在制作一个javascript游戏。我有这个基本的游戏循环引擎。

var left = 0,
    speed = documentHeight/300,
    lastTime = Date.now();

var keyState = {};
window.addEventListener('keydown',function(e){
    keyState[e.keyCode || e.which] = true;
},true);    
window.addEventListener('keyup',function(e){
    keyState[e.keyCode || e.which] = false;
},true);

function gameLoop() {
  const currentTime = Date.now();
  const delta = currentTime - lastTime;
  lastTime = currentTime;

  if (keyState[39]) {
     left -= speed * delta;
     move();
  }
  if (keyState[37]){
     left += speed * delta;
     move();
  }

  function move() {
     element.style.left = left + 'px';
  }

  setTimeout(gameLoop, 20);
}
gameLoop();

然后,只需设置"速度"相对于每毫秒的值(例如每毫秒5px,或每毫秒屏幕高度的0.00033%)。通过这样做并乘以经过的时间,即使您的实际循环速度不是非常一致,您也可以获得更平稳的移动。

附加说明:有时,根据您的应用程序,您可能还想跟踪剩余部分。如果您正在做类似"每秒10px",但已经过了20ms,那就是10 / 1000 * 20 = 0.2px。由于您无法实际移动.2px,因此您可能需要跟踪剩余部分并将其重新添加到下一个循环中。

或者,您可以让您的位置为小数,并在draw()阶段解决它。这可能是一种更清洁的方法,而且我通常采用这种方法。