Wie kann ich mit einer benutzerdefinierten Engine auf mehreren Plattformen ausgeführt werden?

13

Game Engines wie Unity und Unreal können auf mehreren Plattformen ausgeführt werden. Ich frage mich, wie sie das machen.

Ich benutze C ++ und OpenGL seit einer Weile und suche nach Ressourcen, um etwas zu integrieren, das es mir ermöglicht, auf verschiedenen Plattformen zu laufen, ohne es neu zu schreiben. So etwas wie LibGDX, bei dem Sie Code mithilfe einer Basis-API schreiben und diese dann in HTML, Android, iOS usw. konvertieren. Mir ist bewusst, dass ich eine andere Engine verwenden kann, anstatt meine eigene zu schreiben, aber ich bin an der Lernerfahrung interessiert.

DanielCollier
quelle

Antworten:

26

Portieren Sie Ihren Motor zu jeder Plattform. Daran ist nichts Besonderes. Wenn Sie einen Code haben , die nur für Windows ist, dann ist entweder etwas #ifdef Logik in der Datei hinzufügen oder eine zweite Datei hinzufügen (so müßten Sie FooWindows.cppund FooLinux.cppoder was auch immer) , dass Geräte , die Funktion auf dem anderen O (n) die Sie interessieren .

Das Ein-Klick-Publizieren von Inhalten, über die eine Engine wie Unity verfügt, ist zulässig, da Unity selbst vom Endbenutzer niemals geändert wird. Sie schreiben nur Skripte und Daten, daher verfügt die Engine über vorgefertigte Binärdateien für alle Plattformen, und die Schaltfläche zum Veröffentlichen bündelt diese Binärdateien nur mit den Daten.

Andere Engines verwenden Build-Systeme und Cross-Compiler, um das kompilierte Spiel bei Bedarf zu erstellen, genau wie Sie es mit jeder plattformübergreifenden Nicht-Spiel-Anwendung tun würden.

Für Dinge wie HTML5 gibt es Tools wie emscripten, die eine C ++ - Anwendung für die Ausführung in JavaScript kompilieren können. Sie müssen für emscripten im Grunde nur einen anderen Port Ihrer Engine erstellen (da keine beliebige C ++ - Bibliothek / -Funktion verwendet werden kann).

Sie müssen nicht Ihr gesamtes Spiel neu schreiben, aber Sie müssen auf jeden Fall viel Entwicklungs-, Programmier- und Portierungsarbeit für jede neue Plattform leisten, die Sie unterstützen möchten.

Sean Middleditch
quelle
14
Nach meiner Erfahrung mit plattformübergreifender Software (das größte Projekt wäre HotSpot) möchten Sie wirklich vermeiden, dass ifdefs durch den Code geworfen werden. Es ist definitiv besser, etwas wie share/os/<linux>(oder share/cpu/x86) zu haben und den gesamten plattformspezifischen Code dort einzutragen und dann bedingte Includes auszuführen. Das ist zumindest das, was gcc, HotSpot und der Linux-Kernel tun (sicherlich keine harte Regel). Ja, Sie können mit nur einer einzigen Funktion beginnen, die plattformabhängig ist und denkt, es ist übertrieben, aber das bleibt nie so und es wird sonst schnell zu einem Chaos.
Voo
14

Hier gibt es keine magische Kugel. Wenn Sie möchten, dass Ihr Spiel auf mehreren Plattformen läuft, müssen Sie Code für mehrere Plattformen schreiben (oder Bibliotheken von Drittanbietern nutzen, die dies bereits für Sie tun).

Die Dinge, nach denen Sie fragen, stimmen nicht überein: Sie sagen (Betonung meiner)

Was ich suche, sind Ressourcen, um etwas zu integrieren, das es mir ermöglicht, auf verschiedenen Plattformen zu laufen, ohne es neu zu schreiben

aber auch das (Schwerpunkt wieder meins)

Mir ist bewusst, dass ich eine andere Engine verwenden kann, anstatt meine eigene zu schreiben, aber ich bin an der Lernerfahrung interessiert .

Sie müssen so ziemlich das eine oder andere tun: Wählen Sie, ob Sie eine Bibliothek, Engine und / oder Toolchain eines Drittanbieters verwenden möchten, die plattformübergreifende Unterstützung für Sie bietet, oder erstellen Sie Ihren eigenen Code, indem Sie plattformübergreifenden Code schreiben (Ihren Code entwerfen) eigene Abstraktion über die Plattformen, die Ihnen zur Verfügung stehen, und Implementierung dieser Abstraktion für jede Plattform).

Game - Engines wie Unreal oder Unity , die diese entweder Ihren Code gegen die entsprechende Plattform Abstraktion neu kompilieren zu unterstützen, oder Sie benötigen eine Bibliothek oder DLL gegen ihre internen APIs zu bauen, die sie von einem plattformspezifischen Treiber ausführbaren laden , die sie für die entsprechenden zusammengestellt Plattform.


quelle
2

