0

私が使用しているArrayListは2つあり、1つは敵のスプライト用で、もう1つは弾丸用です。アプリを実行すると、エミュレーターでクラッシュすることがあり、いくつかのレベルでは、衝突時にデバイスでクラッシュします。ログには、単純なListIteratorエラーがあることが示され続けます。ListIteratorをどのように実装するか知りたかったのです。私はListIteratorを使用していません。情報や例を探すために検索しましたが、実際にそれを行う方法について少し混乱しています。add()関数はビュークラスのonTouchメソッドで呼び出され、衝突はスレッドクラス内の独自の衝突メソッドで発生します。

ログ:

07-20 19:57:46.604: ERROR/AndroidRuntime(234): Uncaught handler: thread Thread-9 exiting due to uncaught exception
07-20 19:57:46.613: ERROR/AndroidRuntime(234): java.util.ConcurrentModificationException
07-20 19:57:46.613: ERROR/AndroidRuntime(234):     at java.util.AbstractList$SimpleListIterator.next(AbstractList.java:64)
07-20 19:57:46.613: ERROR/AndroidRuntime(234):     at com.android.hitmanassault.HitmanView$HitmanThread.startGame(HitmanView.java:333)
07-20 19:57:46.613: ERROR/AndroidRuntime(234):     at com.android.hitmanassault.HitmanView$HitmanThread.gameStart(HitmanView.java:290)
07-20 19:57:46.613: ERROR/AndroidRuntime(234):     at com.android.hitmanassault.HitmanView$HitmanThread.updateGame(HitmanView.java:393)
07-20 19:57:46.613: ERROR/AndroidRuntime(234):     at com.android.hitmanassault.HitmanView$HitmanThread.run(HitmanView.java:237)

衝突をチェックします:

private void startGame(){
            synchronized(mSurfaceHolder){
                for(Beam bullet: beam){
                    for(Sprite sprite: sprites){
                        if(checkCollision(sprite, bullet)){
                            sprites.remove(sprite);
                            beam.remove(bullet);
                            mScore = mScore + 1;
                            break;
                        }               
                    }
                }
            }       
        }

衝突方法:

public boolean checkCollision(Sprite sprite, Beam bullet){

            boolean retValue = false;
            int SpriteX = sprite.getX();
            int SpriteY = sprite.getY();
            int SpriteXS = sprite.getX() + sprite.getWidth();
            int SpriteYS = sprite.getY() + sprite.getHeight();  
            int BeamX = bullet.getX();
            int BeamY = bullet.getY();
            int BeamXS = bullet.getX() + bullet.getBitmap().getWidth();
            int BeamYS = bullet.getY() + bullet.getBitmap().getHeight();


            if ((BeamX >= SpriteX && BeamX <= SpriteXS) || (BeamXS >= SpriteX && BeamXS <= SpriteXS)) {
                if ((BeamY >= SpriteY && BeamY <= SpriteYS) || (BeamYS >= SpriteY && BeamYS <= SpriteYS)) {
                    retValue = true;
                }
            }   
            return retValue;
        }
4

1 に答える 1

2

別のスレッドがリストを反復処理しているときに要素をリストに追加すると、ConcurrentModificationExceptionが発生します。

ConcurrentLinkedQueueを試すことはできますが、ゲームの整合性モデルの要件に応じて、アーキテクチャを再考する必要があります。

これが問題です。

for(Sprite sprite: sprites) { <------- Iterate
    if(checkCollision(sprite, bullet)) {
        sprites.remove(sprite); <-------- Modify
...

簡単な修正は、削除したいすべての要素を収集し、forループの後でそれらを削除できることです。

ArrayList<Beam> toBeRemoveBeams = new ArrayList<Beam>();
ArrayList<Sprite> toBeRemoveSprites = new ArrayList<Sprite>();
for(Beam bullet: beam){
    for(Sprite sprite: sprites){
        if(checkCollision(sprite, bullet)){
            toBeRemoveBeams.add(beam);
            toBeRemoveSprites.add(sprite);
            mScore = mScore + 1;
            break;
        }               
    }
}
beam.removeAll(toBeRemoveBeams);
sprites.removeAll(toBeRemoveSprites );
于 2011-07-21T01:27:15.393 に答える