Отслеживание ввода игрока

Основываясь на предыдущем уроке Создание вашего первого скрипта, давайте рассмотрим еще одну важную особенность любой игры: предоставление контроля игроку. Чтобы добавить это, нам нужно изменить наш код sprite_2d.gd.

../../_images/scripting_first_script_moving_with_input.gif

У вас есть два важных инструмента для обработки пользовательского ввода в Godot:

  1. Встроенные обратные вызовы ввода, в основном _unhandled_input(). Подобно функции _process() функция _unhandled_input() — это встроенная виртуальная функция, которую Godot вызывает каждый раз, когда игрок нажимает клавишу. Это инструмент, который вы захотите использовать, чтобы реагировать на события, которые не происходят каждый кадр, например, нажатие Space для прыжка. Чтобы узнать больше об обратных вызовах ввода, посмотрите Использование InputEvent.

  2. Синглтон Input. Синглтон - это глобально доступный объект. Godot предоставляет доступ к нескольким из них в скриптах. Это подходящий инструмент для проверки ввода в каждом кадре.

Здесь мы будем использовать синглтон Input, поскольку нам нужно знать в каждом кадре, хочет ли игрок поворачиваться или двигаться.

Для поворота нам стоит использовать новую переменную: direction. В нашей функции _process() замените строку rotation += angular_speed * delta на приведенный ниже код.

var direction = 0
if Input.is_action_pressed("ui_left"):
    direction = -1
if Input.is_action_pressed("ui_right"):
    direction = 1

rotation += angular_speed * direction * delta

Наша локальная переменная direction - это множитель, представляющий собой направление, в котором игрок хочет повернуть. Значение 0 означает, что игрок не нажимает ни стрелку влево, ни стрелку вправо. Значение 1 говорит, что игрок хочет повернуть вправо, а -1 - что игрок хочет повернуть влево.

To produce these values, we introduce conditional statements and the use of Input. A conditional statement starts with the if keyword in GDScript and ends with a colon. The condition is specifically the expression between the keyword and the colon at the end of the line.

Чтобы проверить, была ли нажата клавиша в этом кадре, мы вызываем Input.is_action_pressed(). Метод принимает текстовую строку, представляющую действие ввода, и возвращает true, если клавиша нажата, и false в противном случае.

Два действия, которые мы использовали выше, «ui_left» и «ui_right», предопределены в каждом проекте Godot. Они соответственно срабатывают, когда игрок нажимает стрелки влево и вправо на клавиатуре или же влево и вправо на крестовине геймпада.

Примечание

Вы можете просматривать и редактировать действия ввода в своем проекте, перейдя в Проект -> Настройки проекта и щелкнув вкладку Список действий.

Наконец, мы используем direction как множитель, когда обновляем rotation узла: rotation += angular_speed * direction * delta.

Закомментируйте строки var velocity = Vector2.UP.rotated(rotation) * speed и position += velocity * delta следующим образом:

#var velocity = Vector2.UP.rotated(rotation) * speed

#position += velocity * delta

Это игнорирует код, который перемещал иконку по кругу без ввода пользователя из предыдущего упражнения.

Если запустить сцену с этим кодом, иконка должна вращаться при нажатии Влево и Вправо.

Перемещение при нажатии "вверх"

Чтобы двигаться только при нажатии клавиши, нам нужно изменить код, который вычисляет скорость. Замените строку, начинающуюся с var velocity, на приведенный ниже код.

var velocity = Vector2.ZERO
if Input.is_action_pressed("ui_up"):
    velocity = Vector2.UP.rotated(rotation) * speed

Мы инициализируем velocity со значением Vector2.ZERO, еще одной константой встроенного типа Vector, представляющей двумерный вектор нулевой длины.

Когда игрок выполняет действие "ui_up", мы обновляем значение скорости, заставляя спрайт двигаться вперёд.

Готовый скрипт

Это полный файл sprite_2d.gd для справки.

extends Sprite2D

var speed = 400
var angular_speed = PI


func _process(delta):
    var direction = 0
    if Input.is_action_pressed("ui_left"):
        direction = -1
    if Input.is_action_pressed("ui_right"):
        direction = 1

    rotation += angular_speed * direction * delta

    var velocity = Vector2.ZERO
    if Input.is_action_pressed("ui_up"):
        velocity = Vector2.UP.rotated(rotation) * speed

    position += velocity * delta

Если вы запустите сцену, вы должны иметь возможность вращаться с помощью стрелок влево и вправо, а также двигаться нажатием Вверх.

../../_images/scripting_first_script_moving_with_input.gif

Подведение итогов

В общем, каждый скрипт в Godot представляет собой класс и расширяет один из встроенных классов движка. Типы узлов, от которых наследуются ваши классы, дают вам доступ к таким свойствам, как rotation и position в случае нашего спрайта. Вы также наследуете множество функций, которые мы не использовали в этом примере.

В GDScript переменные, которые вы помещаете в верхней части файла, являются свойствами вашего класса, также называемыми переменными класса. Кроме переменных, вы можете определять функции, которые, по сути, являются методами ваших классов.

Godot предоставляет несколько виртуальных функций, которые вы можете определить для связи вашего класса с движком. К ним относятся _process(), применяющая изменения к узлу каждый кадр, и _unhandled_input(), получающая события ввода, такие как нажатие клавиш и кнопок от пользователей. Есть еще множество других функций.

Синглтон Input позволяет вам реагировать на ввод от игрока в любом месте вашего кода. В первую очередь вы сможете применить его в цикле _process().

В следующем уроке Использование сигналов мы будем изучать на отношения между скриптами и узлами, наблюдая за тем как код приводит в действие узлы.