Inicio     |     Sobre     |     GitHub     |     Games     |     Contato                        

segunda-feira, 18 de janeiro de 2021

Devlog #01: T-Rex Game - O Infinite Runner da Google




    T-Rex Game é um jogo de Infinite Runner disponível no navegador Google Chrome, o jogo ficou popular pois era disponibilizado a um usuário sempre que a internet caía, como uma forma de mantê-lo ativo no navegador até que pudesse voltar a seu uso. Atualmente o jogo já foi recriado e usado para a aplicação de IA. Hoje vamos criar uma versão nossa do jogo para a aplicação de testes e desafios para nossos sistemas inteligentes.
    


    Para o desenvolvimento vamos usar o Unity e a linguagem de programação C#. Em suma, o jogo trata de controlar um dinossauro pulando e abaixando, enquanto ele corre sem parar adiante. Com isso, o jogador deve desviar de obstáculos como cactus e pterodátilos. Quanto mais adiante o jogador chega, mais difícil o jogo fica, aumentando a velocidade de movimento e o tamanho e número de obstáculos.




Figura 1 - Screenshot tirada do jogo original.

O jogo pode ser econtrado aqui: http://www.trex-game.skipser.com/

    Primeiro, recriamos de forma bem simples alguns dos principais elementos do jogo. Utilizando o Gimp, recriei o dinossauro e os pterodátilos. Atenção, esse artigo não é um tutorial, portanto se você for um iniciante pode ter algumas dificuldades ao tentar reproduzi-lo.


Figura 2 - Dino abaixado. (Desenhado usando o Gimp).

    Para fazer o cenário, irei usar alguns assets disponibilizados por Kenny <https://www.kenney.nl/>, cujos links podem ser encontrados na lista abaixo:

      Vale ressaltar que os assets são todos disponibilizados sobre a licença C00, domínio público.

    Muito bem, agora vou montar um cenário simples de exemplo, para ter uma noção de todos os elementos possivelmente presentes no jogo (como pode ser visto na Figura 3).


Figura 3 - Primeira imagem do jogo com elementos disponíveis.

    Antes de começarmos a mexer com a lógica e o desenvolvimento, vale deixar alguns adendos. Primeiramente, para o controle estarei usando o novo Input System do Unity. Um excelente artigo para aprender a usá-lo de forma básica pode ser visto aqui <https://www.raywenderlich.com/9671886-new-unity-input-system-getting-started>. Configure os inputs conforme preferir, lembrando que fora a UI, teremos apenas 2 ações possíveis.


Figura 4 - Configuração dos Inputs.

Agora vamos para a lógica do jogo; Como todo jogo desse estilo, e de estilos similares, a lógica consiste no personagem parado e no ambiente correndo para trás enquanto é gerado a frente. Como esse jogo em específico usa gráficos 2D e é no estilo plataforma, o player/bot deve estar fixado no eixo X e liberado para se mover apenas no eixo Y (para cima e para baixo). Logo, o chão que como de costume, vamos chamar pelo seu nome em inglês (floor) deve ser dividido em partes e suas partes serão prefabs (objetos pré-fabricados). Esses devem ser destruídos ao sair da tela e construídos ao entrar, e devem se mover para trás, no eixo/direção X negativo. Para isso criei um objeto vazio ao qual adicionei apenas um box collider.

    Depois disso, criei animações para o dinossauro, todas bem simples. E para o controle das animações usei uma pequena máquina de estados (Figura 5). São usados ao todo cinco parâmetros (GameIsPlay, Jump, OnFloor, isAlive, Down) para controlar cinco estados (idle, runner, down, jump, die).


Figura 5 - Máquina de estados de animações do dinossauro.

A lógica da máquina de estados é a seguinte:

  • Quando o jogo inicia o estado muda para runner;
  • Se o jogador pressiona pular, o estado muda para jump, até que o dinossauro toque o chão, assim voltando para runner;
  • Se o jogador pressiona abaixar, o estado muda para down, até que a animação acabe, assim voltando para o estado runner;
  • Se o dinossauro tocar qualquer armadilha, o estado muda para die;

    Posteriormente fiz algumas alterações nos controles, adicionando a possibilidade de pausar o jogo e aumentar e diminuir a velocidade do ambiente, mas podem ignorar isso se quiserem, pois é apenas alguns adicionais que podem ser úteis posteriormente. 

