Somehow deltaTime
is usually 0.01667s (60fps) even though targetFrameRate
is 30 (0.03333s), and yes targetFrameRate
is working(adding delay). This makes movement code not work as intended with the specified fps when it is greater than or less than 60, making velocity * deltaTime
broken.
Problem: deltaTime
is always in 60fps and is not affected by targetFrameRate
Here's my code
// Initializes the game loop
window.onload = () => {
PlayerLoop.init();
};
// Gets called every frame
function Update ()
{
console.log(Time.deltaTime);
}
// The specified fps
const targetFrameRate = 30;
// Class that holds time
class Time
{
static unscaledTime = 0;
static unscaledDeltaTime = 0;
static timeScale = 1;
static frameCount = 0;
static time = 0;
static deltaTime = 0;
static maximumDeltaTime = 0.3333333;
}
// Game loop class
class PlayerLoop
{
static #accumulator = 0;
static #requestUpdate ()
{
requestAnimationFrame(this.#update.bind(this));
}
static #update ()
{
Time.unscaledDeltaTime = (performance.now() / 1000) - Time.unscaledTime;
Time.unscaledTime += Time.unscaledDeltaTime;
var deltaT = Time.unscaledDeltaTime;
if (deltaT > Time.maximumDeltaTime) deltaT = Time.maximumDeltaTime;
Time.deltaTime = deltaT * Time.timeScale;
Time.time += Time.deltaTime;
this.#accumulator += Time.deltaTime;
while (this.#accumulator >= 1 / (targetFrameRate))
{
Time.frameCount++;
Update();
this.#accumulator -= 1 / (targetFrameRate);
}
// Render
this.#requestUpdate();
}
static init ()
{
this.#requestUpdate();
}
}
I've fixed it thanks to Annas
My code was missing another delta time that will tell when to update the global Time.deltaTime
variable
Here's My New Code
// Initializes the game loop
window.onload = () => {
PlayerLoop.init();
};
// Gets called every frame
function Update ()
{
console.log(Time.deltaTime);
}
// The specified fps
const targetFrameRate = 30;
// Class that holds time
class Time
{
static unscaledTime = 0;
static unscaledDeltaTime = 0;
static timeScale = 1;
static frameCount = 0;
static time = 0;
static deltaTime = 0;
static maximumDeltaTime = 0.3333333;
}
// Game loop class
class PlayerLoop
{
static #requestUpdate ()
{
requestAnimationFrame(this.#update.bind(this));
}
static #update ()
{
// Frame rate - anti delay value
const slice = (1 / targetFrameRate) - 0.005;
// This is the "other delta time"
let accumulator = (performance.now() / 1000) - Time.unscaledTime;
while (accumulator >= slice)
{
Time.unscaledDeltaTime = (performance.now() / 1000) - Time.unscaledTime;
Time.unscaledTime += Time.unscaledDeltaTime;
let deltaT = Time.unscaledDeltaTime;
if (deltaT > Time.maximumDeltaTime) deltaT = Time.maximumDeltaTime;
Time.deltaTime = deltaT * Time.timeScale;
Time.time += Time.deltaTime;
Time.frameCount++;
Update();
accumulator -= slice;
}
// Render
this.#requestUpdate();
}
static init ()
{
this.#requestUpdate();
}
}
I have removed PlayerLoop.#accumulator
and added accumulator
as the "other delta time". Then I moved all of the Time
update code to the inside of the while loop.
Thank you for everyone who helped