Como posso executar em várias plataformas usando um mecanismo personalizado?


13

Motores de jogos como Unity e Unreal podem rodar em várias plataformas. Eu estou querendo saber como eles fazem isso.

Uso o C ++ e o OpenGL há algum tempo, e o que estou procurando são recursos para integrar algo que me permita executar em diferentes plataformas sem reescrever. Algo como LibGDX, em que você escreve código usando uma API base e, em seguida, a API o converte em HTML, Android, iOS etc. Estou ciente de que posso usar outro mecanismo em vez de escrever o meu, mas estou interessado na experiência de aprendizado.

Respostas:


26

Portar seu mecanismo para cada plataforma. Não há nada de especial nisso. Se você tiver algum código somente para Windows, adicione alguma lógica #ifdef no arquivo ou adicione um segundo arquivo (para que você tenha FooWindows.cppe FooLinux.cppou qualquer outra coisa) que implemente esse recurso nos outros SOs de seu interesse .

O material de publicação com um clique que um mecanismo como o Unity possui é permitido porque o próprio Unity nunca é modificado pelo usuário final. Você está apenas escrevendo scripts e dados, para que o mecanismo tenha binários pré-criados para todas as plataformas e o botão publicar apenas agrupe esses binários com os dados.

Outros mecanismos contam com sistemas de compilação e compiladores cruzados para criar o jogo compilado quando necessário, assim como você faria com qualquer aplicativo de plataforma cruzada que não seja de jogo.

Para coisas como HTML5, existem ferramentas como emscripten que podem compilar um aplicativo C ++ para executar em JavaScript. Você basicamente precisa criar outra porta do seu mecanismo para emscripten (já que ele não pode usar nenhuma biblioteca / recurso C ++ arbitrário).

Você não precisa reescrever todo o jogo, mas definitivamente precisará fazer muito trabalho de desenvolvimento, codificação e portabilidade para cada nova plataforma que deseja oferecer suporte.


14
Na minha experiência de trabalho com software de plataforma cruzada (o maior projeto seria o HotSpot), você realmente deseja evitar a ocorrência de ifdefs no código. Definitivamente, é melhor ter algo como share/os/<linux>(ou share/cpu/x86) e colocar todo o código específico da plataforma e fazer inclusões condicionais. É pelo menos o que o gcc, o HotSpot e o kernel do Linux fazem (não é uma regra difícil). Sim, você pode começar com apenas uma única função que depende da plataforma e acha que é um exagero, mas nunca permanece assim e se torna uma bagunça rapidamente caso contrário.
Voo

14

Não há bala mágica aqui. Se você deseja que seu jogo seja executado em várias plataformas, é necessário escrever um código para várias plataformas (ou aproveitar as bibliotecas de terceiros que já fazem isso por você).

As coisas que você está pedindo não se alinham: você diz (grifo meu)

o que estou procurando são recursos para integrar algo que me permita executar em diferentes plataformas sem reescrever

mas também isso (grifo meu novamente)

Estou ciente de que posso usar outro mecanismo em vez de escrever o meu, mas estou interessado na experiência de aprendizado .

Você precisará fazer uma ou outra: optar por usar uma biblioteca, mecanismo e / ou cadeia de ferramentas de terceiros que forneça suporte para várias plataformas para você, ou criar seu próprio código de plataforma cruzada (projetando seu própria abstração nas plataformas disponíveis e implementando essa abstração para cada plataforma).

Mecanismos de jogo como Unreal ou Unity que oferecem suporte a isso recompilam seu código na abstração de plataforma apropriada ou exigem que você construa uma biblioteca ou DLL contra suas APIs internas, carregadas a partir de um driver específico da plataforma executável que eles compilaram para o apropriado plataforma.


2

