FrameRate gets slow over time

Hello my friends, I’m having trouble with the speed of my program.
I set the default speed to 60 fps, but over time the increment of my variable “time” is slowly increasing.
I wonder how I could solve this “bug”.
I already called setup (), but it did not work.
Maybe I can solve it if there is any code that totally resets the sketch.
Below is my code.

<html>
<head>
<title>Semáfaro</title>
</head>
<body>


<script src="https://cdnjs.cloudflare.com/ajax/libs/processing.js/1.6.6/processing.min.js"></script>
<script type="text/processing" data-processing-target="processing-canvas">

var vermelho;
var laranja;   
var verde;
var tempo;  
 
void setup() {
 size(1300, 400);
 background(255); 
 frameRate(60);
 
 tempo = 0;
 vermelho = false;
 laranja = false;   //Colocamos todas as cores como false.
 verde = false; 
}


// Criamos o projeto do que seria um Semáfaro, onde guardaremos as cores vindo como true/false
var Semafaro = function(vermelho, laranja, verde){
     this.vermelho = vermelho;
     this.laranja = laranja;
     this.verde = verde;
};

//Aqui criamos o método para inicialmente desenhar nosso Semáfaro
Semafaro.prototype.draw = function() {
        
        //Declaramos um array para guardarmos as cores
        var cores = []; 
        
        //Se a cor vermelha vier como true, então guardamos a cor vermelha, se não guardaremos a cor de desligado, sendo ela preta.
        if(this.vermelho){
            cores.push(255);
            cores.push(0);
            cores.push(0);
        }else{
            cores.push(5);
            cores.push(5);
            cores.push(5);
        }
        
        //Se a cor verde vier como true, então guardamos a cor laranja, se não guardaremos a cor de desligado, sendo ela preta.
        if(this.laranja){
            cores.push(237);
            cores.push(76);
            cores.push(7);  
        }else{
            cores.push(5);
            cores.push(5);
            cores.push(5);
        }
    
    //Se a cor verde vier como true, então guardamos a cor verde, se não guardaremos a cor de desligado, sendo ela preta.
        if(this.verde){
            cores.push(15);
            cores.push(235);
            cores.push(7);  
        }else{
            cores.push(5);
            cores.push(5);
            cores.push(5);  
        }
        
    
        
        fill(13, 12, 12);

        rect(800,100,100,190);
        strokeWeight(15);
        line(850,100,850, 0);
        
        //Essa parte é a parte onde colocamos as cores que foram adicionadas ao nosso array de cores
        fill(cores[6], cores[7], cores[8]);
        ellipse(850,260,40,40);
        
        
        fill(cores[3], cores[4], cores[5]);
        ellipse(850,200,40,40);
        
        
        fill(cores[0], cores[1], cores[2]);
        ellipse(850,140,40,40);
};


//Esse nosso método é para ligar o nosso Semáfaro
Semafaro.prototype.ligar = function(){
        
        //Se o tempo for acima de 1000, 'ligue' o vermelho.
        if(tempo > 0){ 
		    this.verde = false;
            this.vermelho = true;			
            this.laranja = false;
        }
        
        //Se o tempo for acima de 3000, 'ligue' o laranja e 'apague' o vermelho.
        if(tempo > 300){ 
		    this.verde = false;
            this.vermelho = false;
            this.laranja = true;
        }
        
        //Se o tempo for acima de 5000, 'ligue' o verde e 'apague' o laranja.
        if(tempo > 600){
			this.verde = true;		
            this.laranja = false;
			this.vermelho = false;            
        }
        
        //Se o tempo for acima de 7000, reiniciaremos a nossa apresentação do Semáfaro
        if(tempo === 900){
            this.desligar(); //Usamos o método interno para desligar nosso Semáfaro.
        }
        
        //Aqui mostramos o nosso tempo.
		println("Tempo em Segundos:");
        println(tempo);
        
};

//Aqui esta o nosso método para desligar o nosso Semáfaro
Semafaro.prototype.desligar = function(){
        setup();		
};

//Parte da Criação dos objetos, onde criamos o nosso Semáfaro, inicialmente desligado.
var semafaro1 = new Semafaro(vermelho,laranja,verde);


//Aqui criamos uma função para  executar o nosso método do Semafaro para o desenhar.
var desenharCena = function (){
    semafaro1.draw(); 
};


//Essa função draw é a função especial da biblioteca
draw = function() {	 
     desenharCena(); //Iniciamos o nosso Cenario.
     semafaro1.ligar(); //Ligamos o nosso semafaro.
     tempo++; //E devido a essa função especial e ao ++, o tempo vai aumentando em +1.
};







</script>
<canvas id="processing-canvas" width="800" height="auto"> </canvas>
</body>
</html>

What does your code do? Can you host it in codepen please?
Do you have a clue where the problem could be?

Kf

1 Like

You have a variable tempo and you are incrementing it in draw() – this is the same thing as the built-in variable frameCount.

However, the frame count is not the same thing as the precise elapsed time – it is approximately 60fps, but may drift a little, or a lot, or experience dramatic lags on certain frames.

If you need to compute things compared to the wall clock, use millis() and check the elapsed number of milliseconds. Also read the reference entries under IO > Time & Date

If you will be checking many times, always compute the latest offset from the program start time – don’t compute a recent interval, otherwise you will get the very same drifting behavior.

3 Likes

Thank you very much, I think only using this to solve.
Despite this resolution, I believe this is a bug, because by the time I define frameRate (60), this should force it to 60, but this does not occur, ie it does not deliver what it promises.

It would be great if it worked that way.

This is not a bug in p5.js – frameRate() defines a maximum throttled rate, not a minimum or exact rate. It would be a bug if you set frameRate(60) and got fps=90. The Processing(Java) API works the same way.

Specifies the number of frames to be displayed every second. For example, the function call frameRate(30) will attempt to refresh 30 times a second. If the processor is not fast enough to maintain the specified rate, the frame rate will not be achieved. Setting the frame rate within setup() is recommended. The default rate is 60 frames per second. This is the same as setFrameRate(val). reference | p5.js

While I am not a JavaScript expert, my understanding is that p5.js does not define a minimum rate because it cannot – it is implemented on JavaScript, and JavaScript events and timing don’t work that way.

In general, FPS usually doesn’t work that way on major video games in other languages, either. There is no minimum. If your computer can calculate the contents of a given frame 60 times a second, or only 15 times, or 5 times, the program will do what it needs to do to calculate each frame – and then update the screen as soon as it is done if it is running late.

Common techniques for making the desired speed a sure thing are:

  1. make code more efficient (e.g don’t repeat calculations you don’t need to, do less in draw())
  2. reduce the amount of pixel data (e.g. use a smaller size())
  3. run the code on faster computer hardware
2 Likes

I have had the same problem in normal processing, not sure about p5.js, but you could try running clear(); at the top of the loop.

clear() will not improve frame rate in either Processing or p5.js.

It is for clearing the values of graphics buffers, that is, it sets a bunch of pixel values – it doesn’t e.g. clear objects or processes out of memory or do garbage collection etc.