This translation is community contributed and may not be up to date. We only maintain the English version of the documentation. Read this manual in English
Цей посібник представляє Defold як альтернативу для розробників ігор на Flash. Він охоплює деякі ключові поняття розробки ігор на Flash та пояснює відповідні інструменти й методи в Defold.
Серед ключових переваг Flash були доступність і низький поріг входження. Нові користувачі могли швидко опанувати програму й почати створювати прості ігри, витративши небагато часу. Defold пропонує схожу перевагу: набір інструментів, призначених для створення ігор, водночас даючи досвідченим розробникам змогу створювати складні рішення для вибагливіших потреб (наприклад, редагувати стандартний скрипт рендерингу).
Ігри на Flash програмують мовою ActionScript (найновіша версія — 3.0), а скрипти для Defold пишуть мовою Lua. Цей посібник не містить докладного порівняння Lua та Actionscript 3.0. Посібник Defold добре знайомить із програмуванням мовою Lua в Defold і містить посилання на надзвичайно корисну книгу Programming in Lua (перше видання), яка безплатно доступна онлайн.
Стаття Джессі Вордена містить базове порівняння Actionscript і Lua, з якого зручно почати. Проте зауважте, що відмінності в будові Defold і Flash глибші за ті, що помітні на рівні мови. Actionscript і Flash є об’єктно-орієнтованими в класичному розумінні — з класами та успадкуванням. У Defold немає ані класів, ані успадкування. Натомість є поняття ігрового об’єкта (game object), який може містити аудіовізуальне представлення, поведінку й дані. Операції з ігровими об’єктами виконують за допомогою функцій, доступних в API Defold. Крім того, Defold заохочує використовувати повідомлення для взаємодії між об’єктами. Повідомлення — це конструкція вищого рівня, ніж виклики методів, і вони не призначені для такого використання. Ці відмінності суттєві, і до них потрібно звикнути, але в цьому посібнику вони докладно не розглядатимуться.
Натомість цей посібник розглядає деякі ключові поняття розробки ігор на Flash та окреслює їхні найближчі відповідники в Defold. У ньому розглянуто подібності й відмінності, а також поширені труднощі, щоб допомогти вам упевнено розпочати перехід із Flash на Defold.
Кліпи (movie clips) — ключовий складник розробки ігор на Flash. Це символи, кожен із яких містить власну часову шкалу. Найближчим відповідником у Defold є ігровий об’єкт.

На відміну від кліпів Flash, ігрові об’єкти Defold не мають часових шкал. Натомість ігровий об’єкт складається з кількох компонентів (component). До компонентів належать, зокрема, спрайти, звуки й скрипти (докладніше про доступні компоненти дивіться в документації про будівельні блоки та пов’язаних статтях). Ігровий об’єкт на знімку екрана нижче складається зі спрайта та скрипту. Компонент-скрипт керує поведінкою й виглядом ігрових об’єктів протягом їхнього життєвого циклу:

Кліпи можуть містити інші кліпи, а ігрові об’єкти не можуть містити ігрові об’єкти. Проте ігрові об’єкти можна робити дочірніми щодо інших ігрових об’єктів, створюючи ієрархії, які можна переміщувати, масштабувати або повертати разом.
У Flash екземпляри (instance) кліпів можна додавати до сцени вручну, перетягуючи їх із бібліотеки на часову шкалу. Це показано на знімку екрана нижче, де кожен логотип Flash є екземпляром кліпу logo:

Як уже згадувалося, у Defold немає поняття часової шкали. Натомість ігрові об’єкти організовано в колекції (collection). Колекції — це контейнери (або префаби), які містять ігрові об’єкти та інші колекції. У найпростішому випадку гра може складатися лише з однієї колекції. Частіше ігри на Defold використовують кілька колекцій, доданих вручну до стартової колекції (bootstrap collection) main або динамічно завантажених через проксі колекцій (collection proxy). Це поняття завантаження «рівнів» або «екранів» не має прямого відповідника у Flash.
У прикладі нижче колекція main містить три екземпляри (перелічені праворуч у вікні Outline) ігрового об’єкта logo (показаного ліворуч у вікні браузера Assets):

