5

我正在使用最后一个版本的 AndEngine,分支 GLES2,有两个设备:HTC Desire 和 Galaxy Nexus。

使用 SpriteGroup 在屏幕上向下滚动时出现问题。新的精灵附加到屏幕顶部的 SpriteGroup 并在它们离开底部时分离。我使用一个池来避免使用太多内存。

一旦有一些精灵分离,一些新附加的精灵开始随机闪烁几帧。这很烦人,我不知道为什么......

我尝试在回收精灵时设置它们的 setVisible(false),我也尝试不使用池,但它并没有改变任何事情。

我认为 SpriteGroup 可能有一个错误,但不确定在哪里。我试图在 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) {
        }
    }
}
4

1 回答 1

3

我有同样的问题(当我将任何精灵设置为不可见时,组中最后添加的可见精灵开始闪烁),并通过覆盖 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();
            }
    };

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

于 2013-06-28T02:45:20.677 回答