Функции представляют собой способ группировки разделов кода, выполняющих связанные действия. Они помогают нам писать более читаемый код и избегать повторения одного и того же кода в нескольких местах.
Функция извлечения квадратного корня может быть вам знакома. У нее есть входные данные и возвращает результат. Функции могут иметь ноль или несколько входных данных и при необходимости возвращать результат.
Функции всегда принадлежат Классу, который является контейнером для связанных функций. Поэтому, когда вы расширяете узел (Node) в Godot, вы создаете Класс, содержащий ваши функции и переменные.
Ваш расширенный класс также унаследует функции и свойства класса, который он расширяет. Свойства — это переменные-члены, объявленные в самой верхней области видимости класса.
Точки входа в код
Одной из унаследованных функций является функция _ready. Она вызывается движком для каждого узла (Node), который входит в дерево сцены. Мы можем переопределить эту функцию, чтобы она выполняла наш код инициализации.
Еще одной унаследованной функцией, которую мы можем переопределить, является функция _process(delta). Ее вызывает движок для каждого кадра видео. Значение входного параметра delta — это прошедшее время с предыдущего кадра. В этой функции мы можем вставить код, который управляет активностью нашей игры.
Эти встроенные функции имеют префикс с подчеркиванием в именах. Для наших пользовательских функций мы, вероятно, будем именовать их так же, как и переменные.
Если вы задавались вопросом «где точка входа в мой код?», то вы видите, что это происходит через встроенные функции, которые мы можем переопределить. Они вызываются движком в моменты инициализации, событий ввода и во время обхода игрового цикла.
Вот как мы могли бы начать разрабатывать код нашей игры:
extends Node2D
# Declare member variables here.
var player
var enemies
var score
# Called when the node enters the scene tree for the first time.
func _ready():
add_enemies()
get_player_details()
func add_enemies():
pass # Add code to do this later
func get_player_details():
pass # Add the code later
# Called every frame.
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
# Called when the node enters the scene tree for the first time.
func _ready():
add(5, 6) # Prints 11 to Output window
var sum = get_sum(2, 4) # Sets sum to 6
var my_int = add_ints(sum, 4) # Sets my_int to 10
my_int = times_2(my_int) # sets my_int to 20
move_x(self, my_int) # Move this node 20 pixels along x axis
move_x(self) # Move by the default value
# This function has no return value
func add(a, b):
print(a + b)
# This function returns a value
func get_sum(a, b):
return a + b
# This function will only accept integer arguments
func add_ints(a: int, b: int):
return a + b
# Generate an error if the return value is not an int
func times_2(n) -> int:
return 2 * n
# This function modifies an object that is passed by reference
func move_x(node: Node2D, dx = 1.5):
node.position.x += dx
В вышеуказанном коде вы можете видеть, что свойство узла изменяется без возврата значения узла. Это работает потому, что значение узла является ссылочным номером на объект, и говорится, что объект передается по ссылке. В отличие от простого числа, которое передается по значению, где оно имеет локальную область видимости для функции и должно быть возвращено, чтобы использовать новое значение.