Hi, I am working in P5.JS and I am trying to achieve multiple frame rates for multiple animations that can have any framerate between 1FPS to 30FPS.
Here is the main question: How to keep the master FPS at frameRate(30) and then have any number of animations be at any FPS between 1-30.
The mod function will allow me to get a few divisions of FPS but this is not good enough as it goes from 30FPS and then 15FPS and that’s a huge difference in speed:
if (frameCount % 2)
// Animate every other frame ~15FPS
if (frameCount % 3)
// Animate one frame out of three
https://p5js.org/reference/#/p5/millis
So there is the timer function in milliseconds which seems like a perfect solution to achieve any FPS I want, but it simply does not keep up with 30FPS, where the same code with no timer and the standard 30 FPS runs perfectly. So it seems this method is not usable for animations?
And then there is deltaTime but I have not been able to figure it. From its description it seems to be exactly what I need but the example on the website is about moving an object on the screen at different rates vs I need the ability to change the state of an object at any FPS , like the background color, as shown in my example code.
The code provided is a simplified version of the main code but it represents the problem well. I’m interested in how else this can be done or if I’m missing something!
Thanks,
4D
let snowflakes = []; // array to hold snowflake objects
let backgroundColor;
let colorflip = true;
let frameRateManager;
let intervalMillis;
let desiredFrameRate = 2;
let FRAMERATEGLOBAL = 30;
function setup() {
createCanvas(400, 600);
fill(240);
noStroke();
frameRate(FRAMERATEGLOBAL)
frameRateManager = new FrameRateManager()
backgroundColor = color('red');
intervalMillis = 33
}
function draw() {
setTimeout(function runFlow() {
if(colorflip) {
backgroundColor = color('pink');
colorflip = false;
} else {
backgroundColor = color('cyan');
colorflip = true;
}
}, intervalMillis);
let t = frameCount / 60; // update time
// create a random number of snowflakes each frame
for (let i = 0; i < random(5); i++) {
snowflakes.push(new snowflake()); // append snowflake object
}
// loop through snowflakes with a for..of loop
// FrameRateManager using mod to control when to make changes at a particular frame rate (or as close as possible)
// if(frameRateManager.drawDesiredFPS(desiredFrameRate)) {
// if(colorflip) {
// backgroundColor = color('pink');
// colorflip = false;
// } else {
// backgroundColor = color('cyan');
// colorflip = true;
// }
//}
background(backgroundColor);
for (let flake of snowflakes) {
flake.update(t); // update snowflake position
flake.display(); // draw snowflake
}
}
// snowflake class
function snowflake() {
// initialize coordinates
this.posX = 0;
this.posY = random(-50, 0);
this.initialangle = random(0, 2 * PI);
this.size = random(2, 5);
// radius of snowflake spiral
// chosen so the snowflakes are uniformly spread out in area
this.radius = sqrt(random(pow(width / 2, 2)));
this.update = function(time) {
// x position follows a circle
let w = 0.6; // angular speed
let angle = w * time + this.initialangle;
this.posX = width / 2 + this.radius * sin(angle);
// different size snowflakes fall at slightly different y speeds
this.posY += pow(this.size, 0.5);
// delete snowflake if past end of screen
if (this.posY > height) {
let index = snowflakes.indexOf(this);
snowflakes.splice(index, 1);
}
};
this.display = function() {
ellipse(this.posX, this.posY, this.size);
};
}
class FrameRateManager {
constructor() {
this.currentFrame = 0
}
drawDesiredFPS(desiredFrameRate) {
this.incrementCurrentFrame();
var fpsMod = FRAMERATEGLOBAL / desiredFrameRate;
return ((this.currentFrame % (Math.round(fpsMod))) === 0 && (this.currentFrame != 0)) ? true : false;
}
incrementCurrentFrame() {
(this.currentFrame >= FRAMERATEGLOBAL) ? (this.currentFrame = 0) : (this.currentFrame += 1);
}
}```