I've been trying to make a simple game in HTML5/JS. I've managed to get a basic skeleton ready for the state machine and game loop, but even making a simple rectangle move around results in some 'tangible' choppiness.
What's more, after leaving it idle for some time (tabbing out), it seems to tick extremely fast, making a simple key-press move the rectangle far more than it should.
I'm using setTimeout for the game's updates. During each 'tick', I call the update function for the current state, which is
State.prototype.update = function(ms) {
this.ticks += ms;
var updates = 0;
while(this.ticks >= State.DELTA_TIME && updates < State.MAX_UPDATES) {
this.updateState();
this.updateFrameTicks += State.DELTA_TIME;
this.updateFrames++;
if(this.updateFrameTicks >= 1000) {
this.ups = this.updateFrames;
this.updateFrames = 0;
this.updateFrameTicks -= 1000;
}
this.ticks -= State.DELTA_TIME;
updates++;
}
if(updates > 0) {
this.renderFrameTicks += updates*State.DELTA_TIME;
this.renderFrames++;
if(this.renderFrameTicks >= 1000) {
this.rps = this.renderFrames;
this.renderFrames = 0;
this.renderFrameTicks -= 1000;
}
this.renderState(updates*State.DELTA_TIME);
}
};
The idea is to call Game.update as frequently as possible using setTimeout, and then pass the elapsed time to State.update. State.update will update the state, only if the time accumulated by the state is greater than or equal to the fixed update time-step. If the state is actually updated, State.update will also render/redraw the current state, ensuring that the state presentation matches the state simulation.
Now, I know that requestAnimationFrame works better than setTimeout, but theoretically the current version should work, unless I've made a fundamental mistake.
This is what I have so far: http://jsbin.com/ogicec/1 (Edit)
You can clearly observe that it has fits of choppiness, and if you tab out for a long period and come back in, it seems to be running 'faster' than normal.
I can't really pinpoint what the problem is, so help would be really appreciated!
EDIT:
I separated my update and render parts for the state, using setTimeout for update and requestAnimationFrame for render. It took care of the tabbing out problem, and the whole thing feels more consistent. But, at the same time, the performance is still choppy and I'd like to ensure it is smooth enough before going on to add more game related code.
Here is the updated JSBin: http://jsbin.com/eyarod/1 (Edit)
setInterval(and I guesssetTimeout) to running once per second, so you may havesetTimeoutoperations that were throttled and are now finally getting to run.setTimeout()usewindow.requestAnimationFrame()it will give you ~60fps and only runs when the tab is being rendered. so if you click to another tab or if the browser is minimized it will not be running.setTimeout()is running all the time eating up valuable CPU cycles when the user may not even have the window showing. Don't upset your user by slowing down the users computer.