В конце предыдущей записи я затронул тему создания «границы» между ядром игровой логики и используемым движком. Думать мне много не надо — движок у меня один, но вот структура его весьма и весьма ветвистая. Надо думать, как правильно «состыковать» два независимых элемента приложения, не создав неудобств.
И снова мне достался выбор из двух вариантов — сделать правильно со стороны ООП, либо сделать эргономичнее со стороны пользования и интеграции с логикой.
Первый вариант действует по схеме: «На каждый класс дадим по классу!» Иными словами есть в GLScene класс TGLBaseMesh и его наследники TGLActor и TGLFreeForm, значит и мне надо создать у себя TMyBaseMesh с TMyActor и TMyFreeForm. Со стороны ООП выглядит все правильно — нет повторяющихся элементов, то есть «правильное» наследование + естественная красота кода. Но вот каково это будет со стороны использования? Захочу я использовать другой движок (алсо DGLE, eXngine, Irrliht.Net, etc), а там структура не такая. Итог: придется изучать весь ООП (абстрактный тоже) нового движка и переписывать файл конверсии с нуля. Удовольствие малоприятное, поэтому мой выбор снова падает в сторону «некрасивости».
А некрасивый тот код, который повторяет себя, нарушает принципы ООП и т.п., но именно такой код в юните конверсии позволит быстро перевести модуль на другой движок, отредактировав 5-7 классов, а не 15-17. Подход заключается в том, чтобы перевести конечные используемые мной классы. То есть только TGLActor, TGLFreeForm, TGLCube, TGLSprite, TGLHUDSprite и другие. Такие свойства как Position, Material, Direction, Up и многие, многие другие будут нещадно повторять друг друга. Зато понадобиться отредактировать, лишь, конечные классы, а не переводить структуру другого движка к структуре GLScene и от структуры GLScene к структуре игровой логики.
Размышления о конверсии ООП, меня привели к размышлению о конверсии инструментария. Если я хочу полной независимости логики от движка, значит мне необходимо воспроизвести по новой инструментарий. «Прощай GLKeyboard» — смутно всплыло в голове, а то вдруг мне захочется пересесть на DirectX с его DirectInput. Выхода у меня не остается, кроме как делать перевод и используемой структуры движка, и используемого от него инструментария.
В итоге будет создано 2 шаблона юнита конверсии uConversionX.pas и uConversionInstrumentsX.pas. Соответственно для GLScene будут использоваться юниты uConversionGLScene.pas и uConversionInstrumentsGLScene.pas. Таким образом, создавая игру, я буду оперировать лишь моими собственным классами, а используемый движок может быть абсолютно любым.
Очень интересные мысли, жаль что у меня их не было, когда я начинал делать свою игру, эх если бы я подумал о том что захочу сменить движок пока делаю игру.
Спасибо за комплимент, стараюсь все предусмотреть. Только опасаюсь, чтобы моя теория не задавила всю практику :-D