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

子のリストの反復を停止する前に、スプライトを切り離しているようです。きれいにやってみましょう。これを試して:

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