Создание вашего первого скрипта
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.
См. также
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, которую мы в сообществе часто используем для прототипирования.
We need to create a Sprite2D node to display it in the game. In the Scene dock, click the Other Node button.
Наберите "Sprite2D" в поисковой строке, чтобы отобразились нужные узлы, затем дважды кликните на Sprite2D, чтобы создать узел.
Вкладка Сцена (Scene) теперь должна содержать только узел Sprite2D.
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.
Примечание
Также вы можете создавать узлы Sprite2D автоматически, перетаскивая изображения в окно просмотра.
Затем нажмите и перетащите значок в окне просмотра, чтобы отцентрировать его в игровом представлении.
Создание нового скрипта
To create and attach a new script to our node, right-click on Sprite2D in the Scene dock and select Attach Script.
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.
Примечание
Названия скриптов C# должны совпадать с названием класса. В этом случае, вы должны назвать файл MySprite2D.cs.
В рабочей области Script должен появиться новый файл sprite_2d.gd и следующая строка кода:
extends Sprite2D
using Godot;
using System;
public partial class MySprite2D : 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!")
public MySprite2D()
{
GD.Print("Hello, world!");
}
Давайте разберём это. Слово func объявляет новую функцию _init. Это конструктор нашего класса. Движок вызывает _init при создании объекта в памяти, если вы определили эту функцию.
Примечание
GDScript - язык с отступами. Отступ (табуляция) в начале строки print() обязателен для работы кода. Если вы пропустите отступ или отступите неправильно, редактор выделит строку красным и выведет сообщение:"Indented block expected" ("Блок отступа пропущен").
Сохраните сцену как sprite_2d.tscn, если ещё не сделали этого, затем нажмите F6 (Cmd + R на macOS) для запуска. Посмотрите в окно вывода Вывод (Output) в панели внизу. Там должно отобразится "Hello, world!".
Удалите функцию _init(), оставив только строку extends Sprite2D.
Поворот вокруг
Теперь сделаем наш узел двигающимся и вращающимся. Для этого добавим две переменных в наш скрипт: скорость перемещения в пикселях в секунду и угловую скорость в радианах в секунду. Добавим следующий код после строки extends Sprite2D.
var speed = 400
var angular_speed = PI
private int _speed = 400;
private float _angularSpeed = Mathf.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
public override void _Process(double delta)
{
Rotation += _angularSpeed * (float)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 крутится на месте.
Примечание
Заметьте, что в C# аргумент delta, принимаемый _Process() – это double. Поэтому нам нужно конвертировать его в float, когда мы применяем его к углу вращения.
Движение вперёд
Теперь давайте заставим узел двигаться. Добавьте следующие две строки в функцию _process(), убедившись, что новые строки имеют такой же отступ, как и строка rotation += angular_speed * delta.
var velocity = Vector2.UP.rotated(rotation) * speed
position += velocity * delta
var velocity = Vector2.Up.Rotated(Rotation) * _speed;
Position += velocity * (float)delta;
Как мы уже видели, ключевое слово var определяет новую переменную. Если вы поместите его в верхней части скрипта, оно определит свойство класса. Внутри функции оно определяет локальную переменную: данная переменная существует только в области действия функции.
Мы определяем локальную переменную velocity, 2D-вектор, представляющий собой направление и скорость. Чтобы заставить узел двигаться вперёд, мы берём константу Vector2.UP класса Vector2, вектор, указывающий вверх, и вращаем его, вызывая метод rotated(). Данное выражение Vector2.UP.rotated(rotation) - вектор, указывающий вперёд относительно нашей иконки. Умноженное на наше свойство speed, это выражение даёт нам скорость, которую мы можем использовать для перемещения узла вперёд.
Мы добавляем velocity * delta к узлу position, чтобы переместить его. Сама позиция имеет тип Vector2, встроенный тип в Godot, представляющий двумерный вектор.
Запустите сцену, чтобы увидеть, что голова Godot движется по кругу.
Примечание
При таком перемещении узла не учитываются столкновения со стенами или полом. В Ваша первая 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
using Godot;
using System;
public partial class MySprite2D : Sprite2D
{
private int _speed = 400;
private float _angularSpeed = Mathf.Pi;
public override void _Process(double delta)
{
Rotation += _angularSpeed * (float)delta;
var velocity = Vector2.Up.Rotated(Rotation) * _speed;
Position += velocity * (float)delta;
}
}