5

HTC Desire と Galaxy Nexus の 2 つのデバイスで、AndEngine の最新バージョンであるブランチ GLES2 を使用しています。

画面を下にスクロールするスプライトで SpriteGroup を使用すると問題が発生します。新しいスプライトは、画面の上部にある SpriteGroup にアタッチされ、画面の下部に移動するとデタッチされます。また、プールを使用して、大量のメモリを使用しないようにしています。

いくつかのスプライトが取り外されるとすぐに、新しく取り付けられたいくつかのスプライトが数フレームの間ランダムに点滅し始めます。これは非常に面倒で、理由がわかりません...

スプライトをリサイクルするときに setVisible(false) しようとしましたが、プールなしでも試しましたが、何も変わりません。

SpriteGroup にバグがある可能性があると思いますが、どこにあるのかわかりません。運がなければ、onUpdateSpriteBatch() のループ中に発生しないように、begin() メソッドで SpriteGroup の子をアタッチしようとしました。

AndEngineExamples プロジェクトに基づく例を次に示します。SpriteBatchExample クラスを直接置き換え、プロジェクトを起動し、Simple/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 のこれら 2 つのメソッドを上書きすることで解決しました:

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 に答える