我有这个GenericPool我用于我在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
// ===========================================================
}
如您所见,我向池中提供了一个TextureRegion,以便像这样在池中创建一个精灵。
FruitPool pool1 = new FruitPool(TextureRegion);
Sprite blueBall = pool1.obtainItem();
然后我使用
将精灵从屏幕上移开后再循环 pool1.recyclePoolItem(blueBall);
我遇到的问题是我有一个Timer,它大约每2秒就会添加一个Sprite。
问题是如果精灵还没有离开屏幕并被回收,我的Logcat中会出现“Sprite has has Parent”错误。
有没有办法让我可以从池中拉出尽可能多的精灵,然后在它离开屏幕时再回收每个精灵以便以后重复使用?
我现在的方式显然不起作用。
感谢帮助伙计们!
编辑:这里也是我根据所选数字添加精灵的方法
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();
}
}
}
答案 0 :(得分:3)
这可能是因为你一旦获得它就试图将精灵附加到场景中(即使它不会在你的代码中发生......),并且一旦它被回收你就不会分开它。
我建议你使用的方法就是这个(我在我的游戏中使用它,我有一个像你这样的精灵池,它工作正常):
FruitPool
s保持对场景的引用。然后,当一个精灵创建(在onAllocatePoolItem
中)时,你将它附加到场景中。你从不再次分离它(除非游戏重置,当然......)onHandleObtainItem
)后,您可以在其上调用reset()
。这会重置所有字段,例如位置,旋转等...... 注意:这会不删除EntityModifier
s!它只是重置它们。你应该在完成后删除它们,否则会导致问题。onHandleRecycleItem
)时,您调用方法setIgnoreUpdate(true)
和setVisible(false)
,因此不会绘制和更新此精灵。这样,当你获得一个项目时:
Sprite sprite = pool.obtainPoolItem();
你不将它附加到场景中,你不会在它上面调用任何重置或初始化方法 - 只需根据需要设置它的位置,然后注册EntityModifier
编辑:以下是该池的完整来源:
public class FruitPool extends GenericPool<Sprite> {
// ===========================================================
// Constants
// ===========================================================
// ===========================================================
// Fields
// ===========================================================
private final TextureRegion mTextureRegion;
private final Scene mAttachedScene;
// ===========================================================
// Constructors
// ===========================================================
public FruitPool(final TextureRegion pFruitTextureRegion, final Scene pScene) {
this.mTextureRegion = pFruitTextureRegion;
this.mAttachedScene = pScene;
}
// ===========================================================
// Getter & Setter
// ===========================================================
// ===========================================================
// Methods for/from SuperClass/Interfaces
// ===========================================================
@Override
protected Sprite onAllocatePoolItem() {
Sprite newSprite = new Sprite(0, 0, this.mTextureRegion);
this.mAttachedScene.attachChild(newSprite); //Attaching it HERE to the scene.
return newSprite;
}
@Override
protected void onHandleObtainItem(final Sprite pItem) {
pItem.reset();
}
@Override
protected void onHandleRecycleItem(final Sprite pItem) {
pItem.setVisible(true);
pItem.setIgnoreUpdate(true); //Just make it ignore updates while it is recycled, DON'T remove it from the scene.
}
// ===========================================================
// Methods
// ===========================================================
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
}