2012-09-19 23 views
5

Estoy usando la última versión de AndEngine, rama GLES2, con dos dispositivos: HTC Desire y un Galaxy Nexus.AndEngine - SpriteGroup parpadea en el recién attachChild

Tengo un problema cuando uso un SpriteGroup con Sprites desplazándose hacia abajo en la pantalla. Los nuevos sprites se unen a un SpriteGroup en la parte superior de la pantalla y se separan cuando salen del fondo. Y uso un grupo para evitar usar mucha memoria.

Tan pronto como haya algunos sprites separados, algunos sprites recién conectados comenzarán a parpadear aleatoriamente durante algunos fotogramas. Esto es muy molesto y no tengo ni idea de por qué ...

Intenté configurarVisible (falso) los sprites al reciclarlos, también probé sin la piscina, pero no cambia nada.

Creo que SpriteGroup puede tener un error, pero no estoy seguro de dónde. Traté de adjuntar a los niños en SpriteGroup en el método begin() para asegurarme de que no sucedió durante el ciclo de onUpdateSpriteBatch(), sin suerte.

Aquí hay un ejemplo basado en el proyecto AndEngineExamples. Puede reemplazar directamente la clase SpriteBatchExample, iniciar el proyecto e ir a Simple/Drawing a SpriteBatch para ver el problema.

¡Gracias de antemano por cualquier idea!

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) { 
     } 
    } 
} 

Respuesta

3

i tenían el mismo problema (última añadió Sprite (s) visible en el grupo empezó a parpadear cuando i establecer cualquier sprite para invisible), y lo resolvió sobrescribiendo esos 2 métodos en 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(); 
      } 
    }; 

fuente: http://www.andengine.org/forums/gles2/blinking-last-sprite-in-spritegroup-t7617.html

Cuestiones relacionadas