この連載では、Scratchで本格ゲームの中身を調べる方法を解説しています。第2回では、スプライトとメッセージの関係を整理します。

前回は、リバースエンジニアリングするゲームを実際に遊んだあと、どんなスプライトを持っているか洗い出してみました。

でも、本格的なゲームには、いくつもの処理が必要になります。それを上手に整理しておかないと、すぐにごちゃごちゃになって、どこに何があるか分からなくなってしまいます。ある処理を追加したら、動かなくなってしまうこともあります。

そこで、すこし本格的なゲームで、プロジェクトの全体像を整理してみましょう。

題材には、恐竜ランニングゲームを使っています。

メッセージとは

Scratchには、全体をまとめるため、いろいろな方法があります。多くのゲームで、全体の構造をまとめるために「メッセージ」を使っているようです。

メッセージは、特定のスプライトやステージから指示を送る機能です。

メッセージでは、「メッセージを送る」ブロック+「メッセージを送って待つ」ブロック、さらに「メッセージを受け取ったとき」ブロックを組み合わせて使うんでした。

メッセージブロックの使い方

たとえば、「メッセージを送る」ブロックから指示を送ると、「メッセージを受け取ったとき」ブロックがそれを受け取って、その下にあるコードを実行していきます。このとき複数の「メッセージを受け取ったとき」ブロックが同時に指示を受け取ることができます。

このメッセージは、異なるスプライトやステージの間でも送受信できます。

DinoRunnerも、これを使っています。

メッセージを見る

では、DinoRunnerのメッセージを洗い出してみましょう。

こんな手順で、プロジェクトに設定されているすべてのメッセージを確認できます。

  1. プロジェクトの中を見る
  2. イベントカテゴリにあるメッセージブロックの▼をクリック
メッセージを見る

これで、設定されているメッセージがすべて表示されます。DinoRunnerでは、次のようになっています。

  • CRASH
  • duck
  • duck_off
  • init_score
  • init_score2
  • jump
  • TITLE
  • render_score
  • render_score2
  • RESTART
  • START
  • update_bestscore

英語で書いてあるので、ちょっと分かりにくいかも知れませんが、簡単な単語ですし、Scratchのゲームでは、これと同じような単語がよくでてきます。

たとえば、こんな感じです。

  • CRASH:クラッシュ
  • duck:しゃがむ
  • score:スコア

「init_score」の「init」は、「initialize」(イニシャライズ:初期化する)の略です。

「render_score」の「render」は、描写するという意味です。「render_score」で、スコアを表示します。

大文字と小文字のメッセージがありますが、私は、ゲームの状況を切り替える「TITLE」「START」「CRASH」「RESTART」を大文字で表すようにしています。

どのスプライトがメッセージを送信しているか

では、どのスプライト + ステージがメッセージを送受信しているのか調べます。ここが、このリバースエンジニアリングの中核となる作業です。これは、かなり推理力が必要になるでしょう。

次の手順で、スプライト+ステージとメッセージの関係を表にまとめます。大きな紙と付箋紙(ポストイット)を用意すると、いいかも知れません。

1. 左側に、ステージと各スプライトの名前を縦方向にならべる
2. 一番上のメッセージに、緑の旗を描く
3. 「旗が押されたとき」ブロックを使っているスプライトをすべて探していく。

このとき、すぐに「隠す」ブロックだけを呼んでいるスプライトは三角を描きます。「隠す」ブロック以外の処理もあるスプライトは黒マルを描きます。DinoRunnerでは、ステージとHeppocodeが黒マルになります。

旗が押された時、スプライトでの処理

4. 「旗が押されたとき」ブロックの下のコードで、「メッセージを送る」ブロックを探す。このメッセージを右枠の上に描く。DinoRunnerの場合は、ステージで「”TITLE”を送る」を呼び出している。

5. 次に「”TITLE”を受け取ったとき」ブロックを探していく。DinoRunnerの場合このブロックは、titleスプライトとstart_button・Heppocodeのコードで見つかるはずだ。

“TITLE”を受け取ったとき

6. 続いて、先ほどと同じように「”TITLE”を受け取ったとき」ブロックの下のコードで、「メッセージを送る」ブロックを探す。DinoRunnerでは、start_buttonスプライトのコードに、「”START”を送る」ブロックがある。

“START”を送る

7. さらに、「”START”を受け取ったとき」ブロックを探していく。

8. 「”START”を受け取ったとき」ブロックに連なるコードから、「メッセージを送る」ブロックを探す。DinoRunnerでは、障害物になるcactusスプライトとbirdsスプライトのコードに、「”CRASH”を送る」ブロックがある。

「jump_button」「duck_button」「score_pannel」スプライトもメッセージを送信している。

“START”からメッセージを送信

このような手順を繰り返して、メッセージを送信しているブロックを探していきます。DinoRunnerの場合、大文字で書いてあるメッセージだけ取り出すと、次のようになります。

大文字のメッセージ だけ洗い出す

青色と緑色の矢印も別のメッセージ送信をあらわしていますが、ゲーム中のアクションに対応しているので、とりあえず行き先を調べるのは後回しにしています。

なかには、「ブロック定義」ブロックを呼び出している場合もあります。

スプライトとメッセージの関係

これで、ゲームを進行する大きな流れを洗い出せました。

順番にメッセージが送られるステップは、こんなふうになります。

  1. 旗を押したら、ステージでTITLEメッセージを送る
  2. TITLEメッセージを受け取ったstart_buttonから、
    STARTメッセージを送る
  3. STARTメッセージを受け取ったcactusかbirdsから、
    CRASHメッセージを送る
  4. CRASHメッセージを受け取ったrestart_buttonから、
    RESTARTメッセージを送る

つまり、ゲーム画面の切り替わりとメッセージが対応しているんです。

ゲーム画面の切り替わりとメッセージが対応している
  • TITLEメッセージ:タイトル画面を表示
  • STARTメッセージ:ゲームプレイの開始
  • CRASHメッセージ:恐竜の衝突 → スコア画面の表示
  • RESTARTメッセージ:ゲームプレイの再スタート

ゲームの流れとコードの関係が、だいぶ整理できましたよね。

こんなふうにゲームの全体像を把握するには、細かなところは気にしないで、メッセージとスプライトの関係をざっくりと見ていくのが良いと思います。

でも、スプライトの処理をどう呼び出しているのか、ある程度理解しておかないと、もやもやしますよね。そこで、次回は、メッセージを受け取ったスプライトが、どのように処理を進めているか、少しだけ掘り下げてみましょう。