この連載では、Scratchで本格ゲームの中身を調べる方法を解説しています。第2回では、スプライトとメッセージの関係を整理します。
- 第1回:スプライトを洗い出す
- 第2回:スプライトとメッセージの関係
- 第3回:恐竜のコードをどう呼び出すか
- 第4回:個別の処理を見ていく
前回は、リバースエンジニアリングするゲームを実際に遊んだあと、どんなスプライトを持っているか洗い出してみました。
でも、本格的なゲームには、いくつもの処理が必要になります。それを上手に整理しておかないと、すぐにごちゃごちゃになって、どこに何があるか分からなくなってしまいます。ある処理を追加したら、動かなくなってしまうこともあります。
そこで、すこし本格的なゲームで、プロジェクトの全体像を整理してみましょう。
題材には、恐竜ランニングゲームを使っています。
メッセージとは
Scratchには、全体をまとめるため、いろいろな方法があります。多くのゲームで、全体の構造をまとめるために「メッセージ」を使っているようです。
メッセージは、特定のスプライトやステージから指示を送る機能です。
メッセージでは、「メッセージを送る」ブロック+「メッセージを送って待つ」ブロック、さらに「メッセージを受け取ったとき」ブロックを組み合わせて使うんでした。
たとえば、「メッセージを送る」ブロックから指示を送ると、「メッセージを受け取ったとき」ブロックがそれを受け取って、その下にあるコードを実行していきます。このとき複数の「メッセージを受け取ったとき」ブロックが同時に指示を受け取ることができます。
このメッセージは、異なるスプライトやステージの間でも送受信できます。
DinoRunnerも、これを使っています。
メッセージを見る
では、DinoRunnerのメッセージを洗い出してみましょう。
こんな手順で、プロジェクトに設定されているすべてのメッセージを確認できます。
- プロジェクトの中を見る
- イベントカテゴリにあるメッセージブロックの▼をクリック
これで、設定されているメッセージがすべて表示されます。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のコードで見つかるはずだ。
6. 続いて、先ほどと同じように「”TITLE”を受け取ったとき」ブロックの下のコードで、「メッセージを送る」ブロックを探す。DinoRunnerでは、start_buttonスプライトのコードに、「”START”を送る」ブロックがある。
7. さらに、「”START”を受け取ったとき」ブロックを探していく。
8. 「”START”を受け取ったとき」ブロックに連なるコードから、「メッセージを送る」ブロックを探す。DinoRunnerでは、障害物になるcactusスプライトとbirdsスプライトのコードに、「”CRASH”を送る」ブロックがある。
「jump_button」「duck_button」「score_pannel」スプライトもメッセージを送信している。
このような手順を繰り返して、メッセージを送信しているブロックを探していきます。DinoRunnerの場合、大文字で書いてあるメッセージだけ取り出すと、次のようになります。
青色と緑色の矢印も別のメッセージ送信をあらわしていますが、ゲーム中のアクションに対応しているので、とりあえず行き先を調べるのは後回しにしています。
なかには、「ブロック定義」ブロックを呼び出している場合もあります。
スプライトとメッセージの関係
これで、ゲームを進行する大きな流れを洗い出せました。
順番にメッセージが送られるステップは、こんなふうになります。
- 旗を押したら、ステージでTITLEメッセージを送る
- TITLEメッセージを受け取ったstart_buttonから、
STARTメッセージを送る - STARTメッセージを受け取ったcactusかbirdsから、
CRASHメッセージを送る - CRASHメッセージを受け取ったrestart_buttonから、
RESTARTメッセージを送る
つまり、ゲーム画面の切り替わりとメッセージが対応しているんです。
- TITLEメッセージ:タイトル画面を表示
- STARTメッセージ:ゲームプレイの開始
- CRASHメッセージ:恐竜の衝突 → スコア画面の表示
- RESTARTメッセージ:ゲームプレイの再スタート
ゲームの流れとコードの関係が、だいぶ整理できましたよね。
こんなふうにゲームの全体像を把握するには、細かなところは気にしないで、メッセージとスプライトの関係をざっくりと見ていくのが良いと思います。
でも、スプライトの処理をどう呼び出しているのか、ある程度理解しておかないと、もやもやしますよね。そこで、次回は、メッセージを受け取ったスプライトが、どのように処理を進めているか、少しだけ掘り下げてみましょう。
3件のコメント
3件のピンバック