Подтвердить что ты не робот

Проверить FPS в JS?

Как я могу проверить fps моего javascript? Я использую это для цикла:

gameloopId = setInterval(gameLoop, 10);
4b9b3361

Ответ 1

В gameLoop просмотрите разницу между new Date и new Date из последнего цикла (сохраните его в переменной).
Другими словами:

var lastLoop = new Date;
function gameLoop() { 
    var thisLoop = new Date;
    var fps = 1000 / (thisLoop - lastLoop);
    lastLoop = thisLoop;
    ...
}

thisLoop - lastLoop - это число миллисекунд, прошедших между двумя циклами.

Ответ 2

Код @Slaks дает вам только мгновенный FPS последнего кадра, который может меняться или вводить в заблуждение с помощью икоты. Я предпочитаю использовать простой для записи и вычисления фильтр нижних частот для удаления быстрых переходных процессов и отображения разумного псевдосредства последних результатов:

// The higher this value, the less the fps will reflect temporary variations
// A value of 1 will only keep the last value
var filterStrength = 20;
var frameTime = 0, lastLoop = new Date, thisLoop;

function gameLoop(){
  // ...
  var thisFrameTime = (thisLoop=new Date) - lastLoop;
  frameTime+= (thisFrameTime - frameTime) / filterStrength;
  lastLoop = thisLoop;
}

// Report the fps only every second, to only lightly affect measurements
var fpsOut = document.getElementById('fps');
setInterval(function(){
  fpsOut.innerHTML = (1000/frameTime).toFixed(1) + " fps";
},1000);

"halflife" этого фильтра - количество кадров, необходимых для перехода на полпути от старого значения к новому, стабильному значению - это filterStrength*Math.log(2) (примерно 70% от силы).

Например, сила 20 будет перемещаться на полпути к мгновенному изменению в 14 кадрах, 3/4 пути в 28 кадрах, 90% пути в 46 кадрах и 99% пути там в 92 кадрах. Для системы, работающей со скоростью около 30 кадров в секунду, внезапный резкий сдвиг в производительности будет очевидным через полсекунды, но все равно "выбросит" однокадровые аномалии, поскольку они будут сдвигать значение всего на 5% от разницы.

Вот визуальное сравнение различных сильных фильтров для игры с частотой 30 кадров в секунду, которая мгновенно падает до 10 кадров в секунду, а затем ускоряет скорость до 50 кадров в секунду. Как вы можете видеть, более низкие значения фильтра более быстро отражают "хорошие" изменения, но также более подвержены временным иконам:
enter image description here

Наконец, вот пример использования приведенного выше кода для фактической проверки цикла игры.

Ответ 3

Я использую это для вычисления fps

  var GameCanvas = document.getElementById("gameCanvas");
  var GameContext = doContext(GameCanvas,"GameCanvas");
  var FPS = 0;
  var TimeNow;
  var TimeTaken;
  var ASecond = 1000;
  var FPSLimit = 25;
  var StartTime = Date.now();
  var TimeBefore = StartTime;
  var FrameTime = ASecond/FPSLimit;
  var State = { Title:0, Started:1, Paused:2, Over:3 };
  var GameState = State.Title;

  function gameLoop() {
    requestAnimationFrame(gameLoop);
    TimeNow = Date.now();
    TimeTaken = TimeNow - TimeBefore;

    if (TimeTaken >= FrameTime) {
      FPS++
      if((TimeNow - StartTime) >= ASecond){
        StartTime += ASecond;
        doFPS();
        FPS = 0;
      }

      switch(GameState){
        case State.Title :
          break;
        case State.Started :
          break;
        case State.Paused :
          break;
        case State.Over :
          break;
      }
      TimeBefore = TimeNow - (TimeTaken % FrameTime);
    }
  }

  Sprites.onload = function(){
    requestAnimationFrame(gameLoop);
  }

  function drawText(Context,_Color, _X, _Y, _Text, _Size){
    Context.font =  "italic "+ _Size +" bold";
    Context.fillStyle = _Color;
    Context.fillText(_Text, _X, _Y);
  }

  function doFPS()(
    drawText(GameContext,"black",10,24,"FPS : " + FPS,"24px");
  }

  function doContext(Canvas,Name){
    if (Canvas.getContext) {
      var Context = Canvas.getContext('2d');
      return Context;
    }else{
      alert( Name + ' not supported your Browser needs updating');
    }
  }

Ответ 4

Как насчет requestAnimationFrame?

var before,now,fps;
before=Date.now();
fps=0;
requestAnimationFrame(
    function loop(){
        now=Date.now();
        fps=Math.round(1000/(now-before));
        before=now;
        requestAnimationFrame(loop);
        console.log("fps",fps)
    }
 );