
アクションゲームでは、キャラクターの動きに合わせて背景も動くものがほとんどだと思います。
前回までの記事でキャラクターの動作とアニメーションがだいたい出来てきたので、今度は背景スクロールのプログラムを追加していきます。
背景スクロールには、スクロールさせる画面数分の背景画像を用意するパターンや1枚の背景画像を使い回すパターンなど、色々なパターンのプログラムが考えられます。
過去の記事で背景スクロールのいくつかのパターンを紹介しています。↓↓↓
- 背景を横スクロールする方法【背景スプライト1個だけのパターン】
- 背景を横スクロールする方法【2画面を左右に無限ループするパターン】
- スーパーマリオ風 背景を横スクロールする方法【2画面以上で一方向に移動するパターン】
- アイスクライマー風 背景を縦スクロールする方法【2画面以上で一方向に移動するパターン】
- シューティングゲーム風 背景を自動的に横スクロールする方法【2画面以上で一方向に移動するパターン】
- シューティングゲーム風 背景を自動的に縦スクロールする方法【2画面以上で一方向に移動するパターン】
今回紹介する背景スクロールのパターンは上記のいずれとも少し違っていて、1枚の背景画像を使い回してスクロールさせ続けるパターンの応用で、さらにリッチなコンテンツにするために1画面に3枚の画像を重ねる形にして、それぞれスクロールさせる速さを変えて奥行きを表現する方法になります。
この記事を読んでいただくと、アクションゲームで奥行きを感じさせながら背景をリッチな感じでスクロールするプログラミングの方法が分かります。
なお、この記事で使用しているスプライト(キャラクター・背景・オブジェクト・音声など)はすべてパブリックドメインの無料の素材をダウンロードして使用しています。
アクションゲームとは、コンピューターゲームのジャンルの1つで、キャラクターをボタンやレバーなどで操作してステージを次々にクリアしたり、勝敗や得点を競うタイプのゲームのこと。反射神経と瞬間的な判断力を競うゲーム。
完成品
この章の内容をご自身のScratch環境に反映すれば、同じ動きを再現することができます。
完成した動き
左右の矢印キーでキャラクターが歩いて移動します。
右方向へ移動してステージの中央まで来ると背景がスクロールし始めます。
背景のスクロールは、手前にある地面は速く、遠くにある雲と空はゆっくりスクロールしているのが分かります。木々のある森は地面より遅く、空より早くスクロールしています。
背景スクロールはずっと永久に行うのではなく、3画面分までスクロールしたらそれ以上スクロールしないように制御しています。
背景が3画面分スクロールしたら、キャラクターはステージの右端まで移動できるようになります。
左方向への移動は、いつでもステージの左端まで移動できます。

使用したスプライト
スプライトは「キャラ1」「地面1」「背景1」「天気1」の4つです。

使用したスプライトの説明は、以前の記事と完全に重複しますので以前の記事の「使用したスプライト」の章をご確認ください。↓↓↓
アクションゲーム用の背景・キャラクター・アイテム等の画像や音声は、パブリックドメインである「スーパーパワーアセットパック(CC0)のprehistoric-platformer」を使っています。
完成したスクリプト
完成したスクリプトの全体です。
【キャラ1のスクリプト】
背景スクロールに必要なスクリプトに絞っているので、前回の記事の「キャラ1」のスクリプトから必要のないアニメーション部分をごっそり削除しています。(「応用編」の章では全部盛りの例を載せています)
背景スクロールのプログラムは、ほぼすべて「横移動」定義ブロックの中に組み込んでいます。
- 背景移動速度:すべてのスプライト用
- 背景移動量:すべてのスプライト用


【地面1のスクリプト】
クローンを2つ並べて(X座標=0と480)作って、2つともX座標を一緒に動かすようにしています。動かす速さは「背景移動速度」です。
「最背面から2つ手前」の階層に配置。

【背景1のスクリプト】
「地面1」スプライトと同様、クローンを2つ並べて(X座標=0と480)作って、2つともX座標を一緒に動かすようにしています。動かす速さは「背景移動速度+1」です。
「最背面から1つ手前」の階層に配置。

【天気1のスクリプト】
「地面1」スプライトと同様、クローンを2つ並べて(X座標=0と480)作って、2つともX座標を一緒に動かすようにしています。動かす速さは「背景移動速度+2」です。
「最背面」に配置(一番奥)。