Ao contrário das outras duas respostas (que são legitimamente específicas de C ++), existe outro caminho. Algumas arquiteturas que vêm à mente:

  • Portar seu mecanismo: modifique ou escreva código para que ele funcione em várias plataformas. Isso é abordado nas respostas acima.
  • Escreva algo acima de uma biblioteca de plataforma cruzada: Este é o exemplo da libGDX, que roda em Java. O Java é executado no Desktop, Android e iOS (via RoboVM). Ao usar algo como Java, você obtém o benefício de plataformas adicionais gratuitas quando a biblioteca / ferramenta subjacente as suporta. Nesse caso, quando o RoboVM foi lançado, o libGDX (quase) "simplesmente funciona" no iOS.
  • Escreva um gerador de código: esta é a abordagem do Haxe e de outras ferramentas. Você tem um idioma principal (por exemplo, Haxe / AS3) e escreve conversores que geram saída para outros idiomas. Por exemplo. Haxe converte em C ++ para Desktop, Java (eu acho) para Android, etc.

Pessoalmente, acho que a abordagem da libGDX é a mais simples: encontre uma linguagem ou plataforma que atenda às suas necessidades e escreva por cima. A geração de código e os mecanismos portáteis são complexos e difíceis de escrever bem.

O libGDX é na verdade uma ótima opção, pois atinge os principais telefones celulares, computadores e web (por meio de applets ou compilador da web do Google).


Mesmo com Java ou C #, você não obtém código de plataforma cruzada magicamente; você ainda precisa conhecer as bibliotecas de terceiros que podem ter dependências de plataforma (por exemplo, SlimDX ou SharpDX seria uma má escolha para um projeto C # de plataforma cruzada).

@ JoshPetrie, você certamente ganha muito "de graça" em comparação com o lançamento de seu próprio mecanismo C ++ e a portabilidade entre plataformas.
ashes999

@ ashes999 obrigado pela resposta, libGDX é brilhante Eu uso, mas vou escrevê-lo para que funcione em várias plataformas e depois use o CMake, estou mais envolvido com o desafio do que usar uma biblioteca ou mecanismo pré-existente
DanielCollier

2

Estou criando um mecanismo de jogo multiplataforma no momento. Estou usando o SDL, que é uma excelente (e adequadamente baixa) biblioteca de plataforma cruzada para a criação de aplicativos gráficos, para aliviar a dor.

Além disso, porém, há muitos "códigos personalizados" para cada plataforma. Você só precisa passar por isso. Descobri que essa é uma fração muito pequena do meu tempo de desenvolvimento até agora, a maior parte do tempo gasto procurando documentos para sistemas com os quais não estou tão familiarizado quanto meu Linux nativo.

Eu desencorajaria você a usar #ifdef qualquer lugar do código. Em vez disso, crie abstrações em torno das primitivas principais (um exemplo dessa primitiva pode ser um soquete TCP).

Quando você encontrar um novo problema que exija soluções diferentes por ambiente, pergunte a si mesmo "posso resolver esse problema usando apenas os primitivos de plataforma cruzada que eu já construí?" Se a resposta for sim: voila, código simples de plataforma cruzada. Caso contrário, descubra quais primitivas estão faltando e as implemente.


0

Se você quiser fazer isso "do zero" como uma experiência de aprendizado, precisará usar a API do Win32, onde poderá encontrar informações sobre como abrir uma janela e um contexto OpenGL no MSDN e no wiki do OpenGL ( http: // www .opengl.org / wiki / Creating_an_OpenGL_Context_ (WGL) ). Para Linux, obtenha uma cópia em segunda mão do Manual de Programação O'Reilly Xlib e do Manual de Referência Xlib e também leia o GLX (extensão OpenGL ao sistema X Window). Veja também http://www.opengl.org/wiki/Tutorial:_OpenGL_3.0_Context_Creation_(GLX)

Então você só precisa fornecer a mesma API para seu aplicativo com funções que fazem a mesma coisa (por exemplo, abrir uma janela), mas que possuem implementações diferentes para cada plataforma. Você reescreve partes do seu mecanismo para diferentes plataformas. Em um jogo que você escreve usando o mecanismo, você só precisa escrever uma vez, mas funcionará em plataformas diferentes.


obrigado pela resposta, mas eu prefiro usar o SDL2 para janelas, sua plataforma cruzada e muito fácil de usar. exatamente como LibGDX usa LWJGL para janelas
DanielCollier
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.