java - AndEngine GenericPool 带有计时器,从池中添加 Sprite

标签 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,以在池中创建一个 Sprite ,如下所示..

FruitPool pool1 = new FruitPool(TextureRegion);
Sprite blueBall = pool1.obtainItem();

然后,我使用

在 Sprite 离开屏幕后对其进行回收
  pool1.recyclePoolItem(blueBall);

我遇到的问题是我有一个计时器,大约每 2 秒添加一个 Sprite。

问题是,如果 Sprite 还没有离开屏幕并被回收,我会在 Logcat 中收到“ Sprite 已经有父级”错误。

有没有一种方法可以让我从池中取出尽可能多的 Sprite ,然后在它们离开屏幕时回收每个 Sprite 以供以后重复使用?

我现在的方式显然不起作用。

感谢大家的帮助!

编辑:这也是我根据所选数量添加 Sprite 的方法

  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();
            }

           }
     }

最佳答案

这可能是因为您在获得 Sprite 后尝试将其附加到场景(即使它不会在您的代码中发生..),并且在回收它后您没有将其分离。

我建议你使用的方法是这样的(我在我的游戏中使用它,我有一个像你一样的 Sprite 池,并且效果很好):

  1. FruitPool 保存对场景的引用。然后,当创建 Sprite 时(在onAllocatePoolItem中),您将其永久附加到场景中。您永远不再将其分离(当然,除非游戏重置......)
  2. 当获得 Sprite (onHandleObtainItem)时,您可以对其调用reset()。这会重置所有字段,例如位置、旋转等...注意:不会删除EntityModifier!它只是重置它们。完成后您应该将其删除,否则会导致问题。
  3. 当 Sprite 被回收时 (onHandleRecycleItem),您可以调用方法 setIgnoreUpdate(true)setVisible(false),这样该 Sprite 就不会被回收。无需绘制和更新。

这样,当您获得元素时:

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

关于java - AndEngine GenericPool 带有计时器,从池中添加 Sprite ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8611074/

相关文章:

java - 名称的冲突持久性单元定义

android - 如何在 AVD 上获取 YouTube 应用程序?

java - Activity 仅在重新加载应用程序后加载首次按下的索引的数据

ANDROID ANDENGINE -- 将场景背景设置为透明

android - eglSwapBuffers 失败 : EGL_BAD_ALLOC AndEngine Android

android - 单词搜索游戏问题

java - Spring 4/既不是 BindingResult 也不是普通目标对象

java - CGLib - 控制实例创建

java - 如何记住上次执行程序时的用户决定

android - 来自 CustomCursorAdapter 的 RunOnUIThread