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

In this lesson, you will code your first script to make the Godot icon turn in circles. As we mentioned in the introduction, we assume you have programming foundations.

This tutorial is written for GDScript, and the equivalent C# code is included in another tab of each codeblock for convenience.

../../_images/scripting_first_script_rotating_godot.gif

См. также

To learn more about GDScript, its keywords, and its syntax, head to the GDScript section. To learn more about C#, head to the C#/.NET section.

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

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

../../_images/scripting_first_script_icon.svg

We need to create a Sprite2D node to display it in the game. In the Scene dock, click the Other Node button.

../../_images/scripting_first_script_click_other_node.webp

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

../../_images/scripting_first_script_add_sprite_node.webp

Вкладка Сцена (Scene) теперь должна содержать только узел Sprite2D.

../../_images/scripting_first_script_scene_tree.webp

A Sprite2D node needs a texture to display. In the Inspector on the right, you can see that the Texture property says <empty>. To display the Godot icon, click and drag the file icon.svg from the FileSystem dock onto the Texture slot.

../../_images/scripting_first_script_setting_texture.webp

Примечание

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

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

../../_images/scripting_first_script_centering_sprite.webp

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

To create and attach a new script to our node, right-click on Sprite2D in the Scene dock and select Attach Script.

../../_images/scripting_first_script_attach_script.webp

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

Change the Template field from Node: Default to Object: Empty to start with a clean file. Leave the other options set to their default values and click the Create button to create the script.

../../_images/scripting_first_script_attach_node_script.webp

Примечание

Названия скриптов C# должны совпадать с названием класса. В этом случае, вы должны назвать файл MySprite2D.cs.

В рабочей области Script должен появиться новый файл sprite_2d.gd и следующая строка кода:

extends Sprite2D

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

Примечание

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

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

Примечание

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

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

Привет, мир!

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

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

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

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

Примечание

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

Сохраните сцену как sprite_2d.tscn, если ещё не сделали этого, затем нажмите F6 (Cmd + R на macOS) для запуска. Посмотрите в окно вывода Вывод (Output) в панели внизу. Там должно отобразится "Hello, world!".

../../_images/scripting_first_script_print_hello_world.webp

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

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

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

var speed = 400
var angular_speed = PI

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

Примечание

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

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

Примечание

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

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

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

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

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

Примечание

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

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

Совет

In the code editor, you can Ctrl + Click (Cmd + Click on macOS) on any built-in property or function like position, rotation, or _process to open the corresponding documentation in a new tab.

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

../../_images/scripting_first_script_godot_turning_in_place.gif

Примечание

Заметьте, что в C# аргумент delta, принимаемый _Process() – это double. Поэтому нам нужно конвертировать его в float, когда мы применяем его к углу вращения.

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

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

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

position += velocity * delta

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

Мы определяем локальную переменную velocity, 2D-вектор, представляющий собой направление и скорость. Чтобы заставить узел двигаться вперёд, мы берём константу Vector2.UP класса Vector2, вектор, указывающий вверх, и вращаем его, вызывая метод rotated(). Данное выражение Vector2.UP.rotated(rotation) - вектор, указывающий вперёд относительно нашей иконки. Умноженное на наше свойство speed, это выражение даёт нам скорость, которую мы можем использовать для перемещения узла вперёд.

Мы добавляем velocity * delta к узлу position, чтобы переместить его. Сама позиция имеет тип Vector2, встроенный тип в Godot, представляющий двумерный вектор.

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

../../_images/scripting_first_script_rotating_godot.gif

Примечание

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

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

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

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

extends Sprite2D

var speed = 400
var angular_speed = PI


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

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

    position += velocity * delta