Novos redatores

Criando um Videogame PONG com Arduino

Eletrogate 8 de junho de 2023

Introdução

Neste post, você vai aprender como montar e programar um jogo de videogame PONG para dois jogadores, com saída de som e imagem para TV, utilizando apenas alguns componentes eletrônicos básicos e uma placa Arduino.


Biblioteca Gráfica TVout

O videogame construído neste projeto gera imagens para TV. Portanto, estaremos utilizando a biblioteca TVout para a plataforma Arduino.

A biblioteca TVout permite a geração de um sinal de imagem de vídeo composto no padrão NTSC ou Pal, a uma resolução de 128×96 píxeis. Esta resolução pode ser definida para um valor diferente, maior ou menor, dependendo dos recursos de memória da placa Arduino que for utilizada.

A TVout pode ser utilizada em diferentes modelos de placas Arduino, mas, dependendo do modelo da placa, as conexões de saída de áudio e vídeo podem ser diferentes. Neste projeto, estaremos utilizando uma placa Arduino Nano.

Instalação

Para instalar a biblioteca TVout, acesse o menu Sketch ► Incluir Biblioteca ► Gerenciar Bibliotecas…

Procure pelo nome “TVout” e execute a instalação.
A biblioteca será instalada dentro deste caminho: “\Documents\Arduino\libraries\TVout

IMPORTANTE: Assim que a instalação terminar, abra o windows explorer e acesse o local onde foi instalada a biblioteca.
Como você pode observar, a pasta “TVoutfonts” se encontra dentro da pasta “TVout” e, desta forma, o Arduino IDE não vai conseguir encontrá-la para compilar o código.
Para corrigir isto, você precisa recortar esta pasta “TVoutfonts” e colocá-la em um nível anterior, ou seja, dentro da pasta “libraries”, de forma que, quando você estiver dentro da pasta Libraries, você possa ver tanto a pasta “TVout” quanto a pasta “TVoutfonts”.


Hardware

Para o desenvolvimento do projeto Videogame PONG com Arduino, siga o diagrama abaixo:

O hardware é composto de duas partes: a primeira é utilizada pela biblioteca TVout para a emissão do sinal de vídeo e som. A segunda é utilizada pelo jogo, propriamente dito, para ler os sinais de posicionamento dos jogadores através dos potenciômetros e ler os estados dos botões 1 e 2.

Saída de Som e Imagem

A biblioteca TVout utiliza dois resistores para a composição de seu sinal de vídeo, um resistor de 1 kOhms e outro de 470 Ohms. Para a saída de som, foi utilizado um resistor de 10 kOhms, mas poderá ser utilizado algum outro resistor com um valor pouco maior do que este.

Entrada de Dados

Para que o jogo saiba como posicionar verticalmente os jogadores, ele utiliza dois potenciômetros de 10 kOhms. Um capacitor de 10uF/25V é utilizado em cada potenciômetro, conectado entre o pino de sinal de entrada analógico e o pino GND, para filtrar o sinal, mantendo a estabilidade da posição vertical dos jogadores na tela.

Os capacitores eletrolíticos não são obrigatórios e possuem seus prós e contras:

Se você NÃO UTILIZAR os capacitores, você terá uma resposta de posicionamento vertical rápida e imediata. Porém, o jogador pode sofrer pequenas variações verticais na tela.

Se você UTILIZAR os capacitores, você terá uma estabilidade da posição vertical. No entanto, a resposta de posicionamento será um pouco mais lenta, devido à carga/descarga dos capacitores.

Os botões 1 e 2 são utilizados para indicar à Arduino quando ela deve dar início a uma partida de Treinamento (botão 1) ou uma partida de Jogador x Jogador (botão 2).


Funcionamento

Este videogame Pong é composto por dois botões de seleção, dois potenciômetros, uma saída de áudio mono e uma saída de vídeo tipo AV/RCA.

O fornecimento de energia do videogame deve ser de 5V, podendo conectar a Arduino Nano à porta USB do computador ou diretamente a um carregador de celular comum por um cabo USB.

Ao iniciar o jogo, será exibida uma tela de abertura.
A qualquer momento, o jogador pode escolher entre três opções:

  • botão 1: Reinicia o jogo em modo Treinamento;
  • botão 2: Reinicia o jogo em modo Player x Player;
  • botão 1 + botão 2 (segurar pressionado ao mesmo tempo, pelo período de 1 a 2 segundos) sai do jogo atual e volta a exibir a tela inicial.
Curto game-play demonstrando o funcionamento do videogame

Software

Para fazer o download do código do jogo, clique neste link: Eletrogate PONG (codigo Arduino).zip

Instalação
  • Extraia o conteúdo do arquivo .ZIP e abra o arquivo “Eletrogate_PONG.ino” através do Arduino IDE,
  • Conecte a Arduino NANO no computador por um cabo USB,
  • Acesse o menu Ferramentas ► Placa ► Arduino AVR Boards e escolha “Arduino Nano“,
  • Acesse o menu Ferramentas ► Processador e escolha “ATmega328p” ou “ATmega328p (Old Bootloader)“, vai depender do firmware presente em sua Arduino Nano,
  • Clique em Sketch ► Carregar ou use o atalho Ctrl + U.
