プレイヤーのコーディング

最後のセクションでは、プロジェクトを設定し、ゲームアートをダウンロードしました。これでコーディングを開始する準備が整いました。まずはプレイヤー操作可能な宇宙船から着手します。

スクリプトの追加方法

ゲームの動作やメカニクスを構築するには、スクリプトを記述してノードやその他のオブジェクトにアタッチします。現在のPlayerシーンでは宇宙船を表示し、その衝突判定ボックスなどを定義していますが、実際には移動できず、仮に他のものと衝突しても何の反応も生じません。この機能を追加するため、これからコードを実装していきます。

Playerノードを選択して、「スクリプトのアタッチ」ボタンをクリックします。

alt alt

ノードスクリプトのアタッチ ウィンドウでオプションを変更する必要はありませんので、単に 作成 ボタンをクリックすると、スクリプトエディターに移動します。

スクリプトの最初の行を見てみてください。これは自動的に追加されたものです。

extends Area2D

この行はこのスクリプトをアタッチすべきオブジェクトのタイプを指定しています。つまり、スクリプトは Area2D が提供するすべての機能にアクセスできるようになります。

スクリプトが『組み込まれている』ノードの種類と、extend 文は常に一致している必要があります。

スクリプトの操作について

単独で存在するスクリプト自体には、ほとんど意味がありません。スクリプトは付加的な機能を定義するものであり、特定のオブジェクトに紐づいて初めて効果を発揮します。単に「あるスクリプト内の変数」ではなく、そのスクリプトによって定義されたオブジェクトのプロパティを参照することになる点が重要です。これは極めて重要な概念です。

移動

まず、船を画面上で移動させる機能から作成してください。以下の動作するコードから始めてみます。

  • プレイヤーが押している入力を検知する
  • その入力方向に宇宙船を移動させる
@export var speed = 150

func _process(delta):
    var input = Input.get_vector("left", "right", "up", "down")
    position += input * speed * delta

これを行ごとに分解してみます。

  • 変数名の前に @export を付けると、インスペクター でその値を調整できるようになります。

alt alt

  • _process() 関数はエンジンによって1フレームごとに呼び出されます。この関数内に書いたコードはすべて毎フレーム実行されます。
  • Input.get_vector() は、指定された4つの入力状態をチェックし、それらの方向に向くベクトルを生成します。
  • 最後に、与えられた入力ベクトルを移動量として船の position に加算します。この時、速度値に合わせてベクトルの大きさを調整し、さらに delta でスケール処理を行います。

シーンを実行するには [現在のシーンを実行] ボタンをクリックしてください。その後、自由に移動してみてください。

alt alt

画面表示を維持する機能

一つの問題点として、プレイヤーが動き続けると画面外へと移動してしまう点が挙げられます。この問題を解決するには、スクリプト上部でプレイヤーの position プロパティを画面矩形内に制限が必要です。以下のように追加してください。

@onready var screensize = get_viewport_rect().size

ここでの @onready は、Godotが Playerノードがシーンツリーに加わるまで screensize変数の値を設定しないように指示しています。本質的には「ゲーム開始を待つ」ということです。なぜなら、ゲームが実行されていない状態ではウィンドウの大きさを取得する方法がないからです。

次のステップは、位置をその screensize 矩形の範囲内で固定することです。position が使用する Vector2 には、clamp() メソッドがあります。position 設定直後に、この行を追加してください。

func _process(delta):
    var input = Input.get_vector("left", "right", "up", "down")
    position += input * speed * delta
    position = position.clamp(Vector2.ZERO, screensize)

もう一度シーンを実行して、画面の端から移動してみてください。船の半分が画面からはみ出していることに気付くはずです。これは、船の position 値が Sprite2D オブジェクトの中心座標に設定されているためです。船のサイズは 16x16 ピクセルであることがわかっているため、clamp() 関数に追加で8ピクセル分を包含するように変更できます。

position = position.clamp(Vector2(8, 8), screensize - Vector2(8, 8))

方向に合わせたアニメーションの適用方法

船が動いている状態では、左または右に移動する際に「傾斜した」船の画像を選択できるほか、対応する『ブースター』アニメーションも表示されます。

移動方向を判断するには、inputベクトルのx値を確認します。値が正であれば右方向へ、負なら左方向へ、0であれば停止中と判定し、それぞれAnimatedSprite2Dの対応するframe値を持つSprite2Dと、適切なanimationを選択します。

func _process(delta):
    var input = Input.get_vector("left", "right", "up", "down")
    if input.x > 0:
        $Ship.frame = 2
        $Ship/Boosters.animation = "right"
    elif input.x < 0:
        $Ship.frame = 0
        $Ship/Boosters.animation = "left"
    else:
        $Ship.frame = 1
        $Ship/Boosters.animation = "forward"
    position += input * speed * delta
    position = position.clamp(Vector2(8, 8), screensize-Vector2(8, 8))

もう一度シーンを再生し、左右へ移動した際に画像が正しく切り替わることを確認してください。次のステップに進む前に、すべてが意図通りに動作することを必ず検証してください。

次のステップでは、Bullet シーンを作成し、プレイヤーが射撃できるようにします。

戻る次へ