衝突判定②
プログラムに置き換える
前ページの続きです。
やりたいことを具体的に細かく分割できたので、
あとはそれをプログラムにしていきます。
まず、
この図の 「★の位置が赤いラインより右側だったら」 というのをプログラムにしてみましょう。 |
改めて確認しておきますが、
自機は(player_x, player_y)の位置に表示されています。
正確には自機の左上の位置が(player_x, player_y)です。
ということは、上図の赤いラインはplayer_xから左に32のところなので
「player_x – 32」の位置だということですね?
同様に、★の左上の位置が(star_x, star_y)です。
以上のことを考えると、「★が赤線より右」というのは。
「star_x が player_x-32 により大きかったら」と表現できると思います。
「star_x が player_x-32 により大きかったら」を
プログラムにするのはできますね?
if(star_x > player_x – 32){ ・・・ } |
です。
if文の中で引き算をしていますが、こういうのは全然OKです。
同様に
1方向の判定ができたら他のも同じ考え方でできますね?
この図の 「★の位置が赤いラインより下だったら」 というのは・・・ |
if(star_y > player_y – 32){ ・・・ } |
で、いいですね?
よく分からなくなったら自分で図を書いてみるといいです。
次に、
この図の 「★の位置が赤いラインより左側だったら」 というのはどうでしょうか。 |
自機や★の位置は「左上を指している」というのを忘れないでください。
この状態では、star_xの位置は赤いラインより左側ですが、自機と★はぶつかってないですね? | |
これはぶつかっています。 |
つまり、★の右端が赤いラインより左にいないといけないわけですね。
ちょっと複雑になってしまうので考え方を変えましょう。
「★の左端が、紫のライン(自機の右端)より左ならば ぶつかっている」と言ってもいいですよね? |
これならプログラムにできそうです。
if(star_x < player_x + 32){ ・・・ } |
ですね。
この場合も同様の考えでいきましょう。 |
if(star_y < player_y + 32){ ・・・ } |
合成
ということで、
(star_x > player_x – 32)であり、
(star_y > player_y – 32)であり、
(star_x < player_x + 32)であり、
(star_y < player_y + 32)であるならば、
自機と★がぶつかっているということがわかりました。
ここまで長かったですね・・・。
さぁ、プログラムを修正しましょう。
;自機と★の衝突判定
if((star_x > player_x – 32) and (star_y > player_y – 32) and (star_x < player_x + 32) and (star_y < player_y + 32)){
end ;プログラム終了
}
await 16
goto *メインループ
資料の レイアウトの関係上、途中で改行されていますが、実際は1行に書いてください。
これで、★に接触するとプログラムが終了するようになったと思います。
実行して試してみてください。
調整
接触すると終了するようになりましたが、
ちょっと衝突範囲が広すぎる気がします。
近づいただけで接触したことになってしまいますね。
今は自機も★もサイズ32で考えていますが、
衝突範囲を実際のサイズよりも小さくしてみましょう。
今回は20にしてみたいと思います。
;自機と★の衝突判定
if((star_x > player_x – 20) and (star_y > player_y – 20) and (star_x < player_x + 20) and (star_y < player_y + 20)){
end ;プログラム終了
}
「どのくらいにしたらちょうどいいか」という質問に対しては
「やってみないとわからない」としか答えようがありません。
今変更した値をもっと小さくすれば当たりにくくなるし、
大きくすれば当たりやすくなります。
シューティングゲームの「かすり」は、こうやって作るんですね。
今回のポイント
-
ゲームプログラムには「作りながら調整する」という作業が必須です。