ゲーム製作でHTML5-Canvasを勉強するぞ!! 第5回

| コメント(0) | トラックバック(0)

5.png 今回は、前回よりもさらにCanvasと関係ない、敵と自機弾との衝突判定を実装します。
衝突判定の方法はいろいろあると思います。

・厳密な形による判定
・矩形による判定
・円形による判定
・etc...

5a.png 難しいことは考えず、判定さえできれば良いときは矩形にしていますが、今回はあえて円形にします。
円形で衝突判定しをするというのは、要するにオブジェクト同士の距離を判定するということです。
各オブジェクトごとに中心(オブジェクトの位置)、半径を定義し、オブジェクト同士の距離が両オブジェクトの半径の和より小さければ衝突しているということになります。

実はCanvasには衝突判定に使えそうな関数があります。

isPointInPath(x, y)
x、yで示される点が現在のパス内にある場合trueを、そうでない場合falseを返す
点がパスに含まれているかを判定する関数です。
これをうまいこと使えば衝突判定ができそうですね。
ほかにも、衝突判定用のCanvasを用意し、そこに透明度50%ぐらいで各オブジェクトを描画して、最終的に描画された色を調べることで判定することもできそうです。
まあ、無理してCanvasを使う必要もないと思いますが(^^;

では、早速プログラムを。

var MyShot = function (x, y)
{
	this.x = x;
	this.y = y;
	this.radius = 4;

var Enemy = function ()
{
	this.x = Math.random() * WIDTH;
	this.y = -20;
	this.radius = 10;
自機弾と敵クラスにそれぞれradiusという変数を追加し、半径を定義しました。
オブジェクトの外接円よりは少し小さめにしています。
外接円だと大きすぎて、衝突していないのに衝突したと判断されたように見えてしまいます。
こういうのはシューティングゲームなどではプレーヤーの不満につながると思いますので、あえて小さめです。

衝突判定は専用の関数を用意しました。

var hitTest = function ()
{
	for (var n = 0; n < enemies.length; n++)
	{
		for (var m = 0; m < myShots.length; m++)
		{
			var d2 = (enemies[n].x - myShots[m].x) * (enemies[n].x - myShots[m].x) + (enemies[n].y - myShots[m].y) * (enemies[n].y - myShots[m].y);
			var r2 = (enemies[n].radius + myShots[m].radius) * (enemies[n].radius + myShots[m].radius);
			if (d2 < r2)
			{
				myShots.splice(m, 1);
				enemies.splice(n, 1);
				n--;
				break;
			}
		}
	}
}

先ほどオブジェクト同士の距離と書きましたが、実際には距離の二乗で判定しています。
わざわざ正確な距離を求める必要はありませんからね。
距離の二乗が半径の和の二乗より小さければ、自機弾と敵をオブジェクト管理配列から削除します。
ちなみにこの関数はとりあえず作ったもので、今後変更予定です。
汎用性がありませんし、耐久性のある敵とかに対応してませんからね。

あとはこのhitTestをメインループから呼び出すだけです。

setInterval(function ()
	{
		hitTest();

		if (!parseInt(Math.random() * 20)) enemies.push(new Enemy());
	
		move();
		draw(ctx);
		
	}, 1000 / 30);

Demo

次回は自機と敵の衝突判定の実装は後回しにして、もう少しCanvasに関係したことをやりたいと思います。

トラックバック(0)

トラックバックURL: http://murakya.net/mt/mt-tb.cgi/11

コメントする

オリジナルゲーム

オンラインツール