Я считаю создание игрового движка следующим дизайнерским подходом.
Основной характеристикой является создание так называемых систем, которые охватывают игровое меню и игровые уровни. Эти системы снабжены такими объектами, как Window
рисовать, Input
принести, Sound
играть, а может и Network
общаться с сервером.
class System // abstract class
{
Window* Window;
Input* Input;
...
System(Window* Window, Input* Input, ...)
{
this->Window = Window;
this->Input= Input;
...
}
virtual Pause() = 0;
virtual Resume() = 0;
}
Основная функция обрабатывает системы, таким образом, меню и уровни. Сказать LevelOne
происходит от System
,
int main()
{
LevelOne Tutorial(&Window, &Input, ...);
Tutorial.Pause();
...
}
Таким образом, мой код становится структурированным и (на мой взгляд) легким для понимания. Но как основная функция может взаимодействовать с системами?
Например, как меню может сообщить основной функции, что пользователь выбрал уровень, и какой именно? Чтобы позволить основной функции удалить меню и создать новый объект уровня.
Я думаю, что вы пытаетесь сделать здесь, это организовать полную архитектуру модель-представление-контроллер, и код, который вы здесь предоставили, является частью модели и контроллера. Смотрите некоторые объяснения по MVC в Интернете:
http://www.codinghorror.com/blog/2008/05/understanding-model-view-controller.html
Если у вас есть единственная функция main (), которая пытается прослушивать сообщения от ваших подсистем и в результате вызывает соответствующие действия, вы пытаетесь реализовать однопоточный цикл реагирующих сообщений. Вы могли бы рассмотреть запуск реактора ACE, который может прослушивать сообщения Qt GUI, а также другие, такие как сетевые события, а затем соответствующим образом вызывать ваши подсистемы (хотя могут быть некоторые проблемы с производительностью):
http://www.cs.wustl.edu/~schmidt/PDF/reactor-rules.pdf
Я не знаком с графическими движками для программирования видеоигр, но большинство графических библиотек предлагают цикл сообщений для вас во время его инициализации, который не требует от вас прохождения такого рода деталей. Все, что вам обычно нужно сделать, это создать свои графические объекты и зарегистрировать их в основном цикле сообщений библиотеки.
И я бы рекомендовал использовать отдельный поток для прослушивания сетевых событий по сравнению с вашим потоком сообщений для прослушивания графических событий. Это отделяет работу и помогает улучшить производительность вашей графики.
Других решений пока нет …