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)