Um thread separado para loop de jogo é obrigatório para jogos simples?

10

Eu sou novo no desenvolvimento de jogos. Para aprender, estou recriando este jogo na plataforma Android. Você pode observar o vídeo do jogo no link acima. É um jogo simples.

Eu li muitos artigos sobre como começar o desenvolvimento de jogos. Quase todos eles recomendaram o uso de um loop de jogo em um thread separado, o que faz sentido para outros jogos. No entanto, para este jogo em particular, preciso iniciar um segmento separado?

jin
fonte
Não tenho certeza se isso é uma duplicata, pois se trata do Android. Há algumas outras considerações sobre o encadeamento em uma plataforma baseada em Java que são diferentes dessa pergunta.
6608 Sean Mayledleditch

Respostas:

8

Um loop de jogo é geralmente recomendado porque é simples . Quase qualquer jogo pode ser desenvolvido e executado adequadamente utilizando um loop, e a maioria dos jogos exigiria um para funcionar adequadamente.

Por exemplo, a maioria dos mecanismos de física exige atualizações constantes confiáveis ​​para uma simulação adequada. Animações e outros conteúdos e gráficos dinâmicos precisam ser atualizados a cada alteração, etc.

Agora esteja ciente de que seu loop não precisa ser executado em um thread separado. De fato, a maioria dos jogos executa o loop no thread principal por simplicidade. Até meus projetos para Android seguem esse princípio.

Agora, a verdadeira questão aqui é qual alternativa você propõe? Se você tem outra idéia de como obter informações com segurança, fazer atualizações e desenhar molduras que funcionem para você, então vá em frente! Caso contrário, um loop de jogo pode ser a maneira mais fácil de começar.


fonte
A alternativa que estou pensando é atualizar a tela usando o thread principal em si, já que todas as ações são em série - o jogador passa pelas bolas da mesma cor e todas as bolas tocadas desaparecem, as bolas restantes caem sob gravidade junto com as bolas de reposição.
jin
Então você não está perguntando se um loop é necessário? Sua principal preocupação é se ele precisa estar em um thread separado, correto?
AturSams
1
corrigir. minha pergunta é sobre thread e não o loop. para um jogo tão simples (embora eu tenha sorte de poder fazer esse jogo), preciso gerar um novo tópico ou tudo pode ser feito no tópico principal?
jin
1
Não, não é necessário. Contanto que você tenha um loop , não será necessário criar um segundo loop .
@jin você realmente deve mudar o título e como você escreve sua pergunta então.
precisa
5

Não , um encadeamento separado não é necessário. Se você não estiver fazendo algo muito intenso (o que não parece ser o caso no jogo que você nos mostrou), tudo pode ser feito no tópico principal.

Um segundo encadeamento é necessário se você estiver processando muito ou enfrentando problemas com a interface do usuário / entrada que não responde. Por exemplo, em jogos mais complexos, você não deseja que a interface do usuário / entrada pare de responder quando a IA estiver calculando sua próxima jogada. Como seu jogo parece responder principalmente à entrada do usuário e à atualização de recursos visuais, não é necessário um segundo segmento.


Respondendo à pergunta original "É necessário um loop".

Não , mas as alternativas são mais complicadas, mais difíceis de implementar e raramente usadas.

Os jogos são por definição interativos. No mínimo, isso está aguardando entrada e atualização de saída. A maneira mais simples de fazer isso é com um loop. Não é necessário gerar um novo tópico para isso.

Mesmo que o jogo que você mencionou pareça simples, ele possui visuais e sons interativos e atualiza constantemente aqueles com base nas informações do usuário.

Também não há muitas alternativas para um loop de jogo. Algum tipo de sistema baseado em interrupção pode ser possível. No entanto, esses sistemas aumentam a complexidade e reduzem outros fatores, como o determinismo. Há uma razão pela qual os loops de jogos são tão comuns, são fáceis de implementar, fáceis de entender, flexíveis e fazem um ótimo trabalho.

MichaelHouse
fonte
A única vez que encontrei interrupções de nível inferior foi quando uma determinada tarefa de HW foi concluída e a CPU / OS precisava ser notificada para que pudessem processá-la adequadamente (lendo os dados do disco na memória e depois sendo avisada de que está pronta para que pudéssemos retornar). controlar o aplicativo e permitir que ele seja processado) para que eu não saiba o que você quer dizer e simplesmente o interprete mal.
AturSams
2

Resposta à pergunta real (um loop do jogo precisa estar em um segmento separado):

