Jasmine Teaで当たり判定!

この記事は、 [Jasmine Tea アドベントカレンダー 2023](https://qiita.com/advent-calendar/2023/jasminetea) の第24日目です。

# はじめに

[Jasmine Tea](https://jasminetea.app) (ジャスミンティー) は、プログラミングの楽しさを多くの人に知ってもらうために作られたプログラミング言語です。初心者が学びやすい仕組みで、実際に社会で使われている多くのプログラミング言語に応用できる基礎が身に付きます。

ここでは、Jasmine Teaを実際に開いて、ゲームで必要となる「当たり判定」の方法について紹介してみたいと思います。

まず、Studio 画面を開いてください。もし Studio 画面をまだ開いたことがなければ、 [Studio画面を表示する - Jasmine TeaでHello, world!](https://qiita.com/yoichiro6642/items/3dc478726f4f73941b46#studio%E7%94%BB%E9%9D%A2%E3%82%92%E8%A1%A8%E7%A4%BA%E3%81%99%E3%82%8B) を参考にして Jasmine Tea の試用を開始してください。

# 当たり判定とは？

多くのゲームでは、キャラクターとキャラクラー、キャラクターと弾、キャラクターと障害物、といったもの同士が触れたりぶつかったときには、何かが起きます。例えば、

* キャラクターとキャラクターが触れれば、RPG であれば会話が始まったり戦闘が始まります。
* キャラクターと弾がぶつかったときには、爆発してゲームオーバーになります。
* キャラクターと障害物が触れれば、その方向に移動できなくなります。

といったようなルールがあります。つまり、ゲームにおいては「当たり判定が全て」と言っても言い過ぎではありません。

Jasmine Tea では、当たり判定を簡単に実現するための関数が2つ提供されています。今日は、それらを紹介します。

# スプライトと図形の当たり判定

今日はスプライトを使うので、スプライトダイアログを使って、キャラクターをスプライトに割り当てておきましょう。以下の手順を行ってください。

1. Studio 画面のエディターの下にある「スプライト」ボタンを押して、スプライトダイアログを開きます。
1. 右のキャラクターから2つ選択して、「スプライト 0」と「スプライト 1」の左の四角にそれぞれドラッグアンドドロップします。
1. スプライトダイアログの「閉じる」ボタンを押します。

![スクリーンショット 2023-12-24 19.09.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632303/9891aabd-b40e-970a-591a-983220f292a8.png)

これで2つのキャラクターを画面に出す準備ができましたが、最初はスプライト 0に割り当てたキャラクターを1つだけ使います。

Studio 画面のエディターに、以下のプログラムを入力してください。

```vb
show 0,(0,150)
speed 0,18
direction 0,3
distance 0,640
move 0
```

「実行」ボタンを押してこのプログラムを実行すると、男の子が実行画面上を右に1周歩きます。

![crash-1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632303/0a6b6c70-23b3-0fc5-d75c-e889060d362c.gif)

次に、男の子が歩く先に、障害物となる図形を [`box` 命令](https://jasminetea.app/docs/references/command-box) を使って描いてみましょう。エディターの `move 0` と書かれた行の次の行に、以下のプログラムを入力してください。

```vb
box (200,150)-(231,181),2,2
```

プログラムを「実行」ボタンを押して実行してみてください。男の子は、赤い四角の障害物の上を何事もなかったかのように通り過ぎます。

![chash-2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632303/ad795e46-c61a-1472-2ede-fd436d2333ab.gif)

このプログラムは、男の子が歩き終わる前に終了しています。 [`do` 命令](https://jasminetea.app/docs/references/command-do) と [`loop` 命令](https://jasminetea.app/docs/references/command-loop) で無限ループを作りましょう。`box` 命令が書かれた行の次の行から、以下のプログラムを入力してください。

```vb
do
loop
```

再度「実行」ボタンを押してプログラムを実行すると、今度は男の子が歩き終わってもプログラムは終了しません。「止める」ボタン、もしくはキーボードの ESCAPE キーを押すと、プログラムを止めることができます。

さて、ここからが本題です。男の子が赤い四角の障害物に当たったことを判定するには、どうしたら良いでしょうか？

これは、「スプライトが表示されている位置に、赤い色が重なっているかどうか」を判定すれば、すなわち当たったと判定できます。Jasmine Tea では、[`touch` 関数](https://jasminetea.app/docs/references/function-touch) を使うことで、スプライトが描かれている場所のグラフィック画面に指定された色が存在するかどうかを確認することができます。

では、`do` 命令と `loop` 命令の間の行に、以下のプログラムを入力してください。

```vb
  if touch(0,2) then
    print "Hit!"
    stay 0
    exit do
  end if
```

[`if` 命令](https://jasminetea.app/docs/references/command-if) の条件式に `touch(0,2)` を指定しています。これにより、「スプライト番号 0 のキャラクターが書かれている領域に、グラフィック画面で色番号 2 となっている箇所があるかどうか」を確認しています。もしこの条件式が成立したときは、次の行から `end if` 命令までの間が実行されます。ここでは、以下のような処理を行っています。

* [`print` 命令](https://jasminetea.app/docs/references/command-print) によりテキスト画面に "Hit!" と表示する。
* [`stay` 命令](https://jasminetea.app/docs/references/command-stay) によって、スプライト 0 の移動を停止させる。
* [`exit do` 命令](https://jasminetea.app/docs/references/command-exit%20do) によって、`loop` 命令の次の行にジャンプして、繰り返しから抜ける。

「実行」ボタンを押して、プログラムを実行してください。

![crash-3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632303/a6e1dbeb-26a1-1ac7-edb4-704be943afc6.gif)

男の子が赤い四角に触れたときに、"Hit!" と表示されてプログラムが終了します。これで、スプライトと図形の当たり判定ができました。

# スプライト同士の当たり判定

次に、キャラクター同士が触れたとき、つまりスプライトの当たり判定について紹介します。まずは、エディター内に入力されているプログラムを全て消去して、以下のプログラムを入力してください。

```vb
show 0,(0,150)
speed 0,18
direction 0,3
distance 0,640
move 0
show 1,(200,150)
do
loop
```

「実行」ボタンを押して、プログラムを実行してください。先ほどは赤い四角でしたが、今度は同じ場所に女の子が立っています。男の子は女の子を素通りして歩き続けます。

![crash-4.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632303/f38e09f2-731d-2658-289e-75dc01093f13.gif)

Jasmine Tea では、スプライト同士が衝突したかどうかを [`crash` 関数](https://jasminetea.app/docs/references/function-crash) で確認することができます。では、`do` 命令の次の行から、以下のプログラムを追記してください。

```vb
  if crash(0,1) then
    print "Hit!"
    stay 0
    exit do
  end if
```

`crash` 関数の引数に、当たり判定したいスプライトの番号を2つ指定します。これを `if` 命令の条件式とすることにより、2つのスプライトが当たったかどうか判定できます。もし衝突していたときは、先ほどと同じ処理を行っています。

「実行」ボタンを押して、プログラムを実行してください。

![crash-5.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632303/81c89a2c-1305-2bc4-db58-f33a7486fba0.gif)

男の子が女の子の手前で止まるのがわかります。

# 明日は何をつくるの？

明日は、音声を使ったプログラムを紹介する予定です。