Search code examples
androidspriteandenginepool

Random Sprite with Sprite Pool


I wanna know how Sprite Pool works, since I dont really understand them. What I'm trying to do is show random sprites each time user touch the button (I already manage the control), but my code doesn't seem right, because it only shows the same sprite again and over again.

This is my code :

public class SpritePool extends GenericPool<Sprite> {
    private ITextureRegion mTexture1, mTexture2, mTexture3, mTexture4, mTexture5;

    private VertexBufferObjectManager mVertexBufferObjectManager;

    private Sprite sprite = null;

    public SpritePool(ITextureRegion pTextureRegion1, ITextureRegion pTextureRegion2, ITextureRegion pTextureRegion3
                    , ITextureRegion pTextureRegion4, ITextureRegion pTextureRegion5, VertexBufferObjectManager pVerTexBufferObjectManager){
                    this.mTexture1 = pTextureRegion1;
                    this.mTexture2 = pTextureRegion2;
                    this.mTexture3 = pTextureRegion3;
                    this.mTexture4 = pTextureRegion4;
                    this.mTexture5 = pTextureRegion5;
                    this.mVertexBufferObjectManager = pVerTexBufferObjectManager;          
            }

    @Override
    protected Sprite onAllocatePoolItem() {

            YesOrNoActivity.setRoll_1(MathUtils.RANDOM.nextInt(5) + 1);

            switch(YesOrNoActivity.getRoll_1()){
                    case 1:
                                    sprite = new Sprite(0, 0, this.mTexture1, this.mVertexBufferObjectManager);
                                    break;
                    case 2:
                                    sprite = new Sprite(0, 0, this.mTexture2, this.mVertexBufferObjectManager);
                                    break;
                    case 3:
                                    sprite = new Sprite(0, 0, this.mTexture3, this.mVertexBufferObjectManager);
                            break;
                    case 4:
                                    sprite = new Sprite(0, 0, this.mTexture4, this.mVertexBufferObjectManager);
                                    break;
                    case 5:
                                    sprite = new Sprite(0, 0, this.mTexture5, this.mVertexBufferObjectManager);
                            break;
            }
            return sprite;
    }

    public synchronized Sprite obtainPoolItem(final float pX, final float pY) {
            Sprite sprite = super.obtainPoolItem();
            sprite.setPosition(pX, pY);
            sprite.setVisible(true);        
            sprite.setIgnoreUpdate(false);
            sprite.setColor(1,1,1);
            return sprite;
    }

    @Override
    protected void onHandleRecycleItem(Sprite pItem) {
            super.onHandleRecycleItem(pItem);
            pItem.setVisible(false);
            pItem.setIgnoreUpdate(true);
            pItem.clearEntityModifiers();
            pItem.clearUpdateHandlers();
    }
}

Hope you guys can help me out, thanks :)


Solution

  • I'm going to show you a simple cow pool from my application to give you an idea of how the pools work. My CowPool is used as a source to generate CowCritters (NPC cows that walk around, graze, and generally do the things you'd expect from cows). Here's the code:

    public class CowPool extends GenericPool<CowCritter> {
    private final String        TAG = this.getClass().getSimpleName();
    
    public CowPool() {
        super();
    }
    
    @Override
    protected CowCritter onAllocatePoolItem() {
        return new CowCritter();
    }
    
    protected void recycle(CowCritter cow) {
        this.recyclePoolItem(cow);
    }
    
    }
    

    You'll see there are two methods, one that allocates a pool item (generates a new cow) and another that recycles the cow. When I need a cow, I don't call either of these methods, instead I call cowPool.obtainPoolItem(). If the pool has a cow in it, it will return the cow. If it doesn't, it will call onAllocatePoolItem(), creating a new cow, and it will return that cow. When I'm done with a given cow, I throw it back in the pool using the recycle() method.

    What's the point of all this?

    Well first of all note that I don't have to do any of this. Instead I could just instantiate a new cow when I need one, and throw it away. The key point to understand is that when I instantiate a new cow, that has overhead. It assigns memory resources. And so forth. Similarly, when I dispose of a cow, that has resources too. At some point the garbage collection is going to have to clean-up said cow, which takes a little bit of processing time.

    Pooling is essentially just a form of recycling. I know I'm going to need a cow again in the future, so rather than permanently dispose of this cow, I stick it in the pool, and later, when I need a cow, the cow is there for me. No garbage collection is involved, because the pool is holding on to the extra cow. And instantiating a new cow is faster because I'm not really instantiating a new cow, the cow is already there in the pool (unless the cow isn't, then it makes one).

    It's important to understand also that pooling is a form of optimization. You're not getting new functionality by pooling; instead, you're getting a potentially smarter handling of resources. I say potentially, because it doesn't always make sense to pool objects.

    I would suggest that you avoid pooling just for pooling's sake. In other words, make sure you're addressing an actual issue. Profile your code and find out where the real bottlenecks are. If the creation or disposal of objects is taking real time or memory, you may want to start pooling. A perfect opportunity for pooling would be bullets. Imagine you're spraying tons of bullets, creating new ones and disposing of the old ones. In such a case, you might get a real performance benefit by pooling instead.

    Hope this helps.