¿Cómo puedo ejecutar en múltiples plataformas usando un motor personalizado?


13

Los motores de juego como Unity e Unreal pueden ejecutarse en múltiples plataformas. Me pregunto cómo hacen esto.

He estado usando C ++ y OpenGL durante un tiempo, y lo que estoy buscando son recursos para integrar algo que me permita ejecutar en diferentes plataformas sin tener que volver a escribir. Algo así como LibGDX donde escribes código usando una API base y luego la API lo convierte a HTML, Android, iOS, etc. Soy consciente de que puedo usar otro motor en lugar de escribir el mío, pero estoy interesado en la experiencia de aprendizaje.

Respuestas:


26

Puerto su motor a cada plataforma. No tiene nada de especial. Si tiene algún código que es solo de Windows, agregue alguna lógica #ifdef en el archivo o agregue un segundo archivo (para que tenga FooWindows.cppy / FooLinux.cppo lo que sea) que implemente esa característica en los otros SO que le interesan .

El material de publicación con un solo clic que tiene un motor como Unity está permitido porque el usuario final nunca modifica Unity. Simplemente está escribiendo scripts y datos, por lo que el motor tiene binarios preconstruidos para todas las plataformas y el botón de publicación solo agrupa esos binarios junto con los datos.

Otros motores dependen de sistemas de compilación y compiladores cruzados para crear el juego compilado cuando sea necesario, tal como lo haría con cualquier aplicación multiplataforma que no sea un juego.

Para cosas como HTML5, existen herramientas como emscripten que pueden compilar una aplicación C ++ para ejecutarse en JavaScript. Básicamente, solo necesita hacer otro puerto de su motor para emscripten (ya que no puede usar ninguna biblioteca / función arbitraria de C ++).

No tiene que reescribir todo el juego, pero definitivamente tendrá que hacer mucho trabajo de desarrollo, codificación y portabilidad para cada nueva plataforma que desee admitir.


14
En mi experiencia trabajando con software de plataforma cruzada (el proyecto más grande sería HotSpot), realmente desea evitar que se arrojen ifdefs a través del código. Definitivamente es mejor tener algo como share/os/<linux>(o share/cpu/x86) y poner todo el código específico de la plataforma allí y luego hacer inclusiones condicionales. Eso es al menos lo que hacen gcc, HotSpot y el kernel de Linux (ciertamente, no es una regla difícil). Sí, puede comenzar con una sola función que depende de la plataforma y pensar que es exagerada, pero nunca se queda así y de lo contrario se convierte en un desastre rápidamente.
Voo

14

No hay una bala mágica aquí. Si desea que su juego se ejecute en múltiples plataformas, debe escribir código para múltiples plataformas (o aprovechar las bibliotecas de terceros que ya lo hacen por usted).

Las cosas que está pidiendo no se alinean: usted dice (el énfasis es mío)

lo que estoy buscando son recursos para integrar algo que me permita ejecutar en diferentes plataformas sin tener que volver a escribir

pero también eso (énfasis mío otra vez)

Soy consciente de que puedo usar otro motor en lugar de escribir el mío, pero estoy interesado en la experiencia de aprendizaje .

Tendrá que hacer uno u otro: elija usar una biblioteca, motor y / o cadena de herramientas de terceros que le brinde soporte multiplataforma, o cree el suyo escribiendo código multiplataforma (diseñe su abstracción propia sobre las plataformas que tiene disponibles e implementación de esa abstracción para cada plataforma).

Los motores de juego como Unreal o Unity que admiten esto vuelven a compilar su código contra la abstracción de plataforma apropiada, o requieren que construya una biblioteca o DLL contra sus API internas, que cargan desde un ejecutable de controlador específico de plataforma que han compilado para el apropiado plataforma.


2