Щоб звертатися до кліпів, створених вручну у Flash, потрібно використовувати ім’я екземпляра, задане вручну:

У Defold до всіх ігрових об’єктів і компонентів звертаються за адресою. Здебільшого достатньо простого імені або скорочення. Наприклад:
"." адресує поточний ігровий об’єкт."#" адресує поточний компонент (скрипт)."logo" адресує ігровий об’єкт з ідентифікатором logo."#script" адресує компонент з ідентифікатором script у поточному ігровому об’єкті."logo#script" адресує компонент з ідентифікатором script в ігровому об’єкті з ідентифікатором logo.Адреса ігрових об’єктів, розміщених вручну, визначається заданою властивістю Id (дивіться правий нижній кут знімка екрана). Ідентифікатор має бути унікальним у поточному файлі колекції, з яким ви працюєте. Редактор автоматично задає ідентифікатор, але ви можете змінити його для кожного створеного екземпляра ігрового об’єкта.

Щоб дізнатися ідентифікатор ігрового об’єкта, виконайте такий код у його компоненті-скрипті: print(go.get_id()). Це виведе в консоль ідентифікатор поточного ігрового об’єкта.
Модель адресації та передавання повідомлень — ключові поняття розробки ігор на Defold. Їх докладно пояснено в посібнику з адресації та посібнику з передавання повідомлень.
Щоб динамічно створювати кліпи у Flash, спочатку потрібно налаштувати ActionScript Linkage:

Це створює клас (у цьому випадку Logo), після чого можна створювати нові екземпляри цього класу. Додати екземпляр класу Logo до сцени Stage можна так:
var logo:Logo = new Logo();
addChild(logo);
У Defold для динамічного створення ігрових об’єктів використовують фабрики (factory). Фабрики — це компоненти, які створюють копії певного ігрового об’єкта. У цьому прикладі створено фабрику з ігровим об’єктом logo як прототипом:

Зауважте, що фабрики, як і всі компоненти, потрібно додати до ігрового об’єкта, перш ніж ними можна буде користуватися. У цьому прикладі ми створили ігровий об’єкт з іменем factories, щоб розмістити в ньому компонент-фабрику:

Щоб створити екземпляр ігрового об’єкта logo, викличте таку функцію:
local logo_id = factory.create("factories#logo_factory")
URL — обов’язковий параметр factory.create(). Також можна додати необов’язкові параметри, щоб задати позицію, поворот, властивості й масштаб. Докладніше про компонент-фабрику дивіться в посібнику з фабрик. Зауважте, що виклик factory.create() повертає ідентифікатор створеного ігрового об’єкта. Цей ідентифікатор можна зберегти для подальших звертань у таблиці (відповіднику масиву в Lua).
У Flash нам знайомі часова шкала Timeline (верхня частина знімка екрана нижче) і сцена Stage (видима під Timeline):

Як зазначено вище в розділі про кліпи, Stage, по суті, є контейнером найвищого рівня гри на Flash і створюється щоразу під час експорту проєкту. За замовчуванням Stage має один дочірній об’єкт — MainTimeline. Кожен кліп, створений у проєкті, матиме власну часову шкалу й може бути контейнером для інших символів (зокрема кліпів).
Відповідником сцени Stage у Flash є колекція в Defold. Під час запуску рушій створює новий ігровий світ на основі вмісту файлу колекції. За замовчуванням цей файл має назву main.collection, але ви можете змінити колекцію, яка завантажується під час запуску, у файлі налаштувань game.project, розташованому в корені кожного проєкту Defold:

Колекції — це контейнери, які використовуються в редакторі для організації ігрових об’єктів та інших колекцій. Вміст колекції також можна створювати скриптом під час виконання за допомогою фабрики колекцій, яка працює так само, як звичайна фабрика ігрових об’єктів. Це корисно, наприклад, для створення груп ворогів або певної схеми розташування монет для збирання. На знімку екрана нижче ми вручну розмістили два екземпляри колекції logos у колекції main.

