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 && bNow.x<eNow.x+eNow.w && eNow.y<bNow.y+bNow.h && bNow.y<=eNow.y+eNow.h){ j.remove(); //弾を消す i.remove(); //敵を消す } } }
上記コードを通した結果を下記のコードで表示してみます。
//結果の表示 System.out.println("実行結果"); for(Iterator<Enemy> i = enemys.iterator(); i.hasNext();){ eNow = i.next(); System.out.println("敵は("+(int)eNow.x+","+(int)eNow.y+")にいます。"); } for(Iterator<Bullet> i = bullets.iterator(); i.hasNext();){ bNow = i.next(); System.out.println("弾は("+(int)bNow.x+","+(int)bNow.y+")にあります。"); }
さて結果は下記のようになりました。やはり問題ないようだな。しっかり想定どおり最初の敵と最初の弾のみ消えている。別の部分に問題があるってことだな。。
実行結果 敵は(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)にあります。