GenericPool для повторного использования спрайтов нужен каждую секунду - PullRequest
0 голосов
/ 06 января 2012

Я создал этот пул, который имеет 5 статических переменных.

public class FruitPool extends GenericPool<Sprite> {
// ===========================================================
// Constants          
// ===========================================================

// ===========================================================          
// Fields         
// =========================================================== 
private  ITextureRegion texture1;
private  ITextureRegion texture2;
private ITextureRegion texture3;
private  ITextureRegion texture4;
private  ITextureRegion texture5;

private Scene mScene;
private Context mContext;
private Camera mCamera;
private LinkedList<Sprite>pool1;

private static Sprite fruitOne;
private static Sprite fruitTwo;
private static Sprite fruitThree;
private static Sprite fruitFour;
private static Sprite fruitFive;
private  Sprite fruit;
// ===========================================================          
// Constructors          
// =========================================================== 
public FruitPool(final ITextureRegion watermelonRegion,
        ITextureRegion cherryRegion,ITextureRegion mBallTextureRegion, ITextureRegion grapeTextureRegion, ITextureRegion strawberryTextureRegion,Scene mScene2, Camera camera, LinkedList<Sprite>items) {

    this.texture1 = watermelonRegion;
    this.texture2 =cherryRegion;
    this.texture3 = mBallTextureRegion;
    this.texture4 = grapeTextureRegion;
    this.texture5 = strawberryTextureRegion;
    this.mScene = mScene2;
    this.pool1 = items;

    this.mCamera = camera;

}
// ===========================================================          
// Getter & Setter          
// =========================================================== 

// ===========================================================          
// Methods for/from SuperClass/Interfaces          
// ===========================================================  
@Override
protected Sprite onAllocatePoolItem() {


     Random randFruit = new Random();

     int textureNumber = randFruit.nextInt(5)+1;

     switch(textureNumber){
     case 1:
         if (fruitOne == null) {
              fruitOne = new Sprite(0, 0, this.texture1);
              Log.e("FruitPool", "Item rremade");
            } else {
              fruit = fruitOne;
              Log.e("FruitPool", "Item exist in pool..Used");
            }
          break;
     case 2:
         if(fruitTwo == null){
          fruitTwo = new Sprite(0, 0, this.texture2);
         }else{
             fruit = fruitTwo;
             Log.e("FruitPool", "Item exist in pool..Used");
         }

         break;
     case 3:
         if(fruitThree == null){
              fruitThree = new Sprite(0, 0, this.texture3);
         }else{
             fruit = fruitThree;
             Log.e("FruitPool", "Item exist in pool..Used");
         }

         break;
     case 4:
         if(fruitFour == null){
             fruitFour = new Sprite(0, 0, this.texture4);
         }else{
             fruit = fruitThree;
             Log.e("FruitPool", "Item exist in pool..Used");

         }

         break;
     case 5:
         if(fruitFive == null){
              fruitFive = new Sprite(0, 0, this.texture5);
         }else{
             fruit = fruitFive;
             Log.e("FruitPool", "Item exist in pool..Used");
         }

         break;

     }


    return fruit;

}
@Override
protected void onHandleObtainItem(final Sprite pItem) {
    pItem.reset();
}
@Override
protected void onHandleRecycleItem(final Sprite pItem) {
    pItem.setVisible(false);
    pItem.setIgnoreUpdate(true);

}



// ===========================================================          
// Methods          
// ===========================================================  

// ===========================================================          
// Inner and Anonymous Classes          
// ===========================================================  
}

Как вы видите в моем методе onAllocate, я проверяю, существует ли элемент, если он возвращается, я возвращаю его в методе.

Так что в своей основной деятельности я использую

          face =  fruitsPool.onAllocatePoolItem();

Это работает изначально, но проблема в том, что я прикрепляю лицо к сцене примерно каждую секунду. И я получаю ошибку, что спрайт уже был прикрепленна сцену.Сначала я нашел единственный способ сделать это - создать новый Sprite каждую секунду и отсоединить его, когда я закончу с ним, но это использует слишком много памяти и приводит к задержке, когда зависает.

Кто-нибудьесть какие-либо указатели на то, что мне нужно сделать, или предложения для меня код?

Ответы [ 2 ]

2 голосов
/ 07 января 2012

Вы никогда звоните onAllocatePoolItem. Этот метод вызывается внутри класса GenericPool<T>, когда пул пуст и запрашивается элемент.

