Post image

Component\Entity System: UI и User events

Вчера, когда в твиттере объявил о том что начинаю разработку Gimmick и во время UAFPUG 51 у людей возникали вопросы по поводу CES. В этой заметке я постараюсь разобрать некоторые из них.

Работа с пользовательским интерфейсом

При начале работы с CES возникает совершенно адекватный вопрос, а как работать с пользовательским интерфейсом? Есть несколько вариантов взаимодействия. На мой взгляд, все они заслуживают внимание.

Отдельный модуль для UI

Самый простой и очевидный способ работы с интерфейсом, вынести его во внешний модуль, например, работающий на Robotlegs, PureMVC или другом архитектурном фреймворке. В этом случае у нас есть слой с графическим интерфейсом, красивыми кнопочками и диалогами, работающий в привычной MVC среде. И есть “игровой” слой где главенствует CES движок. При этом взаимодействие с сущностями в слое с UI происходит так же как и в CES, то есть через компоненты.

Но такой подход чреват некоторыми проблемами. В AIP библиотеки Component/Entity System желателен метода вида getEntityById, так как сохранять сущность вне движка опасно (если она представленная виде объекта), к примеру, сущность может быть удалена.

Элементы UI как компоненты

Более родной метод для CES - создать специализированные компоненты с необходимыми системами. Так диалог превращается из класса набитого функционалом по прорисовке кнопок и текста, в сущность, с компонентами: фон, кнопки, текст. Для каждого компонента создается своя система, которая умеет работать с ним и отображать на экране.

Плюс данного метода очевиден, тесная взаимосвязь с игровыми сущностями. К примеру, чтобы отобразить состояние игрового объекта, добавляем в него компонент “полоса здоровья”.

Минус данного метода - увеличение потребления памяти и ресурса приложения расходуемые на новые компоненты и системы.

Элементы UI как системы

Еще один из способов - создать систему которая занимается работой с элементами UI без дополнительных компонентов и сущностей, напрямую связанна с визуальным слоем. В терминах MVC её можно было бы назвать видом ( View ). Данный метод самый простой, но так же он не дает той гибкости которую предоставляют первые два варианта, но более экономна к ресурсам.

Работа с пользовательскими событиями

Интерфейс пользователя неразрывно связан с событиями производимыми игроком: движения мышь, нажатие на кнопки и другие взаимодействия с программой. Каждое такое событие необходимо отловить и обработать. Как и в случае с UI существуют несколько вариантов сбора и обработки данных событий.

Внешний контроллер пользовательских событий

Работа с внешним контроллером подобна работе с внешним модулем работы с UI и в основном является её частью.

Есть некий класс который слушает пользовательские события и отсылает их в CES с помощью изменения или добавления компонента в сущность. Самая трудоемкая часть - нахождение необходимой сущности для изменения.

Система-контроллер пользовательских событий

Второй вариант - создание системы контроллера. В этом случае система подписывается на события пользователя, при его возникновении находит необходимую сущность и изменяет её с помощью компонентов. Подписываться на события мыши или тапа необходимо на сцену( stage ) для более полного контроля и снижения потребления ресурсов.

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

Это далеко не все вопросы которые мне задавали и в будущем я постараюсь описать другие решения.

Если вы используете Component/Entity System, какие из вышеперечисленных вариантов вы предпочитаете в работе. Или может у вас есть свои методы? Буду рад если опишите их в комментариях :)