znak
Описание
Простейший 2D движок на nimlang.
Языки
- Nim74,7%
- JavaScript19,7%
- HTML2,6%
- Java2,5%
- GLSL0,5%
Znak - Простейший 2D игровой движок на Nimlang
Простейший игровой движок, позволяющий создавать 2D-игры.
ВАЖНО! Поддерживаемые платформы: Web (Wasm+WebGL2), Windows, Linux, Macos, Android (через WebView-обертку)
ВАЖНО! Не забывайте использовать
-версии билдов для разработки иDEBUG-версии билдов для релизов: все внутренние проверки/исключения будут работать только вRELEASE-версиях и удалены для увеличения производительности вDEBUG-версиях.RELEASE
Социальные ресурсы
Официальный блог: https://leopotam.ru
Лицензия
Фреймворк выпускается под лицензией MIT-ZARYA, подробности тут.
Установка / обновление
ВАЖНО! Подразумевается, что проект создан через
и имеет корректныйnimble init-файл (наличие поля.nimbleс именем основного файла - точки входа).bin
При установке или обновлении необходимо каждый раз выполнять следующие операции (в папке проекта):
-
Скачать актуальные исходники пакета любым способом, распаковать и положить в папку внутри проекта, например, в
.deps/znak -
Удалить из папки проекта (при наличии) папку
.tmp -
Выполнить настройку проекта для
(путь доznakдолжен учитывать локальную папку сznak.nim, расширениеznakможно опустить):.nim -
Рестарт LSP (рестарт сессии VSCode в случае использования)
Использование в коде
Подключение пакета в коде происходит следующим образом:
Зависимости для разработки
Рекомендованный способ - через менеджер пакетов (windows - https://scoop.sh/, macos - https://brew.sh/), можно ставить из другого менеджера или в ручном режиме с требуемой настройкой.
GCC
Обязательная зависимость:
Nimlang
Обязательная зависимость:
ВАЖНО! Для корректной работы в в пути до профиля пользователя на должно быть русских букв. Если такие имеются - установку и прочих пакетов следует проводить с флагом для установки в глобальный каталог вне профиля пользователя:
Python
Обязательная зависимость (подойдет любая версия 3.8+):
Emscripten
Обязательная зависимость:
После установки или обновления необходимо выполнить скачивание и активацию актуального окружения для сборки:
OpenJDK
Опциональная зависимость для сборки под Android (можно скачать архивом и настроить путь в переменной окружения ):
ВАЖНО! Путь до
должен быть прописан в переменных окружения какJavaSdk.JAVA_HOME
AndroidSDK
Опциональная зависимость для сборки под Android, ставится как часть (можно скачать архивом и настроить путь в переменной окружения ):
ВАЖНО! Путь до
должен быть прописан в переменных окружения какAndroidSdk.ANDROID_HOME
Утилиты
Инициализация проекта
Утилита настраивает конфигурационные файлы проекта на использование , необходимо вызывать как при первичной инициализации, так и при каждом обновлении ядра (путь до должен учитывать локальную папку с , расширение можно опустить):
В папке проекта будет создан файл конфигурации , содержащий параметры сборки под разные платформы.
ВАЖНО! Если структура файла
будет нарушена - ее можно исправить запускомznak.json. Так же файл можно удалить иznak initсоздаст его заново со значениями по умолчанию.znak init
Сборка бандлов
Утилита собирает все пользовательские бандлы в папке :
ВАЖНО! При каждом обновлении ядра рекомендуется пересобирать бандлы - формат хранения может поменяться.
Если нужно собрать только один бандл - его имя можно указать параметром (имя папки без учета ):
ВАЖНО! Сборка происходит в файлы
внутри папки*.bundleс перезаписью старых файлов. Собираемые бандлы уже добавлены вdata(настроено вызовом.gitignore).znak init
Часть ассетов проходят конвертацию в более оптимальный внутренний формат - этот процесс управляется мета-файлами с расширением , лежащими рядом с ассетами. Например, если есть файл , то файл настроек будет называться .
ВАЖНО! Содержимое мета-файлов валидируется по схеме, получаемой по ссылке автоматически в редактор кода - в intellisense-подсказках появляется перечень поддерживаемых мета-файлом свойств с их описанием. Если схема затерлась, то ее можно восстановить, удалив файл и запустив сборку бандла - мета-файл будет создан заново.
Все и изображения при сборке бандла автоматически конвертируются в -формат с 90% качеством. Если необходимо изменить это значение (100% - сжатие без потерь, 50% - маленький размер с плохим качеством), то это можно сделать через соответствующий мета-файл со следующим содержимым:
ВАЖНО! Хотя изображения конвертируются - имена ресурсов остаются прежними. Т.е если адрес был
, то таким и останется. Имена ассетов берутся с имен мета-файлов без расширенияmy-bundle1://textures/image.png..json
Сборка проекта под десктоп
Выполняет отладочную сборку под текущую ОС:
Для релизной сборки нужно добавить параметр:
Для релизной сборки можно включить контекстное меню для просмотра вывода в консоль:
ВАЖНО! Сборка происходит в папку
. Текущее содержимое папки удаляется!build
Сборка проекта под Web
Выполняет отладочную сборку под Web:
Для релизной сборки нужно добавить параметр:
ВАЖНО! Сборка происходит в папку
. Текущее содержимое папки удаляется!build
Вывод версии
Выполняет вывод версии :
LiveServer для редактирования UIWeb
В случае использования нужно поставить расширение и запускать его из рабочего пространства текущего проекта (папка с бандлами должна быть в корне). Потом можно создавать -ассеты с версткой, автоматически обновляемой в браузере. Для этого достаточно добавить в начало ассета минимальный html-заголовок с подключением js-файла эмуляции апи рантайма, а так же указав кодовую страницу, чтобы браузер не предлагал автоматический перевод с неизвестного языка:
ВАЖНО! Путь до js-файла должен начинаться с
, т.е идти от корня сервера./
ВАЖНО! Заголовок нужен только для предпросмотра верстки в браузере. После завершения редактирования заголовок обязательно надо удалить.
ВАЖНО! При вставке заголовка можно пользоваться встроенными в VSCode
-сокращениями: написатьemmetи нажать tab/enter - готовый шаблон развернется, а курсор переместится в место указания адреса js-скрипта.head>script:src
Примеры
Для работы примеров нужно сделать следующее:
- Создать новый проект через вызов
в пустой папке.znak init - Скачать репозиторий
и скопировать из него папкуznakв папкуexamples/data/examplesв корне текущего проекта.data/examples - Собрать бандлы через
.znak bundle - Скопировать содержимое нужного примера в основной стартовый файл проекта. Например, если проект называется
, а примерgame1, то надо будет скопировать содержимоеbunnymarkвexamples/bunnymark.nimв папке проекта.game1.nim - Можно будет собирать через
илиznak build desktop.znak build web
bunnymark
Стресс-тест отрисовки. Кнопки интерфейса добавляют/удаляют спрайты.
Инициализация
Все параметры устанавливаются один раз, затем выполняется запуск движка:
Сцены
Общие события
Вся игровая логика разбивается на блоки-сцены, одновременно активной может быть только одна сцена. Разделение условное, можно не пользоваться данным механизмом, используя единственную сцену как механизм запуска своей логики.
Чтобы стать сценой, пользовательский тип должен быть -типом и реализовывать следующие методы:
ВАЖНО! Все эти методы опциональны, параметр типа сцены может быть как с модификатором
, так и без него - в зависимости от требований пользовательского кода.var
После создания типа сцены его экземпляр нужно добавить в инициализацию:
ВАЖНО! Первая добавленная сцена становится стартовой, порядок добавления остальных сцен не важен.
Для переключения на новую сцену достаточно вызвать метод с указанием имени из списка зарегистрированных сцен:
Бандлы (паки)
Бандл - это упакованный набор ассетов (контента, данных), загружающийся по сети как отдельный файл. В процессе разработки бандлы расположены в специальной папке текущего проекта - каждая вложенная папка (одного уровня вложенности) является независимым бандлом, упаковывающимся в отдельный -файл. Имя бандла (имя папки) важно и является именем бандла для дальнейшей адресации ассетов. Это имя зашивается внутрь бандла, что позволяет переименовывать конечные -файлы нужным образом для хранения на серверах - связность ассетов от этого не теряется.
ВАЖНО! Ассеты должны находиться в папках-бандлах, нельзя их класть прямо в папку
, это касается и специальных папок-ассетов видаdata,.atlasи т.п..uiatlas
Например, если есть папка-бандл , содержащая спрайт , и папка-бандл , содержащая звук , то в файловой системе они будут расположены так:
<проект>
data
sprites <- бандл "sprites"
sprite1.png <- ассет
sounds <- бандл "sounds"
sfx1.ogg <- ассет
Имя бандла становится частью адреса ассета, упакованного в этот бандл. Например, для ассета имя будет , а для -
Подключение бандла на старте
Часть контента может быть обязательна для работы кода, поэтому должна быть загружена до его запуска. Это можно сделать через предзагрузку бандлов:
Подключение бандла динамически
Загрузка контента
Бандлы позволяют загружать контент по адресам, похожим на url-адреса, где в качестве схемы используется логическое имя бандла, а адрес - путь до контента внутри бандла:
Аналогично работает загрузка для других ассетов - через методы и проверку результата операции.
Шейдеры
Общая информация
Шейдеры пишутся на GLSL с профилем под все платформы. Код вертексной и фрагментной части общий (содержится в одном исходнике), разделяется директивами компилятора. Простейший шейдер:
ВАЖНО! Версию шейдера указывать не нужно, она автоматически подставляется в зависимости от платформы.
Атрибуты
Поддерживаются следующие атрибуты (подключаются автоматически, явно указывать не нужно):
- координаты вершины в локальном пространстве._POS- данные атрибута 1 вершины (если присутствуют)._ATTR0- данные атрибута 2 вершины (если присутствуют)._ATTR1- данные атрибута 3 вершины (если присутствуют)._ATTR2- данные атрибута 4 вершины (если присутствуют)._ATTR3- данные атрибута 5 вершины (если присутствуют)._ATTR4- данные атрибута 6 вершины (если присутствуют)._ATTR5- данные атрибута 7 вершины (если присутствуют)._ATTR6- данные атрибута 8 вершины (если присутствуют)._ATTR7- данные атрибута 9 вершины (если присутствуют)._ATTR8- данные атрибута 10 вершины (если присутствуют)._ATTR9и_MAT_M_ROW0- 6 компонентов упакованной mat3x3 матрицы трансформации вершины в мировое пространство._MAT_M_ROW1
Униформы
Поддерживаются следующие униформы (подключаются автоматически, явно указывать не нужно):
- 1 привязанная к материалу текстура (при наличии)._TEX0- 2 привязанная к материалу текстура (при наличии)._TEX1- 3 привязанная к материалу текстура (при наличии)._TEX2- 4 привязанная к материалу текстура (при наличии)._TEX3- 5 привязанная к материалу текстура (при наличии)._TEX4- 6 привязанная к материалу текстура (при наличии)._TEX5- 7 привязанная к материалу текстура (при наличии)._TEX6- 8 привязанная к материалу текстура (при наличии)._TEX7- 1 параметр материала (при наличии)._PARAM0- 2 параметр материала (при наличии)._PARAM1- 3 параметр материала (при наличии)._PARAM2- 4 параметр материала (при наличии)._PARAM3- 5 параметр материала (при наличии)._PARAM4- 6 параметр материала (при наличии)._PARAM5- 7 параметр материала (при наличии)._PARAM6- 8 параметр материала (при наличии)._PARAM7
ВАЖНО! униформы текстур можно использовать только подряд, не допуская пропусков. Т.е при наличии 2 текстур их следует адресовать как
и_TEX0, но не, например,_TEX1и_TEX0-_TEX2в этом случае не будет проинициализирован корректно. Это правило касается и униформов параметров._TEX2
Так же есть 2 функции, возвращающие матрицу вида и матрицу модели:
- матрица вида._MAT_V()- матрица модели._MAT_M()
Загрузка
Шейдеры хранятся в ресурсах в виде исходного кода и загружаются в движок строкой. Рекомендуется всегда использовать загрузку из бандла:
ВАЖНО! При выходе из текущей области видимости переменной, содержащей ассет, он будет считаться освобожденным автоматически. Если это было последнее место использования - ассет будет выгружен автоматически, включая ресурсы на GPU. Это касается всех типов ассетов (мешей, текстур, атласов, камер и т.д).
Текстуры
Процедурное создание
Текстуры могут быть созданы процедурно следующим образом:
Загрузка из бандла
Текстуры внутри бандла автоматически перепаковываются из и в -формат. На текстуры загружаются в распакованном виде массивом байт в формате R8 и RGBA32 с указанием размера текстуры. Пример загрузки из бандла:
Для загружаемых из бандлов текстур можно настроить значения мипмапов, фильтрации и повторения по умолчанию, не выставляя их для каждой:
Ко всем загруженным после этого текстурам будут применены эти настройки по умолчанию.
ВАЖНО! Эти настройки не применяются для текстур, создаваемых процедурно.
Материалы
Материалы являются контейнерами для настроек отрисовки мешей: шейдер, текстуры, кулинг, блендинг. Настройки задаются в момент создания материала и далее не меняются. Необходимо поменять шейдер или текстуру материала - надо создавать новый материал с нужными настройками.
Каждый материал поддерживает до 8 параметров типа , которые уникальны для этого материала.
ВАЖНО! Параметры материала применяются в момент запроса отрисовки первого экземпляра меша с помощью этого материала. Если поменять параметры после этого - они применятся только в следующем батче/кадре.
Пример создания материала:
Меши
Создание
Меши содержат в себе геометрию для отрисовки. Поддерживаются следующие атрибуты вершин: позиции, текстурные координаты, цвет. Все атрибуты (кроме позиций, которые всегда статика) делятся на 2 категории: статические и динамические. Статические определяют общую неизменяемую часть, а динамические - данные, которые могут отличаться для каждого экземпляра меша.
Поддерживаются атрибуты, пронумерованные от 0 до 9 включительно.
ВАЖНО! Атрибуты статической и динамической части не могут пересекаться (иметь одинаковые индексы) в пределах одного меша.
ВАЖНО! Атрибуты должны быть указаны строго по возрастанию (могут идти не подряд).
Пример создания меша-прямоугольника для отрисовки 2D-спрайта:
ВАЖНО! Атрибуты всегда являются 4-компонентыми float32-данными за исключением атрибута позиции (всегда 2 компонента).
Так же поддерживается упрощенный синтаксис передачи данных о вершинах и индексах в массивах и списках. Пример выше можно переписать следующим образом:
Отрисовка
Вся отрисовка происходит через инстанцирование (instancing) даже если это 1 экземпляр меша. Значения динамические атрибутов передаются в шейдер в тех же позициях, что и статические (автоматическая подстановка). Пример сборки меша и его отрисовки:
ВАЖНО! Последовательно рисуемые одинаковые меши с использованием одного и того же материала будут собраны в один вызов отрисовки, поэтому важно выполнять отрисовку геометрии блоками
+одинаковый меш. Никакой иной автоматической группировки не предусмотрено.одинаковый материал
Работа с UI
Модуль позволяет реализовывать пользовательский интерфейс средствами html5/css3 в режиме оверлея.
Подключение модуля
Все размеры элементов расчитаны на автомасштабирование относительно эталонного разрешения и должны быть указаны в пикселях. Эталонное разрешение указывается в момент стартовой инициализации:
ВАЖНО! Работа с модулем требует обязательного вызова
для своей работы.ZnakInit.useUI()
Установка контента
Контент является полноценной html-версткой, подставляющейся в существующий (ищется через ) или общий корневой элемент (при установке старые данные будут удалены):
ВАЖНО! Если требуются стили, то они через тег
заливаются как часть контента.<style>
ВАЖНО! Если требуется js-код, то он через тег
заливается как часть контента. Перед удалением добавленного таким образом кода и верстки требуется корректно отписаться от всех добавленных этим кодом подписок, для этого можно создать js-функцию с уникальным именем с кодом очистки и вызывать ее через<script>.ZnakApp.runJSCode("имя_функции()")
Обработка событий
По умолчанию все -элементы не принимают ввод и не генерируют события. Чтобы события генерировались, -элементы следует пометить готовым классом (или стилем с ). После этого можно указывать штатные html/js-обработчики событий , и т.д. Для передачи события в -код нужно вызвать специальную функцию , принимающую -атрибут компонента, имя события, массив аргументов (возьмутся первые 4, сам параметр опционален):
События создаются асинхронно и накапливаются в кеше (очищается автоматически каждый кадр) для дальнейшей обработки:
Работа со шрифтами
Поддерживается работа с truetype-шрифтами из бандлов.
Загрузка шрифта
При успешной загрузке будет создан -класс с именем (), который можно использовать на любом -элементе.
Выгрузка шрифта
Работа с ui-атласами
Поддерживается вывод 9patch-спрайтов (спрайты с фиксированными границами определенного размера, далее - слайсы), для этого их надо подготовить специальным образом.
Поддерживается автоматическая упаковка , и изображений в общий ui-атлас в момент сборки бандла. Чтобы папка с набором изображений распозналась как ui-атлас, ее имя которой должно заканчиваться на - при первой попытке сборки будет сгенерирован мета-файл, управляющий дополнительными настройками атласа.
Слайсы имеют специальную маркерную зону для разметки фиксированных зон - это линия толщиной в 1 пиксель снизу и линия толщиной в 1 пиксель справа. Эти зоны не являются частью изображения и отрезаются в момент упаковки. для фиксации зоны достаточно нарисовать сплошную линию от края до конца нужной зоны (слева направо внизу для фиксации зоны слева, справа налево внизу для фиксации зоны справа, сверху вниз справа для фиксации зоны сверху и снизу вверх справа для фиксации зоны снизу).
Пример ( - изображение, - маркер, - прозрачная точка):
000000001
00000000.
00000000.
00000000.
000000001
000000001
11...1111
Итог: слайс размером (8,6) имеет фиксированную область в 2 пикселя слева, 3 пикселя справа, 1 пиксель сверху и 2 пикселя снизу.
Имя атласа как ресурса определяется именем мета-файла без расширения :
Из кода упакованные внутрь атласа слайсы доступны по их имени внутри папки до сборки:
ВАЖНО! Данные слайса представляют собой строку "bundle:asset:t:r🅱️l" для использования в атрибуте
slice-элемента и напрямую обычно не используются - для этого есть готовые компонентыdomиZnakUIGen.slice, которые внутри себя делают нужные вызовы.ZnakUIGen.addSliceBG
Поддержка SafeArea
Достаточно обернуть контент в с классом , либо настроить стиль с (для альбомной ориентации).
Верстка интерфейса кодом
предоставляет набор методов, помогающих генерировать произвольную html-верстку с использованием . На выходе получается строка, готовая для подстановки в общее -дерево.
ВАЖНО! Интерфейс обычно создается однократно на старте, сгенерированный шаблон можно сохранить и позже использовать многократно.
Базовая структура
Все -компоненты должны быть вложены в -блок:
Параметром является область, в которую будет вписан интерфейс: x, y, ширина, высота. Для подстановки текущего размера экрана есть готовая функция:
После формирования структуры интерфейса следует вызвать генерацию общей компоновки в виде строки:
ВАЖНО! Запрос общей компоновки следует делать до начала нового -блока, т.к накопленные данные будут сброшены для сборки нового интерфейса.
Контейнеры и компоновка
Размеры компонентов являются целочисленными -значениями и интерпретируются 3 способами:
- > 0 — фиксированный размер в виртуальных пикселях.
- < 0 —
-доля среди всехflex-компонентов контейнера-родителя.flex - = 0 — обтекание по содержимому (авторазмер).
box — блок-контейнер
Размещает вложенные компоненты вдоль основной оси, направление которой указывается первым параметром ( для горизонтальной ориентации), помечается классом или в зависимости от ориентации:
button — кнопка-контейнер
Интерактивная нажимаемая область (является box-контейнером с горизонтальным выравниванием вложенных компонентов), помечается классом :
ВАЖНО! Кнопка не имеет собственного визуала, его следует настраивать через или .
Компоненты
slice — слайс из UI-атласа
Отрисовывает слайс из , помечается классом :
sprite — спрайт
Отрисовывает спрайт из бандла, помечается классом :
ВАЖНО! Спрайты из не поддерживаются, для вывода спрайта в интерфейсе его придется хранить вне атласа.
text — текст
Выводит текстовую строку с поддержкой заполнения родительского контейнера и автоматической разбивкой по строкам:
inputBox — поле ввода текста
Текстовое поле для ввода пользователем, помечается классом :
При редактировании данных в компоненте будут генерироваться события с типом и актуальным значением в .
hspace / vspace — разделители
Пустая область для отбивки контента:
Настройка классов
К каждому компоненту можно добавить произвольные -классы (все добавленные классы будут применены одновременно к следующему компоненту, а затем список будет очищен):
Есть готовые вспомогательных функции по настройке классов.
addAlignMain - выравнивание по основной оси
Устанавливает выравнивание вложенных компонентов вдоль основной оси контейнера:
Параметр принимает следующие значения:
- 0 — компоненты выравниваются по началу оси.
- 1 — компоненты выравниваются по центру оси.
- 2 — компоненты выравниваются по концу оси.
addAlignCross - выравнивание по поперечной оси
Устанавливает выравнивание вложенных компонентов вдоль поперечной оси контейнера:
Параметр принимает те же значения, что и для .
addAlignCenter - выравнивание по центру
Выполняет выравнивание по центру по обеим осям.
addFont - настройка шрифта
Выполняет подключение загруженного шрифта через назначение компоненту класса .
Настройка стилей
К каждому компоненту можно добавить произвольные стили (все добавленные стили будут применены одновременно к следующему компоненту, а затем список будет очищен):
Есть готовые вспомогательных функции по настройке стилей.
addPadding - отступы
Устанавливает отступы в пикселях от границ внутри контейнера для вложенного контента в порядке , , , (по часовой стрелке, начиная с верха):
addColorFG - цвет контента
Устанавливает основной цвет (), значение может быть в любом виде, поддерживаемом в css3:
addColorBG - цвет фона
Устанавливает фоновый цвет (), значение может быть в любом виде, поддерживаемом в css3:
ВАЖНО! Не рекомендуется применять для спрайтов и слайсов, установка цвета фона отменяет прозрачность изображения.
addGap - отступы между компонентами
Устанавливает расстояние в пикселях между элементами в контейнере (применяется к контейнеру):
Произвольные стили и ограничения
В качестве верстки можно заливать не только визуальные элементы, но и произвольные стили внутри тега .
Базовые компоненты помечаются специальными классами, что позволяет дополнительно настраивать их через стили. Например, все кнопки отмечены классом , добавим к ним анимацию при наведении и нажатии:
ВАЖНО! В случае использования слайса или спрайта (а кнопка обычно использует слайс) нельзя менять цвет фона через - это ломает прозрачность изображения. Менять можно только через фильтр и с явным указанием специального фильтра , который автоматом применяется к слайсу и отменяется новым фильтром. При явном указании цепочкой фильтры объединяются.
Настройка атрибутов
К каждому компоненту можно добавить произвольные атрибуты (все добавленные атрибуты будут применены одновременно к следующему компоненту, а затем список будет очищен):
Есть готовые вспомогательных функции по настройке атрибутов.
addID - уникальный идентификатор
Устанавливает значение уникального в пределах страницы идентификатора :
addSliceBG - фоновый слайс
Устанавливает слайс в качестве фонового изображения контейнера, помечает его классом :
addSpriteBG - фоновый спрайт
Устанавливает слайс в качестве фонового изображения контейнера, помечает его классом :
Настройка событий
Для добавления интерактивности все компоненты должны быть помечены классом и соответствующим атрибутом-событием.
ВАЖНО! Для идентификации конкретного компонента в полученном событии следует настроить каждому его -атрибут через . Для готовых компонентов типа и эта настройка уже сделана.
addEvents - получение событий
Разрешает работу с интерактивными событиями для компонента, помечает его классом :
addEventClick - поддержка onclick
Выполняет настройку поддержки -события для компонента:
Вспомогательная геометрия
Есть поддержка - вспомогательной геометрии, полезной для отладки.
Подключение
Перед использованием модуль надо подключить:
Полилиния
Рисует линию из отрезков, соединяющих указанные точки:
Прямоугольник
Рисует замкнутый прямоугольник, состоящий из 4 линий. Ширина/ высота указаны в матрице как масштаб:
Многоугольник
Рисует замкнутый многоугольник, состоящий из N-вершин (от 3 до 32), равномерно расположенных на единичной окружности/овале. Ширина/ высота овала, на котором лежат точки, указаны в матрице как масштаб:
Пользовательский ввод
Поддержка клавиатуры
Поддерживаются 3 вида событий: нажатие, отпускание и запрос актуального состояния клавиш:
Поддержка мыши
Кнопки мыши эмулируются как кнопки , , клавиатуры. Пример использования ввода с мыши:
Работа с экраном
Методы типа позволяют запрашивать актуальную информацию об окне приложения, менять его размер, а так же работать с полноэкранным режимом.
Инициализация
В момент инициализации поддерживаются следующие методы:
После запуска
После запуска становятся доступными следующие общие методы:
Для десктопа:
ВАЖНО! Переключение полноэкранного режима в веб-сборках невозможно без первого интерактива со стороны пользователя, поэтому запустить перейти в него на старте невозможно, рекомендуется делать пустой стартовый экран с кнопкой, после которого уже можно переключаться в полный экран. Так же пользователь может самостоятельно выйти из полноэкранного режима по нажатию
. Это правило не касается десктопных сборок.ESC
ВАЖНО! Переключение полноэкранного режима в desktop-сборках работает некорректно в случае блокировки изменения размеров окна.
Работа с камерой
Тип позволяет создавать виртуальные камеры и отрисовывать с их помощью текст и меши.
Работа со временем
Методы пакета предоставляют доступ к внутриигровому времени (время с запуска приложения, с последнего кадра, работа с масштабом).
Работа с математикой
Поддерживаются вектора и набор констант и типов, основанных на float32 и int32.
Работа с сохранением данных
Поддерживается чтение и запись строковых данных по ключу в постоянное хранилище, реализованное через .
ВАЖНО! Данные являются общими для всех вкладок игры, открытой с одного домена (протокол + домен + порт) в одном браузере.
Чтение
Для чтения данных по ключу следует использовать следующий метод:
Запись
Для записи данных по ключу следует использовать следующий метод:
ВАЖНО! Для очистки/удаления записи нужно записать в качестве значения пустую строку.
Очистка
Все записанные данные можно удалить одним вызовом:
Работа с сетью
HTTP/GET запросы
WebSockets
Работа с атласами спрайтов
Поддерживается автоматическая упаковка , и изображений в общий атлас в момент упаковки бандла. Чтобы папка с набором изображений распозналась как атлас, ее имя которой должно заканчиваться на - при первой попытке сборки будет сгенерирован мета-файл, управляющий дополнительными настройками атласа.
Атлас из набора спрайтов
Мета-файл может иметь следующее содержимое:
Имя атласа как ресурса определяется именем мета-файла без расширения :
Из кода упакованные внутрь атласа спрайты доступны по их имени внутри папки до упаковки:
ВАЖНО! Запросы спрайтов из атласа по имени - относительно медленные операции, полученные идентификаторы рекомендуется кешировать для быстрой отрисовки.
Кастомная отрисовка
по умолчанию использует для отрисовки специальный шейдер (исходники можно посмотреть в ) и следующий меш:
Т.е в статик-атрибутах только позиции с началом в центре спрайта, в динамике используются 2 атрибута: uv () и color (). Обязательным является только uv , color является опциональным и может быть удален из атрибутов/данных для оптимизации или освобождения места для других данных.
Если требуется кастомная отрисовка спрайтов из атласа с новыми уникальными данными для каждого спрайта, то можно воспользоваться следующим методом:
Атлас из подготовленной заранее равномерной сетки спрайтов
Возможно использование изображения, состоящего из спрайтов, размещенных плотно по регулярной сетке. Для этого так же делаем папку с суффиксом , в нее кладем подготовленное изображение и запускаем - для атласа будет создан мета-файл с настройками по умолчанию. Для переключения сборщика атласа в режим равномерной сетки нужно указать в мета-файле атласа 2 параметра:
Эти числа означают количество спрайтов по горизонтали () и вертикали () - сборщик сам посчитает размеры спрайтов и сгенерирует им имена на основе имени файла-изображения и индексов столбцов и строк (индексы начинаются с 0) по маске . Например, если подготовленный файл имел имя , а и имели значения 3 и 2 соответственно, то будет сгенерирован следующий набор спрайтов внутри атласа:
, , , , , .
Работа с покадровыми анимациями
Поддерживается покадровая анимация из кадров-спрайтов, собранных в атласы. Для создания ассета анимации следует сделать файл с расширением в папке бандла, а потом запустить сборку этого бандла - в результате анализа будет создан сопутствующий мета-файл и сообщено об ошибке его содержимого.
Мета-файл может иметь следующее содержимое:
массив содержит описания кадров с указанием атласа и спрайта в нем для каждого. Так же поддерживается опциональные параметры и для смещения кадра относительно точки привязки. Если кадры берутся последовательно из одного атласа, то параметр достаточно указать только в первом кадре.
Имя атласа как ресурса определяется именем мета-файла без расширения :
Загруженный ассет является источником анимации, которая может проигрываться одновременно несколькими объектами. Для этого под каждый объект нужно создавать отдельное хранилище состояния:
ВАЖНО! Анимация знает размеры каждого спрайта и для отрисовки его размером 1:1 нужно передавать в матрице scale=1.
Взаимодействие с JS
Поддерживается вызов как , так и функций. Для корректной интеграции используются файлы в корне проекта , и , которые подключаются автоматически (при наличии) согласно документации emscripten (--pre-js, --js-library, --closure-args=--externs).
Для полного переопределения -шаблонов базовой верстки нужно создать в корне проекта файлы (отладочные сборки) и (релизные сборки) - содержимое можно взять из соответствующих файлов внутри и настроить как нужно.
Зависимости и манглинг имен
Все -функции, которые будут доступны в , должны быть определены через специальную обертку:
ВАЖНО! Имя поля зависимостей формируется как "имя-функции__deps". Желательно указывать ее даже если зависимостей нет.
В -версии происходит манглинг имен - они сокращаются для экономии места и прямые вызовы по старому строковому имени становятся невозможными. Все функции, которые не являются встроенными или не прописаны в зависимостях у используемых функций - считаются неиспользуемыми и вырезаются из конечного кода. Т.е, условно, если не используется -код для -скачивания данных, то автоматически вырезается не только он из -части, но и его -обертка.
При указании зависимостей существует правило - имя указывается как есть, а при вызове добавляется в начало имени. Для части функций есть исключение - имена в зависимостях начинаются с , при вызове этот символ просто убирается. Функции , которые доступны для вызова из , подчиняются тем же правилам - если есть функция с именем , то в зависимостях она будет указана как , а вызываться - как .
Если есть необходимость сохранить имя объекта или функции как есть (отключить манглинг), то эти исключения следует добавить в , по одному имени на строчку.
В качестве примеров можно посмотреть содержимое папки .
Вызов js-функции из nim
Для вызова -функции ее надо определить через описанный выше механизм в файле в корне проекта, а затем на -стороне описать функцию, как импортируемую из .
ВАЖНО! Передавать из
вnimв качестве параметров можно только простыеjs-типы.C
Например, надо вызвать -функцию , в которую передать строку и число:
На стороне добавляем определение вызываемой функции:
После этого ее можно вызывать:
Вызов nim-функции из js
Для вызова -функции ее надо определить как экспортируемую и доступную в через специальную прагму:
На стороне определяем функцию:
Вызов произвольного JS-кода
Если нужно вызвать произвольный JS-код в виде строки, то можно воспользоваться следующим методом:
Работа со звуком
Модуль позволяет проигрывать звуки, подключив их в слоты. Слоты - это независимые аудиоисточники, способные работать параллельно.
Подключение модуля
ВАЖНО! Модуль требует обязательного вызова
для своей работы.ZnakInit.useSound()
ВАЖНО! Чем меньше слотов, тем лучше для производительности, максимальное количество не ограничено.
Загрузка контента
Контент загружается из бандлов, поддерживаются форматы , , :
Запуск проигрывания
Для проигрывания нужно указать номер слота, ресурс звука и цикличность воспроизведения:
Если в слоте играл другой звук - он будет прерван.
ВАЖНО! Проигрывание невозможно в веб-сборках без первого интерактива со стороны пользователя, поэтому запустить проигрывание фоновой музыки на старте невозможно, рекомендуется делать пустой стартовый экран с кнопкой, после которого уже можно запускать фоновую музыку. Это правило не касается десктопных сборок.
Остановка проигрывания
Для остановки нужно указать номер слота:
Проверка проигрывания
Слот можно проверить - проигрывается в нем звук в текущий момент или нет:
Изменение громкости
Громкость применяется к слоту независимо, проигрывается он или нет:
ВАЖНО! Значение громкости должно быть от 0 до 1.
Панорамирование
Панорамирование применяется к слоту независимо, проигрывается он или нет:
ВАЖНО! Значение панорамирования должно быть от -1 (левый канал) до 1 (правый канал).
Изменение скорости
Изменение скорости применяется к слоту независимо, проигрывается он или нет:
ВАЖНО! Значение скорости должно быть больше 0.1 и меньше 10 (включительно).