Olá, como estão? Hoje iremos desenvolver um jogo chamado Genius com um Arduíno UNO, para isso irá ser usado o KIT iniciante com Arduíno UNO da WJ Componentes.
Componentes Utilizados
OU
Funcionamento do Projeto Jogo Genius
A principio iremos desenvolver no Arduíno UNO, um jogo chamado Genius, caso não conheça clique aqui para ver um vídeo.
Montagem do Projeto Jogo Genius
Logo após compra dos componentes na WJ Componentes, vamos à montagem! Em seguida conectamos os LEDs na protoboard com os resistores que ligamos nos catodos dos LEDs. Portanto para finalizar ligamos o anodo dos LEDs nos pinos 2 , 3, 8 e 9 do Arduíno UNO. Do mesmo modo conectamos os botões na protoboard e ligamos o GND de um lado e do outro ligamos nos pinos 4, 5, 6 e 7 do Arduíno UNO. Sendo assim para finalizar ligamos o GND do Arduíno UNO na protoboard.
Obs.: Cuidado ao conectar os botões, dependendo a forma que conecte eles podem não funcionar corretamente.
Dessa forma segue abaixo uma imagem que demonstrando a montagem do circuito.
Diagrama Esquemático do Projeto Jogo Genius
Código-fonte do Projeto Jogo Genius
Em seguida segue abaixo o código completo do projeto Genius.
//Definições de Pinos --------------------------------------------------------------------------------
byte led[4] = {9, 8, 2, 3}; // Define os pinos dos LED
byte btn[4] = {7, 6, 4, 5}; // Define os pinos dos Botões
//Variáveis Globais ----------------------------------------------------------------------------------
byte score; // Armazena a pontuação
byte sequencia[100] = {}; // Armazena a sequência
byte rodadaAtual = 0; // Armazena a rodadaAtual
byte passoSequencia = 0; // Armazena o próximo passo da sequência
byte botaoPressionado = 0; // Armazena o botão pressionado
bool startGame = false; // Armazena se o jogo iniciou ou não
//Funções Auxiliares ---------------------------------------------------------------------------------
void gameStart(); // Responsável pelo Star do jogo
void proximaRodada(); // Responsável pelo LED seguinte
void aguardarJogador(); // Responsável por esperar o jogador
void aguardarJogada(); // Responsável por espera a jogada
void verificarJogada(); // Responsável por verificar errou
void reproduzirSequencia(); // Responsável por reproduzir sequencia
void piscaLed(); // Responsável por piscar os LEDs
//Setup ----------------------------------------------------------------------------------------------
void setup() {
//Configuração dos LEDs
for (byte i = 0; i < 4; i++) { // Cria um loop para cada LED
pinMode(led[i], OUTPUT); // Configura os LED como OUTPUT
}
//Configuração dos Botões
for (byte i = 0; i < 4; i++) { // Cria um loop para cada botão
pinMode(btn[i], INPUT_PULLUP); // Configura os botões como INPUT_PULLUP
}
}
//Loop -----------------------------------------------------------------------------------------------
void loop() {
for (byte i = 0; i < 4; i++) { // Cria loop verificando cada botão
if (!digitalRead(btn[i]) && !startGame) { // Se os botões e se startGame = false
gameStart(); // Chama função gameStart()
}
}
if (startGame) { // Verifica se startGame = true
score++; // Incrementa score +1
proximaRodada(); // Chama função proximaRodada()
reproduzirSequencia(); // Chama função reproduzirSequencia()
aguardarJogador(); // Chama função aguardarJogador()
delay(1000); // Espera 1s
}
delay(10); // Espera 0,01s
}
//Game Start -----------------------------------------------------------------------------------------
void gameStart() {
piscaLed(); // Chama função piscaLed()
byte sequencia[100] = {}; // Limpa variável sequencia
rodadaAtual = 0; // Limpa variável rodadaAtual
passoSequencia = 0; // Limpa variável passoSequencia
startGame = true; // Atribui a startGame true
score = -1; // Atribui a score -1
}
//Próxima Rodada -------------------------------------------------------------------------------------
void proximaRodada() {
byte num = random(0, 4); // Atribui a num valor de 0 a 4
sequencia[rodadaAtual++] = num; // Atribui a sequência num
}
//Reproduz Sequencia ---------------------------------------------------------------------------------
void reproduzirSequencia() {
for (byte i = 0; i < rodadaAtual; i++) { // Cria um loop com a rodadaAtual
digitalWrite(led[sequencia[i]], HIGH); // Liga o LED da sequência atual
delay(500); // Espera 0,5s
digitalWrite(led[sequencia[i]], LOW); // Desliga o LED da sequência atual
delay(100); // Espera 0,1s
}
}
//Aguarda Jogador ------------------------------------------------------------------------------------
void aguardarJogador() {
for (byte i = 0; i < rodadaAtual; i++) { // Cria um loop com a rodada Atual
aguardarJogada(); // Chama função aguardarJogada()
verificarJogada(); // Chama função verificarJogada()
if (!startGame) { // Verifica se startGame = false
break; // Se for sai do loop
}
passoSequencia++; // Se não atribui +1 a passoSequencia
}
passoSequencia = 0; // Redefine a variável para 0.
}
//Aguarda Jogada -------------------------------------------------------------------------------------
void aguardarJogada() {
bool jogadaEfetuada = false; // Declara uma variável e atribui false
while (!jogadaEfetuada) { // Loop até que a jogadaEfetuada = true
for (byte i = 0; i < 4; i++) { // Cria um loop para cada botão
if (!digitalRead(btn[i])) { // Dizendo qual foi o botão pressionado
botaoPressionado = i; // Atribui o valor de i
digitalWrite(led[i], HIGH); // Liga o LED
delay(300); // Espera 0,3s
digitalWrite(led[i], LOW); // Desliga o LED
jogadaEfetuada = true; // Atribui a jogadaEfetuada true
}
}
delay(10); // Espera 0,01s
}
}
//Verifica Jogada ------------------------------------------------------------------------------------
void verificarJogada() {
if (sequencia[passoSequencia] != botaoPressionado) { // Se o botão clicado foi errado
piscaLed(); // Chama função piscaLed()
delay(1000); // Espera 1s
for(byte i = 0; i<score; i++){ // Cria um loop da quantidade de pontos
digitalWrite(led[0], HIGH); // Liga o LED
delay(500); // Espera 0,5s
digitalWrite(led[0], LOW); // Desliga o LED
delay(500); // Espera 0,5s
}
piscaLed(); // Chama função piscaLed()
startGame = false; // Atribui starGame
}
}
//Pisca LED ------------------------------------------------------------------------------------------
void piscaLed() {
for (byte i = 0; i <= 11; i++) { // Cria um loop de 11 vezes
for (byte j = 0; j < 4; j++) { // Cria um loop para cada LED
digitalWrite(led[j], !digitalRead(led[j])); // Inverte sinal dos LED
}
delay(250); // Espera 0,25s
}
}
Vamos dar uma olhada mais de perto no código:
Definições de Pinos
Em primeiro lugar temos que definir os pinos que iremos usar em nosso projeto.
//Definições de Pinos --------------------------------------------------------------------------------
byte led[4] = {9, 8, 2, 3}; // Define os pinos dos LED
byte btn[4] = {7, 6, 4, 5}; // Define os pinos dos Botões
Variáveis Globais
Em seguida declaramos 6 variáveis globais. Sendo elas score que armazenará a pontuação, sequencia responsável pelos LEDs, rodadaAtual que armazenará a rodada atual, passoSequencia responsável pela próximo sequência, botaoPressionado responsável pelo botão. Por fim temos a variável startGame que é responsável por armazenar a informação do início do jogo.
//Variáveis Globais ----------------------------------------------------------------------------------
byte score; // Armazena a pontuação
byte sequencia[100] = {}; // Armazena a sequência
byte rodadaAtual = 0; // Armazena a rodadaAtual
byte passoSequencia = 0; // Armazena o próximo passo da sequência
byte botaoPressionado = 0; // Armazena o botão pressionado
bool startGame = false; // Armazena se o jogo iniciou ou não
Funções Auxiliares
Agora declaramos as 7 funções auxiliares, para assim dividir o código, para que assim ele fique mais organizado. A primeira delas é a gameStart, responsável por limpar as variáveis, para que assim possamos inicializar o jogo. Em seguida declaramos a função proximaRodada, responsável por escolher aleatoriamente o próximo LED que irá acender. Da mesma forma declaramos as funções aguardarJogador, aguardarJogada e verificaJogada, responsável por esperar o jogador realizar a jogada e realizar a verificação da jogada. Por fim temos duas funções sendo elas reproduzirSequencia, responsável por acender os LEDs na sequência e a função piscaLed, responsável por piscar os LEDs.
//Funções Auxiliares ---------------------------------------------------------------------------------
void gameStart(); // Responsável pelo Star do jogo
void proximaRodada(); // Responsável pelo LED seguinte
void aguardarJogador(); // Responsável por esperar o jogador
void aguardarJogada(); // Responsável por espera a jogada
void verificarJogada(); // Responsável por verificar errou
void reproduzirSequencia(); // Responsável por reproduzir sequencia
void piscaLed(); // Responsável por piscar os LEDs
Funções Setup
Além disso na função setup, será onde iremos configurar os pinos dos LEDs como OUTPUT a partir de um loop. Também configuramos os pinos dos botões como INPUT_PULLUP, para que assim não seja necessário utilizar mais um jumper, por este motivo o sinal do botão é invertido.
//Setup ----------------------------------------------------------------------------------------------
void setup() {
//Configuração dos LEDs
for (byte i = 0; i < 4; i++) { // Cria um loop para cada LED
pinMode(led[i], OUTPUT); // Configura os LED como OUTPUT
}
//Configuração dos Botões
for (byte i = 0; i < 4; i++) { // Cria um loop para cada botão
pinMode(btn[i], INPUT_PULLUP); // Configura os botões como INPUT_PULLUP
}
}
Funções Loop
Agora na função loop, criamos um loop para verificar se algum dos botões foi clicado e se startGame é igual a falso, caso seja chamamos a função gameStart, para que assim possamos limpar todas as variáveis, ou seja, iremos se preparar para inicializar o jogo.
//Loop -----------------------------------------------------------------------------------------------
void loop() {
for (byte i = 0; i < 4; i++) { // Cria loop verificando cada botão
if (!digitalRead(btn[i]) && !startGame) { // Se os botões e se startGame = false
gameStart(); // Chama função gameStart()
}
}
Logo depois, realizamos outra verificação se startGame é igual a true, caso seja quer dizer que o jogo foi inicializado com sucesso. Por isso chamamos as funções proximaRodada, reproduzirSequencia, aguardarJogada e esperamos 1 segundo.
if (startGame) { // Verifica se startGame = true
score++; // Incrementa score +1
proximaRodada(); // Chama função proximaRodada()
reproduzirSequencia(); // Chama função reproduzirSequencia()
aguardarJogador(); // Chama função aguardarJogador()
delay(1000); // Espera 1s
}
delay(10); // Espera 0,01s
}
Funções gameStart
Em seguida vamos para a função gameStart, ela é responsável por limpar todas as variáveis para o início do jogo, para demonstrar que o jogo irá começar, após iremos chamar a função piscaLed, e então vamos limpar as variáveis.
//Game Start -----------------------------------------------------------------------------------------
void gameStart() {
piscaLed(); // Chama função piscaLed()
byte sequencia[100] = {}; // Limpa variável sequencia
rodadaAtual = 0; // Limpa variável rodadaAtual
passoSequencia = 0; // Limpa variável passoSequencia
startGame = true; // Atribui a startGame true
score = -1; // Atribui a score -1
}
Funções proximaRodada
Em seguida vamos para a função proximaRodada, ela é responsável por escolher um LED aleatoriamente que irá acender na próxima rodada. Sendo assim iremos declarar uma nova variável do tipo byte chamada num e atribuímos um número aleatório entre 0 a 4, em seguida atribuímos a sequência[rodadaAtual++] o valor de num.
//Próxima Rodada -------------------------------------------------------------------------------------
void proximaRodada() {
byte num = random(0, 4); // Atribui a num valor de 0 a 4
sequencia[rodadaAtual++] = num; // Atribui a sequência num
}
Funções reproduzirSequencia
Agora vamos para a função reproduzirSequencia, ela é responsável por reproduzir toda a sequência ligando os LEDs, para isso criamos um loop com o número de vezes igual ao número da rodadaAtual e ligamos o LED correspondente, após isso esperamos 0,5 segundos, em seguida desligamos os LEDs e esperamos mais 0,1 segundo.
//Reproduz Sequencia ---------------------------------------------------------------------------------
void reproduzirSequencia() {
for (byte i = 0; i < rodadaAtual; i++) { // Cria um loop com a rodadaAtual
digitalWrite(led[sequencia[i]], HIGH); // Liga o LED da sequência atual
delay(500); // Espera 0,5s
digitalWrite(led[sequencia[i]], LOW); // Desliga o LED da sequência atual
delay(100); // Espera 0,1s
}
}
Funções aguardarJogador
Do mesmo modo vamos para a função aguardaJogardor, ela é responsável por aguardar a jogador, assim criamos um for com número de vezes igual a rodadaAtual, após isso chamamos as funções aguardarJogada e verificarJogada, e iremos verificar se startGame é igual a false, se sim saímos do for e atribuímos 0 a passoSequencia, se não for incrementamos +1 na variável passoSequencia.
//Aguarda Jogador ---------------------------------------------------------------------------------
void aguardarJogador() {
for (byte i = 0; i < rodadaAtual; i++) { // Cria um loop com a rodada Atual
aguardarJogada(); // Chama função aguardarJogada()
verificarJogada(); // Chama função verificarJogada()
if (!startGame) { // Verifica se startGame = false
break; // Se for sai do loop
}
passoSequencia++; // Se não atribui +1 a passoSequencia
}
passoSequencia = 0; // Redefine a variável para 0.
}
Funções aguardarJogada
Agora na função aguardaJogada, ela é responsável por esperar a jogada do jogador, para isso é declarada uma variável chamada jogadaEfetuada e é atribuída falsa a ela, em seguida criamos um loop até que jogadaEfetuada seja igual a true em seguida fazemos outro loop onde será verificado todos os botões e atribuímos i a variável botaoPressionado, após isso é ligado o LED, espera 0,3 segundos, desligar o LED e para finalizar iremos atribuir a jogadaEfetuada true.
//Aguarda Jogada ----------------------------------------------------------------------------------
void aguardarJogada() {
bool jogadaEfetuada = false; // Declara uma variável e atribui false
while (!jogadaEfetuada) { // Loop até que a jogadaEfetuada = true
for (byte i = 0; i < 4; i++) { // Cria um loop para cada botão
if (!digitalRead(btn[i])) { // Dizendo qual foi o botão pressionado
botaoPressionado = i; // Atribui o valor de i
digitalWrite(led[i], HIGH); // Liga o LED
delay(300); // Espera 0,3s
digitalWrite(led[i], LOW); // Desliga o LED
jogadaEfetuada = true; // Atribui a jogadaEfetuada true
}
}
delay(10); // Espera 0,01s
}
}
Funções verificarJogada
Então agora na função verificaJogada, ela é responsável por verificar se o usuário apertou o botão correto, para isso temos que verificar se o botão pressionado é errado, se sim é fim de jogo, portanto esperamos 1 segundo, criamos um for e piscamos um LED a quantidade de vezes igual à quantidade de score, para que assim o usuário saiba quantos acertos teve, em seguida será chamado a função piscarLed e atribuímos false a startGame.
//Verifica Jogada -------------------------------------------------------------------------------
void verificarJogada() {
if (sequencia[passoSequencia] != botaoPressionado) { // Se o botão clicado foi errado
piscaLed(); // Chama função piscaLed()
delay(1000); // Espera 1s
for(byte i = 0; i < score; i++){ // Cria um loop da quantidade de pontos
digitalWrite(led[0], HIGH); // Liga o LED
delay(500); // Espera 0,5s
digitalWrite(led[0], LOW); // Desliga o LED
delay(500); // Espera 0,5s
}
piscaLed(); // Chama função piscaLed()
startGame = false; // Atribui starGame
}
}
Funções piscaLed
Por fim vamos para a função piscaLed, ela é responsável por piscar os LEDs, para isso criamos um loop de 11 vezes, dentro dele criamos outro loop de 4 vezes, para assim piscar todos os LEDs, dentro do loop invertemos o sinal de todos os LEDs e esperar 0,25 segundos.
//Pisca LED -------------------------------------------------------------------------------------
void piscaLed() {
for (byte i = 0; i <= 11; i++) { // Cria um loop de 11 vezes
for (byte j = 0; j < 4; j++) { // Cria um loop para cada LED
digitalWrite(led[j], !digitalRead(led[j])); // Inverte sinal dos LED
}
delay(250); // Espera 0,25s
}
}
Assim finalizamos o código-fonte com a explicação sobre o projeto Genius com Arduíno UNO.
Resultado do Projeto Jogo Genius
Por fim esse foi o resultado obtido com nosso projeto do Jogo Genius.
Agradecemos sua presença
Por fim, espero que tenham gostado e aprendido. Então compartilhem com seus colegas e deixe um comentário de qual projeto deveria ser o próximo aqui no Blog da WJ Componentes!
Enfim estarei deixando o arquivo Arduíno e Fritzing, link dos posts anteriores referentes ao projeto, software e sites utilizados.
Fique à vontade para tirar suas dúvidas nos comentários.
Software e Sites Utilizados
Post Relacionados
- Código Morse com Arduíno UNOOlá, como estão? Hoje iremos desenvolver um decodificador de código… Leia mais: Código Morse com Arduíno UNO
- Como Programar pelo Celular o Arduíno!Olá, como estão? A princípio iremos explicar como programar pelo… Leia mais: Como Programar pelo Celular o Arduíno!
- Como Programar por BlocosOlá, como estão? A princípio iremos falar sobre alguns sites… Leia mais: Como Programar por Blocos
- Contador com Botões no Arduíno UNOOlá, como estão? A princípio iremos realizar um contador. Entretanto… Leia mais: Contador com Botões no Arduíno UNO
- Jogo da Forca com Arduíno UNOOlá, como estão? A princípio iremos falar sobre a Serial… Leia mais: Jogo da Forca com Arduíno UNO
Posts mais Recentes
- Programando Relé RF 4331 -Instruções de emparelhamento do modo de alternância Modo de… Leia mais: Programando Relé RF 433
- Acionando motor DC por meio do pino “Touch” do ESP-32Neste projeto, vamos explorar uma aplicação ainda mais dinâmica e… Leia mais: Acionando motor DC por meio do pino “Touch” do ESP-32
- Acendendo led RGB por meio do pino “Touch” do ESP-32No último post, exploramos o fascinante mundo dos pinos touch… Leia mais: Acendendo led RGB por meio do pino “Touch” do ESP-32
- Utilizando os Pinos touch do ESP32Nesse projeto Vamos aprender a usar os pinos touch´s do… Leia mais: Utilizando os Pinos touch do ESP32
- Como Programar e Localizar o Endereço de uma Tela OLED I2C com Arduinoeste guia, vou levá-lo através dos passos para programar uma… Leia mais: Como Programar e Localizar o Endereço de uma Tela OLED I2C com Arduino
Julio Cesar Bonow Manoel
Cursando Engenharia da Computação pelo Centro Universitário Facens e atua no desenvolvimento de projetos na WJ Componentes. Participante da equipe de robótica Omegabotz.
Deixe um comentário