Al contrario de las otras dos respuestas (que con razón son específicas de C ++), hay otra forma. Algunas arquitecturas que vienen a la mente:

  • Transmita su motor: modifique o escriba código para que funcione en múltiples plataformas. Esto se aborda en las respuestas anteriores.
  • Escriba algo sobre una biblioteca multiplataforma: este es el ejemplo de libGDX, que se ejecuta en Java. Java se ejecuta en escritorio, Android e iOS (a través de RoboVM). Al usar algo como Java, obtienes el beneficio de plataformas adicionales gratuitas cuando la biblioteca / herramienta subyacente las admite. En este caso, cuando salió RoboVM, libGDX (casi) "simplemente funciona" en iOS.
  • Escriba un generador de código: este es el enfoque de Haxe y otras herramientas. Tiene un idioma principal (por ejemplo, Haxe / AS3) y escribe convertidores que generan resultados para otros idiomas. P.ej. Haxe convierte a C ++ para escritorio, Java (creo) para Android, etc.

Personalmente, creo que el enfoque de libGDX es el más simple: encuentre un lenguaje o plataforma que satisfaga sus necesidades y escriba en la parte superior. La generación de código y los motores portátiles son complejos y difíciles de escribir bien.

libGDX es en realidad una gran opción, ya que afecta tanto a los principales teléfonos móviles, computadoras de escritorio como a la web (a través de applets o el compilador web de Google).


Incluso con Java o C #, no obtienes código multiplataforma mágicamente; aún debe conocer las bibliotecas de terceros que pueden tener dependencias de plataforma (por ejemplo, SlimDX o SharpDX sería una mala elección para un proyecto C # multiplataforma).

@JoshPetrie ciertamente obtienes mucho "gratis" en comparación con rodar tu propio motor C ++ y portarlo a través de plataformas.
ashes999

@ ashes999 gracias por la respuesta, libGDX es brillante. Lo uso, pero lo escribiré para que funcione multiplataforma y luego use CMake, estoy más preparado para el desafío que usar una biblioteca o motor preexistente
DanielCollier

2

Estoy construyendo un motor de juego multiplataforma en este momento. Estoy usando SDL, que es una biblioteca multiplataforma excelente (y de nivel adecuado) para crear aplicaciones gráficas, para aliviar el dolor.

Más allá de esto, sin embargo, hay una gran cantidad de "código personalizado" para cada plataforma. Esto solo tienes que pasarlo. He descubierto que es una fracción muy pequeña de mi tiempo de desarrollo hasta ahora, principalmente dedicado a buscar documentos para sistemas con los que no estoy tan familiarizado como mi Linux nativo.

Te desanimaría de usar en #ifdeftodas partes a lo largo de tu código. En cambio, cree abstracciones alrededor de las primitivas clave (un ejemplo de tal primitiva podría ser un socket TCP).

Cuando encuentre un nuevo problema que requiera diferentes soluciones por entorno, pregúntese "¿puedo resolver este problema usando solo las primitivas multiplataforma que ya he construido?" Si la respuesta es sí: voila, código simple multiplataforma. De lo contrario, descubra qué primitivas se está perdiendo e impleméntelas.


0

Si desea hacer esto "desde cero" como una experiencia de aprendizaje, deberá utilizar la API Win32, donde puede encontrar información sobre cómo abrir una ventana y un contexto OpenGL en MSDN y en la wiki de OpenGL ( http: // www .opengl.org / wiki / Created_an_OpenGL_Context_ (WGL) ). Para Linux, obtenga una copia de segunda mano del Manual de programación O'Reilly Xlib y el Manual de referencia de Xlib y también lea en GLX (OpenGL Extension to the X Window System). Ver también http://www.opengl.org/wiki/Tutorial:_OpenGL_3.0_Context_Creation_(GLX)

Entonces solo necesita proporcionar la misma API a su aplicación con funciones que hagan lo mismo (por ejemplo, abrir una ventana) pero que tengan implementaciones diferentes para cada plataforma. Reescribe partes de su motor para diferentes plataformas. Luego, un juego que escribes usando el motor solo tienes que escribir una vez, pero funcionará en diferentes plataformas.


gracias por la respuesta, pero prefiero usar SDL2 para ventanas, su plataforma cruzada y muy fácil de usar. cómo LibGDX usa LWJGL para ventanas
DanielCollier
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.