O que é o Game loop
Já parou pra pensar no trabalho que o computador tem para mostrar, em tempo real o que está acontecendo dentro de um jogo?
Pense, por exemplo, no jogo "Desafio nas alturas" que criamos no curso Unity 2D parte 1. Nesse jogo, temos um avião sendo desenhado no meio da tela, junto com o cenário.
Acontece que isso não é uma imagem estática e, quando clicarmos na tela, queremos que o avião vá para cima.
Mas o que é preciso para isso funcionar?
Vamos por partes, se antes eu tinha um avião 10 unidades para baixo do que ele está agora, a pessoa que está jogando precisa ver essa diferença na posição assim que mudarmos. Ou seja, precisamos desenhar um avião na posição nova.
<br />principal {
desenhaOAviãoNovo();
}
Me parece que só desenhar um avião na posição nova não ajudou muito. Agora temos dois aviões na tela e fica até confuso saber qual é o avião real.
Uma forma resolver isso é apagar o pedaço da tela onde estava o avião anteriormente e depois desenhar um novo avião na posição correta.
<br />principal {
limpaOEspaçoDoAvião();
boaSorteParaDesenharOFundoNoLugarOndeApagou();
desenhaOAviãoNovo();
}
Melhorou, mas agora apagamos parte do nosso cenário junto com o avião antigo. E olha que difícil vai ser para ver exatamente quais pixels estão brancos para depois desenhar a parte correta da imagem do céu nesses pixels.
Mas espera, quem faz esse trabalho todo é o computador. Por que não apagamos a cena inteira de depois redesenhamos cada um dos elementos do nosso jogo?
Fazendo isso nós vamos ter uma tela completamente branca e nela vamos desenhar o céu, o piso e o avião nessa sequência.
<br />principal {
limpa();
desenhaBackground();
desenhaChão();
desenhaAvião();
}
Dessa forma, conseguimos desenhar o avião e o fundo do jogo juntos. E é exatamente isso que o nosso computador faz quando estamos jogando, toda vez que ele precisa mudar a posição de alguma coisa na tela, ele apaga ela inteira e redesenha todos os elementos.
Mas isso é só parte do que precisamos fazer para nosso jogo funcionar, como é que nós verificamos se nosso avião precisa ou não se movimentar?
Nesse curso, utilizamos a Unity e nela podemos criar comportamentos para nossos objetos e assim podemos verificar se o mouse está ou não sendo pressionado. Isso é comumente feito dentro do método `Update´.
<br />private void Update()
{
if (Input.GetButtonDown("Fire1"))
{
this.transform.Translate(0,10,0);
}
}
Esse código verifica quando o mouse foi pressionado e faz o avião subir 10 unidades dentro da nossa tela. E como já vimos, quando isso acontecer, precisamos desenhar a tela inteira novamente para que quem estiver jogando veja essas alterações em tempo real.
Acontece que um jogo tem muitas peças que precisam ser atualizadas e redesenhadas o tempo todo. Nesse caso do jogo "Desafio nas alturas", precisamos saber quando o mouse está pressionado e para ter certeza que não iremos perder nenhum clique, o computador está executando o método Update
o tempo todo.
Mas o que significa "o tempo todo"?
Significa que, sempre que possível, o computador vai executar a função update
dentro do script do avião e mover ele se for necessário. Importante ressaltar que é exatamente isso, sempre que possível ele vai atualizar o estado do jogo. Isso porque, se algumas dessas tarefas demorar para ser executada, vamos sentir nosso jogo lento e travando.
Essas duas tarefas - atualizar as informações dos objetos que estão na cena e redesenhar a tela - formam o que chamamos de Game loop
Dentro da fase de atualização, o computador pega cada um dos elementos do seu jogo e verifica nas "regras do jogo" se algo precisa ser mudado de posição, destruído, começar uma animação, etc.Na fase de desenho, ele seleciona todos os elementos que podem ser desenhados e redesenha a cena inteira.
Legal, nosso jogo então roda em loop mas, quão rápido é isso?
Atualmente, os jogos tem uma taxa de atualização de 30 a 60 quadros por segundo, isso significa que nosso computador deve executar esse loop inteiro de 30 a 60 vezes por segundo.
Cada volta nesse loop demora algo entre 16 e 33 milissegundos. Se nós temos muitas verificações para fazer, ou muitos objetos para serem desenhados essa volta pode demorar mais e aí sentimos o jogo travando.
No caso que vimos aqui, o desafio nas alturas, estamos utilizando a Unity, uma game engine que facilita nosso trabalho porque não precisamos nos preocupar em desenhar a cena, só precisamos atualizar as informações de cada objeto e a própria unity cuida do resto. Essa mesma abordagem é encontrada em outras *engines *como a Cocos Creator, Construct, Scratch, etc…
Em outros casos, como no P5JS ou na própria API do canvas, o responsável por apagar e desenhar a tela somos nós mesmos. O que é uma experiência interessante de se fazer e ajuda a entender um pouco melhor como o computador funciona.
Falando em diferentes engines, aqui na Alura temos cursos de Unity, Unreal engine e CocosCreator e, se você quiser conhecer o Construct ou o P5JS, pode ver os cursos da Alura Start.
Perguntas Frequentes:
O que é o Game Loop?
É o principal laço de instruções do jogo. Ele tem duas tarefas principais: atualizar as informações dos objetos que estão na cena (em especial os personagens que mudam de posição e reagem às interações do jogador) e redesenhar a tela de acordo com as informações atualizadas. Fazemos isso em um loop infinito, tomando cuidado de não gastar muito tempo, o que geraria um "lag" na tela (e queda do framerate)