Моделирование «синглетонов» в системе компонентов

Я пишу базовую реализацию Астероидов как упражнение в обучении мыслить в сущностях и компонентах, и большая часть из них довольно проста. Но одна вещь, с которой я сталкиваюсь, - это ситуации, когда данная система нуждается в определенном объекте /компоненте, и я знаю, что есть только один из них. Примеры:

  • MovementSystem должен знать границы World, так что он знает, когда переносить на другую сторону экрана.
  • LevelSystem должен знать компонент GameState, поэтому он знает, должен ли он создавать новые астероиды.
  • InputSystem должно знать состояние Keyboard компонент

(и т.д.).

ECS, который я использую, ручная, но концептуально похожа на систему RADBMS системы сущностей Адама Мартина Beta - Java . То, что я делаю повторно для таких случаев, как указано выше, запрашивает EntityManager для всех компонентов данного типа и принимает «первый «(ака) только один:

World world = entityManager.getAllComponentsOfType(World.class).iterator().next()

Это работает, но кажется неуклюжим и делает код досадно неочевидным. Альтернативы, о которых я думал:

  • заставляют каждую систему перебирать «все» этих компонентов, как и любой другой тип компонента
  • добавить явную поддержку для компонентов «singleton» в EntityManager
  • не используйте компоненты для этих вещей; внедрить их в системы каким-то другим способом и жить с тем, что это делает дизайн значительно менее чистым.

Существует ли типичное или известное решение этой проблемы?

5 голосов | спросил David Moles 18 J0000006Europe/Moscow 2014, 21:26:00

3 ответа


13

Помните, что не увлекайтесь сущностями и компонентами. Совершенно нормально not иметь World как компонент. Если вы точно знаете, что будет только что-то, не имеет смысла делать его компонентом. Компоненты используются для повторного использования во многих объектах в сочетании с другими компонентами.

Это не делает игру менее чистой, она делает код чище. Системы сущностей - это всего лишь инструмент для части вашей игры, и это не обязательно должно быть хорошей системой. Используйте его только там, где имеет смысл вы .

ответил MichaelHouse 18 J0000006Europe/Moscow 2014, 21:47:29
1

Как говорили другие, одиночные игры не должны быть реализованы как компоненты. Хранение этих данных непосредственно в системах или в каком-либо внешнем одноэлементном классе прекрасен, если только системы обращаются к нему. Однако, если вы действительно хотите, чтобы ваш дизайн был «чистым» (он делает сериализацию всего состояния игры намного проще, если все данные находятся в компонентах, например), рассмотрите возможность использования статического поля или геттера в компоненте напрямую, например. "World.instance".

ответил Maroy 15 J000000Tuesday14 2014, 10:48:12
0

Одним из способов сделать это является внедрение системы обмена сообщениями в вашем приложении. Затем вы можете создавать события при создании конкретных компонентов.

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

ответил ed4053 18 J0000006Europe/Moscow 2014, 22:37:27

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132