Come verifico il fps del mio javascript? Sto usando questo per ciclo:Controllare l'FPS in JS?
gameloopId = setInterval(gameLoop, 10);
Come verifico il fps del mio javascript? Sto usando questo per ciclo:Controllare l'FPS in JS?
gameloopId = setInterval(gameLoop, 10);
In gameLoop
, guarda la differenza tra new Date
e new Date
dall'ultimo ciclo (memorizzarlo in una variabile).
In altre parole:
var lastLoop = new Date;
function gameLoop() {
var thisLoop = new Date;
var fps = 1000/(thisLoop - lastLoop);
lastLoop = thisLoop;
...
}
thisLoop - lastLoop
è il numero di millisecondi che passano tra i due anelli.
Il codice di @Slaks fornisce solo l'FPS istantaneo dell'ultimo frame, che può variare o essere fuorviante con singhiozzo. Preferisco usare un filtro passa-basso di facile write-and-elaborazione per rimuovere transienti veloci e visualizzare una pseudo-media ragionevole di risultati recenti:
// 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);
Il 'emivita' di questo filtro il numero dei fotogrammi necessari per spostarsi a metà strada dal vecchio valore in un nuovo valore stabile: è filterStrength*Math.log(2)
(circa il 70% della forza).
Ad esempio, un punto di forza di 20
si sposterà a metà strada ad una variazione istantanea 14 fotogrammi, 3/4 del tragitto in 28 fotogrammi, il 90% del tragitto in 46 cornici, e il 99% del tragitto in 92 frame. Per un sistema che gira a circa 30fps, un improvviso, drastico cambiamento nelle prestazioni sarà ovvio in mezzo secondo, ma continuerà a "buttare via" le anomalie a frame singolo in quanto modificheranno il valore solo del 5% della differenza.
Ecco un confronto visivo di diverse intensità del filtro per un gioco a ~ 30 fps che ha un calo momentaneo a 10 fps e successivamente aumenta la velocità a 50 fps. Come si può vedere, i valori del filtro inferiori riflettono in modo più rapido 'buoni' i cambiamenti, ma sono anche più sensibili a singhiozzo temporanei:
Infine, ecco an example di utilizzare il codice per realtà di riferimento un ciclo 'gioco' di cui sopra .
Grafica molto bella! Come hai fatto? –
@BennyNeugebauer Quanto sopra è stato creato in Excel, solo perché è stato leggermente più facile per una tantum di [utilizzando HTML5 Canvas per una grafica abbastanza IIR] (http://phrogz.net/js/framerate-independent-low-pass- filter.html). – Phrogz
C'è qualche ragione per cui ottengo fps infiniti quando si utilizza il frame di animazione della richiesta. Sto usando una forza filtro di 1 per l'FPS più accurato? accade di tanto in tanto (Fps infiniti): http: // jsfiddle.net/CezarisLT/JDdjp/10/ – Kivylius
Io lo uso per il calcolo 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');
}
}
Che dire 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)
}
);
sto ottenendo fps: -1295907214150 sto usando fps come globale Edit: si fa la stessa cosa come un var locale -12 e roba – CyanPrime
@Cyan: Ho dimenticato di aggiungere parentesi; scusa. Dovrebbe funzionare ora. – SLaks
Ha funzionato, grazie mille. – CyanPrime