
このブログテーマでは、スクラッチの初心者から上級者まで、ちょっとお役に立つ情報を不定期で紹介していきます。
スクラッチ講座、投稿記事のまとめはこちら(一分間スクラッチ講座 まとめ)でご参照ください。
前回の記事では作成したブロックにボールが当たったら削除される、さらに当たったボールがはね返るという動きを作ってみました。上下からの衝突時の跳ね返りの場合は、作成したプログラムで問題はないのですが、左右からの跳ね返りの場合は想定外の動きをします。
この記事では横からの跳ね返りにも対応できるプログラムをご紹介します。
下の動画は不定期配信の「ファイブボックス一分間スクラッチ講座」です。ご興味のある方は併せてご参照ください。
上下と左右の跳ね返り
前回作成したプログラムは上下からの跳ね返りにのみ有効です。
例えば下の図のように、ボールが60度の向きをもってブロックに衝突した場合、ボールは120度の向きをもってはね返ります。ボールが侵入してくる向きを「入射角」、はね返るときの向きを「反射角」とすると次の式が成り立ちます。
反射角=180度 - 入射角

一方、横からの衝突の場合、この反射角をとってしまうと、ボールがどんどん内部へ侵入し続けることになります。
横からの侵入の場合、例えば-30度の向きをもって侵入した場合、下の図のように30度に向かってはね返ります。このとき以下の式が成立します。
反射角= 0度 - 入射角
※0度は省略可

上下と左右の衝突判定
ボールがブロックに上下から当たったのか、左右から当たったのかを知るには、ブロックに色を付けるなどの工夫が必要です。しかし今回は、ブロックの段ごとに色を変化させているので、この方法はちょっと難しいようです。
そこで今回は、ボールが衝突したブロックに対し、自分自身(ブロッククローン)とボールの距離を計測し、上下、または左右からの衝突を判定します。
作成したブロックは横幅100、大きさを50%にしているので、ブロックの横幅は50になります。一方ボールは大きさ46,50%の大きさなので23の直径になります。 もしボールが横から衝突した場合、ボールとブロックのx座標の差は(50/2)+(23/2) で36.5になります。(衝突した瞬間にボールが速度5で進んでいるので、場合によっては32ぐらいになってしまいますが、いったんこの誤差は無視して) 今回は当たったタイミングで、2つのスプライトのx座標の差が36より大きければ横からの衝突、そうでなければ縦からの衝突とします。

ブロックのプログラムの修正
事前にボールがどの方向から衝突したかを保存する、変数「しょうとつ方向」を作成します。

作成済みの、メッセージ「げきは」を受け取ったときのプログラムを以下のように修正します。
メッセージ「げきは」を受け取ったとき
- もし「ボール」に触れたなら(作成済み)
- もし(ボールのx座標 – x座標)の絶対値>36 なら
- 変数:しょうとつ方向 を「よこ」にする
- そうでなければ
- 変数:しょうとつ方向 を「たて」にする
- このクローンを削除する(作成済み)
- もし(ボールのx座標 – x座標)の絶対値>36 なら

ブロックやボールの大きさを違うものにしている場合は、それぞれの作品中のブロックの大きさ、ボールの大きさによって、サンプル中に登場した「36」の値を調整してみてください。
ボールのプログラムの修正
こちらも作成済みの定義「はね返り」を修正します
定義「はね返り」
- ブロックに触れたではないまで -1歩動かす(作成済み)
- もし 変数:しょうとつ方向 =「たて」なら (上下方向からの衝突なら)
- (180 – 向き)度に向ける
- でなければ(変数:しょうとつ方向 =「よこ」/横からの衝突なら)
- (0 – 向き)度に向ける

今回の修正はこれだけです。 実際に起動させてみると、横からの跳ね返りでも正しい動きができたと思います。
ファイブボックスでは、スクラッチやUnityの個別指導のオンラインレッスンを行っています。