Jump to content

Best practice for pool of similar sprites?


buttonsrtoys
 Share

Recommended Posts

I'm writing an Asteroids game and currently have 3 pools/groups of asteroids ('big', 'med', 'sm')  which is resulting in a lot of redundant code. I'm thinking it would be cleaner to have a single shared pool, but it's not clear to me how to specify which one to get from the group? E.g., below is not supported.

bigAsteroid = asteroid.group.getFirstExists(false, 'big');

What are people doing for pools of similar sprites?

 

Link to comment
Share on other sites

Maybe, it makes sense, to write some function for quering objects by attribute. It may looks like

asteroids.get('big') //returns an array of asteroidsAsteroids.prototype.get = function(query){    //here you can make any type of objects storage  //like asteroids = [..] and looping it  //or asteroids = {big: [..], sm: [..], etc..} and get some pre-sorted array}
Link to comment
Share on other sites

Hi, in my game I am using this generic Pool class (written in Typescript, but should be easy to rewrite into JS):

module Utils {    export class Pool<T> {        private _classType: any;        private _count: number = 0;        private _pool: T[] = [];        private _canGrow: boolean = true;        // -------------------------------------------------------------------------        constructor(aClassType: any, aCount: number) {            this._classType = aClassType;            for (var i = 0; i < aCount; i++) {                // create new item                var item = this.newItem();                // store into stack of free items                this._pool[this._count++] = item;            }        }        // -------------------------------------------------------------------------        public createItem(): T {            if (this._count === 0) {                return this._canGrow ? this.newItem() : null;            } else {                return this._pool[--this._count];            }        }        // -------------------------------------------------------------------------        public destroyItem(aItem: T): void {            this._pool[this._count++] = aItem;        }        // -------------------------------------------------------------------------        private newItem(): T {            return new this._classType;        }        // -------------------------------------------------------------------------        public set canGrow(aCanGrow: boolean) {            this._canGrow = aCanGrow;        }    }}

Use it like this to create pool:

this._pool = new Pool<BoardFloor>(BoardFloor, Constants.ITEMS_COUNT);

And:

 createItem() ... creates new item of pooled type (or returns null if growing of pool is prohibited),

 destroyItem(item) ... returns item back to pool

Link to comment
Share on other sites

buttonsrtoys says:

...currently have 3 pools/groups of asteroids ('big', 'med', 'sm')  which is resulting in a lot of redundant code...

 

 

 This leads me to idea, he should have one asteroid class with size parameter. Making separate class for big, small, medium asteroid seems like overhead ...

 

 His problem is ideal for pool - take from pool + parametrize (set size).

 

 Even in case there were 3 different classes for small/medium/big asteroid, I would create 3 pools as pooling would save me object creation / destruction. The class in code is generic, so it is easy to create 3 different pools with only one codebase.

Link to comment
Share on other sites

My shared pool is working well for me and cut out a lot of redundant code. I use the sprite key as a type identifier and loop the pools array (below). I don't doubt that classes would have been a better practice, and may investigate this in the future.

getFromSharedPool: function(key) {   for (var i = 0, len = this.group.children.length; i < len; i++) {     var sprite = this.group.children[i];     if (sprite.key === key && !sprite.alive) {        return this.group.getAt(i);     }   }   return null;},

Edit: I ended up creating classes as @vita and @tom suggested. I went with a base class for all asteroids and a subclass for each size. Codes small and easy to maintain. The subclasses are handy because they allow for each size to have a different method for handling when they got shot. E.g., they each have a 'getKilled()' method where bigger asteroids subdivide a before getting killed and the smallest asteroid just dies. They each also know their particular score value which varies and report it when they're killed. I'm also still using the same shared pool above which is working well. I only use if for the asteroids. There's only one instance of the ship and the enemy ship, so no need to add them to the pool.

 

Thanks for the thoughts! They were super helpful!!

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...