Использование пула для переработки и повторного использования спрайтов - PullRequest
0 голосов
/ 05 января 2012

Я создал этот общий пул, чтобы повторно использовать некоторые спрайты, которые я добавляю в сцену.

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;
// ===========================================================          
// 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 rand = new Random();
     Random randFruit = new Random();
     Sprite fruit = null;
      float x = rand.nextInt((int) mCamera.getWidth() - texture1.getHeight());
     int textureNumber = randFruit.nextInt(5)+1;

     switch(textureNumber){
     case 1:
          fruit = new Sprite(x, 0, this.texture1);
          break;
     case 2:
         fruit = new Sprite(x, 0, this.texture2);
         break;
     case 3:
         fruit = new Sprite(x, 0, this.texture3);
         break;
     case 4:
         fruit = new Sprite(x, 0, this.texture4);
         break;
     case 5:
         fruit = new Sprite(x, 0, this.texture5);
         break;

     }










    mScene.attachChild(fruit);


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

Код работает хорошо, но, похоже, он не использует повторно использованные спрайты, а выделяет новые каждый раз ..

Я получаю спрайт, вызывая

  face =  fruitsPool.onAllocatePoolItem();

Есть предложения?

РЕДАКТИРОВАТЬ:

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

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 = null;
private static Sprite fruitTwo= null;
private static Sprite fruitThree = null;
private static Sprite fruitFour = null;
private static Sprite fruitFive = null;
private  Sprite fruit = null;
// ===========================================================          
// 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          
// ===========================================================  
}

И я звоню

 Sprite sprite = fruitPool.onAllocatePoolItem();

 then i attach it to the scene(this method i use is called about every second)

Но каждый раз, когда я получаю сообщение об ошибке, у сущности (спрайта) уже есть родитель и он был прикреплен.

Или в других случаях спрайты просто возвращают ноль.

Что-то я делаю неправильно или отсутствует?

Ответы [ 2 ]

2 голосов
/ 05 января 2012
Ключевое слово

new используется для создания нового экземпляра класса, вызывая один из конструкторов для этого класса.Он не проверяет, существует ли какой-либо экземпляр или нет.

Вам необходимо написать логику, чтобы проверить, существует ли какой-либо экземпляр класса.если нет, создайте новый экземпляр, если он существует, используйте экземпляр

см. http://java.sun.com/developer/technicalArticles/Programming/singletons/

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

Это потому, что в своем выражении switch(textureNumber) вы каждый раз создаете new Sprite() и возвращаете его вызывающей стороне.Вам следует проверить, был ли спрайт создан ранее, и вернуть этот экземпляр обратно вызывающей стороне.

Редактировать : (на основе комментариев)

Из того, что я понимаю,когда вы recycle() просто скрывают спрайт, поэтому вы хотите получить ссылку на него.

Что вы можете сделать, это сделать ваши спрайты статическими объектами как частью вашего класса, а затем изменить оператор switch,вот так:

private static Sprite fruitOne;
private static Sprite fruitTwo;
private static Sprite fruitThree;
. . .

//Other code in here

switch(textureNumber) {
  case 1:
    if (fruitOne == null) {
      fruit = new Sprite(x, 0, this.texture1);
    } else {
      fruit = fruitOne;
    }
    break;
  case 2:
    if (fruitTwo == null) {
      fruit = new Sprite(x, 0, this.texture2);
    } else {
      fruit = fruitTwo;
    }
    break;

   //Rest of code here. . .

По сути, этот код проверяет, существует ли уже созданный экземпляр Sprite, а если нет - он его создаст.

...