スクリプトの作り方
ここからはプログラムを作っていく中でポイントとなる部分を説明します。
まず、背景をスクロールするための仕様を考え、以下のようにしました。
- キャラクターがステージ中央付近にいる状態で右矢印キーを押すと背景がスクロールする
- 背景スクロールは「地面1」スプライトが1番スピードが速く、「背景1」スプライトは2番目に速く、「天気1」は1番遅いスピードで動く
- 右矢印キーを離すと背景スクロールが止まる
- 3画面分スクロールすると、背景スクロールが止まる
また、同じように左右の矢印キーを使用するキャラクターの左右の動きについても(前回までの記事の内容から)考え直して、以下の仕様に変更して背景スクロールと組み合わせることとしました。
- キャラクターの右方向への移動について、背景がスクロールしている間はステージ中央までしか移動できない。ただし、(最大の)3画面分スクロールしていたら(背景スクロールは停止中で)ステージ右端まで移動できる。
- キャラクターの左方向への移動は、いつでもステージ左端まで移動できる。
ポイント①:背景をスクロールさせるための変数を定義する
変数は2つ使用します。1つ目は「背景移動速度」変数、2つ目は「背景移動量」変数です。2つとも「すべてのスプライト用」で作ります(他のスプライトから読み取る必要がある、または今後読み書きする可能性があるため)。
2つの変数の役割を以下のように定義します。
- 背景移動速度・・・その瞬間の背景がスクロールする速さを入れておく変数(プラスは右へ、マイナスは左へスクロール)
- 背景移動量・・・背景がトータルでどのくらい移動したかの距離を入れておく変数
下の図のように、いずれも初期値は0とします。

ポイント②:「横移動」定義ブロックを改良する
キャラクターの動かし方によって背景のスクロールのさせ方を変えるので、背景の動作に影響を与えるのは「地面1」や「背景1」や「天気1」のスプライトではなく「キャラ1」スプライトということになります。
そのため、背景スクロールを制御するプログラムは「キャラ1」スプライトに作る必要がある、ということになります。
背景スクロールも「キャラ1」スプライトの左右の動きも右向き矢印キーや左向き矢印キーを使うというところは共通です。
すでに「横移動」定義ブロックの中で「もし(右向き矢印キーが押された)なら」ブロックや「もし(左向き矢印キーが押された)なら」ブロックが使われているので、この部分を改良することで実現させます。
※同じ条件を同じタイミングで動いてしまうように複数作ってしまうと、コンピューターは一瞬でも早く動くどこか1か所の条件だけ実行してしまい、思ったように動きにならない可能性が高いです。
前回までの記事で作っていた下図の「横移動」定義ブロックを改良します。

条件①:右矢印キーを押している・背景は3画面スクロールしていない・キャラ1はステージ中央に達していない
このとき「キャラ1」は右に3歩ずつ動き、背景スクロールはしません(「背景移動速度」変数は0のまま)。

条件②:右矢印キーを押している・背景は3画面スクロールしていない・キャラ1はステージ中央に達している
このとき「キャラ1」は移動せず、背景スクロールは左方向に3ずつ移動することになります (「背景移動速度」変数の値が-3のため)。
同時に「背景移動量」変数の値が-3ずつ数字が大きくなっていきます(-3, -6, -9, -12・・・)。※この変数が、背景が全体でどのくらい移動したか分かるようになっています。

条件③:右矢印キーを押している・背景は3画面スクロールした・キャラ1はステージ右端に達していない
このとき「キャラ1」は、ステージ右端に達するまで右に3歩ずつ動くことができます。
そして背景が動かないように「背景移動速度」変数の値を0にします。

条件④:左矢印キーを押している・キャラ1はステージ左端に達していない
このとき「キャラ1」は、ステージ左端に達するまで左に3歩ずつ動くことができます。
そして背景が動かないように「背景移動速度」変数の値を0にします。

条件⑤:左右矢印キーどちらも押していない
このとき「キャラ1」は、左右どちらにも動きません。もちろん、背景が動かないように「背景移動速度」変数の値を0にします。

ポイント③:背景をスクロールさせる
3つの背景画像を動かす部分のスクリプトをつくっていきます。
「地面1」スプライトのスクロール
X座標をずらしながら2つのクローンをつくります。1つはX座標=0、もう1つはX座標=480です。

ステージには1つ目のクローンが配置され、ステージから見えないX=480の位置に2つ目のクローンが配置される。下の図のような形になる↓↓↓

クローンが配置できたら早速動かしますが、動かす条件は「背景移動速度」変数の値が0以外のとき、とします(0のときは動かしません)。
実際には、「X座標を(背景移動速度)ずつ変える」ブロックで動かします。この変数の値は「横移動」定義ブロックの中で-3に設定されるので、左方向に3歩ずつ動くことになります。
左方向に動き続けて、ステージの外側に出て見えなくなるところでX座標をステージの右側に移動させて、また左方向に3歩ずつ動き続けます。

