初心者のためのゲームプログラミング入門

プログラミングとゲームの杜

初心者のためのプログラミング入門 & ゲームプログラムの作り方入門

Visual C# 2017 入門

34.メテオ4 隕石の移動と当たり判定

 

今回は [ メテオ3 Timer と自機の操作 ] の続きです。

プログラミングできるようになるには、プログラミングするのが一番です。
ピアノが弾けるようになりたいのに、けん盤や楽譜だけ見ていても上達しません。
当サイトでサンプルを入力し改造するのも勉強になりますが、
他にもプログラミングした方がいいでしょう。
何を作ればいいのか分からない場合には、よく使うアプリやゲームを
マネて自作してみるのはどうでしょうか?
ただ、同じものを作るのはむずかしいと思います。
そんな時はデフォルメすればいいのです。
ほんの一部の機能(または遊び)だけを再現してみましょう。自分のできる範囲で制作するのです。

 

 

隕石の表示と移動

隕石ですが最大で10個表示することにします。
まずはプログラムを次のように変更してください。

 

隕石の表示と移動

 

62 行目は、命令が長くなってしまったので2行に分けています。
1行で入力してもいいのですが、今後の説明と合わせたいなら2行に分けてください。

 

実行してみましょう。
隕石が画面の上から下へ移動します。

 

隕石の絵を移動させる

 

 

配列とは

10個の隕石を動かすために、配列を使っています。
配列とは、同じ名前の変数を複数使うために用意されたものです。

変数と同じく宣言をしますが、角括弧 [ ] を付けます。読み方はかくかっこです。
中の数値はいくつ用意するか指定します。

 

c# 配列とは

 

 

int [] enX = new int [10] としたなら、enX [0] から enX [9] まで使えるようになります。
つまり10個の変数が用意されたことになります。

配列を使う理由は、まとめて処理しやすくするためです。
10個の隕石のために、10個の変数を宣言してそれぞれに値を代入するとなると、20行ものプログラムになります。

配列を使えば、宣言に1行、代入に4行程度で済みます。
今回のプログラムでも for 文を使って、10個の隕石座標にセットしています。

 

配列を使うメリット

 

for 文ですが、これはくり返し処理するための命令です。

for ( int i=0; i<10; i++)

これは変数 i を宣言して、0から9まで変化させながら波かっこ { } の中を
くり返すことになります。
enX [0] から enX [5] の値をすべて55にしたいなら次のように書きます。

for (int i=0; i<6; i++)
{
enX [ i ] = 55;
}

 

 

隕石の発生について

メソッド initGame の中で行っている隕石の座標処理を見てみましょう。
enX にはx座標をセットします。
画面サイズ(pBase のサイズ)は横 480 なので、これにおさまるように
乱数を作ります。
隕石のサイズも考えて、480 より小さい 450 としました。

 

初期配置の考え方

 

 

次はY座標です。
乱数を1から 900 までの間で発生させ 1000 を引いています。
これは画面の上、画面外から隕石を発生させるためにしています。
1から 900 までの長さにした理由は、隕石落下にバラツキを持たせるためです。

 

y座標の隕石出現位置

 

 

隕石の移動について

移動については簡単です。
Y座標 enY に+5して下方向へ移動させます。
この値が大きければ移動が速くなります。
あとは gg.DrawImage を使って隕石を描画するだけです。

 

隕石の移動について

 

変数 RR は隕石の半径なので2倍しています。
enY が pBase.Height よりも大きいときは、隕石が画面外へ出たことになるので
画面の上に戻す処理を入れてます。
初期設定のときより乱数の幅が狭いのは、すでに散らばっているからです。

 

 

自機と隕石の当たり判定をしよう

自機と隕石の当たり判定をします。
timer1_Tick の下にメソッド hitCheck を追加してください。
このメソッドは timer1_Tick の最後で呼び出します。(83 行目)
忘れずに追加しましょう。

 

自機と隕石の当たり判定

 

 

実行してみてください。
当たり判定ができているか調べるために、タイトルに hit を表示するようにしました。
自機と隕石を重ねてみて確認しましょう。

 

当たったかどうかを調べる方法

 

 

当たり判定のしくみ

当たり判定の方法はいろいろあります。
前回の突破ゲームでは、2つの四角い範囲が当たっているか調べました。
しかし今回は隕石が丸いため、適切な方法とはいえません。
ここは2点間の距離による当たり判定をおこないます。
しくみについては次のページでくわしく説明しています。

[ 2点間の距離による当たり判定 ]

 

プログラムは次のようになっています。
97, 98 行目は隕石の中心を算出しています。

 

2点間の距離で当たり判定をする

 

 

 

当たり判定として重要なのは、どの距離と比較するかです。
今回は隕石の半径と比較しました。
つまり、自機の厚みは計算に入れてません。

 

どの距離と比較するか

 

隕石の半径と比較しているため、自機の絵が隕石と重なっていても(右図)
当たっていないことになります。
自機の中心が隕石の半径距離に入って「当たっている」となるのです(左図)

 

 

 

当たったら処理を止めよう

自機と隕石が当たったら処理を止めるようにします。
プレイヤーのやられかたは色々ありますが、当たったことがはっきりと分かるように動きを止めることにします。

当たり判定用のフラグ hitFlg を作ります。
タイプを Boolean で宣言していることに注意してください。
このようなフラグを作成したときには、初期処理 initGame の中で初期化しましょう。
これは基本ですね。

 

フラグを使って流れを管理する

 

処理を止めるのは簡単で timer1_Tick の中の処理をさせなければいいのです。
hitFlg が真(true)ならばメソッドを抜けるようにします。(60 行目)
あとは当たり判定の中で、フラグを立てる(true にする)だけです。(108 行目)
タイトルを使って hit 表示していた部分は削除してください。

 

これで自機と隕石が当たったら画面が止まります。
自機の操作もできなくなります。
実行して確認してみましょう。