シューティングゲームやプラットフォームゲームをつくる上では絶対に必要になってくる背景スクロールのテクニックをいくつかのパターンに分けて紹介しています。
今回は、2画面以上の背景スプライトを一方向(左方向のみ)に一定速度で自動的に横スクロールする方法を紹介します。シューティングゲームで使われるような画面スクロールで、一度過ぎた画面へは戻れないように制御する方法です。
この記事を読んでいただくと、シューティングゲームのように2つ以上の画面(背景)を一定速度で自動的に横スクロールするスクリプトの作り方とそのコツが分かります。
スクリプトの作り方
完成した動き
今回は、背景を5画面分(5つの背景スプライト)用意しました。
背景画像同士のつなぎ目がきれいにつながるようにコスチューム画面で横幅や図形の色を調整して合わせています。
背景スプライトは左方向へは画面スクロールしますが、右方向へはスクロールしないように制御しています。また、最後の画面ではそれ以上スクロールしないようにスクロールを停止しています。
ネコのスプライトの動きは、左方向はステージの左端まで移動可能、右方向はステージの右端まで移動可能で、壁にぶつかったら爆発するようにコスチュームを変化させています。
※爆発アニメーションの画像は「ぴぽや倉庫」様の素材を使わせてもらいました。
※このプログラムを流用すれば、画面数をいくつ増やしても対応することができます。
完成したスクリプト
完成したスクリプトの全体です。スプライトは「ネコ」と「背景1~背景5まで」の合計6個です。
【スプライト】
【ネコのスクリプト】
- X移動量:すべてのスプライト用
- 背景画面の数:すべてのスプライト用
【背景1のスクリプト】
「画面番号」変数は、「このスプライトのみ」で作成して背景1専用の変数とします。
「リセットを受け取ったとき」は、ネコが壁にぶつかったときに受け取るメッセージで、「背景1」を初期状態にリセットするスクリプトです。
- 画面番号:このスプライトのみ
【背景2~背景5のスクリプト】
「画面番号」変数は、「このスプライトのみ」で作成して背景2~背景5それぞれ専用の変数とします。
「リセットを受け取ったとき」は、ネコが壁にぶつかったときに受け取るメッセージで、「背景2~5」を初期状態にリセットするスクリプトです。
※背景2~5のスクリプトは、「画面番号を○○にする」ブロックに入れる数字が異なるだけで、それ以外はまったく同じスクリプトです。
- 画面番号:このスプライトのみ
スクリプトの説明
プログラムを作っていく中でポイントとなる部分を説明します。
ポイント①:背景スプライトを用意する
今回は5つの背景スプライトを用意しました。
サイズはそれぞれ「背景1:496×371」「背景2:502×464」「背景3:498×371」「背景4:500×371」「背景5:500×371」ですが、このとおりのサイズにする必要はありません。
Scratchの画面サイズは横480×縦360ですが、ぴったりのサイズで作ると画面スクロールしたときに左右の端に少しスキマが発生する場合があるので少し横長に作っておきます。※この部分は作った背景画像によって異なるので動かしてみて確認しながら調整してください。
ポイント②:背景スプライトをスタート位置にセットする
プログラムを開始した直後に背景スプライトの位置を決めます。
背景1は座標(X, Y)=(0, 0)、背景2は1画面分右にずらして配置する必要があるので (X, Y)=(480, 0)、背景3以降も同様に1画面分ずつ右にずらしてに配置します。(下図参照)
それぞれの背景スプライトに対して、以下のスクリプトを実行してスタート位置に移動させます。
それぞれ1画面分ずつずらして配置するので、X座標は480pxずつ変化させます。
- 背景1の座標:(X, Y)=(0, 0)
- 背景2の座標:(X, Y)=(480, 0)
- 背景3の座標:(X, Y)=(960, 0)
- 背景4の座標:(X, Y)=(1440, 0)
- 背景5の座標:(X, Y)=(1920, 0)
ただし、きちんとX座標がセットされているか確認しようと変数を表示しても正しく表示されない場合があります。これはScratchの仕様でスプライトの移動範囲が限定されているためなので解消できません。
実際のX座標は、変数を使って動的に変えているのできちんと計算はされています。そのため、その背景が表示されるタイミングまでは隠しておき、使うタイミングになってから表示するようなプログラムにします。
ポイント③:背景を自動的にスクロールさせる
背景のスクリプト
背景スプライトを移動させるスクリプトは、すべての背景で共通で「X移動量」変数の値が変化した分だけ左右に移動することができます。(下図参照)
「X移動量」変数の値は、ネコのスプライト側でコントロールしている変数で「ずっと-2ずつ」変化させています。つまり、背景は左方向に2pxずつ動き続けることになります。※右方向には動かないようにしています。
また「背景2~背景5」のスクリプトでは、以下のスクリプトブロックがありますが、これは、その背景がステージの右端まで近づいてきたら表示させ、ステージの左端に流れていったら非表示にするためです。
ネコのスクリプト
今回は背景をシューティングゲームのように自動的に横スクロールさせるのが目的ですが、その部分のプログラムはとてもシンプルです。
背景スクロールのプログラム以外にキャラクターが「上下左右に動くプログラム」と「壁に当たったときの当たり判定と爆発アニメーションのプログラム」と「最後の画面はスクロールを止めるプログラム」があるので合わせて説明します。
見やすくするためにそれぞれを定義ブロックに入れてスクリプトをまとめています。
背景スクロールに関わる部分
背景をスクロールするためにネコのスプライト側では、「X移動量」変数の値を「ずっと-2ずつ変える」だけです。
これと背景スプライト側のプログラムが連動することで背景1~5が左方向に移動し続けるようになっています。
定義ブロック:上下左右の移動
ネコのスプライトを上下左右の矢印キーでステージ上を移動させるためのプログラムです。
「上下左右の移動」定義ブロックの仕様は、単純にそれぞれの方向の矢印キーが押されたらX座標またはY座標を10pxずつ変化させるだけなので、むずかしい所はないと思います。
定義ブロック:左右端っこの画面スクロールを制限する
左端の背景スプライトと右端の背景スプライトをそれ以上スクロールさせないようにするためのプログラムです。
「左右端っこの画面のスクロールを止める」定義ブロックの仕様を簡単に説明すると下記のようになっています。
・左端の背景を右方向に移動させないために「X移動量」変数がプラスの値にならないようにする
・右端(最終画面)の背景スプライトがステージの枠にピッタリ収まったらそれ以上スクロールしないようにする(白い余白が見えてしまうため)
定義ブロック:壁に当たったら状態をリセットする
ネコのスプライトが壁に触れたら爆発アニメーションの後、最初からやり直すためにすべての状態をリセットするためのプログラムです。
「当たり判定」定義ブロックの仕様を簡単に説明すると下記のようになっています。
壁の色に触れたら、
・7個のコスチュームを連続的に表示することで爆発のアニメーションを表現
・「X移動量」変数と座標を初期化してスタート位置に戻す
・「リセットを送る」で背景スプライトを初期状態に戻す
ここまでのポイントを押さえてスクリプトを作ることができたら、シューティングゲームのように2つ以上の画面(背景)を一定速度で自動的に横スクロールさせるプログラムは完成です!
失敗しやすいポイント
今回作ったスクリプトでは、ステージの外に配置した「背景2~背景5」は最初「隠す」ブロックで非表示して、表示させるタイミングになったら表示するようにしています。
これはナゼかというと、Scratchの仕様では移動できる(スクロールできる)範囲に制限があるので、意図的に表示を消しておかないとステージの外側にあるべき(本来見えているべきでない)画面が右端に少しだけ表示されたままになってしまうためです。
また、どのスプライトが「最前面」になっているかもとても重要です。その状態によって背景スプライトのつなぎ目がつながって見えるか切れて見えるかが変わることがあります。
気になる場合は、背景1スプライトから順番に「最前面に移動する」ブロックを1回ずつクリックしておくのがおススメです。
応用編
今回応用編は特にありません。
同じように背景を自動的に縦スクロールさせるパターンのプログラムについても別の記事で説明しています。↓↓↓
まとめ
さいごに、今回の記事で説明した『シューティングゲームのように2つ以上の画面(背景)を一定の速さで自動的に横スクロールするスクリプトの作り方』のポイントをまとめます。
- ポイント①:背景スプライトを用意する(少し横長につくる)
- ポイント②:背景スプライトをスタート位置にセットする(表示されるタイミングまでは隠しておく)
- ポイント③:背景を自動的にスクロールさせる(左右端の画面はスクロールを制限する)
背景のスクロールは、シューティングゲームやプラットフォームゲームなどのさまざまなゲームプログラムの中で使われています。
背景スクロールを使いこなせるようになると作品の幅がぐっと広がっていくと思いますので、ぜひチャレンジしてみてください。
どうでしたか?上手くできたでしょうか?
他にも役に立つTips(ティップス)記事をたくさん書いてますので、ぜひ見てみてください。(記事のタイトルに「Tips」と書いていたり「Tips」タグを貼ってあります)