2011年8月28日日曜日

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 && 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)にあります。

0 件のコメント:

コメントを投稿