Como devo desenvolver meu jogo Android com eficiência? [fechadas]

11

Anexei uma imagem de um fluxograma que fiz na pintura. Fluxograma do conceito de jogo

A imagem mostra como eu quero desenvolver meu jogo. Quero um jogo que funcione muito bem com codificação inteligente, fácil de atualizar e recursos de anúncios ao longo do tempo. Minha plataforma de destino é o smartphone Android e todo o código será gravado em java com recursos inflados por XML, se isso interessar. Não estou procurando por código rígido, embora o pseudo-código ajude, prefiro sugestões e conselhos dos profissionais.

Minhas perguntas são:

É uma boa maneira de programar um jogo ou existem maneiras melhores de fazer isso? Existem modificações que precisam ser feitas? Qualquer sugestão seria útil porque eu não sou experiente em programação de jogos, por isso preferiria o conselho de alguém que escreveu vários jogos e sabe por experiência própria como deve configurar o código para executar com eficiência.

kdavis8
fonte

Respostas:

12

Muitos jogos para Android não são grandes o suficiente para justificar salvar / carregar ou opções / preferências, não importa personagens personalizados e similares simplesmente porque eles são jogados de improviso por 10 minutos no trem para casa.

Não cometa o erro que cometi de embarcar em algo com um amplo escopo para um primeiro jogo Android. Faça vários jogos menores e escolha algo maior

Especificidades do Android:

Estrutura:

Eu recomendaria ter quase todo o jogo em uma classe de atividade. O Android trabalha com a ideia de que cada atividade é como um miniaplicativo, semi-independente das outras atividades no aplicativo. O aplicativo é essencialmente uma pilha de atividades, com o usuário vendo o que está no topo.

Quando você abre uma em cima, ela geralmente é destruída e será recriada na próxima vez que o usuário iniciar uma nova atividade (intenção de iniciar a atividade). Isso dificulta a manutenção de estados entre as atividades e leva a uma única arquitetura de atividades

Você pode querer ter uma atividade do tipo Tela inicial com um menu "Novo jogo / Carregar jogo / Opções", e fazer disso a atividade de inicialização. No entanto, você precisará ter um menu no jogo e também na sua atividade de jogo, que terá a maioria das mesmas funções

Em meu próprio aplicativo, criei um "MenuActivity" que possui as funções que iniciam um novo jogo, salvam, carregam, alteram opções. Em seguida, minha HomeActivity estende isso, assim como minha GameActivity.

Como tudo está em uma classe Activity, eu recomendaria fazer uma hierarquia de classes de atividade e usar lotes de escopo privados, protegidos e padrão. Fazendo dessa maneira, você pode pelo menos dividir as coisas em arquivos diferentes para não ter um arquivo de Atividade incontrolável. Por exemplo, para o meu próprio aplicativo:

GraphicsEngine extends MenuActivity.

PhysicsEngine extends GraphicsEngine.

GameLogicActivity extends PhysicsEngine.

UIActivity extends GameLogicActivity.

Como meu aplicativo é opengl-es 3D, muitas coisas que eu faço não funcionam com atividades cruzadas, então tudo está na mesma atividade, então talvez eu esteja inclinado a usar uma arquitetura de atividade

-

Rosqueamento

Para a atividade do jogo, você tem dois threads (ou 3, se estiver fazendo coisas 3D em 3D). Um segmento é a interface do usuário / segmento principal. Esse é o segmento em que a atividade é iniciada, executada e é fornecida a você pelo android.

Esse thread da interface do usuário é o único no qual você pode atualizar os elementos da interface do usuário (visualizações, layouts etc.). É também aquele em que qualquer ouvinte para entrada do usuário será executado. Você não vê nenhuma mecânica do thread da interface do usuário, apenas que ele roda em um loop em segundo plano em algum lugar.

O segundo segmento, você mesmo (eu recomendaria o uso do AsyncTask , apesar de todas as suas deficiências). Isso faz todas as coisas que não são da interface do usuário que você faz em um loop de jogo normal, como atualização de movimento, cálculo de colisões, cálculos de combate e assim por diante.

Você cria esse segmento / classe AsyncTask como uma classe interna de sua atividade. Dessa forma, você pode ter alguns objetos de escopo de atividade ( Vector<Spaceship>) que podem ser acessados ​​pelo thread da interface do usuário e pelo loop do jogo.

Como a lógica do jogo está em andamento no segmento do loop do jogo, esse é o único segmento que realmente precisará alterar os valores das variáveis ​​(atualizar a velocidade do tanque, reduzir o HP do jogador). O thread da interface do usuário apenas lê valores, portanto, deve haver problemas mínimos de simultaneidade.

