Это продолжение этого вопроса, на который я ответил, но этот вопрос затрагивает гораздо более конкретную тему.
Этот ответ помог мне понять Entity Systems даже лучше, чем статья.
Я прочитал (да) статью о Entity Systems, и она сказала мне следующее:
Сущности - это всего лишь идентификатор и массив компонентов (в статьях говорится, что хранение сущностей в компонентах не является хорошим способом ведения дел, но не предоставляет альтернативы).
Компоненты - это фрагменты данных, которые указывают, что можно сделать с определенной сущностью.
Системы являются «методами», они выполняют манипуляции данными на объектах.
Это кажется действительно практичным во многих ситуациях, но часть о компонентах, являющихся просто классами данных, беспокоит меня. Например, как я могу реализовать свой класс Vector2D (Position) в Entity System?
Класс Vector2D содержит данные: координаты x и y, но он также имеет методы , которые имеют решающее значение для его полезности и отличают класс от всего двухэлементного массива. Пример метода: add()
, rotate(point, r, angle)
, substract()
, normalize()
, и все другие стандартный, полезные, и абсолютно необходимы методы , что позиции (которые являются экземплярами класса Vector2D) должны иметь.
Если бы компонент был просто держателем данных, у него не было бы этих методов!
Вероятно, может появиться одно из решений, заключающееся в том, чтобы внедрить их в системы, но это кажется очень нелогичным. Эти методы - вещи, которые я хочу выполнить сейчас , чтобы они были завершены и готовы к использованию. Я не хочу ждать, пока MovementSystem
кто-то прочитает дорогой набор сообщений, которые инструктируют его выполнить вычисление позиции сущности!
И в статье очень четко говорится, что только системы должны иметь какую-либо функциональность, и единственное объяснение этому, которое я мог найти, было «избегать ООП». Прежде всего, я не понимаю, почему я должен воздерживаться от использования методов в сущностях и компонентах. Затраты памяти практически одинаковы, и в сочетании с системами их очень легко реализовать и объединить интересными способами. Системы, например, могут предоставлять базовую логику только сущностям / компонентам, которые сами знают реализацию. Если вы спросите меня - это, по сути, получение положительных отзывов как от ES, так и от ООП, что, по мнению автора статьи, сделать невозможно, но мне кажется хорошей практикой.
Подумайте об этом таким образом; В игре есть много разных типов прорисовываемых объектов. Простые старые изображения, анимации ( update()
и getCurrentFrame()
т. Д.), Комбинации этих примитивных типов, и все они могут просто предоставить draw()
метод для системы рендеринга, который затем не должен заботиться о том, как реализован спрайт объекта, только об интерфейсе (ничья) и позиции. И тогда мне понадобится только система анимации, которая будет вызывать специфичные для анимации методы, которые не имеют ничего общего с рендерингом.
И еще одна вещь ... Есть ли действительно альтернатива массивам, когда речь идет о хранении компонентов? Я не вижу другого места для хранения компонентов, кроме массивов внутри класса Entity ...
Возможно, это лучший подход: хранить компоненты как простые свойства сущностей. Например, компонент позиции будет приклеен к entity.position
.
Только другой способ будет иметь какое - то странную справочную таблицу внутри системы, что ссылки на различные объекты. Но это кажется очень неэффективным и более сложным для разработки, чем просто хранение компонентов в объекте.