Іноді потрібно завантажити цілком новий ігровий світ. Компонент проксі колекції дає змогу створити новий ігровий світ на основі вмісту файлу колекції. Це стане в пригоді, наприклад, для завантаження нових ігрових рівнів, мініігор або сюжетних вставок.
Часову шкалу Flash переважно використовують для анімації, застосовуючи різні покадрові техніки або інтерполяцію форми чи руху. Загальне налаштування FPS (кадрів за секунду) проєкту визначає тривалість показу кадру. Досвідчені користувачі можуть змінювати загальну частоту кадрів гри або навіть окремих кліпів.
Інтерполяція форми дає змогу інтерполювати векторну графіку між двома станами. Здебільшого вона корисна лише для простих фігур і способів застосування, як показує наведений нижче приклад перетворення квадрата на трикутник:

Інтерполяція руху дає змогу анімувати різні властивості об’єкта, зокрема розмір, позицію й поворот. У прикладі нижче змінено всі перелічені властивості.

Defold працює з растровими зображеннями, а не з векторною графікою, тому не має відповідника інтерполяції форми. Проте інтерполяція руху має потужний відповідник — анімацію властивостей. Її виконують у скрипті за допомогою функції go.animate(). Функція go.animate() інтерполює властивість (наприклад, колір, масштаб, поворот або позицію) від початкового значення до бажаного кінцевого значення, використовуючи одну з багатьох доступних функцій плавності (зокрема власних). Якщо у Flash користувач мав самостійно реалізовувати складніші функції плавності, то в рушій Defold багато функцій плавності уже вбудовано.
У Flash для анімації графіки використовують ключові кадри на часовій шкалі, а в Defold один з основних способів анімації графіки — покадрова анімація імпортованих послідовностей зображень. Анімації організовано в компоненті ігрового об’єкта, відомому як атлас. У цьому прикладі маємо атлас ігрового персонажа з анімаційною послідовністю run. Вона складається з низки файлів png:

У Flash список відображення визначає, що показано й у якому порядку. Порядок об’єктів у контейнері (наприклад, Stage) визначається індексом. Об’єкти, додані до контейнера методом addChild(), автоматично займають верхню позицію в індексі, починаючи з 0 та збільшуючи значення з кожним доданим об’єктом. На знімку екрана нижче ми створили три екземпляри кліпу logo:

Позиції у списку відображення позначено числами біля кожного екземпляра logo. Якщо не враховувати код для керування позиціями x/y кліпів, наведений вище результат можна отримати так:
var logo1:Logo = new Logo();
var logo2:Logo = new Logo();
var logo3:Logo = new Logo();
addChild(logo1);
addChild(logo2);
addChild(logo3);
Те, чи відображається об’єкт поверх іншого або під ним, визначається їхніми відносними позиціями в індексі списку відображення. Це добре видно, якщо поміняти місцями індексні позиції двох об’єктів, наприклад:
swapChildren(logo2,logo3);
Результат матиме такий вигляд (з оновленими індексними позиціями):

Позиції ігрових об’єктів у Defold представлені векторами з трьох змінних: x, y та z. Позиція z визначає глибину ігрового об’єкта. У стандартному скрипті рендерингу доступні позиції z лежать у діапазоні від -1 до 1.
Ігрові об’єкти з позицією z поза діапазоном від -1 до 1 не рендеритимуться, а отже, не будуть видимими. Це поширена пастка для розробників, які лише починають працювати з Defold, і про неї варто пам’ятати, якщо ігровий об’єкт не видно там, де ви очікуєте його побачити.
У Flash редактор лише опосередковано задає індекс глибини (і дає змогу змінювати його командами на кшталт Bring Forward та Send Backward), а Defold дає змогу задавати позицію z об’єктів безпосередньо в редакторі. На знімку екрана нижче видно, що logo3 відображається поверх інших і має позицію z 0.2. Інші ігрові об’єкти мають позиції z 0.0 та 0.1.

