Logicky Blog

Logickyの開発ブログです

Java LinkedListのテスト(Android Game 敵と弾の当たり判定〜削除)

Androidでゲームを作っているのですが、敵も沢山いて、プレイヤーが撃った弾も沢山ある場合、敵毎に全ての弾と当たり判定を実施する必要があります。敵が弾に当たっている場合は、敵と当たっている弾を削除します。簡単に出来ると思っていたのですが、今これにハマっています。。よって頭を整理しながらまとめていきたいと思います。

敵と弾は数が自在に調整できた方がいいので、今回のテスト対象であります、LinkedListに格納していきます。ArrayListかLinkedListかどちらを選択するかについてですが、このページを見て、削除が多いのでLinkedListを使うことにします。敵はEnemyクラスのインスタンスになり、弾はBulletクラスのインスタンスになります。

まず、Enemyクラスは下記とします。

public class Enemy {
    float x, y, w = 30, h = 30;

    public Enemy(float X, float Y){
        x = X; y = Y;
    }
}


次に、Bulletクラスは下記とします。(今回はテストなので分かり易くする為に弾の大きさを敵と同じ��しました。)

public class Bullet {
    float x, y, w = 30, h = 30;

    public Bullet(float X, float Y){
        x = X; y = Y;
    }
}


次に、EnemyクラスとBulletクラスを格納するためのLinkedListを2つ作ります。

private LinkedList<Enemy> enemys = new LinkedList<Enemy>();
private LinkedList<Bullet> bullets = new LinkedList<Bullet>();


次に、敵と弾のインスタンスを3つずつ作成し、LinkedListに格納します。インスタンス作成時の引数はx座標とy座標になりますので、最初の敵と最初の弾はまさに同じ場所にいて、その他の敵と弾は全く別の場所にいることになります。つまり、後程のコードで、うまく最初の敵と最初の弾だけ消えればゴールになります。

//敵の生成
enemys.add(new Enemy(10,10));
enemys.add(new Enemy(30,50));
enemys.add(new Enemy(100,100));
//弾の生成
bullets.add(new Bullet(10,10));
bullets.add(new Bullet(200,200));
bullets.add(new Bullet(300,300));


それでは、実際に当たり判定処理と、当たっている場合の削除をしてみます。想定するコードは下記です。

//敵と弾の衝突判定
Enemy eNow; Bullet bNow;
for(Iterator<Enemy> i = enemys.iterator(); i.hasNext();){
    eNow = i.next();
    for(Iterator<Bullet> j = bullets.iterator(); j.hasNext();){
        bNow = j.next();
        if(eNow.x<bNow.x+bNow.w &amp;&amp; bNow.x<eNow.x+eNow.w &amp;&amp;
                eNow.y<bNow.y+bNow.h &amp;&amp; bNow.y<=eNow.y+eNow.h){
            j.remove(); //弾を消す
            i.remove(); //敵を消す
        }
    }
}


上記コードを通した結果を下記のコードで表示してみます。

//結果の表示
System.out.println(&quot;実行結果&quot;);
for(Iterator<Enemy> i = enemys.iterator(); i.hasNext();){
    eNow = i.next();
    System.out.println(&quot;敵は(&quot;+(int)eNow.x+&quot;,&quot;+(int)eNow.y+&quot;)にいます。&quot;);
}
for(Iterator<Bullet> i = bullets.iterator(); i.hasNext();){
    bNow = i.next();
    System.out.println(&quot;弾は(&quot;+(int)bNow.x+&quot;,&quot;+(int)bNow.y+&quot;)にあります。&quot;);
}


さて結果は下記のようになりました。やはり問題ないようだな。しっかり想定どおり最初の敵と最初の弾のみ消えている。別の部分に問題があるってことだな。。

実行結果
敵は(30,50)にいます。
敵は(100,100)にいます。
弾は(200,200)にあります。
弾は(300,300)にあります。


試しに弾の位置を少し変えて実行してみよう。最初の弾の位置をずらしました。

//敵の生成
enemys.add(new Enemy(10,10));
enemys.add(new Enemy(30,50));
enemys.add(new Enemy(100,100));
//弾の生成
bullets.add(new Bullet(30,40));
bullets.add(new Bullet(200,200));
bullets.add(new Bullet(300,300));


実行結果は下記のとおり。これは敵・弾ともに消えているけど、敵はもう一匹消えるべきだな。最初の敵と2番目の敵に両方当たっているはずだからね。まあでも今は敵同士は離れているので、これが問題ではないな。

実行結果
敵は(30,50)にいます。
敵は(100,100)にいます。
弾は(200,200)にあります。
弾は(300,300)にあります。