Как я могу работать на нескольких платформах, используя собственный движок?

13

Игровые движки, такие как Unity и Unreal, могут работать на нескольких платформах. Мне интересно, как они это делают.

Я уже давно пользуюсь C ++ и OpenGL, и мне нужны ресурсы для интеграции чего-то, что позволит мне работать на разных платформах без переписывания. Что-то вроде LibGDX, где вы пишете код с использованием базового API, а затем API преобразует его в HTML, Android, iOS и так далее. Я знаю, что могу использовать другой движок вместо написания своего собственного, но мне интересен опыт обучения.

DanielCollier
источник

Ответы:

26

Перенесите свой двигатель на каждую платформу. В этом нет ничего особенного. Если у вас есть код , который является для Windows-только, то либо добавить #ifdef логику в файле или добавить второй файл (так что вы бы FooWindows.cppи FooLinux.cppили любой другой ), реализующий функцию , что на других ОС (а) вы заботитесь о ,

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

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

Для таких вещей, как HTML5, существуют такие инструменты, как emscripten, которые могут компилировать приложение C ++ для запуска в JavaScript. Вам просто нужно сделать другой порт вашего движка для emscripten (так как он не может использовать произвольную библиотеку / функцию C ++).

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

Шон Миддледич
источник
14
По моему опыту работы с кроссплатформенным программным обеспечением (самый большой проект был бы HotSpot), вы действительно хотите избежать использования ifdefs через код. Определенно лучше иметь что-то вроде share/os/<linux>(или share/cpu/x86) и помещать туда весь специфичный для платформы код, а затем делать условные включения. Это, по крайней мере, то, что делают gcc, HotSpot и ядро ​​Linux (конечно, это не жесткое правило). Да, вы можете начать только с одной функции, которая зависит от платформы, и подумать, что она излишня, но она никогда не останется такой, и в противном случае она быстро превратится в беспорядок.
Во
14

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

То, о чем вы просите, не совпадает: вы говорите (выделение мое)

я ищу ресурсы для интеграции чего-то, что позволит мне работать на разных платформах без переписывания

но и это (снова акцент мой)

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

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

Игровые движки, такие как Unreal или Unity, которые поддерживают это, либо перекомпилируют ваш код для соответствующей абстракции платформы, либо требуют, чтобы вы построили библиотеку или DLL на основе их внутренних API-интерфейсов, которые они загружают из исполняемого файла драйвера для конкретной платформы, который они скомпилировали для соответствующего Платформа.


источник
2

В отличие от двух других ответов (которые по определению специфичны для C ++), существует другой способ. Некоторые архитектуры, которые приходят на ум:

  • Портируйте ваш движок: измените или напишите код, чтобы он работал на разных платформах. Об этом говорится в ответах выше.
  • Напишите что-нибудь выше кроссплатформенной библиотеки: это пример libGDX, который работает на Java. Java работает на рабочем столе, Android и iOS (через RoboVM). Используя что-то вроде Java, вы получаете преимущество бесплатных дополнительных платформ, когда базовая библиотека / инструмент поддерживает их. В этом случае, когда вышел RoboVM, libGDX (почти) «просто работает» на iOS.
  • Написать генератор кода: это подход Haxe и других инструментов. У вас есть основной язык (например, Haxe / AS3), и вы пишете конвертеры, которые генерируют выходные данные для других языков. Например. Haxe конвертируется в C ++ для рабочего стола, Java (я думаю) для Android и т. Д.

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

libGDX на самом деле отличный выбор, поскольку он распространяется как на основные мобильные телефоны, так и на настольные ПК и в Интернете (через апплеты или веб-компилятор Google).

ashes999
источник
Даже с Java или C # вы волшебным образом не получаете кросс-платформенный код; Вы все еще должны быть осведомлены о сторонних библиотеках, которые могут иметь зависимости от платформы (например, SlimDX или SharpDX будут плохим выбором для кроссплатформенного проекта C #).
@JoshPetrie, вы, безусловно, получаете много «бесплатно» по сравнению с прокруткой собственного движка C ++ и переносом его на разные платформы.
ashes999
@ ashes999 спасибо за ответ, libGDX великолепен, я его использую, но собираюсь написать его, чтобы он работал кроссплатформенно, а затем использую CMake, я больше в этом заинтересован, чем использую уже существующую библиотеку или движок
DanielCollier
2

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

Помимо этого, есть много «пользовательского кода» для каждой платформы. Это вам просто нужно пройти. До сих пор я обнаружил, что это очень небольшая часть моего времени разработки, в основном потраченная на поиск документации для систем, с которыми я не так знаком, как мой родной Linux.

Я бы отговорил вас от использования #ifdefповсюду в вашем коде. Вместо этого создайте абстракции вокруг ключевых примитивов (примером такого примитива может быть сокет TCP).

Когда вы сталкиваетесь с новой проблемой, которая требует разных решений для каждой среды, спросите себя: «Могу ли я решить эту проблему, используя только кроссплатформенные примитивы, которые я уже создал?» Если ответ да: вуаля, простой кроссплатформенный код. В противном случае выясните, какие примитивы вам не хватает, и реализуйте их.

scpayson
источник
0

Если вы хотите сделать это «с нуля» в качестве учебного процесса, вам нужно будет использовать Win32 API, где вы можете найти информацию об открытии окна и контексте OpenGL на MSDN и на OpenGL wiki ( http: // www .opengl.org / wiki / creation_an_OpenGL_Context_ (WGL) ). Для Linux получите подержанную копию Руководства по программированию O'Reilly Xlib и Справочного руководства по Xlib, а также ознакомьтесь с GLX (Расширение OpenGL для системы X Window). Смотрите также http://www.opengl.org/wiki/Tutorial:_OpenGL_3.0_Context_Creation_(GLX)

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


источник
спасибо за ответ, но я бы предпочел просто использовать SDL2 для управления окнами, его кроссплатформенность и простота использования. как LibGDX использует LWJGL для управления окнами
DanielCollier