Зауважте, що позиція z ігрового об’єкта, вкладеного в одну або кілька колекцій, визначається його власною позицією z разом із позиціями z усіх його батьківських об’єктів. Наприклад, уявіть, що наведені вище ігрові об’єкти logo розміщено в колекції logos, яку, своєю чергою, розміщено в main (дивіться знімок екрана нижче). Якби колекція logos мала позицію z 0.9, то позиції z ігрових об’єктів усередині неї дорівнювали б 0.9, 1.0 та 1.1. Отже, logo3 не рендерився б, оскільки його позиція z більша за 1.

Позицію z ігрового об’єкта, звісно, можна змінювати зі скрипту. Припустімо, наведений нижче код міститься в компоненті-скрипті ігрового об’єкта:
local pos = go.get_position()
pos.z = 0.5
go.set_position(pos)
hitTestObject і hitTestPoint
Базове виявлення колізій у Flash виконують за допомогою методу hitTestObject(). У цьому прикладі маємо два кліпи: bullet і bullseye. Їх показано на знімку екрана нижче. Синя обмежувальна рамка стає видимою, коли вибрати символи в редакторі Flash, і саме ці рамки визначають результат методу hitTestObject().

Виявлення колізій за допомогою hitTestObject() виконують так:
bullet.hitTestObject(bullseye);
Використання обмежувальних рамок у цьому випадку було б недоречним, оскільки в наведеній нижче ситуації було б зареєстровано влучання:

Альтернативою hitTestObject() є метод hitTestPoint(). Цей метод має параметр shapeFlag, який дає змогу перевіряти влучання за фактичними пікселями об’єкта, а не за обмежувальною рамкою. Виявлення колізій за допомогою hitTestPoint() можна виконати так:
bullseye.hitTestPoint(bullet.x, bullet.y, true);
Цей рядок перевіряє позицію x та y кулі (у цьому випадку її лівий верхній кут) на потрапляння всередину форми мішені. Оскільки hitTestPoint() перевіряє точку відносно форми, вибір точки (або точок!) для перевірки має ключове значення.
Defold містить фізичний рушій, який може виявляти колізії та давати скрипту змогу реагувати на них. Виявлення колізій у Defold починається з додавання компонентів об’єктів колізій до ігрових об’єктів. На знімку екрана нижче ми додали об’єкт колізії до ігрового об’єкта bullet. Об’єкт колізії позначено червоним прозорим прямокутником (видимим лише в редакторі):

Defold містить модифіковану версію фізичного рушія Box2D, який може автоматично моделювати реалістичні колізії. У цьому посібнику передбачається використання кінематичних об’єктів колізій, оскільки вони найбільше нагадують виявлення колізій у Flash. Докладніше про динамічні об’єкти колізій читайте в посібнику з фізики Defold.
Об’єкт колізії має такі властивості:

Використано форму прямокутника, оскільки вона найкраще підходила до зображення кулі. Іншу форму для двовимірних колізій — сферу — використаємо для мішені. Якщо задати тип Kinematic, то обробку колізій виконуватиме ваш скрипт, а не вбудований фізичний рушій (докладніше про інші типи дивіться в посібнику з фізики). Властивості Group і Mask визначають відповідно, до якої групи колізій належить об’єкт і з якою групою колізій його потрібно перевіряти. За поточних налаштувань bullet може стикатися лише з target. Уявіть, що налаштування змінено так:

Тепер кулі можуть стикатися з мішенями та іншими кулями. Для порівняння, ми налаштували об’єкт колізії мішені так:

