I have this GenericPool i am using for a Game i am creating in AndEngine.
public class FruitPool extends GenericPool<Sprite> {
// ===========================================================
// Constants
// ===========================================================
// ===========================================================
// Fields
// ===========================================================
private final TextureRegion mTextureRegion;
// ===========================================================
// Constructors
// ===========================================================
public FruitPool(final TextureRegion pFruitTextureRegion) {
this.mTextureRegion = pFruitTextureRegion;
}
// ===========================================================
// Getter & Setter
// ===========================================================
// ===========================================================
// Methods for/from SuperClass/Interfaces
// ===========================================================
@Override
protected Sprite onAllocatePoolItem() {
return new Sprite(0, 0, this.mTextureRegion);
}
@Override
protected void onHandleObtainItem(final Sprite pItem) {
pItem.reset();
}
@Override
protected void onHandleRecycleItem(final Sprite pItem) {
pItem.setVisible(true);
pItem.setIgnoreUpdate(true);
}
// ===========================================================
// Methods
// ===========================================================
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
}
As you see i supply a TextureRegion to the pool to create a sprite in the pool like this..
FruitPool pool1 = new FruitPool(TextureRegion);
Sprite blueBall = pool1.obtainItem();
I then recycle the sprites after it has gone off the screen using
pool1.recyclePoolItem(blueBall);
The issue i a having is that i have a Timer that adds a Sprite just about every 2 seconds.
The problem is if the sprite hasnt gone off the screen yet and been recycled i get a “Sprite already has Parent” error in my Logcat.
Is there a way i can make it possible to pull as many Sprites as i want out of the Pool and then recycle each one as it goes off the screen to be later reused?
The way i have it right now clearly isnt working.
Thanks for the help Guys!
EDIT: Also here is the method where i add the sprites depending on the number selected
private void addFace2() {
Random rand = new Random();
Random randFruit = new Random();
if(isGameRunning){
face = null;
int fruitNumber = randFruit.nextInt(6) + 1;
switch(fruitNumber) {
case 1:
//Item 1 code
face = pool1.obtainPoolItem();
this.pool1List.add(face);
break;
case 2:
face = pool2.obtainPoolItem();
this.pool2List.add(face);
break;
case 3:
face = pool3.obtainPoolItem();
this.pool3List.add(face);
break;
//etc. . .
case 4:
face = pool4.obtainPoolItem();
this.pool4List.add(face);
break;
case 5:
face = pool5.obtainPoolItem();
this.pool5List.add(face);
break;
}
this.mFaceCount++;
Log.e("Faces: ", "Face" + this.mFaceCount);
if(face !=null){
int rangeDuration = maxDuration2 - minDuration2;
int actualDuration = rand.nextInt(rangeDuration) + minDuration2;
MoveYModifier mod = new MoveYModifier(actualDuration, face.getY(), mCamera.getHeight());
face.registerEntityModifier(mod);
if(face.hasParent()){
Log.e("Face", "Face has parent");
}else{
this.mScene.attachChild(face);
thump.play();
}
}
}
It’s probably because you try to attach the sprite to the scene once you obtained it (Even though it won’t happen in your code..), and you didn’t detach it once it is recycled.
The approach I suggest you to use is this (I am using it in my game where I have a sprite pool like yours, and it works fine):
FruitPools hold references to your scene. Then, when a sprite is created (InonAllocatePoolItem) you attach it to the scene, for good. You never detach it again (Unless the game resets, of course…)onHandleObtainItem) you callreset()on it. That resets all it’s fields, like position, rotation, etc… Note: this does not remove theEntityModifiers! It just resets them. You should remove them when they are done, otherwise it will cause problems.onHandleRecycleItem) you call the methodssetIgnoreUpdate(true)andsetVisible(false)so this sprite won’t be drawn and updated.This way, when you obtain an item:
You don’t attach it to the scene, and you don’t call any reset or initialization methods on it – just set it’s position as you want, and register the
EntityModifier.EDIT: Here is the full source for the pool: