VisualBasic 2017 入門
34.メテオ4 隕石の移動と当たり判定
今回は [ メテオ3 Timer と自機の操作 ] の続きです。
プログラミングできるようになるには、プログラミングするのが一番です。
ピアノが弾けるようになりたいのに、けん盤や楽譜だけ見ていても上達しません。
当サイトでサンプルを入力し改造するのも勉強になりますが、
他にもプログラミングした方がいいでしょう。
何を作ればいいのか分からない場合には、よく使うアプリやゲームを
マネて自作してみるのはどうでしょうか?
ただ、同じものを作るのはむずかしいと思います。
そんな時はデフォルメすればいいのです。
ほんの一部の機能(または遊び)だけを再現してみましょう。
自分のできる範囲で制作するのです。
隕石の表示と移動
隕石ですが最大で10個表示することにします。
まずはプログラムを次のように変更してください。
実行してみましょう。
隕石が画面の上から下へ移動します。
配列とは
10個の隕石を動かすために、配列を使っています。
配列とは、同じ名前の変数を複数使うために用意されたものです。
変数と同じく宣言をしますが、カッコ()を付けます。
中の数値はいくつ用意するか指定します。
enX (9) としたなら、enX (0) から enX (9) まで使えるようになります。
つまり10個の変数が用意されたことになります。
配列を使う理由ですが、まとめて処理しやすいところです。
10個の隕石のために、10個の変数を宣言して、それぞれに値を代入するとなると20行ものプログラムになります。
配列を使えば、宣言に1行、代入に3行程度で済みます。
今回のプログラムでも For 文を使って、10個の隕石座標にセットしています。
それから For Next ですが、このセットで1つの命令になっています。
For と Next の間にある処理を、指定された数だけループします。
For i As Long = 0 To 9
これは変数 i を宣言して、0から9まで変化させながらループさせるという指定です。
次のように書けば enX (0) から enX (9) のすべてに 55 を代入することができます。
For i As Long = 0 To 9
enX (i) = 55
Next
隕石の発生について
サブルーチン gameInit 内で行っている隕石の座標処理を見てみましょう。
enX にはx座標をセットします。
画面サイズ(pBase のサイズ)は横 480 なので、これにおさまるように
乱数を作ります。
隕石のサイズも考えて、480 より小さい 450 としました。
次はY座標です。
乱数を1から 900 までの間で発生させ 1000 を引いています。
これは画面の上、画面外から隕石を発生させるためにしています。
1から 900 までの長さにした理由は、隕石落下にバラツキを持たせるためです。
隕石の移動について
移動については簡単です。
Y座標 enY に+5して下方向へ移動させます。
この値が大きければ移動が速くなります。
あとは g.DrawImage を使って隕石を描画するだけです。
変数 RR は隕石の半径なので2倍しています。
enY が pBase.Height よりも大きいときは、隕石が画面外へ出たことになるので
画面の上に戻す処理を入れてます。
初期設定のときより乱数の幅が狭いのは、すでに散らばっているからです。
自機と隕石の当たり判定をしよう
自機と隕石の当たり判定をします。
プログラムを次のように変更してください。
サブルーチン hitCheck を作成して、Timer1_Tick の最後で呼び出します。
実行してみましょう。
当たり判定ができているか調べるために、タイトルに hit 表示するようにしました。
確認してみましょう。
当たり判定のしくみ
当たり判定の方法はいろいろあります。
前回の突破ゲームでは、2つの四角い範囲が当たっているか調べました。
しかし今回は隕石が丸いため、あまり良い方法ではありません。
ここは2点間の距離による当たり判定をおこないます。
しくみについては次のページでくわしく説明しています。
[ 2点間の距離による当たり判定 ]
プログラムは次のようになっています。
当たり判定として重要なのは、どの距離と比較するかです。
今回は隕石の半径と自機の中心点を比較しました。
つまり、自機の厚みは計算に入れてません。
右図では隕石の半径内に中心が入っていないため、絵が重なっていても当たっていないことになります。
左図では半径内に中心が入っているので、当たっていると判断されます。
当たったら処理を止めよう
自機と隕石が当たったら処理を止めるようにします。
プレイヤーのやられかたは色々ありますが、当たったことがはっきりと分かるように動きを止めることにします。
当たり判定用のフラグ hitFlg を作ります。
タイプを Boolean で宣言していることに注意してください。
このようなフラグを作成したときには、初期処理 gameInit の中で初期化しましょう。
これは基本ですね。
処理を止めるのは簡単で Timer1_Tick の中の処理をさせなければいいのです。
hitFlg が真(True)ならばサブルーチンを抜けるようにします。(37 行目)
あとは当たり判定の中で、フラグを立てる(True にする)だけです。(75 行目)
タイトルを使って hit 表示していた部分は削除してください。
これで自機と隕石が当たったら画面が止まります。
自機の操作もできなくなります。
実行して確認してみましょう。