Skip to main content
added 515 characters in body
Source Link
GameAlchemist
  • 1.4k
  • 7
  • 10

To allowFirst Rq : A key rule in Javascript : avoid system lag, with a very simple principle : do not feed the game to pausegarbage collector.
So : Reuse your Arrays, do not create closures, use integers and evennot strings, pool your objects, ... a lot of simple rules too long to go faster orexplain in a few words.

Now that you've done that, to avoid a slow-motiondown/ fast forward behaviour, you have to to to handle the time and timers by yourself. And drop a frame or more if you have to.

Rq : A secondary benefit of handling your game time/timers is that it will allow to nicely pause the game, and even to go faster or bullet-time if you want.

So how to handle your game time ?
So insideInside your run() loop you should measure the time between two calls (delta), and add up that 'real' time to your game time... Unless (and that's the trick) too much time elapsed (there was a pause or a system lag) : in that case you consider that just one frame elapsed.
Scale that time delta to allow bullet time / fast speed.

And for the game timers either :
a) you implement your own game timers (gameSetTimeout/intervalgameSetInterval) (tricky, costlysomehow complex)
b) you only check your entities against the game time for time-related actions.
expl, for a human that turns into a zombie after a given time :

if (this.willDyeisDead && (gameTime - this.willDyeTime-*gameTime*<0DeathTime > ZombieToHumanTurnTime)) { 
                this.type          = 'zombie'; 
                this.willDyeisDead        = false   ; 
                this.isDeadisLivingDead  = true    ; 
                this.target        = 'brain' ;  // :)
           }  

(you can write this in a neater way with a : if (this.shouldDyeshouldTurn()) ... )

So now that you have your game time :
a), you must have your entityentities update depending on game time :

So with delta = delta between current game time and previous frame game time :

this.update ( dtdelta ) {  // position update for a simple entity having velocity.
    this.x = this.x + this.velocity.x*dt;x*delta; // depends on dt (ms)
    this.y = this.y + this.velocity.y*dt;y*delta; // depends on dt (ms)
}

a) whenever the game is stopped (tab change in browser, ...) the time between two frames will be > typical time : only consider that 1 frame elapsed. And your game will just resume where it was.
b) fast/slow motion : you can choose to make the game time increment by the 'real' time, scaled by a factor. so with a factor > 1 you go faster, and with factor < 1 you go bullet time... Nice ! (The 'dt' you use for update should be scaled also.)

noticeNotice that window.performance.now is a much more accurate timer available (with a polyfill) on almost all current platforms.

To allow the game to pause, and even to go faster or slow-motion, you have to handle the time and timers by yourself.
So inside your run() loop you should measure the time between two calls, and add up that time to your game time.

And for the timers either :
a) you implement your own game timers (gameSetTimeout/interval) (tricky, costly)
b) you only check your entities against the game time for time-related actions.
expl :

if (this.willDye && (this.willDyeTime-*gameTime*<0)) { 
                this.type    = 'zombie'; 
                this.willDye = false   ; 
                this.isDead  = true    ; 
                this.target  = 'brain' ;  // :)
           }

(you can write this in a neater way with a : if (this.shouldDye()) ... )

So now that you have your game time :
a) you must have your entity update depending on time :

this.update ( dt ) {  // position update for a simple entity having velocity.
    this.x = this.x + this.velocity.x*dt; // depends on dt (ms)
    this.y = this.y + this.velocity.y*dt; // depends on dt (ms)
}

a) whenever the game is stopped (tab change in browser, ...) the time between two frames will be > typical time : only consider that 1 frame elapsed. And your game will just resume where it was.
b) fast/slow motion : you can choose to make the game time increment by the 'real' time, scaled by a factor. so with a factor > 1 you go faster, and with factor < 1 you go bullet time... Nice ! (The 'dt' you use for update should be scaled also.)

notice that window.performance.now is a much more accurate timer available (with a polyfill) on almost all current platforms.

First Rq : A key rule in Javascript : avoid system lag, with a very simple principle : do not feed the garbage collector.
So : Reuse your Arrays, do not create closures, use integers and not strings, pool your objects, ... a lot of simple rules too long to explain in a few words.

Now that you've done that, to avoid a slow-down/ fast forward behaviour, you have to to handle the time and timers by yourself. And drop a frame or more if you have to.

Rq : A secondary benefit of handling your game time/timers is that it will allow to nicely pause the game, and even to go faster or bullet-time if you want.

So how to handle your game time ?
Inside your run() loop you should measure the time between two calls (delta), and add up that 'real' time to your game time... Unless (and that's the trick) too much time elapsed (there was a pause or a system lag) : in that case you consider that just one frame elapsed.
Scale that time delta to allow bullet time / fast speed.

And for the game timers either :
a) you implement your own game timers (gameSetTimeout/gameSetInterval) (somehow complex)
b) you only check your entities against the game time for time-related actions.
expl, for a human that turns into a zombie after a given time :

if (this.isDead && (gameTime - this.DeathTime > ZombieToHumanTurnTime)) { 
                this.type          = 'zombie'; 
                this.isDead        = false   ; 
                this.isLivingDead  = true    ; 
                this.target        = 'brain' ;  // :)
           }  

(you can write this in a neater way with a : if (this.shouldTurn()) ... )

So now that you have your game time, you must have your entities update depending on game time :

So with delta = delta between current game time and previous frame game time :

this.update ( delta ) {  // position update for a simple entity having velocity.
    this.x = this.x + this.velocity.x*delta; // depends on dt (ms)
    this.y = this.y + this.velocity.y*delta; // depends on dt (ms)
}

Notice that window.performance.now is a much more accurate timer available (with a polyfill) on almost all current platforms.

Source Link
GameAlchemist
  • 1.4k
  • 7
  • 10

To allow the game to pause, and even to go faster or slow-motion, you have to handle the time and timers by yourself.
So inside your run() loop you should measure the time between two calls, and add up that time to your game time.

And for the timers either :
a) you implement your own game timers (gameSetTimeout/interval) (tricky, costly)
b) you only check your entities against the game time for time-related actions.
expl :

if (this.willDye && (this.willDyeTime-*gameTime*<0)) { 
                this.type    = 'zombie'; 
                this.willDye = false   ; 
                this.isDead  = true    ; 
                this.target  = 'brain' ;  // :)
           }

(you can write this in a neater way with a : if (this.shouldDye()) ... )

So now that you have your game time :
a) you must have your entity update depending on time :

this.update ( dt ) {  // position update for a simple entity having velocity.
    this.x = this.x + this.velocity.x*dt; // depends on dt (ms)
    this.y = this.y + this.velocity.y*dt; // depends on dt (ms)
}

a) whenever the game is stopped (tab change in browser, ...) the time between two frames will be > typical time : only consider that 1 frame elapsed. And your game will just resume where it was.
b) fast/slow motion : you can choose to make the game time increment by the 'real' time, scaled by a factor. so with a factor > 1 you go faster, and with factor < 1 you go bullet time... Nice ! (The 'dt' you use for update should be scaled also.)

notice that window.performance.now is a much more accurate timer available (with a polyfill) on almost all current platforms.