Как я могу проверить fps моего javascript? Я использую это для цикла:
gameloopId = setInterval(gameLoop, 10);
Как я могу проверить fps моего javascript? Я использую это для цикла:
gameloopId = setInterval(gameLoop, 10);
В gameLoop
просмотрите разницу между new Date
и new Date
из последнего цикла (сохраните его в переменной).
Другими словами:
var lastLoop = new Date;
function gameLoop() {
var thisLoop = new Date;
var fps = 1000 / (thisLoop - lastLoop);
lastLoop = thisLoop;
...
}
thisLoop - lastLoop
- это число миллисекунд, прошедших между двумя циклами.
Код @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 кадров в секунду. Как вы можете видеть, более низкие значения фильтра более быстро отражают "хорошие" изменения, но также более подвержены временным иконам:
Наконец, вот пример использования приведенного выше кода для фактической проверки цикла игры.
Я использую это для вычисления 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');
}
}
Как насчет 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)
}
);