コンテンツへスキップ

クローン同士の当たり判定の作り方|同時実行の落とし穴

「にゃんこ大戦争」のようなタワーディフェンスを作ろうとしたときや、「シューティングゲーム」で自分の弾と敵の当たり判定を作ろうとしたときなど、クローン同士の当たり判定がうまくできずに悩んだ方はいませんか?実は、クローン同士の当たり判定を正しくプログラミングするのはスクラッチの技術の中でも特に難しい部類に入ります。この記事では、動画なども使ってなるべく分かりやすく説明したいと思います。

本記事は、下記のスクラッチの作品を使って説明しています。併せてご確認ください。

scratch-clones-collision1

問題

次のようなプログラムを書いて、100人のピコと100人のギガをクローンさせます。ピコとギガは、相手に当たったときに消える(クローンを削除する)ようにさせたいとします。

scratch-clones-collision2
「間違いピコ」のプログラム:ギガにふれると消える
scratch-clones-collision3
「間違いギガ」のプログラム:ピコにふれると消える

結果

このプログラムを実行した結果は以下のようになりました。100人ずつのピコとギガをクローンしたのに、2人のギガが残ってしまいました。

原因(同時実行の落とし穴)

間違いピコ(A)と間違いギガ(B)のプログラムは以下の通りです。参考プログラムの「よくある間違い」ボタンが押されたときに、ピコとギガはそれぞれ100個のクローンを作ります。下記の「クローンされたとき」のプログラムは(ほぼ)同時に何度も実行されることになります。

scratch-clones-collision4

スクラッチの同時実行のプログラムの落とし穴はここにあります。間違いピコ(A)と間違いギガ(B)はお互い前に進み接触します。このときプログラムはどの順序で実行されると思いますか?

次のような場合もあると思います。この場合は、接触したピコとギガのクローンはお互い消えます。
 A2 ⇒ B2(ピコと触れる) ⇒ A3 ⇒ B3 ⇒ A4(ピコ消える) ⇒ B4(ギガ消える)

次のような場合もあります。この場合は、ピコと接触したもののギガは消えません。先ほどの動画で2人のギガが残った理由はこのためだと思われます。
 A2 ⇒ B2(ピコと触れる) ⇒ A3 ⇒ A4(ピコ消える) ⇒ B3 ⇒ B2(ピコはすでに消えているので「B4」は実行されずにギガは前に進む)

スクラッチではプログラムの実行順序を制御(同時実行制御)できないので、このような問題が起こりやすいです。

この問題をスクラッチで完全に防ぐことはできませんが、次の方法を使うことで問題を軽減することはできます。

正解例(クローン同士の当たり判定の作り方)

まずは、正解例の動画をご確認ください。正しく作ることが出来れば、下記のように100人ずつ作ったクローンが全て消えます。

ここで重要なのは、クローンされたピコやギガに「ID(●番目のピコ・ギガ)」が割り当てられていることです。クローンごとに異なる動きをさせたいとき、このようにクローンに「ID(識別番号)」をつけます。

クローンごとに「ID」をつけるのは簡単です。「ID」をつけたいスプライトを選択し、変数名を「ID」にして、「このスプライトのみ」にチェックを入れて「OK」ボタンを押すだけです。

scratch-clones-collision5

クローンごとに「ID」を割り当てるのは右記のようにプログラミングします。

「ID」を1ずつ変えながら「クローンを作る」だけです。

これを実行すると、「ID」を割り当てたクローン(ピコやギガ)ができます。

scratch-clones-collision6

「ID」さえつけてしまえば、後は色々な方法でクローン同士の当たり判定を制御できます。私はリストを使って実現しました。考え方は以下の通りです。

scratch-clones-collision7
① 相手にあたったときにリストにその「ID」を追加します
scratch-clones-collision8
② それぞれのリストに値が入っているときに当たり判定の処理(衝突処理)を実行します。具体的には「メッセージ」を送ります。
scratch-clones-collision9
③ メッセージを受け取った時、リストの1番目にある「ID」をもつクローンだけ当たり判定時の処理をします。

① ② ③ のプログラムはそれぞれ下記の通りです。

scratch-clones-collision10
① 相手にあたったときにリストにその「ID」を追加します。「もし」の条件に「衝突処理をするピコのIDにIDがふくまれるではない」を付けます。この条件がないと同じIDが何度もリストに追加されます(衝突処理が重複して実行されることを防いでいます)。
scratch-clones-collision11
② それぞれのリストに値が入っているとき、当たり判定の処理(衝突処理)を実行します。具体的には「メッセージ」を送ります。
scratch-clones-collision12
③ メッセージを受け取った時、リストの1番目にある「ID」をもつクローンだけ当たり判定時の処理をします。衝突処理をしたら、リストからその「ID」を削除します。

以上で、クローン同士の当たり判定の作り方の解説を終わります。クローンは便利ですが、そのまま使うとどのクローンも同じ動作をしてしまいますよね。「ID」 をつけることでクローンごとに動作を変えられるのでぜひ活用してみてください。ただし、クローンごとに全く動作が違うものを作る場合は、無理にクローンを使用せずにスプライトを分けたほうがよい場合もあるので注意してくださいね。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA