第4回:個別の処理を見ていく - Scratchの本格横スクロールゲームをリバースエンジニアリングしよう!
2022-1-11
Scratchの本格ゲームの中身を調べる方法を解説しています。第4回では、横スクロールやジャンプ処理・スコア表示といった、個別の処理を見ていきます。
- 第1回:スプライトを洗い出す
- 第2回:スプライトとメッセージの関係
- 第3回:恐竜のコードをどう呼び出すか
- 第4回:個別の処理を見ていく
題材には、恐竜ランニングゲームを使っています。
前回まで、次の手順でリバースエンジニアリングを進めてきました。
- まずは遊んでみる
- 中を見る
- スプライトを調べる
- メッセージを調べる
- 変数とリストを調べる
- コードの細部を調べる
特に、プロジェクトの全体像をメッセージを中心に整理しました。でも、ゲームは細かなところまで作り込んであります。今回は、それを順番に調べてみましょう。
地面の横スクロール
横スクロールする地面は、ground1とground2というスプライトで実現しています。この2つは、ほとんど同じコードになっています。
ground1は、「go」ブロックで横スクロールを実現しています。
まず、初期設定で「x座標 = 0、y座標 = 0」にしているので、画面中央からスタートします。そして、「ずっと」ブロックで、「x座標をScroll_Xずつ変える」で、左に移動しています。
それから、x座標が-460より小さくなったら、右端に戻るため「x座標 = 460」にしています。
これで、ground1のスプライトが、左方向にスクロールしていきます。
ground2も、ほとんど同じ動きをしますが、初期値がすこし違っています。
「go」ブロックを見ると、初期設定で「x座標 = 480、y座標 = 0」となっていて、画面中央ではなく、画面右端からスタートします。
あとは、ground1と同じように横スクロールしていきます。
つまり、初期設定で、ground1とground2が画面一つ分ずれているのです。この2つの同時に実行することで、地面の横スクロールがずっと続いていくように見せています。
ちなみに、横スクロールは、@digitarhyth@さんの無限スクロールを参考にしています。
また、次のプロジェクトで実験として実現しています。
雲のアニメーション
雲は、cloudスプライトで実現しています。6個の雲が、左方向に横スクロールしていきます。
このとき、位置によって、サイズとスピードを調整して、遠近感を表します。「クローン」で、次のように作っています。
- 「line = 1」のとき、大きさ60%
- 「line = 2」のとき、大きさ90%
- 「line = 3」のとき、大きさ120%
横スクロールの処理の考え方は、地面と同じです。
CRASHメッセージとRESTARTメッセージを受け取らないので、恐竜が衝突したときも、再スタートしたときも雲は動き続けます。
ジャンプと地面
恐竜のdinoスプライトでは、「go_2」ブロックで、「jump」と「check_ground」を呼び出して、ジャンプと地面のチェックをしています。
恐竜のジャンプは、「Jump」ブロックで処理しています。
「move_Y」変数で縦方向の移動距離を表しています。「Ground_level」変数は、恐竜や障害物(サボテンと翼竜)の縦方向の基準位置を表しています。
恐竜が「y座標 = Ground_level」かつ「move_Y = 0」なら、ジャンプしていないことになります。このとき、Jumpボタンが押されるか、上向き矢印キーが押されると、「jump_flag = on」になって、ジャンプが始まります。
「jump_flag = on」でなければ、ジャンプしません。
ジャンプ中の場合は、「move_Y」変数を「-2」ずつ変えています。
そして、y座標を「move_Y」変数ずつ変えて、ジャンプと落下を表します。
ちなみに、「90 + move_Y 度に向ける」ブロックで、ジャンプ中に恐竜を少しゆらしています。
ジャンプした恐竜が地面に着地したかどうか、「check_ground」ブロックで調べています。恐竜のy座標が「Ground_level」変数より小さくなったら、move_Yをゼロにして、恐竜のy座標を「Ground_level」変数に合わせています。
スコアを表示する
DinoRunnerでは、次の3つのスプライトでスコアを表示しています。
- ゲームプレイ中のスコア:score engine
- 衝突時のスコア:score engine2
- 衝突時に表示するベストスコア:bestscore engine
スコアは、ドットフォントで表示するため、次の「スコア表示エンジン」プロジェクトを使っています。
このプロジェクトは、0から9までの数字をコスチュームに持っていて、これを切り替えて数字を表示します。
スコア表示エンジンは、次の手順で使います
1. コードに次の値を設定する
- score_MAX_LENGTH:スコアの桁数
- score_LETTER_WITDH:スコア1文字の幅
- x座標、y座標:スコアを表示する位置
- 大きさ:表示する倍率
2. メッセージ名をプロジェクトに合わせて書き換える
3. スコアとして表示する値を、Score変数に代入する
4. スプライトを初期化するため、init_scoreメッセージを受信する
5. スコアを更新するため、render_scoreメッセージを受信する
DinoRunnerでは、スコアの初期化と更新を「score_panel」スプライトでやっています。衝突時のスコアとベストスコアは、同じタイミングで表示するので、init_score2メッセージとrender_score2メッセージを送信しています。
コードの動きを自分なりに調べるには
Scratchのゲームをリバースエンジニアリングする場合、こんな感じで、コードの細部を調べていきます。
今回は、DinoRunnerの細部のコードを簡単に紹介しました。自分で調べて、よく分からなときは、次の方法を試してみましょう。
- 処理の流れを、頭のなかで想像する
- 処理の流れを、書き出してみる
- コードの一部を修正するか、スプライトの一部を非表示にして、どのように流れが変わるか実験してみる
- コードの一部を取り出した別のプロジェクトを作ってみる
たとえば、恐竜のdinoスプライトを非表示にすると、地面や雲・障害物の動きが確認しやすくなります。
こんなバリエーションを作ってみた
ここまで、全4回にわたって、私なりのリバースエンジニアリングの方法を解説してきました。DinoRunnerのコードには、すっかり詳しくなったと思います。
あなたも、ぜひ自分なりにリバースエンジニアリングしてみてください。
私も、これを元にして、次の横スクロールゲームを作っています。
オリジナルの横スクロールゲームを作ったら、ぜひ教えてくださいね。