使用Andengine安全地删除精灵

时间:2012-02-19 18:08:10

标签: sprite andengine

我创造了很多球精灵,随机地在屏幕上反弹。触摸后,我想将球从场景中移除。 (如果不止一个球占据相同的空间,那么此刻也会被移除)。

我意识到scene.detachChild必须在runOnUpdateThread上运行,所以在我的Ball sprite子类中,我通过覆盖onAreaTouched触摸了detachChild:

        @Override
    public boolean onAreaTouched(TouchEvent pSceneTouchEvent, float pTouchAreaLocalX, float pTouchAreaLocalY)
    {
        ((BaseGameActivity) thisAct).runOnUpdateThread(new Runnable() {
            @Override
            public void run() {
                /* Now it is save to remove the entity! */


                    //scene.unregisterTouchArea(Ball.this);
                    scene.detachChild(Ball.this);

            }
        });
        return false;
    }

我必须将主Activity传递给球精灵的构造函数,然后从主活动场景中移除球。

如果我取消注释scene.unregisterTouchArea(Ball.this)行,停止精灵作用于触摸(这不会影响删除,但认为最好停止正在处理的触摸),我将收到indexOutOfBoundsException我认为这与不在runOnUpdateThread中分离sprite有关。

**java.lang.IndexOutOfBoundsException: Invalid index 90, size is 90
at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:257)
at java.util.ArrayList.get(ArrayList.java:311)
at org.anddev.andengine.entity.scene.Scene.onSceneTouchEvent(Scene.java:320)**

两个问题:

  1. 我是否正确使用覆盖onAreaTouched处理球子类内的精灵的删除,或者我应该以某种方式将删除重新放回到主要活动中(我首先需要一个子类)?

  2. 如果我包含unregisterTouchArea,我知道为什么会得到IndexOutOfBoundsException?

  3. 感谢您的帮助。

2 个答案:

答案 0 :(得分:3)

永远不要在TouchListener中删除。你应该坚持使用IUpdateHandler

1。)没有必要进行子类化,你可以在任何可以访问场景的地方进行删除。

2。)由于您在TouchListener中执行删除操作,因此会发生IndexOutOfBoundException。当您删除精灵时,某些方法可能会为场景添加新内容。将删除放在UpdateHandler中解决了这个问题。

答案 1 :(得分:0)

/*
         * Removing entities can only be done safely on the UpdateThread. Doing
         * it while updating/drawing can cause an exception with a suddenly
         * missing entity. Alternatively, there is a possibility to run the
         * TouchEvents on the UpdateThread by default, by doing:
         * engineOptions.getTouchOptions().setRunOnUpdateThread(true); when
         * creating the Engine in onLoadEngine();
         */
        MainActivity.this.runOnUpdateThread(new Runnable() {
            @Override
            public void run() {
                /* Now it is safe to remove the entity! */
                mScene.detachChild(face);
            }
        });