1

我是 AndEngine 游戏开发(或一般游戏开发)的新手,我正在开发一款非常简单的游戏。设置是我在游戏中有 4 个主要精灵:

a.) 战斗机 b.) 坦克 c.) 步兵 d.) 炸弹

游戏处于当前无限循环中。战机从左边出来,在屏幕上放大,每秒又从右边出来。坦克从屏幕左侧出来,走到屏幕中间,放下一些走到屏幕右侧的步兵。然后坦克将面朝左并回到它原来的地方。

玩家可以点击屏幕来发射一个直接向下的炸弹。当它击中坦克或士兵时,炸弹会爆炸(留下爆炸精灵)并且炸弹以及它所碰撞的物体(坦克或士兵)从场景中脱离。

我的困境是,我似乎无法解决涉及碰撞的逻辑。我的意思是肯定的,我得到了这些功能,但我在逻辑上被难住了。这是游戏本身的快照:

在此处输入图像描述

这是我的片段(这个函数是从 onCreateScene 更新处理程序中调用的:

    protected void checkTankCollision() {
    // TODO Auto-generated method stub

    int numCompares = bombGroup.getChildCount();
    for (int i = 0; i < numCompares; i++) {
        Sprite s = (Sprite) bombGroup.getChildByIndex(i);
        for (int j = 0; j < numCompares; j++) {
            Sprite s2 = (Sprite) tankGroup.getChildByIndex(j);
            if (s.collidesWith(s2)) {
                // boom
                AnimatedSprite boom = createExplosion();
                boom.setPosition(s.getX(), s.getY());
                getEngine().getScene().attachChild(boom);

                // WARNING: cannot detach from the list
                // while looping through the list
                final Sprite a = s;
                final Sprite b = s2;

                // this will do the action after the scene is done updating
                getEngine().getScene().postRunnable(new Runnable() {

                    @Override
                    public void run() {
                        a.detachSelf();
                        b.detachSelf();
                    }
                });
            }
        }
    }

}

一些炸弹发射后,游戏力量关闭。它给出了 indexOutOfBoundsException 错误。

这是logCat:

    09-22 00:12:14.565: E/AndroidRuntime(924): FATAL EXCEPTION: UpdateThread
    09-22 00:12:14.565: E/AndroidRuntime(924): java.lang.IndexOutOfBoundsException:  Invalid index 1, size is 1
    09-22 00:12:14.565: E/AndroidRuntime(924):  at  java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251)
    09-22 00:12:14.565: E/AndroidRuntime(924):  at java.util.ArrayList.get(ArrayList.java:304)
    09-22 00:12:14.565: E/AndroidRuntime(924):  at  org.andengine.entity.Entity.getChildByIndex(Entity.java:612)
    09-22 00:12:14.565: E/AndroidRuntime(924):  at com.cs119.bombthetank2.BombTankActivity.checkTankCollision(BombTankActivity.java:660)
    09-22 00:12:14.565: E/AndroidRuntime(924):  at com.cs119.bombthetank2.BombTankActivity$4.onUpdate(BombTankActivity.java:194)
    09-22 00:12:14.565: E/AndroidRuntime(924):  at org.andengine.engine.handler.UpdateHandlerList.onUpdate(UpdateHandlerList.java:47)
    09-22 00:12:14.565: E/AndroidRuntime(924):  at org.andengine.entity.Entity.onManagedUpdate(Entity.java:1395)
    09-22 00:12:14.565: E/AndroidRuntime(924):  at org.andengine.entity.scene.Scene.onManagedUpdate(Scene.java:284)
    09-22 00:12:14.565: E/AndroidRuntime(924):  at org.andengine.entity.Entity.onUpdate(Entity.java:1167)
    09-22 00:12:14.565: E/AndroidRuntime(924):  at org.andengine.engine.Engine.onUpdateScene(Engine.java:591)
    09-22 00:12:14.565: E/AndroidRuntime(924):  at org.andengine.engine.Engine.onUpdate(Engine.java:586)
    09-22 00:12:14.565: E/AndroidRuntime(924):  at org.andengine.engine.Engine.onTickUpdate(Engine.java:548)
    09-22 00:12:14.565: E/AndroidRuntime(924):  at org.andengine.engine.Engine$UpdateThread.run(Engine.java:820)

Entity 和 Scene 活动是 AndEngine 的一部分,那里真的不可能有错误。BombTheTank2 是我活动的名称,所以是的,错误就在那里。

4

2 回答 2

2

在停止遍历子列表之前,您似乎正在分离 Sprite。让我们以干净的方式来做。试试这个:

protected void checkTankCollision() {
    int numCompares = bombGroup.getChildCount();
    final ArrayList<Sprite> toBeDetached = new ArrayList<Sprite>();
    for (int i = 0; i < numCompares; i++) {
        Sprite s = (Sprite) bombGroup.getChildByIndex(i);
        for (int j = 0; j < numCompares; j++) {
            Sprite s2 = (Sprite) tankGroup.getChildByIndex(j);
            if (s.collidesWith(s2)) {
                // boom
                AnimatedSprite boom = createExplosion();
                boom.setPosition(s.getX(), s.getY());
                getEngine().getScene().attachChild(boom);

                // WARNING: cannot detach from the list
                // while looping through the list
                toBeDetached.add(s);
                toBeDetached.add(s2);

            }
        }
    }
    runOnUpdateThread(new Runnable() {
        @Override
        public void run() {
            for (Sprite s : toBeDetached) {
                s.detachSelf();
            }
            toBeDetached.clear();
        }
    });
}

编辑:实际问题出在其他地方——Erasmus 意外地迭代了 Tank 组的次数与 Bomb 组的次数相同。解决方案是检查坦克的数量并尽快停止迭代。

我个人总是使用 For-Each 循环,除非我真的需要知道索引,它为我省去了很多麻烦 :-)

于 2012-09-21T17:50:56.000 回答
1

我认为您需要在 UpdateThread 上进行“分离”,所以不要这样做

            getEngine().getScene().postRunnable(new Runnable() {

                @Override
                public void run() {
                    a.detachSelf();
                    b.detachSelf();
                }

试试这个

runOnUpdateThread(new Runnable() {

                    @Override
                    public void run() {
                        a.detachSelf();
                        b.detachSelf();
                    }

每次分离某些东西时,都应该减少 numCompares 值,一旦分离某些东西,包含这些实体的数组现在就更小了。由于您在开始时拉动数组长度,因此您最终会超过数组的末尾 - 因此您的 IndexOutOfBounds 错误。分离仍然需要在 UpdateThread 上运行。

于 2012-09-21T15:51:02.413 回答