Распределение типов игровых объектов

Я переношу 2D-игру на основе плитки на C++, потому что я действительно не фанат Java (некоторые функции хороши, но я просто не могу к этому привыкнуть). Я использую мозаичные карты TMX. Этот вопрос касается того, как перевести определения объектов в реальные игровые объекты. В Java я использовал отражение для выделения объекта указанного типа (учитывая, что он получен из базовой сущности игры).

Это работало нормально, но эта функция недоступна в C++ (я понимаю, почему, и я не жалуюсь. Я нахожу отражение беспорядочным, и я не решался использовать его в Java, ха-ха). Мне просто было интересно, как лучше всего перевести эти данные. Моя идея заключалась в базовом классе, из которого могли бы происходить все сущности (это кажется довольно стандартным), а затем загрузчик выделял бы производные типы на основе значения «типа» из карты TMX. Я придумал два способа сделать это.

  1. Гигантский распределительный блок. Долго и противно. Я сомневаюсь, что кто-нибудь предложит это (но это очевидно).
  2. Используйте std::map, который будет отображать произвольные имена типов в функцию для выделения указанных классов, соответствующих указанным именам типов.
  3. Наконец, я подумал о создании сущностей одного базового класса и использовании сценариев для сущностей разных типов. Сами скрипты будут регистрировать свой тип сущности в системе, хотя игра должна будет загружать указанные сценарии типа сущности при загрузке (это можно сделать с помощью одного основного сценария объявления типа сущности, что уменьшит количество правок на одну сущность до 2). : создание сущности и регистрация сущности).

в то время как второй вариант выглядит довольно хорошо, мне не нравится менять 3 фрагмента кода для каждого типа (определение класса сущности, определение функции распределения и добавление функции в std::map). Вариант 3 звучит великолепно, за исключением двух моментов, на мой взгляд: я боюсь скорости сущностей, управляемых исключительно скриптами. Кроме того, я знаю, что добавление сценариев в мой движок само по себе будет большим проектом (добавление всех вспомогательных функций для взаимодействия с библиотекой будет интересным).

Кто-нибудь знает лучшее решение? Может быть, не лучше, но просто чище. С меньшим количеством правок кода для каждого типа объекта.


person Caleb1994    schedule 13.05.2012    source источник


Ответы (1)


Вы можете уменьшить количество изменений кода в решении 2, если используете самостоятельную регистрацию на фабрике. Недостатком является то, что сущности знают эту фабрику (саморегистрация), и эта фабрика должна быть глобальным (например, одноэлементным) экземпляром. Если для вас это не проблема, этот узор может быть очень красивым. Каждый новый тип требует только компиляции компоновки одного нового файла.

Вы можете реализовать самостоятельную регистрацию следующим образом:

// foo.cpp
namespace 
{ 
  bool dummy = FactoryInstance().Register("FooKey", FooCreator); 
}

Абстрактная фабрика, шаблонный стиль, Джим Хислоп и Херб Саттер

person hansmaad    schedule 13.05.2012
comment
Мне нравится эта идея, но я думаю, стоит упомянуть, что для этого объекту потребуется какая-то статическая процедура инициализации (чтобы зарегистрировать себя без явного вызова основной функции, что сокращает количество правок кода). .) Это изначально невозможно в C++, но может быть достигнуто так: class Foo { private: static bool __st_init; static bool static_init(){ /* do whatever is needed at static init time */ return true; // or false to indicate static init fail } }; bool Foo::__st_init = Foo::static_init(); - person Caleb1994; 14.05.2012
comment
Что ж, в комментариях код выглядит ужасно, но, надеюсь, вы понимаете мою точку зрения. - person Caleb1994; 14.05.2012
comment
Очень интересно, это решение похоже на мое, но более точно. Мне также нравится абстрактная фабрика, реализованная на этой странице. В общем, отличная штука. Большое спасибо! - person Caleb1994; 14.05.2012