使用requestAnimationFrame在javascript中使用简单的30fps游戏循环?

时间:2017-02-03 07:49:21

标签: javascript frame-rate game-loop

我正在写一个纸牌游戏,所以我需要使用window.requestAnimationFrame设置一个基本的游戏循环。我需要将fps设置为30fps,因为它是一个节奏缓慢的纸牌游戏,我只需要一个简单可行的游戏循环。我的游戏循环如下。

function loop(timestamp) {
          var progress = timestamp - lastRender

          update(progress)
          draw()

          lastRender = timestamp
          window.requestAnimationFrame(loop)
        }
        var lastRender = 0
        window.requestAnimationFrame(loop)

我怎样才能使fps设置为30fps?我感谢任何帮助!谢谢!

2 个答案:

答案 0 :(得分:0)

FPS代表每秒帧数。

  

1000/30 = 30 fps

尝试这个基本功能:

function animate() {
  setTimeout(function() {
    requestAnimationFrame(animate);
  }, 1000 / 30);
}

答案 1 :(得分:0)

您应该simulatingdrawing分开。

以下是我每毫秒({1}}每毫秒(1000次)的例子。每个模拟都会取消之前的模拟。请求动画帧。

如果浏览器刷新了"勾选"它会有simulation我们的更新(增加我们的计数器)。

1秒钟后我停下来,我们应该将您的显示器刷新率大约视为drawn



count




编辑 - 为什么要分离关注点

在画布上绘图是一项昂贵的操作,如果可以避免,通常不希望在每一帧上运行。

当事情发生变化时,基本上只需要重新绘制。

在下面的示例中,我创建了大量的框,模拟它们并绘制它们:



//counter
var count = 0;
//draw function
function draw() {
    count++;
  }
  //Animation frame handle
var animationFramHandle;
//Run every millisecond
var interval = setInterval(function() {
  //Cancel requestAnimationFrame
  cancelAnimationFrame(animationFramHandle);
  //request new requestAnimationFrame
  animationFramHandle = requestAnimationFrame(draw);
}, 1);
//Wait 1 second
setTimeout(function() {
  //Stop simulation
  clearInterval(interval);
  cancelAnimationFrame(animationFramHandle);
  console.log("ticks in a second:", count);
}, 1000);




注意如何模拟它们比绘制它们更快。

根据经验,每帧之间只有//DOM elements var canvas = document.createElement("canvas"); canvas.width = 400; canvas.height = 400; document.body.appendChild(canvas); var ctx = canvas.getContext("2d"); ctx.fillStyle = "rgba(0,0,0,0.1)"; var drawNode = document.createElement("p"); document.body.appendChild(drawNode); //Variables var simulations = 0; var simulationTime = 0; var requestAnimationFrameHandle; //Boxes to simulate and draw var boxes = []; while (boxes.length < 10000) { boxes.push({ x: Math.random() * canvas.width, y: Math.random() * canvas.height, s: 5 }); } //Draw function function draw() { var t = Date.now(); //Clear ctx.clearRect(0, 0, canvas.width, canvas.height); //Draw for (var bIndex = 0; bIndex < boxes.length; bIndex++) { var box = boxes[bIndex]; ctx.fillRect(box.x, box.y, box.s, box.s); } //Log drawNode.innerHTML = ("New draw after " + simulations + " simulations<br>Drawing took " + (Date.now() - t) + " ms<br>Simulation time is " + simulationTime + " ms"); simulations = 0; } //Simulate function function simulate(force) { if (force === void 0) { force = false; } simulations++; if (Math.random() * 1000 > 800) { var t = Date.now(); for (var bIndex = 0; bIndex < boxes.length; bIndex++) { var box = boxes[bIndex]; box.x = Math.abs(box.x + (Math.random() * 3 - 1)) % canvas.width; box.y = Math.abs(box.y + (Math.random() * 3 - 1)) % canvas.height; } simulationTime = Date.now() - t; cancelAnimationFrame(requestAnimationFrameHandle); requestAnimationFrameHandle = requestAnimationFrame(draw); } } setInterval(simulate, 1000 / 120);毫秒,所以如果我们可以节省绘制所需的毫秒数,那么我们很乐意这样做并将这样的帧计算时间集中在更大的操作上(如寻路或碰撞检测或游戏中的任何重物)。

这样我们也可以以不同于绘制速率的速率运行我们的模拟,这在处理异步任务时很方便。