Методы only , которые вы должны вызывать извне вашего FruitPool класса:

  1. obtainPoolItem чтобы получить предмет из пула; Не onAllocatePoolItem.
  2. recyclePoolItem для переработки предмета. Не забудьте позвонить, когда закончите с предметом.
  3. batchAllocatePoolItems, но вам это не нужно в вашем случае. Его можно использовать, когда вы хотите создать элементы пула в определенный момент; Но инициация Sprite не является тяжелым процессом, поэтому вам не нужно.

Вы не должны вызывать другие методы.

Опять вы нарушаете назначение пула объектов! onAllocatePoolItem должен всегда возвращать новый объект! Не существующий! Вот почему вы получаете

У сущности уже есть родитель

ошибка.

Кстати, когда я впервые создал этот класс для вас, я прикрепил спрайт к сцене, когда она была создана. Почему ты не делаешь это сейчас?

Я отредактировал его и добавил несколько комментариев.

public class FruitPool extends GenericPool<Sprite> {
// ===========================================================
// Constants          
// ===========================================================

// ===========================================================          
// Fields         
// =========================================================== 
private ITextureRegion[] mTextureRegions = new ITextureRegion[5];
private Scene mScene;
private int mCount;
// ===========================================================          
// Constructors          
// =========================================================== 
public FruitPool(final ITextureRegion watermelonRegion, ITextureRegion cherryRegion,ITextureRegion mBallTextureRegion, ITextureRegion grapeTextureRegion, ITextureRegion strawberryTextureRegion,Scene attachedScene) {
    this.mTextureRegions[0] = watermelonRegion;
    this.mTextureRegions[1] =cherryRegion;
    this.mTextureRegions[2]= mBallTextureRegion;
    this.mTextureRegions[3]= grapeTextureRegion;
    this.mTextureRegions[4] = strawberryTextureRegion;
    this.mScene = attachedScene;
}
// ===========================================================          
// Getter & Setter          
// =========================================================== 

// ===========================================================          
// Methods for/from SuperClass/Interfaces          
// ===========================================================  
@Override
protected Sprite onAllocatePoolItem() {
    //This method is called internally by GenericPool<T> class.
    //It is called when the pool is out of items, so a new one should be allocated.
    //Remember - you MUST create a new item here! Don't return a reference to an existing one.
    int fruitPos = MathUtils.random(0, 4);
    final Sprite fruit = new Sprite(0, 0, this.mTextureRegions[fruitPos]);
    this.mScene.attachChild(fruit);
    return fruit;
}
@Override
protected void onHandleObtainItem(final Sprite pItem) {
    //Before we return the sprite to the caller, we reset it's fields.
    //This method is called internaly by GenericPool<T> class.
    pItem.reset();
}
@Override
protected void onHandleRecycleItem(final Sprite pItem) {
    //When an item is recycled, this method is called. We make it invisible and set it to ignores updates.
    //We DONT detach it from the scene, just make it ignore updates.
    //Again, this method is called internally by GenericPool<T>class.
    pItem.setVisible(false);
    pItem.setIgnoreUpdate(true);
}
// ===========================================================          
// Methods          
// ===========================================================  

// ===========================================================          
// Inner and Anonymous Classes          
// ===========================================================  
}

Помните - вы не присоединяете / отсоединяете спрайт от пула! Он прикрепляется один раз при создании.

1 голос
/ 06 января 2012

Я не уверен, поможет ли это. Посмотрите, поможет ли это. Зачем вам нужен LinkedList? Вы можете использовать массивы, верно?

private final Fruit fruits[] = new Fruits[4];
//Initialize this in the constructor...
for(int i =0; i < fruits.length; i++) {
    fruits[i] = new Fruits();
}

@Override
protected Sprite onAllocatePoolItem() {


     Random randFruit = new Random();

     int textureNumber = randFruit.nextInt(5)+1;

     switch(textureNumber){
     case 1:
         if (fruitOne == null) {
              fruitOne = fruits[textureNumber];
              //new Sprite(0, 0, this.texture1);
              //use setters to set the values here..
              Log.e("FruitPool", "Item rremade");
            } else {
              fruit = fruits[textureNumber];
              Log.e("FruitPool", "Item exist in pool..Used");
            }
          break;
     case 2:
         if(fruitTwo == null){
              fruitTwo = fruits[textureNumber];
          //new Sprite(0, 0, this.texture1);
          //use setters to set the values here..
              Log.e("FruitPool", "Item rremade");
         }else{
             fruit = fruits[textureNumber];
             Log.e("FruitPool", "Item exist in pool..Used");
         }
....
...