Разделение логики игры и рендеринга - PullRequest
28 голосов
/ 03 мая 2010

Как лучше всего отделить код рендеринга от собственно игрового движка / логического кода? И это даже хорошая идея, чтобы отделить их?

Предположим, у нас есть игровой объект под названием Рыцарь. Рыцарь должен быть отображен на экране, чтобы пользователь мог его увидеть. Теперь у нас есть два варианта. Либо мы даем Knight метод Render/Draw, который мы можем вызвать, либо создаем класс рендерера, который заботится о рендеринге всех рыцарей.

В сценарии, где эти двое разделены, Рыцарь должен по-прежнему содержать всю информацию, необходимую для его визуализации, или это тоже должно быть разделено?

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

Фреймворки, такие как XNA, считают, что объединение объекта и рендеринга - хорошая идея, но мы боимся привязываться к конкретной среде рендеринга, в то время как создание отдельного компонента рендеринга дает нам больше свободы для изменения фреймворка в любой ситуации. данное время.

Ответы [ 3 ]

21 голосов
/ 03 мая 2010

Я бы создал отдельный KnightRenderer класс. Преимущества:

  • Чистое разделение между игровой логикой и рендерингом. Сам Knight может даже работать на игровом сервере и вообще ничего не знать о рендеринге.
  • Меньшие, более простые классы, связанные с одним-единственным функционалом.

Все, что KnightRenderer должен знать о Knight (должность, статус), должно быть доступно для чтения в Knight.

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

6 голосов
/ 17 января 2011

Я знаю, что опаздываю, но для будущих читателей вас может заинтересовать учебник, который я написал.

Я не настоящий эксперт, но вот как я вижу правильное разделение интересов:
http://aurelienribon.wordpress.com/2011/04/26/logic-vs-render-separation-of-concerns/

alt text

6 голосов
/ 03 мая 2010

Я бы постарался сделать ваши объекты как можно более универсальными и избегать максимально возможного кодирования фактов игрового процесса в ваш код.

например. у вас есть класс Entity, Object или Actor, и у этого класса есть указатель на процесс принятия решений (его AI) и указатель на его графическое представление.

Принятие решений обязательно связано с фактами геймплея; действительно, является частью игрового факта. Так что это где-то, где вы могли бы назвать вашего лица, принимающего решения "KnightAi" или что-то.

С другой стороны, графическое представление - это просто немного графики. Он будет нарисован так же, как и любой другой объект. У вас есть модель или несколько растровых изображений и некоторые анимации или нет ... Это можно / можно просто назвать как-то как "Модель" и будет загружать информацию, которая ей сообщается, чтобы загрузить, определяет, как выглядит сущность для игрока. Когда дело доходит до рендеринга вашего коня, коня или замка, вы, скорее всего, обнаружите, что все они делают одно и то же только с разными данными. Все виды данных, которые они имеют, даже одинаковы, просто различается их содержание.

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

...