Agora vamos aos códigos, primeiro desenvolvi um código simples capaz de mover qualquer objeto constantemente em determinada direção (Código 1), também criei um código para o objeto vazio fixo em um ponto da tela, cujo objetivo é destruir qualquer objeto que saia da tela (Código 2). Em seguida, desenvolvi o código (Código 3) para os controles do player, lembrando que estamos usando o novo sistema de Inputs. E por fim, vemos um dos códigos mais importantes de qualquer tipo de jogo, o GameManager (Códigos 4, 5, 6 e 7). O GameManager é onde encontramos toda lógica de funcionamento do jogo, as mecânicas etc.


Código 1 -  ObjectMoveDinoRunner.cs


Código 2 - ObjectsDestroyALGC.cs


Código 3 - ControllerDinoRunner.cs


Código 4 -  EnvironmentManagerDinoRunner.cs (Variáveis em uso)


Código 5 -  EnvironmentManagerDinoRunner.cs (Start and Update)


Código 6 -  EnvironmentManagerDinoRunner.cs (Instanciando novos objetos)


Código 7 -  EnvironmentManagerDinoRunner.cs (Pause e Restart)

    Um adicional que fiz, foi o algoritmo que chamei de BufferMemoryData (Código 8), onde coloquei apenas uma variável e o coloquei para não ser destruído de modo a sempre salvar a variável enquanto estiver no jogo. Esse é um código temporário apenas para salvar a melhor pontuação mesmo depois de morrer e reiniciar o jogo.

Código 8 - BufferMemoryData.cs

Para tudo funcionar, o Código 1 deve estar dentro de todos os objetos que se movimentam, no caso o chão, os cactos e os pterodáctilos. Esses objetos devem estar travados no eixo Y, de modo que não podem mudar sua altura, apenas se movem no eixo X. Fiz o código de forma que caso os eixos do objeto estejam trocados, é possível selecionar o eixo correto que moverá o objeto na direção X menos. Lembrando que todos os objetos devem ter um colisor, e o objeto que os destrói deve ter também um corpo rígido.


Figura 8 - Inspector de objetos que se movem e seleção da direção correta, levando em conta que eles se moverão apenas para o X -.

    Por fim, atenção ao ajuste do GameManager (Figura 9), não esqueça de referenciar os objetos. E cuidado com a física (força e gravidade) do salto do jogador.


Figura 7 - GameManager

    Por fim, a interface pode ser feita a gosto de cada um, no meu caso, fiz algumas indicações para os controles e criei uma área para a pontuação e uma área onde posteriormente ficarão os Outputs do jogo e dos sistemas que irão jogar.


Figura 8 - UI Menu

    Na continuação desse mini projeto, vamos fazer alguns ajustes, como na altura do salto, criar e adicionar novos prefabs de cactos, e salvar os dados de pontuação. Também começaremos a pensar no jogo como um game não apenas para seres humanos, mas também para os sistemas inteligentes (ou inteligências artificiais como são popularmente conhecidos). Com isso, vamos desenvolver um esquema de sensores para que seja possível colocarmos algoritmos inteligentes para jogar esse game. E ao final do desenvolvimento vou disponibilizar o projeto e o jogo completo para download.

    Nas próximas semanas, vamos aproveitar algumas lógicas desse minigame para desenvolver outro jogo muito parecido, que ficou popular graças ao jogo Flappy Bird. Assim teremos dois diferentes ambientes para aplicar os testes de nossas IAs. Gostou desse artigo? Deixe suas dúvidas, comentários e dicas. Até a próxima!!


Creative Commons License

Um comentário:

  1. Thank you for your comment. Follow for more articles on this topic. Check out my website with posts in English https://carolsalvato.com/index.php/blog/

    ResponderExcluir