Entity / Component System и пользовательский интерфейс «Entities»

14

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

Это кажется мне очень странным. Я всегда понимал сущности как «игровые модели», такие как игроки, враги, бонусы и т. Д. С другой стороны, с точки зрения повторного использования кода повторное использование компонентов для пользовательского интерфейса имеет смысл.

Как (и где) проблемы UI / GUI вписываются в систему сущностей / компонентов?

(Примечание: этот вопрос не зависит от платформы, поскольку он относится к нескольким платформам / языкам)

ashes999
источник
3
Я думаю, что это кажется вам логичным только потому, что вы делаете 2d игру. Представьте, что вы сделаете 3d-игру (с 2d графическим интерфейсом), почти никакая логика рендеринга не может быть повторно использована, и компоненты 2d графического интерфейса в трехмерном мире не будут иметь большого смысла. Вы должны построить GUI поверх системы компонентов. Например, ваш GameplayScreen создает объектный мир с компонентами, и одним из компонентов будет камера с «холстом», на которую будет рисовать ваш рендерер. И этот холст станет фоном этого экрана.
Кикаймару
1
@ Kikaimaru у вас есть точка зрения о 2D. Может быть, я слишком увлечен MVC, но это похоже на сочетание «модели» (игровые объекты) и вида / контроллера (компоненты пользовательского интерфейса). Это работает, конечно, но так ли это должно работать? Есть ли лучшие способы? Как это делают другие?
ashes999
@ ashes999 Ваш комментарий и первый вопрос глубоко из моего сердца :)
Нарек
@ Armen Я никогда не получал удовлетворительного ответа на это.
ashes999
@ ashes999 мне. Везде говорят, что нельзя смешивать MVC с ECS, но почему? Разве это не было бы хорошо? Разное оружие для разных задач, вы согласны?
Нарек

Ответы:

4

После использования нескольких систем компонент-сущностей, особенно CraftyJS, я более или менее получил ответ на мой вопрос: да, вы можете повторно использовать компоненты (особенно спрайты или изображения и обработчики щелчков мыши в 2D-играх) для графического интерфейса.

В большинстве случаев у вас есть доступ только к ECS, а не к базовым системам (например, к системе рисования). В этом случае можно использовать компоненты, поскольку у вас нет другого выбора.

Если у вас есть доступ к базовой системе (например, Ruby roguelike с прямым доступом к Curses), вы можете обнаружить, что рисование / рендеринг непосредственно в этой системе более эффективен (меньше кода, меньше хрупких, более естественных), чем использование множества сущности и компоненты.

ashes999
источник
Где вы размещаете логику продвинутых элементов пользовательского интерфейса? То есть. бар здоровья, который должен знать, когда игрок получил удар и насколько уменьшить бар. Я не могу понять, нужна ли ему определенная система, или сценарий, или что-то еще ...
Эмир Лима
@EmirLima для чего-то подобного, я бы поместил большую часть логики пользовательского интерфейса в панель здоровья (изменяя размер панели здоровья) и заставлял игрока генерировать событие, когда его ударили, указывая, какова новая / измененная ценность здоровья. (Панель состояния может зафиксировать это событие и соответствующим образом отреагировать.)
ashes999
Но что представляет собой объект Health-Bar в этой архитектуре? Это сущность с компонентом «планка здоровья»? Класс, который наследует от Entity? Обычный объект с вызовами обновления жестко запрограммирован?
Эмир Лима
1
@EmirLima Я бы смоделировал индикатор здоровья как сущность, а игрока - как сущность. Вы можете делать все, что имеет для вас смысл.
ashes999
1

В 2D или 3D компонентная система объектов (ECS) должна, по крайней мере, иметь доступ к системе GUI, если она не является частью той же ECS.

Лично я бы не совмещал их. Повторное использование кода для графического интерфейса действительно происходит только на верхнем уровне. Реагирование на мышь / клавиатуру, рендеринг и так далее. Функции, выполняемые различными кнопками, или информация, отображаемая в определенных списках, на самом деле не могут быть достаточно общими для повторного использования.

Например, я бы предположил, что компоненты для объектов GUI будут что-то вроде position, renderи gui. Где компонент GUI будет определять тип действия, которое предпринимает объект GUI. Тем не менее, это действие будет довольно уникальным и специфичным для контекста. Это приводит к тому, что система, которая обрабатывает компоненты графического интерфейса, является очень большой и по существу предназначена для обработки каждой из функций графического интерфейса пользователя (загрузка игры, сохранение игры, поиск сервера и т. Д.). Звучит грязно.

Я бы предпочел сделать стандартный файл класса для каждого «экрана» графического интерфейса. Соберите всю функциональность этого экрана в одном месте (со ссылками на общий класс функциональности). Это намного аккуратнее и проще в управлении.

Однако, как я уже сказал, ECS должен иметь доступ к системе GUI. Он должен иметь возможность предоставлять информацию в графический интерфейс на основе сущностей в своих системах. Например, при наведении курсора на союзное подразделение выскочит окно GUI со всей информацией об этом подразделении. Где зависание над вражеским единством выскочит окно GUI с ограниченной информацией. Скорее всего, вы не хотите программировать GUI, чтобы узнать разницу между ними, вы хотите попросить объект отобразить его информацию.

Таким образом, сущности, вероятно, все еще будут иметь некоторый компонент GUI, но они будут объектами «в игре», а не сущностями GUI. Этот компонент будет использовать внешнюю систему GUI для создания своего интерфейса GUI.

MichaelHouse
источник
Похоже, система, которая у меня есть, сильно отличается от той, которую вы описали. У меня есть такие классы сущностей, TouchButtonкоторые состоят из таблицы спрайтов и слушателя касания-нажатия. Для всплывающего окна модуля я, вероятно, реализовал бы это как комбинацию компонента спрайта + компонента прослушивания мыши. Хм.
ashes999