2012-09-19 9 views
5

Używam ostatniej wersji AndEngine, gałąź GLES2, z dwoma urządzeniami: HTC Desire i Galaxy Nexus.AndEngine - SpriteGroup miga na nowo attachChild

Mam problem z używaniem SpriteGroup z Sprites przewijaniem w dół na ekranie. Nowe sprite'y są dołączane do grupy Sprite na górze ekranu i odłączane, gdy schodzą z dołu. Używam puli, aby uniknąć używania dużej ilości pamięci.

Po oderwaniu kilku duszków, niektóre nowo dołączone duszki zaczynają migać losowo na kilka klatek. Jest to bardzo denerwujące i nie mam pojęcia, dlaczego ...

Próbowałem ustawić sprite (fałszywe) sprite podczas ich recyklingu, próbowałem również bez puli, ale to się nie zmienia.

Myślę, że SpriteGroup może mieć błąd, ale nie wiem gdzie. Próbowałem dołączyć dzieci w SpriteGroup do metody begin(), aby upewnić się, że nie nastąpiło to podczas pętli onUpdateSpriteBatch(), bez powodzenia.

Oto przykład oparty na projekcie AndEngineExamples. Możesz bezpośrednio zastąpić klasę SpriteBatchExample, uruchomić projekt i przejść do Simple/Drawing a SpriteBatch, aby zobaczyć problem.

Z góry dziękuję za każdy pomysł!

package org.andengine.examples; 

import java.util.Iterator; 

import org.andengine.engine.camera.Camera; 
import org.andengine.engine.handler.timer.ITimerCallback; 
import org.andengine.engine.handler.timer.TimerHandler; 
import org.andengine.engine.options.EngineOptions; 
import org.andengine.engine.options.ScreenOrientation; 
import org.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy; 
import org.andengine.entity.scene.Scene; 
import org.andengine.entity.scene.background.Background; 
import org.andengine.entity.sprite.Sprite; 
import org.andengine.entity.sprite.batch.SpriteGroup; 
import org.andengine.entity.util.FPSLogger; 
import org.andengine.opengl.texture.TextureOptions; 
import org.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlas; 
import org.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlasTextureRegionFactory; 
import org.andengine.opengl.texture.region.ITextureRegion; 
import org.andengine.opengl.vbo.VertexBufferObjectManager; 
import org.andengine.ui.activity.SimpleBaseGameActivity; 
import org.andengine.util.adt.list.SmartList; 
import org.andengine.util.adt.pool.GenericPool; 

public class SpriteBatchExample extends SimpleBaseGameActivity { 
    // =========================================================== 
    // Constants 
    // =========================================================== 

    private static final int CAMERA_WIDTH = 720; 
    private static final int CAMERA_HEIGHT = 480; 

    // =========================================================== 
    // Fields 
    // =========================================================== 

    private BitmapTextureAtlas mBitmapTextureAtlas; 
    private ITextureRegion mFaceTextureRegion; 

    private float mSecondsElapsedSinceLastGeneration = 0; 

    // =========================================================== 
    // Constructors 
    // =========================================================== 

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

    // =========================================================== 
    // Methods for/from SuperClass/Interfaces 
    // =========================================================== 

    @Override 
    public EngineOptions onCreateEngineOptions() { 
     final Camera camera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT); 