A parte complicada é conseguir que o thread da interface do usuário faça atualizações a pedido do thread do loop do jogo. Há algumas maneiras de fazer isso. Se você ler a documentação do AsyncTask, ela possui o método publishProgress () / onProgressUpdate (). Na verdade, isso está adicionando coisas à fila de tarefas do thread da interface do usuário a ser executada no próximo loop.

O manipulador faz exatamente a mesma coisa, onde você implementa o método handleMessage () e esse método é realmente executado pelo próximo loop do thread da interface do usuário.

Por fim, qualquer entrada do usuário, estando no encadeamento da interface do usuário, você pode atualizar os elementos da interface do usuário imediatamente (assim, dentro da implementação de qualquer ouvinte onClick / onTouch). Se você precisar atualizar os objetos do jogo, poderá usar coisas como sincronizar ou implementar sua própria fila de atualizações no AsyncTask que, como o thread da interface do usuário, será executado na próxima vez em que executar o loop do jogo

Guia de segmentação para Android .

-

UI

Quanto à estrutura real da interface do usuário na atividade única, eu recomendo ter um layout de quadro como layout básico. Os elementos filho em um layout de quadro funcionam como uma fila. O primeiro elemento é desenhado primeiro, o segundo é desenhado em cima do primeiro, o terceiro em cima do segundo.

Dessa forma, você pode ter vários arquivos de layout XML e, gerenciando os filhos do layout de quadro, pode trocar facilmente conjuntos de visualizações dentro e fora.

Se você sempre tiver o SurfaceView na parte inferior (primeiro filho no layout do quadro), poderá usar todas as visualizações / widgets usuais do Android (botões, visualizações de texto, visualizações de rolagem) etc. sobre a parte superior da visualização de superfície, o que acontece a parte gráfica do jogo.

Por exemplo, se algo estiver carregando, você pode pausar o loop do jogo / fazer com que pule tudo, adicione uma tela opaca de 'loading' como o último filho do layout do quadro e o usuário verá 'loading' aparecer na tela , sem saber que outras visões estão por trás disso. Dessa forma, você não precisa remover visualizações que demoram muito para serem configuradas ou causam complicações cada vez que são adicionadas / removidas.

Eu também recomendaria o uso de lotes View.setVisibility. Você pode, por exemplo, adicionar um layout inteiro de 'inventário' ao layout do quadro base e, em seguida, apenas definirVisibility (View.Visible) quando o usuário clicar para visualizar seu inventário e definirVisibility (View.Gone) quando fechá-lo novamente. Dessa forma, você nem gerencia os filhos do layout do quadro, apenas adiciona tudo e torna as coisas visíveis / invisíveis quando e quando o usuário faz coisas diferentes

Isso ajuda a enfiar novamente; à medida que o usuário clica para abrir seu inventário, o onCLickListener é tratado no encadeamento da interface do usuário, o inventário é visível nele e o método updateInventory é chamado, novamente a partir do encadeamento da interface do usuário, com apenas getters em todos os objetos do jogo chamados

Aqui está o diagrama que fiz para uma pergunta anterior sobre a idéia de layout de atividade / quadro único:

insira a descrição da imagem aqui

Spoon Thumb
fonte
Então, na sua opinião, eu deveria ter um layout de quadro para armazenar todos os componentes do loop do jogo, certo? Se eu fizesse isso, como obteria visualizações na classe HUD para ter interatividade com o SurfaceView, por exemplo, um d-pad virtual / analógico virtual? Eu tentei fazer coisas assim antes e tive erros.
precisa saber é o seguinte
Vou reescrever minha resposta para torná-la um pouco mais clara
Spoon Thumb
Reescrevi minha resposta. Espero que isso fique mais claro
Spoon Thumb
Muito obrigado para a repartição que realmente soletra as coisas, um monte há realmente amável de bons tutoriais lá fora, para o desenvolvimento do jogo android
kdavis8
11

Muito do que vejo no seu diagrama está relacionado à interface do usuário, e isso parece bastante razoável. Há apenas uma pequena parte do seu diagrama reservada para a lógica real do jogo, e isso é muito vago.

Eu acho que você está se esforçando demais. Eu sugiro que você comece a escrever o código. Escolha um problema específico e comece a resolvê-lo. Você aprenderá tanto que, quando tiver uma idéia melhor de qual é o espaço do problema, terá uma perspectiva completamente diferente (e mais útil).

entalhe
fonte
2
Eu não poderia concordar mais com isso. Escolha uma arquitetura de design que se adapte ao jogo e à sua preferência e comece a codificar. Quando você encontrar um problema específico de desempenho, otimize até que ele funcione. Cada mecanismo individual do seu jogo terá suas próprias características de desempenho e possíveis otimizações - você deve pensar neles individualmente, não como um todo.
Polynomial
onde encontrar um guia para esses padrões de arquitetura de jogos? Seria realmente útil para mim.
24512 bot_bot