Одинаковая логика игры в двух отдельных графических библиотеках

11

Какая философия кода / структура абстракции / дизайн программы позволят использовать игру как с 2D, так и с 3D-графикой (отдельно), БЕЗ необходимости перекодировать игровую логику?

Мы говорим о том, чтобы взять один и тот же код, изменить минимум вещей (например, обмениваться именами файлов для 2D-ресурсов с именами файлов для 3D-ресурсов) и, возможно, подключить несколько специализаций базового класса для шаблонов / шаблонов.

Чтобы представить его в реальном контексте, где это имеет смысл: представьте себе многопользовательскую LAN-игру, в которой есть один первоклассный, требовательный к производительности 3D-клиент для игроков с некоторыми действительно хорошими игровыми платформами и более скромный 2D-клиент для старых пыльные коробки, которые кто-то нашел на чердаке. Но это все та же игра - регистрируются те же события (кто-то взял монетку), используется тот же сетевой протокол, миры пропорциональны и т. Д.

Чтобы поместить это в контекст MVC: контроллеры одинаковы (нажатие клавиши «Вверх» установит ускорение игроков на уровне 3,5 единиц / секунду), виды полностью различаются (2D и 3D), и модель такая же за исключением всего, что напрямую связано с графикой (проверка столкновений для среды выполняется каждые 5 секунд, и он использует тот же алгоритм. Обратите внимание, что это будет означать, что есть Е-Z-координата для всех игровых объектов в 2D-версии, но это просто игнорировать или отображаться пользователю по-другому, например, с помощью тени, которая отображается слева дальше, когда игрок находится в воздухе).

Что делает эту тему такой увлекательной, так это то, что она заставит разработчика иметь очень четкое представление о том, как его данные структурированы и как происходит управление. Обратите внимание, что это не означает использование чего-либо, кроме графической библиотеки, такой как SDL, D3DX или OpenGL. Нет игровых движков!

Так как это в основном теоретический вопрос, я оставлю языки программирования вне его, но если вы хотите привести пример, вы можете использовать любой язык, который вам нравится, C ++, если вы хотите работать в полную силу, или даже Brainfuck, если вы чувствуете, до задачи (Будут оценены любые конкретные ответы, а также любые абстрактные!).

Тоби
источник
Я не уверен , что это практично. Так много игровой логики использует векторную математику, вам придется либо делать все в 3D, прежде чем конвертировать в 2D, или что-то еще для рендеринга, или вам придется полностью абстрагировать свою векторную библиотеку - что, несомненно, будет непрактично?
tenpn
Ищите термин «слой абстракции» и знакомьтесь с ним, потому что вы двое собираетесь работать вместе некоторое время.
Заратустра

Ответы:

8

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

Подумайте о локализации строк: вместо жесткого кодирования строки «Inventory» в вашей игре, вы бы вместо этого вызвали вашу (возможно, пользовательскую) библиотеку локализации, которая выполняла бы некоторые процессы и возвращала правильную строку, в зависимости от контекста игра.

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

При этом вы ограничиваете / ограничиваете какие команды вы можете дать своему графическому движку. Вот некоторые основные из них:

  1. Draw (графический объект) в (место)
  2. Изменение (альфа, поворот и т.д.) свойство (графического объекта)
  3. Move (графический объект) в (место)
  4. Построить карту (название уровня / структура данных)

И некоторые другие, которые вы найдете, как вы работаете над проектом.

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

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

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

Надеюсь, это поможет вам начать =]

Джастин Л.
источник
2

Построение архитектуры вашей игры с парадигмой, достаточно близкой к MVC, чтобы обеспечить полную абстракцию кода дисплея, вероятно, будет довольно сложно для любого крупного проекта. Тем не менее, кажется, что самым большим препятствием для создания игры, которая поддерживает как 2D, так и 3D-клиент, было бы создание игры, в которой оба клиента в равной степени способны.

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

В качестве примера ловушки, если вы не проектируете для ограниченного набора функций, вы можете создать уровни, на которых важная информация или объекты были бы видны только под определенными углами. Хотя это было бы хорошо для 3D-клиентов, которые имеют 360-градусную свободу просмотра, если только ваш 2D-клиент явно не поддерживает угол обзора, который обеспечивает видимость каждого из этих важных объектов, вы могли бы ухудшить работу пользователей клиента.

Было бы лучше установить конкретное количество углов обзора для 2D-клиента (8 или 16 или около того) и разработать весь контент, чтобы соответствовать этим ограничениям. К сожалению, если у вас есть уровни и объекты, которые предназначены для просмотра только с определенного набора углов, это может выглядеть довольно странно в 3D-клиенте.

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

Чарльз Эллис
источник
0

Я думаю, что вы в значительной степени ответили на свой вопрос:

Чтобы поместить это в контекст MVC: Контроллеры одинаковы (нажатие клавиши «Вверх» установит ускорение игроков на 3,5 единиц / секунду), Представления совершенно разные (2D против 3D), и Модель такая же за исключением всего, что напрямую связано с графикой.

Таким образом, предоставив адекватную абстракцию между вводом, игровой логикой и т. Д. И графикой, вы решите проблему.

В этом и заключается смысл модели MVC, особенно в том, что касается настольных и веб-приложений: несколько клиентов могут обращаться к одним и тем же данным и манипулировать ими (например, веб-интерфейс, мобильный клиент и настольный клиент для электронной почты).

Шон Джеймс
источник
0

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

Для этого вы можете использовать более или менее сложные методы программирования. Единственное, что вам нужно, это способ получить «лишние» данные, которые вам необходимо отобразить для каждого игрового объекта. Самый простой способ - получить нулевые дополнительные данные! Если игровым объектом является «Волшебник», нарисуйте Волшебника.

Если вам нужны более сложные методы, подумайте о полиморфизме, шаблоне сувениров, хэш-таблицах, указателях void * и т. Д. Не переусердствуйте в этом (большинство из этих методов более сложны).

Винсент Шейб
источник