Jak mogę uruchomić na wielu platformach za pomocą niestandardowego silnika?

13

Silniki gier, takie jak Unity i Unreal, mogą działać na wielu platformach. Zastanawiam się, jak to robią.

Używam C ++ i OpenGL od jakiegoś czasu i szukam zasobów do zintegrowania czegoś, co pozwoli mi działać na różnych platformach bez przepisywania. Coś takiego jak LibGDX, w którym piszesz kod przy użyciu podstawowego interfejsu API, a następnie interfejs API konwertuje go na HTML, Android, iOS i tak dalej. Zdaję sobie sprawę, że zamiast pisać własny mogę użyć innego silnika, ale interesuje mnie nauka.

DanielCollier
źródło

Odpowiedzi:

26

Przenieś silnik na każdą platformę. Nie ma w tym nic specjalnego. Jeśli masz kod tylko dla systemu Windows, dodaj albo logikę #ifdef w pliku, albo dodaj drugi plik (abyś miał FooWindows.cppi tak dalej FooLinux.cpp), który implementuje tę funkcję w innych systemach operacyjnych, na których Ci zależy .

Publikowanie za pomocą jednego kliknięcia, które ma silnik taki jak Unity, jest dozwolone, ponieważ sam Unity nigdy nie jest modyfikowany przez użytkownika końcowego. Po prostu piszesz skrypty i dane, więc silnik ma wbudowane pliki binarne dla wszystkich platform, a przycisk publikowania łączy te pliki binarne razem z danymi.

Inne silniki polegają na systemach kompilacji i kompilatorach krzyżowych, aby w razie potrzeby tworzyć skompilowaną grę, podobnie jak w przypadku aplikacji wieloplatformowych innych niż gry.

W przypadku HTML5 istnieją narzędzia takie jak emscripten, które mogą skompilować aplikację C ++ do działania w JavaScript. Musisz po prostu zrobić inny port silnika dla emscripten (ponieważ nie może on używać dowolnej biblioteki / funkcji C ++).

Nie musisz przepisywać całej gry, ale na pewno będziesz musiał wiele pracy w zakresie programowania, kodowania i przenoszenia dla każdej nowej platformy, którą chcesz obsługiwać.

Sean Middleditch
źródło
14
Z mojego doświadczenia w pracy z oprogramowaniem typu crosssplatform (największym projektem byłby HotSpot), naprawdę chcesz uniknąć wyrzucania ifdefs przez kod. Zdecydowanie lepiej jest mieć coś takiego share/os/<linux>(lub share/cpu/x86) i umieścić tam cały kod specyficzny dla platformy, a następnie zastosować warunkowe dołączenia. Tak przynajmniej robią gcc, HotSpot i jądro Linuksa (z pewnością nie jest to trudna zasada). Tak, możesz zacząć od jednej funkcji, która zależy od platformy i myślisz, że to przesada, ale nigdy tak nie jest i szybko stanie się bałaganem.
Voo,
14

Tu nie ma magicznej kuli. Jeśli chcesz, aby Twoja gra działała na wielu platformach, musisz napisać kod dla wielu platform (lub wykorzystać biblioteki innych firm, które już to robią).

Rzeczy, o które prosisz, nie pasują do siebie: mówisz (podkreśl moje)

szukam zasobów do zintegrowania czegoś, co pozwoli mi działać na różnych platformach bez przepisywania

ale także to (ponownie podkreśl moje)

Zdaję sobie sprawę, że zamiast pisać własny mogę użyć innego silnika, ale interesuje mnie nauka .

Będziesz musiał zrobić jedno lub drugie: wybierz bibliotekę, silnik i / lub zestaw narzędzi innej firmy, który zapewnia wsparcie dla wielu platform, lub zbuduj własny, pisząc kod dla wielu platform (projektując własna abstrakcja na platformach, które masz do dyspozycji, i implementacja tej abstrakcji dla każdej platformy).

Silniki gier jak Unreal czy Jedności, które obsługują ten albo rekompilacji kodu na odpowiednią platformę abstrakcji, lub wymagać, aby zbudować bibliotekę lub DLL przed ich wewnętrznych interfejsów API, które ładują z platformy konkretnego pliku wykonywalnego kierowcę, który je sporządził dla odpowiedniego Platforma.


źródło
2

