・実行画面
・当たり判定
今回のプログラムでは、自機・敵・弾がすべて「長方形」なので、
実は当たり判定はあっけないほど簡単だったりします(長方形にしたのは、
わかりやすくするためで別に「手抜き」ではない....
というのは説得力ないか、やはり)。当たり判定とは、
キャラクタが「重なっているか」という判定なので、長方形なら弾の「端」
の座標が自機や敵の「内側」にめりこんでいるかどうかを調べれば良いのです。
例えば、左上の端の座標が(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) { /* 自機の弾と敵 */
・ゲームの制御
次にゲームオーバーや新しいゲームの開始、といったゲームの制御を考えてみます。 このゲームは、スレッドの中でゲーム中の処理をする構造になっているので、 処理をゲーム中とゲームオーバー(開始前)とで変えてやれば良いでしょう。 ゲーム中ならゲームの処理を行い、 ゲーム中でなければマウスボタンをクリックしてゲームを始めるよう、 メッセージを出して促します。そのために、ゲームの状態を示す変数st を作りました。この変数が1ならゲーム中、0ならゲームオーバー(あるいは開始前) である事を意味します。流れとしては、
if (st==0) { /* ゲーム中でなければ */ メッセージを表示 ・ ・ ・ } if (st==1) { /* ゲーム中なら */ ゲーム中の処理 ・ ・ ・ }
という感じですね。メッセージは、FontMetrics オブジェクトで得た文字列の横幅を基にセンタリング(中央寄せ)してあります。 それから、ゲーム中の処理も移動・弾・判定と処理ごとに関数に整理しました。 特に、移動の部分では敵が自機の弾から「逃げる」処理を入れてみましたので、 その部分をいろいろいじってみるとおもしろいでしょう。
これでいちおう敵との「戦い」ができるようになったので、 とりあえず「シューテングゲームを作る」は終えたいと思います。 後は、難易度調整や得点などの処理を入れて、 皆さん独自のゲームを完成させてください。