Главная » Хабрахабр » [Из песочницы] Что еще за Defold и с чем его едят?

[Из песочницы] Что еще за Defold и с чем его едят?

image

Это небольшой разбор игрового движка Defold на практическом примере(под Andoid), а также немного субъективной критики и похвалы, ну вообщем обзор. Кому интересно узнать об этом двигателе больше, есть одно интервью, почитайте. Информации о Defold в сети мало, так что это будет вклад в очень небольшую копилку.

Немного прелюдии

Итак, Defold — это сравнительно молодой(с 2011 года), кросс-платформенный двигатель с визуальным редактором, похожим на Gobot, Construct или Cocos Creater. В основном он предназначен для 2D (для работы с 3D все еще не хватает инструментов), язык программирования — Lua. От аналогичных двигателей отличается стабильной производительностью на мобильных(ровные 60 fps без лагов со звуком), небольшим размером билда(2-4 мб в зависимости от платформы), удобной системой gui и go, крутые настройки анимации(кривые ключей), а также полностью подчиняемым редактором(ниже расскажу, интрига). На сайте, под учетной записью, есть возможность хранить файлы проекта. Вносить изменения в проект может любой разрешенный член команды, что в общем-то удобно, хотя я сам не всегда мог этим пользоваться, т.к. наш рабочий прокси не дает редактору доступ. У Defold'а есть особенности в написании кода, хотя их я бы отвел к минусам(подробности ниже). И да, чуть не забыл, команда Defold очень отзывчивая, заслуживает уважения. Несколько раз обращался за помощью на форум — тут же, в течении 10 минут отвечали, помогали. Один раз была проблема при запуске редактора на Ubuntu, ребята не могли сначала помочь, но, через пару часов со мной связался их лидер и разрешил ситуацию. Оказалось, на linux есть баг со стандартными дровами на видео, так что надо установливать родные. Также на сайте есть ассеты, куда же без них. Ну, закончим прелюдию, поехали!

Стартуем!

Регистрируемся и скачиваем на сайте редактор Defold версии 2 (1 уже не поддерживается), там же создаем свой проект и скачиваем. Проект затем храним на сайте, либо локально (если боимся, что хитрый Дефолд будет подглядывать). Далее открываем через редактор свой проект(на картинках будет мой), смотрим:

Не буду увлекать вас разбором интерфейса, его можно изучить самому. Слева файлы, справа внутренности выбранной ноды, посередине редактор. Там стандартный набор скриптов, шрифтов и прочего для работы двигателя, можете изучить. Видите папку builtins? В настройках проекта(на картинке посередине) есть строчка(выделенная) Main collection, там ссылка на основной файл коллекции, с которого начинается ваше приложение, откроем его: Все остальное — ваши собственные файлы.

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

Все ее содержимое при выполнении будет создано, скрипты инициализированы. Коллекция может содержать любые объекты(скрипты, спрайты, звуки и т.д), а также вложенные в нее другие коллекции. Proxy — отличная штука, в них обычно оборачивают различные уровни вашей игры, например. Коллекции можно оборачивать в Proxy. Их можно отгружать, загружать(при загрузке происходит создание вложенной коллекции), ставить на паузу, замедлять, ускорять процессы.

Это оболочки для объектов, которые незаменимы, если необходимо создавать и удалять объекты динамически, в процессе исполнения. Также, очень удобная штука — Factory и Collection Factory.

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

Кстати, на скрипты можно вешать свойства. Это скрипт внутри шипа, в методе update он проверяет, если собственное положение меньше, чем положение персонажа(игрок в центре камеры) плюс небольшой запас, то удаляет сам себя. Например у меня есть объект factory collection, внутри которого овца npc.

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

Cоздаем npc:

Внутренний экзмпляр скрипта меняет свои свойства(уникальность через self.):

И вот наши овечки бегут с разной скоростью:

Методы нельзя сворачивать(как например в Sublime), а когда строчек становится много, приходится долго и мучительно крутить колесом, выискивая нужное. Кстати, о редакторе кода — он примитивный. В ассетах Defold есть инструкция, как приучить Sublime к заполнению методов из редактора. Также нет увеличения масштаба, но это мелочи.

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

Ну, а теперь о том, как работает движок

Defold принимает на рендер две отдельные ветки, это GUI и GO.

Он существует отдельно, настраивается по экрану и всегда рендерится поверх всего остального. GUI — как уже понятно из названия, это интерфейс пользователя. Это как бы тоже коллекция, но с ограничениями. GUI имеет свои собственные методы, не имеющие отношения к GO, хотя и сходные с ним. Отличная и удобная штука, хотя есть нюанс — из GUI нельзя напрямую обратиться к каким-либо игровым объектам, только через глобальные переменные, либо через сообщения(дальше расскажу). На один GUI принимается один скрипт, с расширением .gui_script.

Во внутрь принимает все, включая другие GO. GO — это игровой объект (что-то типа ноды трансформации), содержит информацию о перемещении, повороте, масштабе и т.д. Используется для коллекций, это обязательная оболочка для любого количества объектов(как бы группа).

