AndEngine GenericPool with Timer从池中添加精灵

时间:2011-12-23 00:06:27

标签: java android andengine

我有这个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();
            }

           }
     }

1 个答案:

答案 0 :(得分:3)

这可能是因为你一旦获得它就试图将精灵附加到场景中(即使它不会在你的代码中发生......),并且一旦它被回收你就不会分开它。

我建议你使用的方法就是这个(我在我的游戏中使用它,我有一个像你这样的精灵池,它工作正常):

  1. FruitPool s保持对场景的引用。然后,当一个精灵创建(在onAllocatePoolItem中)时,你将它附加到场景中。你从不再次分离它(除非游戏重置,当然......)
  2. 获取精灵(onHandleObtainItem)后,您可以在其上调用reset()。这会重置所有字段,例如位置,旋转等...... 注意:这会删除EntityModifier s!它只是重置它们。你应该在完成后删除它们,否则会导致问题。
  3. 当精灵被回收(onHandleRecycleItem)时,您调用方法setIgnoreUpdate(true)setVisible(false),因此不会绘制和更新此精灵。
  4. 这样,当你获得一个项目时:

    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          
          // ===========================================================  
    }