Подтвердить что ты не робот

Игры: Кто отвечает за показ?

Должны ли сущности знать, как нарисовать себя? Я использовал этот подход: он прост и работает, но после изучения MVC-шаблонов я чувствую себя неловко об этом. Трудно изменить стиль искусства, когда вся логика отображения похожа на модель.

Можно было бы ввести класс вида, который принимает уровень как аргумент и рисует его, но это будет означать, что он должен идентифицировать типы сущностей и ввести "switch" -statement, о котором я узнал, также плохо.

Где следует размещать код для рисования, способным к расширению, легко меняющимся, чистым и сухим?

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

Короткий ответ заключается в том, что это зависит от того, насколько сложны ваши игровые объекты. Для простых объектов это не имеет большого значения.

Когда вы попадаете в гораздо более сложные объекты, вы должны переосмыслить свой подход. В общем, вы захотите противостоять желанию иметь цикл uber, который выполняет итерацию по каждому объекту и вызывает некоторую функцию update/render/whatever. Это совсем не масштабируется, если только каждое обновление, рендеринг или любая другая иерархия не совпадают. Это отлично подходит для такой игры, как Geometry Wars, но не для чего-то более сложного.

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

Некоторые полезные ссылки:

http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/ http://research.scee.net/files/presentations/gcapaustralia09/Pitfalls_of_Object_Oriented_Programming_GCAP_09.pdf

Я очень рекомендую обе; первый идет в обоснование дизайна для создания игровых объектов из компонентов, то есть компонент рендеринга, физический компонент, компонент ИИ. Второй относится к характеристикам производительности различных подходов к игровым объектам.

Ответ 3

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

Тем не менее, нет причин, по которым вы не должны пытаться отделить состояние от презентации. Сущности не должны знать, как рисовать себя как таковые - это означало бы, что они знают об операциях рендеринга, что необязательно, но должно быть возможно спросить их, как они выглядят в этот момент времени, а затем использовать эту информацию для визуализировать сцену. например. 2D-объект должен иметь возможность возвращать текущий кадр анимации. Или 3D-объект должен иметь возможность вернуть свою 3d-сетку, положение и ориентацию. Здесь нет необходимости в инструкции switch, если у вас есть общие представления, которые вы можете вернуть рендереру. Сущности с дико отличающимися алгоритмами рендеринга, возможно, должны были бы вернуть в этот момент довольно разные объекты.

Ответ 4

Обычно я решаю эту проблему с наследованием.

Например, в проекте, над которым я работаю, в настоящий момент я использую Test-Driven Development для написания логики игры с ручным тестированием для рендеринга. Этот пример ниже в С# показывает приблизительную идею.

class GameObjecet {
    // Logic, nicely unit tested.
}

class DrawableGameObject : GameObject {
    // Drawing logic - manual testing
}

Это, как правило, то, что я нашел лучшим решением. Это позволяет тестировать код, не загромождая логику игры презентационным кодом, таким как рисование, загрузка модели и т.д.