はじめてのGodot 第2回: 宇宙船をキーボードで動かそう — はじめてのGDScript
前回は宇宙船を画面に表示しました。今回はプログラムを書いて、矢印キーで動かします。プログラミングが初めての人にとって、連載で一番大きな一歩の回です。ゆっくり進めましょう。
今回のゴール

矢印キーで宇宙船が上下左右(と斜め)に動く。
スクリプトをアタッチする
Godotでは、ノードに「スクリプト」というプログラムを取り付けて動きを与えます。
- シーンドックで
Playerを選択 - 右クリック→「スクリプトをアタッチ」
- 設定はそのまま「作成」(
player.gdというファイルができます)
画面中央がコードエディタに切り替わり、こんな内容が表示されます。これは、上中央のワークスペースが自動で「スクリプト」に切り替わったためです(第1回で紹介したあのタブです)。部品の配置に戻りたくなったら、上中央の「2D」を押せばさっきの画面に戻れます。今回は「スクリプト」のまま進めます。
extends Sprite2D
これは「このプログラムはSprite2D(画像表示ノード)の機能を引き継いで、さらに付け足す」という宣言です。今は深く考えず「1行目はお約束」と思ってOKです。
動かすコードを書く
次のように書き換えてください(コピペでOKですが、一度手で打つとエラー体験ができておすすめです。理由は後述)。
extends Sprite2D
var speed = 400
func _process(delta):
var direction = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
position += direction * speed * delta
保存(Ctrl+S / MacはCmd+S)して F5(MacはCmd+B)で実行してみてください。矢印キーで宇宙船が動いたら成功です。
何が書いてあるのか、1行ずつ
var speed = 400 — 変数
var は「変数」を作る命令です。変数は名前付きの入れ物で、ここでは speed(速さ)という名前の入れ物に 400 を入れています。
なぜ直接 400 と書かずに変数にするのか? 後から変えやすいからです。試しに 400 を 1000 にして実行してみてください。爆速になります。100 ならノロノロです。気持ちいい速さを探してみてください。これがゲーム開発の「調整」という作業で、変数はそのための仕組みです。
func _process(delta): — 毎フレーム呼ばれる関数
ゲームは、パラパラ漫画のように1秒間に60回ほど画面を描き直しています。この1回1回を「フレーム」と呼びます。
_process は特別な関数で、Godotが毎フレーム自動で呼び出してくれます。つまりここに書いたことは1秒に60回実行されます。「ゲームの心臓部」だと思ってください。
Input.get_vector(...) — キー入力を方向に変換
Input.get_vector() は、4つのキーの押され具合を「方向」としてまとめてくれる便利な命令です。"ui_left" などはGodotにあらかじめ用意されている入力名で、矢印キーに対応しています。
右を押せば (1, 0)、上なら (0, -1)、右上なら斜めの方向が direction に入ります。
position += direction * speed * delta — 実際に動かす
position はノードの現在位置です(前回インスペクタでいじったアレです)。そこに「方向 × 速さ × delta」を毎フレーム足し込むことで移動します。
delta を掛けるのはなぜ? delta には「前のフレームからの経過時間(秒)」が入っています。これを掛けておくと、60フレーム/秒のPCでも30フレーム/秒の古いPCでも、1秒あたりの移動距離が同じになります。掛け忘れると、性能のいいPCほどゲームが速くなる昔のゲームのようなバグになります。「動く処理にはdeltaを掛ける」と覚えてください。
わざとエラーを出してみよう
ここで大事な練習をします。position の行の先頭にあるTab(字下げ)を消して、保存してみてください。
Parse Error: Unexpected identifier "position" in class body.
という赤いエラーが出ます。GDScriptでは字下げ(インデント)が「その行が関数の中身かどうか」を決めます。Tabを消すと position の行が関数の外(クラスの直下 = class body)に押し出され、「こんな場所に position があるのはおかしい」と怒られるのです。Tabを打ち直せば直ります。
エラーは敵ではありません。「どの行の・何が・どうおかしいか」を教えてくれる案内板です。この連載ではこれから何度もエラーに会いますが、毎回「行番号→メッセージ」の順に読めば必ず直せます。
つまずきポイント
Identifier "postion" not found: スペルミスです。エラーメッセージに間違った綴りがそのまま表示されるので、コードと見比べてください(positionの打ち間違いが定番)- 保存したのに反映されない: 実行中のゲームは古いままです。一度閉じて
F5(MacはCmd+B)し直してください - 動きがカクカクする:
deltaの掛け忘れがないか確認してください
今回学んだこと
- スクリプトはノードに取り付けるプログラム
varで変数(名前付きの入れ物)を作る。数値を変えれば挙動が変わる_process(delta)は毎フレーム呼ばれるゲームの心臓部- 動く処理には
deltaを掛けてフレームレートの影響をなくす - エラーは「行番号→メッセージ」の順に読む案内板
次回予告
今の宇宙船は画面の外まで飛んでいけてしまいます。第3回では画面の中に閉じ込める処理を書きながら、「関数を自分で作る」ことを学びます。