使用 Andengine 安全删除精灵

发布于 2025-01-07 06:31:23 字数 1399 浏览 1 评论 0原文

我正在创建很多在屏幕上随机弹跳的球精灵。当被触摸时,我希望将球从场景中移除。 (如果多个球占据同一空间,此时该球也将被移除)。

我意识到 scene.detachChild 必须在 runOnUpdateThread 上运行,因此在我的 Ball sprite 子类中,我通过重写 onAreaTouched 来分离触摸时的Child:

        @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 中分离精灵有关。

**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 吗?

感谢您的任何帮助。

I am creating lots of ball sprites which bounce around the screen randomly. When touched, I want to the ball to be removed from the scene. (If more than one ball occupies the same space, that will be removed as well at the moment).

I realise the scene.detachChild must be run on the runOnUpdateThread, so within my Ball sprite subclass, I detachChild on touch by overriding onAreaTouched:

        @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;
    }

I have to pass in the main Activity to the constructor of the ball sprite and then remove the ball from the main Activities scene.

If I uncomment the scene.unregisterTouchArea(Ball.this) line, to stop the sprites acting on touches (this doesn't affect the removal, but thought it better to stop the touch being processed), I will receive the indexOutOfBoundsException that I think is related to not detaching sprites from within a runOnUpdateThread.

**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)**

Two questions:

  1. Am I correct to process the removal of the sprite within the ball subclass, using the override onAreaTouched, or should I somehow take the removal back into the main activity (do I need a subclass in the first place)?

  2. Any idea why I get the IndexOutOfBoundsException if I include the unregisterTouchArea?

Thanks for any help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

孤单情人 2025-01-14 06:31:23

切勿在 TouchListener 中进行删除。您应该坚持使用 IUpdateHandler

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

2.) 发生 IndexOutOfBoundException 是因为您在 TouchListener 中进行了删除。当您删除精灵时,可能有某种方法会向场景添加新的东西。将删除放入 UpdateHandler 中可以解决此问题。

Never do removal in the TouchListener. You should stick with a IUpdateHandler.

1.) It is not necessary to subclass you might do the removal everywhere where you have access to a scene.

2.) The IndexOutOfBoundException happens because you do the removal in the TouchListener. Probably some method adds new things to the scene while you are removing the sprite. Putting the removal in an UpdateHandler solves this.

暗恋未遂 2025-01-14 06:31:23
/*
         * 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);
            }
        });
/*
         * 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);
            }
        });
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文