関数
関数は、関連するアクションを実行するコードのセクションをまとめる方法です。これにより、コードがより読みやすくなり、同じコードを複数の場所で繰り返すことを避けることができます。
平方根関数は馴染みがあるかもしれません。この関数は入力を受け取り、出力を返します。関数には入力がない場合もあれば、複数の入力がある場合もあり、結果を返すことも返さないこともあります。
関数は常に クラス に属します。クラスは関連する関数をまとめるためのコンテナです。そのため、Godotでノードを拡張するとき、関数や変数を含むクラスを作成していることになります。
拡張したクラスは、拡張元のクラスの関数とプロパティも継承します。プロパティとは、クラスの最上位スコープで宣言されたメンバー変数のことです。
コードのエントリーポイント
継承された関数のひとつに
_ready
関数があります。この関数は、シーンツリーにノードが追加されるたびにエンジンによって呼び出されます。この関数をオーバーライドすることで、初期化コードを実行することができます。
もう一つの継承関数として
_process(delta)
関数があります。この関数は、各フレームでエンジンによって呼び出されます。delta
は前のフレームからの経過時間を示す入力値です。この関数内でゲームのアクティビティを駆動するコードを挿入することができます。
これらの組み込み関数には、名前にアンダースコアの接頭辞が付いています。一方、カスタム関数では、変数と同じように命名するのが一般的です。
「コードのエントリーポイントはどこにあるの?」と思った場合、組み込み関数をオーバーライドすることでエントリーポイントが提供されることがわかります。これらの関数は、初期化、入力イベント、ゲームループの処理中にエンジンによって呼び出されます。
次のようにしてゲームコードを開発し始めることができます:
extends Node2D
# メンバー変数をここで宣言します。var playervar enemiesvar score
# ノードが初めてシーンツリーに追加されたときに呼び出されます。func _ready(): add_enemies() get_player_details()
func add_enemies(): pass # ここに後でコードを追加します。
func get_player_details(): pass # 後でコードを追加します。
# 毎フレーム呼び出されます。func _process(delta): process_inputs(delta) process_enemy_activity(delta) update_score()
func process_inputs(delta): pass
func process_enemy_activity(delta): pass
func update_score(): pass
ここでは、宣言型プログラミングのアプローチを使用しました。実行したい内容(関数名)を記述しますが、どのようなコードで実装するかはまだ決めていません。
関数の入力
関数への入力は「引数」と呼ばれます。引数がない場合、引数のリスト、型指定された引数、デフォルト値付きの引数などが考えられます。
関数の戻り値
return
キーワードを使用すると、任意の時点で関数から値を返すことができます。これにより、関数を終了し、呼び出された場所に値(または null
値)を返します。
return
キーワードが使われていない場合、コードは関数の終わりまで実行され、null
値を返します。
戻り値を必ず使用する必要はありません。関数を呼び出すだけで戻り値をキャプチャしなくても動作します。しかし、戻り値が
null
ではない場合、コードの論理に潜むバグを警告するため、エラーウィンドウに警告が表示される場合があります。
また、戻り値の型を指定することで、さらなるバグ防止効果を得ることができます。
以下は、さまざまな方法で関数を定義した例です:
extends Node2D
# ノードがシーンツリーに追加されたときに呼び出されます。func _ready(): add(5, 6) # 11 を出力ウィンドウに表示 var sum = get_sum(2, 4) # sum に 6 を設定 var my_int = add_ints(sum, 4) # my_int に 10 を設定 my_int = times_2(my_int) # my_int に 20 を設定 move_x(self, my_int) # このノードを x 軸方向に 20 ピクセル移動 move_x(self) # デフォルト値で移動
# この関数は値を返しませんfunc add(a, b): print(a + b)
# この関数は値を返しますfunc get_sum(a, b): return a + b
# 整数引数のみを受け付ける関数func add_ints(a: int, b: int): return a + b
# 戻り値が整数でなければエラーを生成func times_2(n) -> int: return 2 * n
# 参照渡しされたオブジェクトを変更する関数func move_x(node: Node2D, dx = 1.5): node.position.x += dx
上記コードでは、ノードのプロパティが戻り値を返さずに変更されています。これは、ノード値がオブジェクトへの参照番号であり、オブジェクトが参照渡しされているためです。一方、単純な数値は値渡しされ、関数のローカルスコープ内で扱われるため、新しい値を使用するには戻り値を返す必要があります。
演習
参照渡しされたオブジェクトを変更し、値を返す例を作成してみましょう。このような場合、処理が成功したか失敗したかを示すブール値を返すのは便利です。上記のコードにこの例を追加してみてください。
注意点
関数内のすべての処理は、次のフレームが画面に表示される前に終了する必要があります(
yield
または await
ステートメントを使用して、関数を一時停止し、特定のイベントを待機する場合を除く)。