A better way of object pooling with impact.js (HTML5)

UPDATE:  Object pooling  has been added to the latest version (1.23) of Impact.js.  Still, it’s good to know how pooling works!  Moreover, the method for object pooling which I illustrate below creates zero garbage and is  far more efficient. Your performance will improve considerably if you implement pooling in this manner. 

I’m nearly done with the sequel to my last game, and am putting the finishing touches on Super Rawr-Type Redux. In doing so, I wanted to significantly improve the performance over its predecessor, and that would mean that I would need a more efficient way to pool my objects — my bullets and particles in particular.  At times, I’m throwing hundreds of bullets and particles on screen at once, so the creation then disposal of so many objects can quickly dampen the frame rate.

Along came Vincent Piel with his excellent object pooling tutorials for javascript.  This one in particular covers object pooling in impact.js specifically, and I found it to be invaluable for my game.  It took me a bit of time and a few times to read it over before i finally got the hang of it. Furthermore, the github repo he has highlights how it is used a bit more.

He was even kind enough to e-mail back and forth with me for a bit so that I could get it working in my own game, which seemed to help him find a few ways to simplify and correct the code in his own plugin.

Essentially, object pooling in impact is done in three steps:

  1. The object is created, and its default values are set. If anything arguments need to be passed in, now is not the time to do it — instead, we’re looking to just create objects, then pass in the arguments at a later time. Therefore, all of your objects being pooled must be able to handle any number of arguments **including none**.
  2.  After the object is created, it is immediately deactivated, and stored in the pool.
  3. When the object is ready to be used, it is removed from the pool, and any arguments that need to be passed in will now be accepted.Number 2 is what put me through a loop for a bit, because I couldn’t wrap my head around it, but once I understood that the default properties are initialized when it is created, and then any arguments I’m passing in are received AFTER the object is removed from the pool, it all made sense.To further clarify, here is what the init() function in my bullet class looks like:
init: function (x, y, settings) {
     var noArgs = (arguments.length == 0);
     if (!noargs) this.parent(x, y, settings);
     this.bulletCount = noArgs ? 0 : settings.bulletCount ;
     this.vel.x = noArgs ?  0 : this.speed.x;
     this.vel.y = noArgs ?  0 : Math.sin(this.angle * 2) * this.speed.y;
 },

Update: Vincent got in touch with me to state that there is a more efficient way of running this code. Therefore, I’ve adjusted the code block above. His reasoning:

Since this.speed won’t be set with an empty call, your version would
put an awful undefined or NaN in vel.x and vel.y. Which might be
misleading for internal optimizations of the interpreter.

One example of this is with my enemy bullets. Their angle is based on the angle of the animation from the ship firing them. So, if my enemy ship is pointed up and to the left, it then passes that info to the bullet, and the bullet is now fired in that direction.

When objects are ready to be disposed of, rather than killing them, they are simply deactivated, and brought back into the pool.

Sounds like a lot, huh? Fortunately, Vincent has made it very easy to implement. His object pooling plugin does all of the work, and all you need to do is add a few functions so your own game.

In my main.js file, I have:

.requires(
    ....
 '    impact.gaPooling',
    ....

init: function () {
    ....
    // this.setTitle();
    ....
 },
poolEntities: function () {
     ga.autoPoolEntities();
     EntityPlayerBullet.setupInitPool(50);
     EntityEnemyTurretBullet.setupInitPool(50);
     EntityExplosionParticleGreen.setupInitPool(50);
     EntityExplosionParticleRed.setupInitPool(50);
     EntityExplosionParticleBlue.setupInitPool(180);
     EntityExplosionParticleGrey.setupInitPool(180);
 },

To get your objects pooled, it involves three steps:
1) Including the plugin

2) calling ‘ga.autoPoolEntities();’

3) Calling the name of the entity, followed by the ‘setupInitPool’ function, and passing in the number of entities to create.

That’s all you need to do! I’ve noticed a significant performance improvement from this. Previously, my framerate would drop to about 30-35 fps when I had more than 100 active particles on screen at once, but with this pooling method, I’m able to get at least twice as many before noticing any sort of impact on performance.

-----------------------


subscribe-to-youtube

One thought on “A better way of object pooling with impact.js (HTML5)

  1. Pingback: Super Rawr-Type Redux is released for the browser | Dave Voyles

Leave a Reply