Як я можу працювати на декількох платформах за допомогою користувацького двигуна?


13

Ігрові двигуни, такі як Unity та Unreal, можуть працювати на безглуздих платформах. Мені цікаво, як вони це роблять.

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

Відповіді:


26

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

Публікація одним натисканням кнопки, яку має такий двигун, як Unity, оскільки кінцевий користувач ніколи не змінюється. Ви просто пишете сценарії та дані, тому двигун має заздалегідь вбудовані бінарні файли для всіх платформ, а кнопка публікації просто поєднує ці файли разом із даними.

Інші двигуни покладаються на системи побудови та крос-компілятори для створення компільованої гри, коли це потрібно, як і у будь-якому неігровому кросплатформенному додатку.

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

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


14
З мого досвіду роботи з кросплатформою програмного забезпечення (найбільший проект був би HotSpot), ти дійсно хочеш уникнути попадання ifdefs через код. Однозначно краще мати щось на кшталт share/os/<linux>(або share/cpu/x86) і помістити туди весь специфічний код платформи, а потім зробити умовне включення. Так принаймні те, що роблять gcc, HotSpot та ядро ​​Linux (звичайно, не важке правило). Так, ви можете почати лише з однієї функції, залежної від платформи, і вважаєте, що це надмірно, але вона ніколи не залишається такою, і в іншому випадку це швидко стає безладом.
Voo

14

Тут немає ніякої чарівної кулі. Якщо ви хочете, щоб ваша гра працювала на декількох платформах, вам потрібно написати код для декількох платформ (або використовувати сторонні бібліотеки, які вже роблять це для вас).

Те, що ви просите, не співпадає: ви говорите (моє наголос)

Я шукаю - це ресурси, щоб інтегрувати щось, що дозволить мені працювати на різних платформах без переписування

але і це (наголос мій знову)

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

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

Ігрові двигуни, такі як Unreal або Unity, що підтримують це або перекомпілюють ваш код на відповідну платформу абстракції, або вимагають, щоб ви створили бібліотеку або DLL проти їх внутрішніх API, які вони завантажують з виконуваного для платформи виконавчого файлу, який вони склали для відповідного платформа.


2

На відміну від двох інших відповідей (які справедливо є C ++ - специфічними), є інший спосіб. Деякі архітектури, які приходять на думку:

  • Порт вашого двигуна: Змініть або запишіть код так, щоб він працював на декількох платформах. Про це йдеться у відповідях вище.
  • Напишіть щось над бібліотекою між платформами. Це приклад libGDX, який працює на Java. Java працює на робочому столі, Android та iOS (через RoboVM). Використовуючи щось на кшталт Java, ви отримуєте перевагу від безкоштовних додаткових платформ, коли основна бібліотека / інструмент підтримує їх. У цьому випадку, коли вийшов RoboVM, libGDX (майже) "просто працює" на iOS.
  • Написати генератор коду: Це підхід Хакс та інших інструментів. У вас є основна мова (наприклад, Haxe / AS3), і ви пишете перетворювачі, які генерують вихід для інших мов. Напр. Haxe перетворюється на C ++ для робочого столу, Java (я думаю) для Android тощо.

Особисто я вважаю, що підхід libGDX є найпростішим: знайдіть мову або платформу, яка відповідає вашим потребам, і напишіть зверху. Генерація коду та портативні двигуни складні і важко писати.

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


Навіть за допомогою Java або C # ви не отримаєте чарівний код платформи; ви все ще повинні бути відомими сторонніми бібліотеками, які можуть мати залежність від платформи (наприклад, SlimDX або SharpDX були б поганим вибором для міжплатформного проекту C #).

@JoshPetrie ви, звичайно, отримаєте багато "безкоштовно" порівняно з прокаткою власного двигуна C ++ та перенесенням його на платформи.
ashes999

@ ashes999 спасибі за відповідь, libGDX геніальний, я його використовую, але я збираюся його написати, щоб він працював між платформою, а потім використовував CMake, я більше в ньому для завдання, ніж використання попередньо існуючої бібліотеки чи двигуна
DanielCollier

2

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

Крім цього, існує багато "спеціального коду" для кожної платформи. Це ви просто повинні пройти. Я вважав, що це поки що невелика частина мого часу розробки, в основному я витрачав на пошук документів для систем, з якими я не такий знайомий, як мій рідний Linux.

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

Коли ви стикаєтеся з новою проблемою, яка потребує різних рішень в середовищі, запитайте себе: "Чи можу я вирішити цю проблему, використовуючи лише крос-платформні примітиви, які я вже створив?" Якщо відповідь - так: вуаля, простий код крос-платформи. Інакше з’ясуйте, яких примітивів вам не вистачає, і реалізуйте їх.


0

Якщо ви хочете зробити це "з нуля" як досвід навчання, тоді вам потрібно буде використовувати API Win32, де ви можете знайти інформацію про відкриття вікна та контексту OpenGL на MSDN та на вікі OpenGL ( http: // www .opengl.org / wiki / Creating_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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.