Зверніть увагу, що властивість Group має значення target, а Mask — bullet.
У Flash виявлення колізій відбувається лише за явного виклику зі скрипту. У Defold виявлення колізій безперервно виконується у фоновому режимі, доки об’єкт колізії ввімкнений. Коли виникає колізія, повідомлення надсилаються всім компонентам ігрового об’єкта (передусім компонентам-скриптам). Це повідомлення collision_response і contact_point_response, які містять усю інформацію, потрібну для бажаної обробки колізії.
Перевага виявлення колізій у Defold полягає в тому, що воно досконаліше, ніж у Flash, і може виявляти колізії між відносно складними формами з мінімальними зусиллями на налаштування. Колізії виявляються автоматично, тому не потрібно перебирати різні об’єкти в різних групах колізій та явно виконувати перевірки влучання. Основний недолік — відсутність відповідника shapeFlag із Flash. Однак для більшості випадків достатньо поєднань базових форм прямокутника й сфери. Для складніших випадків можна використовувати власні форми.
Об’єкти подій і пов’язані з ними слухачі використовуються для виявлення різних подій (наприклад, клацань мишею, натискань кнопок, завантаження кліпів) і запуску дій у відповідь. Для роботи доступно багато різновидів подій.
Відповідник системи обробки подій Flash у Defold має кілька складників. По-перше, кожен компонент-скрипт має набір функцій зворотного виклику, які виявляють певні події. Це:
enterFrame у Flash.Усі перелічені вище функції зворотного виклику необов’язкові, і їх можна видалити, якщо вони не використовуються. Докладніше про налаштування введення дивіться в посібнику з введення. Під час роботи з проксі колекцій часто виникає одна проблема — докладніше про неї дивіться в цьому розділі посібника з введення.
Як зазначено в розділі про виявлення колізій, події колізій обробляються через надсилання повідомлень задіяним ігровим об’єктам. Їхні компоненти-скрипти отримують повідомлення у функціях зворотного виклику on_message.
Для кнопок Flash використовує окремий тип символів. Кнопки використовують спеціальні методи обробки подій (наприклад, click і buttonDown), щоб виконувати дії, коли виявлено взаємодію користувача. Графічна форма кнопки в розділі Hit символу кнопки визначає область натискання кнопки.

Defold не має вбудованого компонента кнопки, а також не дає змоги легко виявляти клацання за формою певного ігрового об’єкта так, як це працює з кнопками у Flash. Найпоширеніше рішення — використовувати компонент GUI, зокрема тому, що на позиції компонентів GUI в Defold не впливає ігрова камера (якщо вона використовується). API GUI також містить функції для визначення того, чи введення користувача, як-от клацання й дотики, відбувається в межах елемента GUI.
У Flash команда trace() допомагає під час налагодження. Її відповідник у Defold — print(), який використовується так само, як trace():
print("Hello world!"")
За допомогою однієї функції print() можна вивести кілька змінних:
print(score, health, ammo)
Також є функція pprint() (форматоване виведення), корисна під час роботи з таблицями. Ця функція виводить вміст таблиць, зокрема вкладених. Розгляньмо такий скрипт:
factions = {"red", "green", "blue"}
world = {name = "Terra", teams = factions}
pprint(world)
Він містить таблицю (factions), вкладену в таблицю (world). Звичайна команда print() вивела б унікальний ідентифікатор таблиці, але не її фактичний вміст:
DEBUG:SCRIPT: table: 0x7ff95de63ce0
Використання функції pprint(), як показано вище, дає змістовніший результат:
DEBUG:SCRIPT:
{
name = Terra,
teams = {
1 = red,
2 = green,
3 = blue,
}
}
Якщо у вашій грі використовується виявлення колізій, ви можете перемикати налагодження фізики, надсилаючи таке повідомлення:
msg.post("@system:", "toggle_physics_debug")
Налагодження фізики також можна ввімкнути в налаштуваннях проєкту. До ввімкнення налагодження фізики наш проєкт мав би такий вигляд:

Увімкнення налагодження фізики показує об’єкти колізій, додані до наших ігрових об’єктів:

Коли виникають колізії, відповідні об’єкти колізій підсвічуються. Також відображається вектор колізії:

Насамкінець, інформацію про відстеження використання процесора й пам’яті дивіться в документації профайлера. Докладніше про складніші методи налагодження читайте в розділі про налагодження посібника Defold.
Якщо у вас виникнуть запитання або труднощі, форуми Defold — чудове місце, щоб звернутися по допомогу.