Ligando o seu videogame PONG

Assim que você já tiver montado o circuito e enviado o código do jogo para sua Arduino, você já pode começar a jogar:

  • Conecte a saída de vídeo no conector AV/RCA amarelo da TV,
  • Conecte a saída de áudio no conector AV/RCA branco da TV,
  • Conecte a Arduino Nano a um cabo USB e conecte a outra ponta deste cabo USB a um carregador de celular comum e ligue na tomada.
Entendendo a lógica de funcionamento…

A programação do jogo é bem simples de entender. Vamos conferir o funcionamento de cada uma das partes através da explicação que segue logo abaixo:

Parte 1
bibliotecas e variáveis iniciais


Logo no início do código, incluímos a biblioteca “TVout.h” para geração das imagens de vídeo composto, a biblioteca “fontALL.h” que fornece à TVout as imagens das fontes de textos, e incluímos o arquivo “imagens.h” que possui as imagens gráficas que serão utilizadas ao longo do jogo para desenhar todos os elementos do cenário.

Em seguidam instanciamos um objeto da classe TVout para podermos utilizar suas funcionalidades ao longo do código. Declaramos aqui, também, algumas variáveis importantes:

  • modoDeJogo:
    0 = “sem ação”,
    1 = “modo Treinamento”,
    2 = “modo Player x Player”,
    99 = “modo Game-Over”
  • p1_posY, p2_posY:
    guardam os valores das posições verticais dos jogadores
  • p1_score, p2_score:
    guardam os valores das pontuações dos jogadores
Parte 2
desenhando as pontuações dos jogadores


A função “desenharScores” é responsável por desenhar as pontuações dos jogadores.
Ela especifica a fonte de texto que deverá ser utilizada, desenha as pontuações de cada jogador, e assim que um dos jogadores alcançar 15 pontos ela muda a variável “modoDeJogo” para 99 para indicar que o jogo terminou.

Parte 3
desenhando a quadra do jogo


A função “desenharQuadra” é responsável por desenhar a quadra utilizando diversos elementos gráficos independentes: desenha as barras horizontais superior e inferior, as quatro pequenas barras verticais nas quinas dos cantos, a rede no meio da quadra e, se estiver em modo de jogo Treinamento, desenha uma parede tampando toda a área direita da tela.

Parte 4
reiniciando o jogo em modo Treinamento


A função “reiniciarJogo_Treinamento” serve para reiniciar o jogo em modo Treinamento.

Ela volta as pontuações dos jogadores para zero, altera o modo de jogo para 1 (Treinamento), aguarda um tempo de meio segundo e depois chama a função “resetarBola(1)” para que a posição e direção da bola sejam reiniciados partindo do lado esquerdo da tela.

Parte 5
reiniciando o jogo em modo Jogador x Jogador


A função “reiniciarJogo_PlayerVsPlayer” serve para reiniciar o jogo em modo Jogador contra Jogador.

Ela volta as pontuações dos jogadores para zero, altera o modo de jogo para 2 (Player x Player), aguarda um tempo de meio segundo e depois chama a função “resetarBola(1)” para que a posição e direção da bola sejam reiniciados partindo do lado esquerdo da tela.

Parte 6
desenhando os dois jogadores na tela


A função “desenharJogadores” é responsável por desenhar os jogadores na tela.

Ele vai determinar as posições verticais de cada um dos dois jogadores através da leitura dos sinais analógicos que chegam pelas portas A0 e A1 (que variam de 0 a 1023) e mapeando estes sinais em valores inteiros proporcionais que variam entre 2 e 80 (as respectivas posições superior e inferior dos jogadores na tela).
Primeiro a função desenha o jogador 1 (esquerda), e se o modo de jogo for 2 (Player x Player) ela desenha também o jogador 2 (direita).

Parte 7
emitindo os sons do jogo


A função “tocarSom” serve para emitir uma determinada frequência sonora por um determinado período.
O tipo de som que será emitido vai depender do valor soundID que for passado como parâmetro.

Parte 8
estrutura da bola e reinício de sua posição


Os jogadores são elementos que se movimentam apenas na vertical e, por isso, precisam somente de uma variável para determinar sua posição na tela. Já a bola possui uma velocidade horizontal, velocidade vertical, posição horizontal e posição vertical. Por isso, criamos uma estrutura structBola para guardar estas informações de forma organizada em um só lugar.

A função “resetarbola” reinicia a posição e velocidade da bola conforme o valor que recebe como parâmetro. Este valor inteiro indica de qual lado da tela a bola deve partir. Se receber o valor 1, ela ajusta a posição e velocidade da bola para que ela seja lançada a partir do lado esquerdo da tela; se receber o valor 2, ela ajusta a posição e velocidade da bola para que ela seja lançada a partir do lado direito da tela.

Esta função é usada quando um modo de jogo é selecionado a partir dos botões 1 e 2 e também quando um jogador acaba de fazer um ponto.

Parte 9
desenhando a bola na tela


