ゲームプログラミング練習帳

シューテングゲームを作る>第三回当たり判定とゲームの管理

 前回で、自機を動かして弾を打てるようになり、また敵も弾を打ってくるようになりました。 今回は、その弾と自機・敵との「当たり判定」をする部分を作りましょう。 これができれば、弾に当たれば「やられる」ようになり、 敵との「真剣勝負」が行われるわけです。

・実行画面

・当たり判定

 今回のプログラムでは、自機・敵・弾がすべて「長方形」なので、 実は当たり判定はあっけないほど簡単だったりします(長方形にしたのは、 わかりやすくするためで別に「手抜き」ではない.... というのは説得力ないか、やはり)。当たり判定とは、 キャラクタが「重なっているか」という判定なので、長方形なら弾の「端」 の座標が自機や敵の「内側」にめりこんでいるかどうかを調べれば良いのです。
 例えば、左上の端の座標が(X1,Y1)、(X2,Y2)である物体1、物体2 二つの物体を考えてみましょう。二つの物体とも大きさは縦横共に8ドットとします。 この二つの物体が「重なっているか」判定する式は、

 X 方向がX1<X2 かつ X1+7>X2

 Y 方向がY1<Y2 かつ Y1+7>Y2 になります。

 X 方向で考えれば、「重なる」ためにはX2(物体2の左端) がX1(物体1の左端) とX1+7(物体1の右端) の間にある事が必要ですね。 これは、X2 がX1 の右側(X 方向に正)にあり、しかもX1+7 の左側にある、 という事を意味しますから、上のような条件になるわけです。
 このプログラムでは、自機のX 座標がx, 敵のX 座標がex で大きさは32*16、弾の座標はそれぞれ(lx,ly) (elx,ely) ですので、 当たり判定は以下のようになります(なお、 31でなく32を足した座標で判定するのは「かすめた」のも当たりと判定するから)。

	if (elx>x && elx<x+32 && ely>280 && els) { /* 敵弾と自機 */

	if (lx>ex && lx<ex+32 && ly<24 && ls) { /* 自機の弾と敵 */


 Y 方向は自機・敵とも上下の端で固定ですから、単純にある値以下・以上で判定しました。 なお、ls, els は弾が発射されているかを示すフラグで、 発射されている時にのみ当たり判定を有効にしています。 自機か敵どちらかが弾に当たっていたら爆発イメージを表示して、ゲームを終了させます(st を0 にする)。

・ゲームの制御

 次にゲームオーバーや新しいゲームの開始、といったゲームの制御を考えてみます。 このゲームは、スレッドの中でゲーム中の処理をする構造になっているので、 処理をゲーム中とゲームオーバー(開始前)とで変えてやれば良いでしょう。 ゲーム中ならゲームの処理を行い、 ゲーム中でなければマウスボタンをクリックしてゲームを始めるよう、 メッセージを出して促します。そのために、ゲームの状態を示す変数st を作りました。この変数が1ならゲーム中、0ならゲームオーバー(あるいは開始前) である事を意味します。流れとしては、

	if (st==0) { /* ゲーム中でなければ */

		メッセージを表示
			・
			・
			・

	}

	if (st==1) { /* ゲーム中なら */

		ゲーム中の処理
			・
			・
			・

	}

 という感じですね。メッセージは、FontMetrics オブジェクトで得た文字列の横幅を基にセンタリング(中央寄せ)してあります。 それから、ゲーム中の処理も移動・弾・判定と処理ごとに関数に整理しました。 特に、移動の部分では敵が自機の弾から「逃げる」処理を入れてみましたので、 その部分をいろいろいじってみるとおもしろいでしょう。

 これでいちおう敵との「戦い」ができるようになったので、 とりあえず「シューテングゲームを作る」は終えたいと思います。 後は、難易度調整や得点などの処理を入れて、 皆さん独自のゲームを完成させてください。

プログラムソース表示
戻る  トップページへ