こんな感じの動きになる↓↓↓

「背景1」スプライトのスクロール
「背景1」スプライトも基本的に「地面1」スプライトと同じ動きです。
違いは下図赤枠で囲った部分だけで、動かす速さを「背景移動速度+1」とします。つまり「-3+1=-2」となり「地面1」スプライトより1歩分遅く動くことになります。

「天気1」スプライトのスクロール
「天気1」スプライトも基本的に「地面1」や「背景1」スプライトと同じ動きです。
違いは下図赤枠で囲った部分だけで、動かす速さを「背景移動速度+2」とします。つまり「-3+2=-1」となり「地面1」スプライトより2歩分遅く、「背景1」スプライトより1歩分遅く動くことになります。

ここまでのポイントを押さえれば、アクションゲームで奥行きを感じさせながら背景スクロールを表現するスクリプトを完成させることができると思います。
失敗しやすいポイント
背景スクロールの説明のところで「もし(X座標<-460)なら」という条件が気になった方がいるかもしれません。
Scratchはステージのサイズが、横480×縦360となっているので、X座標=0の位置から1画面分左に動かすのであれば「もし(X座標<-480)なら」とするのが画面サイズとピッタリ合うのではないか?と思います。
理論上はその通りですが、Scratchの仕様上スプライトはステージの上下左右の端から約20pxくらいはみ出してしまうようです。
例えば、「地面1」のスクリプトの一部を下図のように-470に変更して実行してみるとどうなるか見てみましょう。

下図のアニメーションが上のスクリプトを実行した例です。↓↓↓
-460から-470にたった10px分ずらしただけで、地面が途中で途切れてしまっていることから、クローンを移動させるブロック(X座標を480、Y座標を-30にする)が実行されていないことが分かります。

このことからもスプライトをスクロールなどするときは、ステージの端っこから20px程度余裕をもって条件を設定する必要があることが分かると思います。
応用編
前回記事までのキャラ1のアニメーションをすべて組み込む
前回記事までに「キャラ1」スプライトのアニメーションとして、「待つ」「歩く」「ジャンプ」「落ちる」「回転」「攻撃」の6つを実装していましたのでそれらをすべて組み込みました。

背景画像の連続性を保つ
「地面1」「背景1」「天気1」スプライトのプログラムの中で、それぞれ2つ目のクローンをつくる直前に「(-1×向き)度に向ける」のブロックを組み入れていますが、これはスクロールする背景画像の連続性をある程度たもつためです。

極端な例ですが、もし背景画像が下の図のように左端が円形・右端が長方形になっていた場合

「(-1×向き)度に向ける」ブロックを入れていないと下図のようにクローンが配置されることになります。

これだと2つのクローンの境目がハッキリと分かってしまいます。
このような状態を避けるために、2つ目のクローンをつくるときに左右を180度反転させます。すると、下の図のように境目の絵柄がぴったりと合います。

このように1枚の画像で背景スクロールさせるときのちょっとしたテクニックを使うと良いと思います。
スクロールさせる長さは自由自在
背景をスクロールさせる長さ(距離)は、「キャラ1」スプライトの「横移動」定義ブロック内の1か所でコントロールしています。ここの数字を変えればスクロールさせる長さを変えることができます。
たとえば、3画面分であればステージの横幅である480×3=1440なので、マイナス符号をつけて「-1440」とすればOKです。4画面分であれば480×4=1920になります。

まとめ
さいごに、今回の記事で説明した『アクションゲームで奥行きを感じさせながら背景をリッチな感じでスクロールするプログラミング』のポイントをまとめます。
- ポイント①:背景をスクロールさせるための変数を定義する
- ポイント②:「横移動」定義ブロックを改良する(5つの「もし~なら」条件を設定する)
- ポイント③:背景をスクロールさせる(3つの背景画像が動く速さをずらす)
単なる背景スクロールではなく奥行きまで表現するとゲームのリッチさが全然違ってきます。
今回説明したようなポイントを押さえれば、スクロールが必要なほかのジャンルのゲームでも全く同じプログラムを使って表現することができると思いますので、今回の記事の内容をぜひ再現してみてください。
どうでしたか?上手く再現できたでしょうか?
他にも役に立つTips(ティップス)記事をたくさん書いてますので、ぜひ見てみてください。(記事のタイトルに「Tips」と書いていたり「Tips」タグを貼ってあります)