この記事では、複数の背景を異なる速度で移動させることで、擬似的に奥行きを表現する「多重スクロール」の実装方法について紹介します。
目次
多重スクロールの実装方法
素材データ
今回使用する素材データです
このデータには以下の2つのファイルが含まれています。


プロジェクトを作成し、この2つの画像ファイルをプロジェクトに追加します。

ルートシーンの作成
2Dシーン(Node2D)を作成し、名前を「Main」に変更しておきます。

ParallaxBackground / ParallaxLayerを作成する
次に「ParallaxBackground」を作成します。

これは多重スクロールの背景を管理するためのノードです。このノードの下に配置された「ParallaxLayer」を制御するためのノードです。
ということで「ParallaxLayer」を作成します。

今回は背景を2枚使用するので、2つの「ParallaxLayer」を用意します。
背景スプライトを作成する
次に「bg_back.png」を「ParallaxLayer」ノードの下に配置します。

画面の左上に合わせたいので、スプライトのインスペクターから以下のようにします。
- Offset > Centerd: チェックを外して左上基準にする
- Transform > Positon: (x, y) = (0, 0) にする

bg_sky.png を “ParallaxLayer2” の下に “BgSky” として同じように配置し、BgSkyスプライトの位置に合わせます。
プレイヤーの作成
シーンノードの作成
2Dシーン(Node2D) を新規作成し、名前を “Player” に変更します。

Iconスプライトの作成
次に “icon.png” を原点に配置して、”Icon”スプライトを作成します。

Camera2Dノードの作成
さらに “Camera2D” ノードを追加します。

Camera2D のインスペクターから「Current」にチェックを入れ、カメラを有効にします。

プレイヤースクリプトの作成
Playerノードにスクリプトをアタッチして、以下のように記述します。
extends Node2D
# 移動速度
const SPEED := 400.0
func _process(delta: float) -> void:
# 移動量を求める
var velocity = Vector2()
if Input.is_action_pressed("ui_left"):
velocity.x = -1
elif Input.is_action_pressed("ui_right"):
velocity.x = 1
if Input.is_action_pressed("ui_up"):
velocity.y = -1
elif Input.is_action_pressed("ui_down"):
velocity.y = 1
# 移動する
position += velocity * SPEED * delta
押したキーの方向に合わせて移動するスクリプトとなります。
これでプレイヤーは完成です。
プレイヤーを配置して動かす
Mainシーンに戻り、”Player” シーンを配置します。

では、実行して動作を確認します。

ですが、特に背景は移動しません。これは背景スクロールの設定をしていないためです。
ParallaxLayerの設定をする
「ParallaxLayer」ノードを選択して 「ParallaxLayer > Motion > Mirroring」から “x” の値を “800” にします。

これは “ParallaxLayer” 以下の描画を X方向に繰り返す値です。”bg_back.png” の横幅は 800px なので、ここに “800” を指定しています。
同様に 「ParallaxLayer2」ノードの値も設定します。

“bg_sky.png” の横幅も 800px なので、こちらも 800 となります。
では実行して動作を確認します。

スクロールはできているのですが、時々背景が表示されなくなります。これは背景画像が 800px で、画面サイズが 800px であることを想定しているためです。
ということで、メニューの「プロジェクト > プロジェクト設定」を選びます。

「Display > Window」を選択し、Widthを「800」、Heightを「480」に変更します。

設定できたら実行して動作を確認します。

左右移動で、無事スクロールできるようになりました。
視差表現を行う
ただこれだけだと単にスクロールしているだけです。
プレイヤーを中心に、前面に街並み(bg_back.png)、背面に空(bg_sky.png) が存在していると想定して、視差表現を行うようにします。
前面の画像に最背面の画像を含めてしまったため、多少わかりにくいですが、イメージとしては以下のようになります。

前面にあるものほど移動速度を速くし、後ろにあるものほど速度が遅くすると、奥行きがあるように感じられます。
具体的なパラメータとしては、”ParallaxLayer” (前面の街並み) の 「Motion > Scale」のX値を「2」にします。


では実行すると、奥行きのある多重スクロールとなります。

完成プロジェクトファイル
今回作成したプロジェクトファイルを添付しておきます。
参考
この記事は以下の動画を参考に作成しました。