W przeciwieństwie do pozostałych dwóch odpowiedzi (które są słusznie specyficzne dla C ++), istnieje inny sposób. Niektóre architektury, które przychodzą na myśl:

  • Przenieś silnik: zmodyfikuj lub napisz kod, aby działał na wielu platformach. Zostało to rozwiązane w odpowiedziach powyżej.
  • Napisz coś powyżej biblioteki wieloplatformowej: To jest przykład libGDX, który działa na Javie. Java działa na komputerach stacjonarnych, Androidzie i iOS (przez RoboVM). Korzystając z czegoś takiego jak Java, zyskujesz korzyść z bezpłatnych dodatkowych platform, gdy bazowa biblioteka / narzędzie je obsługuje. W tym przypadku, kiedy wyszedł RoboVM, libGDX (prawie) „po prostu działa” na iOS.
  • Napisz generator kodów: jest to podejście Haxe i innych narzędzi. Masz podstawowy język (np. Haxe / AS3) i piszesz konwertery, które generują dane wyjściowe dla innych języków. Na przykład. Haxe konwertuje do C ++ na komputery stacjonarne, Java (myślę) na Androida itp.

Osobiście uważam, że podejście libGDX jest najprostsze: znajdź język lub platformę, która spełnia twoje potrzeby, i pisz na wierzchu. Generowanie kodu i przenośne silniki są złożone i trudno je dobrze napisać.

libGDX to naprawdę świetny wybór, ponieważ działa zarówno na głównych telefonach komórkowych, komputerach stacjonarnych, jak i na sieci (za pośrednictwem apletów lub kompilatora internetowego Google).

ashes999
źródło
Nawet w Javie lub C # nie otrzymujesz kodu międzyplatformowego w magiczny sposób; nadal musisz znać biblioteki innych firm, które mogą mieć zależności od platformy (na przykład SlimDX lub SharpDX byłby złym wyborem dla wieloplatformowego projektu w języku C #).
@JoshPetrie na pewno dostajesz dużo „za darmo” w porównaniu do tworzenia własnego silnika C ++ i przenoszenia go na różne platformy.
ashes999
@ ashes999, dziękuję za odpowiedź, libGDX jest genialny. Używam go, ale zamierzam go napisać, aby działał na różnych platformach, a następnie użyj CMake, jestem bardziej zaangażowany w wyzwanie niż w użyciu wcześniejszej biblioteki lub silnika
DanielCollier
2

Obecnie buduję wieloplatformowy silnik gry. Używam SDL, która jest doskonałą (i odpowiednio niskim poziomem) biblioteką między platformami do budowania aplikacji graficznych, aby złagodzić ból.

Poza tym istnieje wiele „niestandardowego kodu” dla każdej platformy. Trzeba po prostu przejść. Odkryłem, że jest to bardzo niewielki ułamek mojego czasu programowania, głównie spędzonego na szukaniu dokumentów dla systemów, których nie znam tak dobrze jak mój macierzysty Linux.

Zniechęcam cię do używania #ifdefwszędzie w całym kodzie. Zamiast tego buduj abstrakcje wokół kluczowych operacji podstawowych (przykładem takiej operacji podstawowej może być gniazdo TCP).

Gdy napotkasz nowy problem, który wymaga różnych rozwiązań w zależności od środowiska, zadaj sobie pytanie „czy mogę rozwiązać ten problem przy użyciu tylko prymitywów międzyplatformowych, które już zbudowałem?” Jeśli odpowiedź brzmi tak: voila, prosty wieloplatformowy kod. W przeciwnym razie dowiedz się, jakich prymitywów brakuje, i zaimplementuj je.

scpayson
źródło
0

Jeśli chcesz to zrobić „od zera” jako doświadczenie edukacyjne, musisz użyć Win32 API, w którym możesz znaleźć informacje na temat otwierania okna i kontekstu OpenGL w MSDN i na wiki OpenGL ( http: // www .opengl.org / wiki / Creating_an_OpenGL_Context_ (WGL) ). W przypadku systemu Linux uzyskaj kopię podręcznika programowania O'Reilly Xlib i podręcznika referencyjnego Xlib, a także przeczytaj GLX (rozszerzenie OpenGL do systemu X Window). Zobacz także http://www.opengl.org/wiki/Tutorial:_OpenGL_3.0_Context_Creation_(GLX)

Następnie wystarczy podać ten sam interfejs API do aplikacji z funkcjami, które robią to samo (np. Otwierają okno), ale mają różne implementacje dla każdej platformy. Przepisujesz części silnika na różne platformy. Następnie grę, którą piszesz za pomocą silnika, musisz napisać tylko raz, ale będzie działać na różnych platformach.


źródło
dziękuję za odpowiedź, ale wolałbym po prostu użyć SDL2 do okienkowania, jego platformy i jest bardzo łatwy w użyciu. jak LibGDX używa LWJGL do okien
DanielCollier