A função “desenharBola” é responsável por processar tudo o que diz respeito à bola.

Ela desenha a imagem da bola na tela, altera seu movimento de acordo com a sua atual velocidade horizontal e vertical, verifica se a bola acertou algum dos jogadores ou algum dos cantos da quadra para poder inverter sua velocidade horizontal/vertical, e também confere se a bola ultrapassou algum dos limites esquerdo ou direito da tela para poder marcar pontos para os jogadores.

Se o modo de jogo for 2 (Treinamento) ela vai considerar todo o lado direito como uma barreira e vai fazer com que a bola tenha sua velocidade horizontal invertida quando acertar o lado direito em qualquer posição.

Parte 10
a função Setup


A função “setup” é a funcão que é executada uma única vez sempre que o Arduino é iniciado.
Nesta função fizemos os ajustes iniciais que precisamos para o jogo funcionar:
Executamos uma função de randomização de acordo com os valores analógicos atuais, inicializamos o objeto da classe TVout em uma resolução de 128×94 píxeis, colocamos o modo de jogo como zero (sem ação), setamos os pinos dos botões 1 e 2 como entrada de dados, e desenhamos na tela a imagem de abertura do jogo.

Enquanto o modo de jogo estiver como zero a tela de abertura continuará sendo exibida e a função “loop” não irá executar nenhum comando do jogo propriamente dito.

Parte 11
a função Loop


A função “loop” é executada logo após a função “setup”, e ela é executada continuamente.
Ela lê os atuais estados dos botões 1 e 2. Se o botão 1 for pressionado ela executa a função que reinicia o jogo em modo Treinamento, se o botão 2 for pressionado ela executa a função que reinicia o jogo em modo Jogador x Jogador, se os botões 1 e 2 forem pressionados ao mesmo tempo, ela executa a função que reinicia o jogo do zero, exibindo a tela inicial.

Se o modo de jogo atual for zero (“sem ação”), a função loop cancela a execução dos próximos comandos e reinicia; se o modo de jogo atual for diferente de zero ela dá prosseguimento à execução dos próximos comandos.

A função loop também é responsável por chamar as diversas outras funções do jogo: desenharQuadra, desenharScores, desenharJogadores e desenharBola.

Ao final da função loop, verificamos se o modo de jogo é 99 (“game-Over”). Se sim, executamos uma série de comandos que irão escrever na tela quem foi o vencedor, e também vai encerrar o jogo:

  • selecionamos uma fonte de texto,
  • escrevemos o texto “– vencedor –” no centro da tela,
  • selecionamos outra fonte de texto um pouco maior,
  • conferimos qual dos jogadores possui a maior pontuação e, com base nisso, escrevemos na tela “Player 1” ou “Player 2” dependendo de quem foi o vencedor.
  • Alteramos o modo de jogo para zero (“Sem ação”).

Desta forma o jogo permanece exibindo na tela a informação de quem foi o vencedor e fica aguardando que o jogador aperte o botão 1 ou 2 para dar início a uma nova partida.


Conclusão

A construção de um videogame simples serve como exemplo para demostrar que uma placa Arduino e componentes básicos de eletrônica e programação servem para muitas outras coisas além de acender LEDs, emitir beeps, ler botões e ativar relés e motores.

É importante observar que os campos da robótica e automação residencial são bem mais importantes do que o desenvolvimento de jogos antigos, no entanto, devemos sempre explorar as mais diversas possibilidades e capacidades destes dispositivos (Componentes eletrônicos, módulos, Arduino, Esp32, Esp8266, STM32) para que novas ideias possam surgir como inovações no mercado, uma sempre complementando a outra.

A exemplo destas novas ideias temos pessoas que utilizaram esta simples biblioteca TVout para diversos projetos criativos:

  • Desenvolvimento de jogos eletrônicos simples (como este Pong);
  • Construção de um multímetro que exibe as informações na tela da TV;
  • Construção de um radar que utiliza o sensor ultrassônico HC-SR04 para ler os obstáculos à sua volta e montar uma imagem de radar na tela da TV;
  • Um projeto que lê os dados de um teclado PS2 e utiliza uma versão básica de Basic e a biblioteca TVout para funcionar como um simples computador que mostrar seus textos e comandos na tela da TV.

Sobre o Autor


Etienne Gomide

Programador e Desenvolvedor de Sistemas Embarcados. Bacharel em Sistemas de Informação pela Faculdade Federal de Viçosa (FDV). Trabalhou nas empresas CIENTEC e ORIONTEC como programador. Atua como Técnico em TI na Universidade Federal de Viçosa (UFV). Tem como passatempo o desenvolvimento de jogos e projetos para Arduino/esp8266/esp32/stm32.


Eletrogate

8 de junho de 2023

A Eletrogate é uma loja virtual de componentes eletrônicos do Brasil e possui diversos produtos relacionados à Arduino, Automação, Robótica e Eletrônica em geral.

Tenha a Metodologia Eletrogate dentro da sua Escola! Conheça nosso Programa de Robótica nas Escolas!

Eletrogate Robô

Cadastre-se e fique por
dentro de novidades!