На Defold я пересел из дружелюбного Android Studio с Libgdx, и вот, что меня потрясло: к объектам нельзя обратиться напрямую, только через костыльные методы или через сообщения, которые все равно, не дают творческой свободы, есть серьезные ограничения. Дальше, начинается самое интересное. В Дефолде, увы пользуешься тем, что есть, и, если чего не хватает, просишь разработчиков добавить необходимую функцию, либо ищешь обход. Если сравнивать с тем же Libgdx, там я спокойно мог даже переписать существующий класс из библиотеки Либа и обратиться уже к нему. Пришлось добавлять костыль, узнающий длительность звука по воспроизводимому файлу. Например, при работе со звуком, нельзя узнать закончилось ли воспроизведение! Вместо этого, в скрипт, который находится в одном GO с физическим телом, прилетает сообщение(не всегда каждый кадр, особенно на мобильном) с информацией о столкновении, и все. А что касается упрощенного Box2D(внезапно понеслась критика), так оттуда исчезли славные методы по обнаружению и обработки перед, во время и после столкновения! GO нельзя масштабировать вместе с физическим телом, в редакторе оно у вас поменяет масштаб, а в игре нет(вроде обещали исправить). Также нельзя перемещать тело, если оно физическое, можно только кинематическое, а менять это свойство во время исполнения нельзя. Вообщем, я немного побунтовался на этот счет и (решив эти проблемы через костыли) успокоился, все-таки скорость Дефолда и его редактор перевесили тормозной Libgdx(Да простят читатели мне мою субъективность!) и отсутствие нормального редактора(Помню как-то смастерил под Либ редактор карт в Autodesk Maya, но это уже совсем другая история...). GO нельзя масштабировать в минус(например отзеркалить по X), в редакторе все получится, но в исполнении вернется на исходную.

Метод msg.post() и как к нему относиться

Вообщем, у каждого объекта есть url(например «main:/main_pers#spine_anim»), по которому можно прислать сообщение, и даже вместе с ним прикрепить переменные. Сообщения летят к адресату в напрямик, не ожидая в очереди на обработку. Это и удобно, и также создает путаницу иногда. Сообщения часто нужны для того, чтобы переслать информацию из GO в GUI(например, ваша овечка поймала пузырик с фруктом, обновляем счет очков в GUI).

и наоборот(энергия закончилась, сообщаем овечке, что пора спать).

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

По сути это строки, однако, на мобильных платформах строки отключаются для экономии ресурсов(где, блин, это написано!?), вместо них идет хэш. Еще один нюанс — это адреса объектов. Поэтому, резервируйте адреса в переменные через метод msg.url() и не трогайте. Вроде ничего, да, но если ваша игровая логика шлет сообщения через отредактированые строки, то жди беды, почтовая служба не вручит письмо адресату. Например, для того, чтобы выяснить, стоит ли овечка на земле, нужно добавить дополнительное кинематическое тело чуть ниже ног, и у него спрашивать, есть ли вхождение в землю. Собственно, это мелочи, но первое время страшно отнимает драгоценное время.

Dragon bones вместо Spine

Без проблем, используем дракона, ведь позвончик очень даже платный. Но, как всегда есть но. У позвоночника есть функция — скин, у дракона ее нет. Как решить? Руками. Открывает json из spine и смотрим где есть skin, анализируем, копируем, вставляем в наш json от дракона и правим как надо, вот и все. Скрипт на питоне экономит вам приличную сумму. Что касается скриптов, так это вообще сказка. Так как все файлы текстовые, то и редактирование можно автоматизировать. Вот например, собрал в редакторе уровень используя общий атлас с большим количеством текстур(более 300), однако использовал не все, только около 100. Чтобы руками не перебирать, я «наПитонил» оптимизатор атласа — все, что используется в коллекции, остается, остальное выкидывается. Очень удобно, когда можно что-то автоматизировать.

Share и Admob

Кнопку Share можно найти в ассетах и пристроить за пару минут. Осторожно с ассетами! Ассет Admob например, существенно замедляет билд, а также вообще не дается, когда нет подключения к сети. В случае с Admob(Не буду писать как его встроить, все есть в документации на гитхабе), еще приходится делать проверку на платформу, иначе билд на окнах выдаст ошибку. Поэтому, при разработке, отложите рекламу и прочие ассеты напоследок, т.к. билд у Дефолда без них очень быстрый. Что касается локализации, можно создать себе вот такой словарик:

dict["ru"]["lang"]="Я русский" dict["en"]["lang"]="Ya ne russkiy"

и менять текст при инициализации, обращаясь следующим образом:

language=sys.get_sys_info().language label.set_text("game:/go#label",dict[language]["lang"]

Вот, в принципе и все, по итогу Дефолд очень крутой(когда в нем разобрался), поэтому всем советую. Кому интересно, что у меня из под него вышло, смотрите трейлер здесь(не ради пиара, моя ЦА — дети).


Оставить комментарий

Ваш email нигде не будет показан
Обязательные для заполнения поля помечены *

*

x

Ещё Hi-Tech Интересное!

На основе здравого смысла: выращиваем DevOps с нуля

Накануне DevOps Conf Russia 2018 мы поговорили с техническим директором «Учи.ру» Алексеем Ваховым об этапах развития платформы, о том, какие инструменты они используют и насколько там все DevOps-ово. Работал разработчиком C++ в огромных системах (десятки миллионов строк кода). Алексей Вахов ...

[Перевод] Руководство по Node.js, часть 3: хостинг, REPL, работа с консолью, модули

Перед вами третья часть перевода руководства по Node.js. Сегодня мы поговорим о выборе хостинга для Node.js-проектов, о том, как работать с Node.js в режиме REPL и как запускать скрипты с аргументами, о взаимодействии с консолью и о модулях. [Советуем почитать] ...