Im Gegensatz zu den beiden anderen Antworten (die zu Recht C ++ - spezifisch sind) gibt es einen anderen Weg. Einige Architekturen, die mir in den Sinn kommen:

  • Portieren Sie Ihre Engine: Ändern oder schreiben Sie Code so, dass er plattformübergreifend funktioniert. Dies wird in den obigen Antworten angesprochen.
  • Schreiben Sie etwas über eine plattformübergreifende Bibliothek: Dies ist das Beispiel für libGDX, das auf Java ausgeführt wird. Java läuft auf Desktop, Android und iOS (über RoboVM). Wenn Sie so etwas wie Java verwenden, profitieren Sie von kostenlosen zusätzlichen Plattformen, wenn die zugrunde liegende Bibliothek / das zugrunde liegende Tool diese unterstützt. In diesem Fall "funktioniert" libGDX (fast) nur unter iOS, als RoboVM herauskam.
  • Schreiben Sie einen Code-Generator: Dies ist der Ansatz von Haxe und anderen Tools. Sie haben eine Kernsprache (z. B. Haxe / AS3) und Sie schreiben Konverter, die Ausgaben für andere Sprachen generieren. Z.B. Haxe konvertiert nach C ++ für Desktop, Java (glaube ich) für Android usw.

Persönlich finde ich den Ansatz von libGDX am einfachsten: Finden Sie eine Sprache oder Plattform, die Ihren Anforderungen entspricht, und schreiben Sie darüber. Code-Generierung und tragbare Engines sind komplex und schwer zu schreiben.

libGDX ist eine großartige Wahl, da es sowohl für große Mobiltelefone als auch für Desktops und das Internet (über Applets oder den Web-Compiler von Google) geeignet ist.

ashes999
quelle
Selbst mit Java oder C # erhalten Sie keinen plattformübergreifenden Code. Sie müssen immer noch die Bibliotheken von Drittanbietern kennen, die möglicherweise plattformabhängig sind (SlimDX oder SharpDX wären beispielsweise eine schlechte Wahl für plattformübergreifende C # -Projekte).
@JoshPetrie Du bekommst mit Sicherheit eine Menge "umsonst" im Vergleich dazu, Deine eigene C ++ - Engine zu rollen und sie über Plattformen zu portieren.
Asche999
@ ashes999 Dank für die Antwort, ist Libgdx brilliant ich es verwende , aber ich werde es schreiben , so dass es Cross - Plattform dann verwenden CMake funktioniert, ich bin mehr drin für die die Herausforderung als eine Pre vorhandenen Bibliothek oder Engine
DanielCollier
2

Momentan baue ich eine plattformübergreifende Game-Engine. Ich verwende SDL, eine hervorragende (und entsprechend niedrige) plattformübergreifende Bibliothek zum Erstellen von Grafikanwendungen, um die Schmerzen zu lindern.

Darüber hinaus gibt es jedoch jede Menge "benutzerdefinierten Code" für jede Plattform. Das musst du nur durchstehen. Ich fand, dass es ein sehr kleiner Teil meiner bisherigen Entwicklungszeit ist, und habe hauptsächlich Dokumente für Systeme nachgeschlagen, mit denen ich nicht so vertraut bin wie mit meinem nativen Linux.

Ich würde Sie davon abhalten, #ifdefüberall in Ihrem Code zu verwenden. Erstellen Sie stattdessen Abstraktionen um Schlüsselprimitive (ein Beispiel für ein solches Primitiv könnte ein TCP-Socket sein).

Wenn Sie auf ein neues Problem stoßen, das je nach Umgebung unterschiedliche Lösungen erfordert, fragen Sie sich: "Kann ich dieses Problem nur mit den plattformübergreifenden Grundelementen lösen, die ich bereits erstellt habe?" Wenn die Antwort ja lautet: voila, einfacher plattformübergreifender Code. Stellen Sie ansonsten fest, welche Grundelemente Ihnen fehlen, und implementieren Sie sie.

scpayson
quelle
0

Wenn Sie dies als Lernerfahrung "von Grund auf" tun möchten, müssen Sie die Win32-API verwenden. Dort finden Sie Informationen zum Öffnen eines Fensters und eines OpenGL-Kontexts auf MSDN und im OpenGL-Wiki ( http: // www .opengl.org / wiki / Creating_an_OpenGL_Context_ (WGL) ). Für Linux erhalten Sie eine gebrauchte Kopie des O'Reilly Xlib-Programmierhandbuchs und des Xlib-Referenzhandbuchs sowie Informationen zu GLX (OpenGL-Erweiterung für das X Window-System). Siehe auch http://www.opengl.org/wiki/Tutorial:_OpenGL_3.0_Context_Creation_(GLX)

Dann müssen Sie Ihrer Anwendung nur die gleiche API mit Funktionen bereitstellen, die dasselbe tun (z. B. ein Fenster öffnen), aber für jede Plattform unterschiedliche Implementierungen haben. Sie schreiben Teile Ihres Motors für verschiedene Plattformen neu. Dann ein Spiel, das Sie mit der Engine schreiben, müssen Sie nur einmal schreiben, aber es wird auf verschiedenen Plattformen funktionieren.


quelle
Vielen Dank für die Antwort, aber ich würde lieber nur SDL2 für die Fensterung verwenden, es ist plattformübergreifend und sehr einfach zu bedienen. Wie LibGDX LWJGL zum
Fenstern