Создание вашего первого скрипта

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

../../_images/scripting_first_script_rotating_godot.gif

См.также

Подробнее о GDScript, его ключевых словах и синтаксисе, читайте в Основы GDScript.

Настройка проекта

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

Нам нужно создать узел Спрайт для отображения в игре. В панели Сцены, кликните на кнопку Другой Узел.

../../_images/scripting_first_script_click_other_node.png

Наберите "Sprite" в поисковой строке, чтобы отобразились нужные узлы, затем дважды кликните на Sprite, чтобы создать узел.

../../_images/scripting_first_script_add_sprite_node.png

Вкладка Сцены теперь должна содержать только узел Sprite.

../../_images/scripting_first_script_scene_tree.png

Узлу Sprite нужна текстура для отображения. В Инспекторе справа вы можете увидеть, что в свойстве текстуры указано "[пусто]". Чтобы отобразить иноку Godot, кликните и перетащите файл ``icon.png``из файловой системы панели на слот текстуры.

../../_images/scripting_first_script_setting_texture.png

Примечание

Также вы можете создавать узлы Sprite автоматически, перетаскивая изображения в Окно просмотра.

../../_images/scripting_first_script_dragging_sprite.png

Then, click and drag the icon in the viewport to center it in the game view.

../../_images/scripting_first_script_centering_sprite.png

Создание нового скрипта

Чтобы создать и прикрепить новый скрипт к нашему узлу, нажмите правой кнопкой мыши на Спрайт в панели сцены и выберите "Прикрепить Скрипт".

../../_images/scripting_first_script_attach_script.png

The Attach Node Script window appears. It allows you to select the script's language and file path, among other options.

Change the Template from Default to Empty to start with a clean file. Leave the other options by default and click the Create button to create the script.

../../_images/scripting_first_script_attach_node_script.png

The Script workspace should appear with your new Sprite.gd file open and the following line of code:

extends Sprite

Каждый файл GDScript неявно является классом. Ключевое слово extends определяет класс, который наследует или расширяет данный скрипт. В этом случае Sprite означает, что наш скрипт получит доступ к свойствам и функциям узла Sprite, включая классы, которые он расширяет, такие как Node2D, CanvasItem и``Node``.

Примечание

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

К унаследованным свойствам относятся те, которые вы можете видеть в инспекторе, например, texture узла.

Примечание

По умолчанию, Инспектор отображает свойства узла в "Title Case", слова с заглавными буквами вначале, разделенные пробелом. В GDScript эти свойства записываются в "snake_case", строчными буквами, разделенными подчёркиванием.

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

Привет мир!

Наш скрипт ничего не делает. Давайте заставим его вывести "Hello, world!" в панель вывода в нижней части экрана.

Добавьте следующий код в ваш скрипт:

func _init():
    print("Hello, world!")

Давайте разберём это. Слово func объявляет новую функцию _init. Это конструктор нашего класса. Движок вызывает _init при создании объекта в памяти, если вы определили эту функцию.

Примечание

GDScript - язык с отступами. Отступ (табуляция) в начале строки print() обязателен для работы кода. Если вы пропустите отступ, редактор выделит строку красным, и выведет сообщение: "Unexpected indentation."

Сохраните сцену, если ещё не сделали этого, затем нажмите :kbd:`F6`для запуска. Посмотрите в окно вывода в панели внизу. Там должно отобразится "Hello, world!"

../../_images/scripting_first_script_print_hello_world.png

Удалите функцию _init(), оставив только строку extends Sprite.

Поворот вокруг

Теперь сделаем наш узел двигающимся и вращающимся. Для этого добавим две переменных-члена в наш скрипт: скорость перемещения в пикселях в секунду и угловую скорость в радианах в секунду.

extends Sprite

var speed = 400
var angular_speed = PI

Переменные-члены располагаются в начале скрипта, перед функциями. Каждый экземпляр узла с прикреплённым к нему скриптом имеет собственную копию свойств speed и angular_speed.

Примечание

Углы в Godot задаются в радианах, как и в некоторых других движках, но вы можете использовать встроенные функции и свойства для работы с градусами.

Для перемещения иконки мы должны обновлять её позицию и вращение каждый кадр игрового цикла. Для этого используем виртуальную функцию _process класса Node. При объявлении этой функции в любом классе, наследуемом от Node (например, Sprite), Godot будет вызывать её каждый кадр и передавать в аргументе delta время, прошедшее от предыдущего кадра.

Примечание

Игры работают в цикле, отображая множество изображений в секунду, каждое из которых называется кадром. Скорость, с которой игра создаёт эти изображения, измеряется в кадрах в секунду (Frame Per Second). Большинство игр нацелены на 60 FPS, хотя вы можете найти такие цифры, как 30 кадров в секунду на более медленных мобильных устройствах или от 90 до 240 для игр виртуальной реальности.

The engine and game developers do their best to update the game world and render images at a constant time interval, but there are always small variations in frame render times. That's why the engine provides us with this delta time value, making our motion independent of our framerate.

В нижней части скрипта определите функцию:

func _process(delta):
    rotation += angular_speed * delta

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

Примечание

Обратите внимание, что _process(), как и _init(), начинается с символа подчёркивания. По соглашению, виртуальные функции, то есть встроенные функции Godot, которые вы можете переопределить - начинаются с символа подчёркивания.

Строка внутри функции, rotation += angular_speed * delta, увеличивает угол вращения нашего спрайта каждый кадр. Здесь rotation — это свойство, унаследованное от класса Node2D, который расширяет класс Sprite. Именно он управляет вращением узла, используя радианы для измерения угла поворота.

Совет

В редакторе кода вы можете нажать Ctrl+ЛКМ на любом встроенном свойстве или функции, таких как position, rotation, или _process чтобы открыть соответствующую документацию в новой вкладке.

Запустите сцену, чтобы увидеть, что иконка Godot крутится на месте.

../../_images/scripting_first_script_godot_turning_in_place.gif

Движение вперёд

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

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

position += velocity * delta

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

We define a local variable named velocity, a 2D vector representing both a direction and a speed. To make the node move forward, we start from the Vector2 class's constant Vector2.UP, a vector pointing up, and rotate it by calling the Vector2.rotated() method. This expression, Vector2.UP.rotated(rotation), is a vector pointing forward relative to our icon. Multiplied by our speed property, it gives us a velocity we can use to move the node forward.

We add velocity * delta to the node's position to move it. The position itself is of type Vector2, a built-in type in Godot representing a 2D vector.

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

../../_images/scripting_first_script_rotating_godot.gif

Примечание

При таком перемещении узла не учитывается столкновение со стенами или полом. В Ваша первая 2D игра вы узнаете другой подход к перемещению объектов при обнаружении столкновений.

Our node currently moves by itself. In the next part Listening to player input, we'll use player input to control it.

Complete script

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

extends Sprite

var speed = 400
var angular_speed = PI


func _process(delta):
    rotation += angular_speed * delta

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

    position += velocity * delta