Створення першого сценарію
У цьому уроці ви напишете свій перший скрипт, щоб значок Годо обертався по колу. Як ми вже згадували in the introduction, ми припускаємо, що у вас є основи програмування.
Цей посібник написано для GDScript, а еквівалентний код C# для зручності включено в окрему вкладку кожного блоку коду.
Дивись також
Щоб дізнатися більше про GDScript, його ключові слова та синтаксис, перейдіть до розділу Скрипт. Щоб дізнатися більше про C#, перейдіть до розділу C#/.NET.
Налаштування проєкту
Будь ласка create a new project почати з чистого аркуша. Ваш проект має містити одне зображення: значок Godot, який ми часто використовуємо для створення прототипів у спільноті.
Нам потрібно створити вузол Sprite2D для його відображення в грі. У доку Scene натисніть кнопку .
Введіть "Sprite2D" у рядку пошуку, щоб відфільтрувати вузли, і двічі клацніть на Sprite2D, щоб створити вузол.
Ваша вкладка Scene тепер повинна містити лише вузол Sprite2D.
Вузол Sprite2D потребує текстури для відображення. У Inspector праворуч ви можете побачити, що властивість Texture має значення <empty>. Щоб відобразити іконку Godot, клацніть і перетягніть файл icon.svg з дока FileSystem у слот Texture.
Примітка
Ви можете створювати вузли Sprite2D автоматично, перетягуючи зображення на область перегляду.
Потім клацніть і перетягніть піктограму у вікні перегляду, щоб відцентрувати її в області перегляду гри.
Створення нового сценарію
Щоб створити та приєднати новий скрипт до нашого вузла, клацніть правою кнопкою миші на Sprite2D у панелі сцени та виберіть .
З’явиться вікно Attach Node Script. Воно дозволяє вам вибрати мову скрипта та шлях до файлу, серед інших опцій.
Змініть поле Template з Вузол: За замовчуванням на Об'єкт: Порожній, щоб почати з чистого файлу. Залиште інші параметри встановленими за замовчуванням і натисніть кнопку , щоб створити скрипт.
Примітка
Назви скриптів 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 використовує для керування пам’яттю вашої програми.
Успадковані властивості включають ті, які ви можете побачити в доці Inspector, як-от текстура нашого вузла.
Примітка
За замовчуванням Inspector відображає властивості вузла в «Title Case», з великими літерами, розділеними пробілом. У коді GDScript ці властивості представлені в «snake_case», тобто малими літерами, розділеними підкресленням.
Ви можете навести курсор на назву будь-якої властивості в Inspector, щоб побачити опис та її ідентифікатор у коді.
Привіт, всесвіт!
Наш скрипт наразі нічого не робить. Давайте змусимо його надрукувати текст "Привіт, світ!" до нижньої панелі виводу, щоб почати.
Додайте наступний код до свого сценарію:
func _init():
print("Hello, world!")
public MySprite2D()
{
GD.Print("Hello, world!");
}
Давайте розберемо його. Ключове слово func визначає нову функцію під назвою _init. Це спеціальна назва для конструктора нашого класу. Движок викликає _init() для кожного об'єкта або вузла після його створення в пам'яті, якщо ви визначаєте цю функцію.
Примітка
GDScript — це мова на основі відступів. Для того, щоб код працював, необхідна вкладка на початку рядка з текстом print(). Якщо ви пропустите його або неправильно відступите рядок, редактор виділить його червоним і відобразить таке повідомлення про помилку: «Очікується блок із відступом».
Збережіть сцену як 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, як-от Sprite2D, Godot буде викликати цю функцію кожен кадр і передавати їй аргумент під назвою delta, тобто час, що минув від останнього кадру.
Примітка
Ігри працюють, відтворюючи багато зображень за секунду, кожне з яких називається кадром, і роблять це циклічно. Ми вимірюємо швидкість, з якою гра створює зображення в кадрах за секунду (FPS). Більшість ігор націлені на 60 FPS, хоча ви можете знайти і 30 FPS на повільних мобільних пристроях або від 90 до 240 для ігор віртуальної реальності.
Розробники рушія та ігор роблять усе можливе, щоб оновлювати ігровий світ і відтворювати зображення через постійний проміжок часу, але завжди є невеликі зміни в часі візуалізації кадрів. Ось чому рушій надає нам це значення дельта-часу, завдяки чому наш рух не залежить від частоти кадрів.
У нижній частині скрипту визначте функцію:
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. Він контролює обертання нашого вузла і працює з радіанами.
Порада
У редакторі коду ви можете Ctrl + Click (Cmd + Click у macOS) на будь-якій вбудованій властивості або функції, такій як position, rotation або _process, щоб відкрити відповідну документацію в новій вкладці.
Запустіть сцену, щоб побачити, як значок 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. Цей вираз, Vector2.UP.rotated(rotation), є вектором, спрямування вперед відносно нашої піктограми. Помножений на нашу властивість speed, він дає нам швидкість, яку ми можемо використовувати для переміщення вузла вперед.
Ми додаємо velocity * delta до position вузла, щоб перемістити його. Сама позиція має тип Vector2, вбудований у Godot тип , що представляє 2D вектор.
Запустіть сцену, щоб побачити, як голова 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;
}
}