     return new EngineOptions(true, ScreenOrientation.LANDSCAPE_FIXED, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), camera); 
    } 

    @Override 
    public void onCreateResources() { 
     BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/"); 

     this.mBitmapTextureAtlas = new BitmapTextureAtlas(this.getTextureManager(), 32, 32, TextureOptions.BILINEAR); 
     this.mFaceTextureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mBitmapTextureAtlas, this, "face_box.png", 0, 0); 
     this.mBitmapTextureAtlas.load(); 
    } 

    @Override 
    public Scene onCreateScene() { 
     this.mEngine.registerUpdateHandler(new FPSLogger()); 

     final Scene scene = new Scene(); 
     scene.setBackground(new Background(0.09804f, 0.6274f, 0.8784f)); 

     final SpriteGroup spriteGroup = new SpriteGroup(this.mBitmapTextureAtlas, 500, this.getVertexBufferObjectManager()); 
     spriteGroup.setPosition(0, 0); 
     scene.attachChild(spriteGroup); 

     final SpritePool lPool = new SpritePool(mFaceTextureRegion, getVertexBufferObjectManager()); 
     final SmartList<Sprite> lSpriteList = new SmartList<Sprite>(); 

     final float lCharactersPeriod = 0.4f; 

     scene.registerUpdateHandler(new TimerHandler(0.05f, true, new ITimerCallback() { 
      @Override 
      public void onTimePassed(final TimerHandler pTimerHandler) { 
       final float lSecondsElapsedSinceLastUpdate = 0.1f; 

       final Iterator<Sprite> li = lSpriteList.iterator(); 
       while (li.hasNext()) { 
        final Sprite lChar = li.next(); 
        boolean lRemoveChar = false; 

        // Character destruction OR movement 
        final float lY = lChar.getY(); 
        if (lY > CAMERA_HEIGHT) { 
         lRemoveChar = true; 
        } else { 
         lChar.setPosition(lChar.getX(), lY + 60 * lSecondsElapsedSinceLastUpdate); 
        } 

        if (lRemoveChar) { 
         // Remove character from scene 
         lChar.detachSelf(); 
         lPool.recyclePoolItem(lChar); 
         li.remove(); 
        } 
       } 

       // Character generation 
       mSecondsElapsedSinceLastGeneration += lSecondsElapsedSinceLastUpdate; 
       if (mSecondsElapsedSinceLastGeneration > lCharactersPeriod) { 
        // generate sprite 
        final Sprite lSprite = lPool.obtainPoolItem(); 
        lSprite.setPosition((float) Math.random() * CAMERA_WIDTH, 0); 
        spriteGroup.attachChild(lSprite); 
        lSpriteList.add(lSprite); 
        mSecondsElapsedSinceLastGeneration -= lCharactersPeriod; 
       } 
      } 
     })); 

     return scene; 
    } 

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

    // =========================================================== 
    // Inner and Anonymous Classes 
    // =========================================================== 
    static class SpritePool extends GenericPool<Sprite> { 
     // =========================================================== 
     // Constants 
     // =========================================================== 

     // =========================================================== 
     // Fields 
     // =========================================================== 
     private final VertexBufferObjectManager mVertexBufferObjectManager; 
     private ITextureRegion mFaceTextureRegion; 


     // =========================================================== 
     // Constructors 
     // =========================================================== 
     public SpritePool(final ITextureRegion pFaceTextureRegion, final VertexBufferObjectManager pVertexBufferObjectManager) { 
      mFaceTextureRegion = pFaceTextureRegion; 
      mVertexBufferObjectManager = pVertexBufferObjectManager; 
     } 


     // =========================================================== 
     // Methods for/from SuperClass/Interfaces 
     // =========================================================== 
     @Override 
     protected Sprite onAllocatePoolItem() { 
      final Sprite lSprite = new Sprite(50, 0, mFaceTextureRegion, mVertexBufferObjectManager); 
      lSprite.setIgnoreUpdate(true); 
      return lSprite; 
     } 

     @Override 
     protected void onHandleRecycleItem(final Sprite pSprite) { 
     } 

     @Override 
     protected void onHandleObtainItem(final Sprite pSprite) { 
     } 
    } 
} 

Odpowiedz

3

miałem sam problem (ostatni dodaje widoczny ikonki (i) w grupie, rozpoczęły migać Ilekroć ustawić dowolny ikonki na niewidoczny) i rozwiązany przez nadpisanie tych 2 metod w SpriteGroup:

SpriteGroup result = new SpriteGroup(atlas, capacity, vertexBufferObjectManager) { 
    @Override 
    protected boolean onUpdateSpriteBatch() { 
      return false; 
    } 

    @Override 
    protected void onManagedUpdate(float pSecondsElapsed) { 
      super.onManagedUpdate(pSecondsElapsed); 
      final SmartList<IEntity> children = this.mChildren; 
      if(children != null) { 
        final int childCount = children.size(); 
        for(int i = 0; i < childCount; i++) { 
          this.drawWithoutChecks((Sprite)children.get(i)); 
        } 
        submit(); 
      } 
    }; 

źródło: http://www.andengine.org/forums/gles2/blinking-last-sprite-in-spritegroup-t7617.html