I have a javascript game that will run really fast on some computers and really slow on others. I've been doing some research and I've found that I need to update my loop based on time, but I can't seem to find any good examples of this for javascript. Can someone point me to the right direction on how to get a game to run at 30fps on any hardware?
Thanks
Normally games work from a Delta Time, that is, the amount of time since the last frame was rendered.
Psuedocode (roughly C#):
DateTime lastFrameTimeStamp = DateTime.Now;
void Draw()
{
TimeSpan timeSinceLastFrame = DateTime.Now.Subtract(lastFrameTimeStamp);
float deltaTime = timeSinceLastFrame.TotalSeconds;
// Do all of your movement and other time-based math based on the deltaTime, Like:
float x = x + (MovementPerSecond * deltaTime);
lastFrameTimeStamp = DateTime.Now;
}
Using a Delta Time prevents all dependency on CPU power or how often frames get drawn.
You can't force a game to run at 30fps if the hardware is unable achieve it. If what it is doing is taking more than 1/30th of a second, you're out of luck.
You can use requestAnimationFrame to let it run as fast as it can though. See here: http://paulirish.com/2011/requestanimationframe-for-smart-animating/
You could have a timer function which you can measure how long you are executing for, then call back to yourself at your ((required interval) - (execution time)), in pseudo code
function timer(){
var timeStart = new Date();
// Your stuff
setTimeout (timer, (1000/30) - (new Date() - timeStart));
}
What you are looking for is a simple implementation of delta timing in JavaScript. Implememting it in JavaScript is a relatively simple task. In fact it's so simple that it can be achieved in less than 25 lines of code (stripping out blank lines and comments):
function DeltaTimer(render, interval) {
var timeout;
var lastTime;
this.start = start;
this.stop = stop;
function start() {
timeout = setTimeout(loop, 0);
lastTime = Date.now();
return lastTime;
}
function stop() {
clearTimeout(timeout);
return lastTime;
}
function loop() {
var thisTime = Date.now();
var deltaTime = thisTime - lastTime;
var delay = Math.max(interval - deltaTime, 0);
timeout = setTimeout(loop, delay);
lastTime = thisTime + delay;
render(thisTime);
}
}
Using it is even more simple. Let's learn by example:
var timer = new DeltaTimer(render, 1000 / 30);
var start = timer.start();
var body = document.body;
var frame = 0;
function render(time) {
time -= start;
body.innerHTML += (frame++) + ". " + time + " ms<br/>";
if (time >= 1000) {
var stop = timer.stop() - start;
body.innerHTML += "<br/>" + stop + " ms (stopped)";
}
}
I think the code is pretty self explanatory. For the live demo click on this link.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With