A razão pela qual as pessoas geralmente recomendam o uso de um encadeamento separado é porque não desejam que o processamento pesado interfira na interatividade da interface do usuário. Você é o único que pode dizer se é necessário um segmento separado para o seu jogo. Depende inteiramente do mecanismo e da estrutura se o loop principal do jogo em seu design atual pode interferir no tempo de resposta da interface do usuário. Pensei que você geralmente assume que não vai (em pequenos projetos), a menos que você tenha um motivo para pensar de outra forma.

Outro motivo para manter o código em threads separados é manter o código modular e simples. A combinação de dois pedaços de código não relacionados pode fazer com que o código se torne menos legível e mantenível a longo prazo.

Um loop de jogo precisa ser executado em seu próprio segmento separado? Possivelmente. Se houver um problema com o tempo de resposta ou o código e você precisar de vários itens da interface do usuário para responder, independentemente do processamento pesado, ou simplesmente desejar dividir o código em tarefas específicas que ocorrem simultaneamente por motivos de design, siga-o. No entanto, é considerada uma prática de programação avançada .

Um exemplo simples, mas talvez não ótimo, para ilustrar é um jogo para dois jogadores. Você pode executar duas instâncias de uma classe que lida com a entrada do usuário e converte em alterações de estado na instância do personagem do jogador.

Algumas estruturas incentivam / exigem que você utilize um sistema baseado em evento / interrupção, como o ActionScript3.0. Nesse caso, o código do loop normalmente irá para o OnEnterFrameevento ou algo semelhante que ocorre 20 - 60 ou 120 vezes por segundo.


Resposta à pergunta original (Preciso de um loop principal):

Tudo se resume ao contador do programa . Se você estiver criando um jogo que funcionará mais do que um tempo predeterminado e não gerará código, então será necessário solicitar ao PC do usuário que repita algumas instruções que ele já processou e o que possivelmente será alterado. enquanto isso é o estado (os valores armazenados nos objetos e globais do jogo).

Como você sabe que precisará repetir as instruções, existem várias maneiras de concluir esta tarefa e processar continuamente as mesmas instruções. Todos esses métodos envolvem mover o contador do programa de volta à instrução atualmente relevante. As instruções de fluxo de controle mais comuns que fazem com que o código seja repetido são chamadas de loops, outra é a gotoinstrução que raramente é usada no código moderno e tem um efeito semelhante nesse caso (completamente não relevante para você).

Então, para responder à sua pergunta anterior, você precisa de um loop? Sim você faz.

AturSams
fonte
1
Tanto quanto eu sei, estruturas baseadas em eventos, como o AS3, ainda possuem um loop de jogo por baixo. Estou falando de interrupções de nível inferior, não de uma estrutura que implemente um sistema de eventos.
Michaelhouse
Hmm ... não acho que as pessoas usem interrupções de nível mais baixo nos jogos. AFAIK são usados ​​principalmente pela CPU para monitorar operações de E / S. Eu estava pensando em uma abstração de nível superior como uma prática de design, em que você responde à entrada do usuário ou à atividade de hardware (sem pesquisa), em vez de executar várias instruções a cada quadro e depois pedir ao HW para renderizar o resultado.
AturSams
1
Sim, muitas vezes as pessoas não as usam mais. Como eu disse, eles são mais difíceis de usar e temos maneiras muito melhores de fazer as coisas agora. Entendo o que você está dizendo, e certamente é uma maneira diferente de pensar nas coisas, mas é apenas na superfície que parece diferente, por baixo do mesmo tipo de loop.
Michaelhouse
Concordo com o @ Byte56, que se resume a um loop, a menos que estejamos falando de eventos no nível do kernel que usam interrupções de E / S.
precisa
1
Eu sei disso, mas quase tudo o que fazemos é o mesmo abaixo da superfície (como eu disse, alterando o valor do contador de programa). Isso não é segredo e eu apontei na resposta. A programação baseada em eventos é aparentemente diferente porque movemos o contador do programa para diferentes funções quando ocorrem diferentes eventos. Obviamente, é provável que haja uma pesquisa de loop para verificar se esses eventos ocorreram recentemente, mas, como princípio de design, é aparentemente diferente.
AturSams 14/03
0

Apenas para adicionar as respostas de outras pessoas aqui, algo que ninguém mencionou explicitamente: Se você correr o risco de executar o loop do jogo em um segundo segmento e ele não responder, você corre o risco de o SO encerrar seu aplicativo. É por isso que é recomendável usar um thread separado. Portanto (por exemplo), os NDKs native_app_glue.c/ .hgeram um thread separado para o seu loop.

Engenheiro
fonte