我使用的是最后一个版本的andengine,branch gles2,有两个设备:htc desire和galaxy nexus。
当在屏幕上向下滚动sprites时使用spritegroup时出现问题。新精灵将附加到屏幕顶部的精灵组,并在它们离开底部时分离。我用一个池来避免占用太多内存。
一旦有一些精灵分离,一些新附加的精灵开始随机闪烁几帧。这很烦人,我不知道为什么…
我试着在回收雪碧时设置可见(假)雪碧,我也试过不使用游泳池,但它不会改变任何事情。
我认为spritegroup可能有一个bug,但不确定在哪里。我尝试在begin()方法中附加spritegroup中的子对象,以确保在onupdatespritebatch()的循环中不会发生这种情况,但没有成功。
下面是一个基于andengineexamples项目的示例。您可以直接替换spritebatchexample类,启动项目并转到simple/drawing a spritebatch来查看问题。
提前谢谢你的任何想法!

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

最佳答案

我也有同样的问题(上次在组中添加的可见精灵在我将任何精灵设置为不可见时开始闪烁),并通过覆盖sprite group中的这两个方法解决了这个问题:

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

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

07-27 13:30