Olá pessoal! Nesse post você vai aprender a criar um game simples e dinâmico utilizando alguns componentes de fácil aquisição, um layout legal e uma programação não muito complicada. Pra isso usarei o processamento do Arduino Uno em conjunto com alguns expansores I2C PCF8574. O projeto é uma mistura de campo minado e batalha naval no Arduino e a criatividade é o limite!
O objetivo do jogo é invadir o território inimigo para pontuar, lançar minas terrestres aleatórias para tirar “vidas” (pontos) do adversário e torcer para não estar nas coordenadas dos mísseis lançados pelo Arduino. Ganha o jogo quem alcançar os pontos previamente acordados pelos jogadores.
Os CIs PCF8574 serão utilizados para gerenciar em torno de 45 portas de saída, ampliando as já existentes no Arduino.
Material Necessário
- 01 – Arduino UNO R3
- 01 – Display LCD LCD de 16×2 com módulo I2C acoplado
- 01 – Display 7 segmentos anodo comum
- 15 – Leds RGB
- 08 – PCF8574
- 22 – Resistores de 200 homs
- 12 – Resistores de 10k homs
- 01 – Buzzer
- 12 – Push Button
- 02 – Fonte DC Chaveada 5V 2A Plug P4
- 02 – Conector Adaptador Plug P4 Macho com Borne
- 01 – Conector Adaptador Plug P4 Fêmea com Borne
- 01 – Placa Fenolite Perfurada
Estrutura do tabuleiro
O jogo será composto de 15 leds RGB na seguinte ordem: 3 linhas por 5 colunas. Do lado esquerdo mais abaixo teremos 5 push buttons conforme teclas de direção de um controle (em cruz). No centro serão 2 push button para o “select” e outro para o “start”. No lado direito a mesma configuração dos controles de direção para o jogador 2. Mais acima iremos dispor de um display de LCD de 16×2 para mostrar o placar, as penalidades e algumas dicas de jogo. No lado oposto ao tabuleiro, um display de 7 segmentos para simular um “dado eletrônico”. Por fim, um buzzer para animar ainda mais o jogo.
As coordenadas do tabuleiro
As posições do tabuleiro serão numeradas na seguinte ordem conforme figura acima: o primeiro led na parte superior esquerda, será a posição (1), seguindo da esquerda para a direita e de cima para baixo até o último led na última linha a direita, posição (15). No início do jogo o jogador 1 será identificado com um led azul na posição (6), e o jogador 2 com um led verde na posição (10). A coluna da esquerda (posições 1, 6 e 11) será a base do peão azul, assim como a última coluna da direita (posições 5, 10 e 15) será a base do peão verde. São as bases que devem ser alcançadas para pontuar.
Regras do jogo de campo minado e batalha naval no Arduino
O primeiro passo a ser executado no início do jogo é o sorteio de quem irá começar, bem como o nível e a pontuação a ser alcançada. Após isso será pedido ao jogador em questão para “rolar” o dado. Para isso pressionando o botão central do seu controle, o valor mostrado é referente ao número de passos a ser dado pelo seu peão no tabuleiro, indiferente da direção a ser tomada. A cada nova rodada, o dado deve ser “jogado” novamente.
O deslocamento dos “peões”, identificado pela cor do leds, até a extremidade oposta do tabuleiro pontuará com 5 pontos. No caso do último movimento cair na mesma posição do oponente dentro da base dele, causará uma volta do seu peão para a sua base, diminuindo 5 pontos do seu placar.
O movimento do peão será feito com as teclas de direção. Para pontuar, o peão deve cair exatamente na casa da invasão no último movimento válido. Nesse momento ficará exposto ao ataque do seu oponente que irá lançar uma “mina terrestre” aleatoriamente no tabuleiro através do botão central do controle. A cada término de deslocamento o oponente irá disparar essa mina no campo de batalha, em caso de coincidir com sua posição, acarretará -10 pontos no seu placar, e lhe mandará de volta para a sua base.
No caso do movimento de seu oponente passar pela sua posição, sem que você esteja na sua base, você retornará automaticamente a uma das três posições iniciais da sua base. Primeira coluna para o jogador 1 e última coluna para o jogador 2.
O vencedor do jogo será aquele que alcançar uma pontuação pré-definida pelos participantes no início do jogo.
O nível de dificuldade será selecionado no começo do jogo. este nível de dificuldade irá determinar o lançamento de um ou mais mísseis pelo gerente do jogo (o Arduino),tirando 10 pontos, caso um dos jogadores esteja no local da “queda” do míssil. Esse lançamento será aleatório em todo o tabuleiro, inclusive nas bases. Esse míssil irá pontuar negativamente, mas não mexerá na posição do peão.
Níveis de dificuldade do jogo de campo minado e batalha naval no Arduino
- Nível 1 (Fácil) = nenhum míssil será lançado, Jogador contra jogador.
- Nível 2 (Médio) = 1 míssil a cada 3 jogadas.
- Nível 3 (Difícil) = 2 mísseis a cada 5 jogadas.
- Nível 4 (Louco) = 3 mísseis aleatoriamente independente do número de jogadas.
OBS: Todos os passos do jogo serão mostrados no display para um bom andamento do jogo, as regras são bem intuitivas.
Boa sorte e bom divertimento!
Circuito no simulador Proteus
Uma prévia de alguns componentes usados
- O componente que requer mais atenção no circuito é o PCF8574 (Expansor de 8 portas com comunicação I2C) a partir de uma comunicação serial com o Arduino. Essa conexão se dá através dos pinos analógicos A4 (serial dados) e A5 (serial clock) gerenciados pela biblioteca Wire.
- Os pinos desse CI são dispostos da seguinte forma: Pinos A1, A2 e A3 são usados para setar o endereço de comunicação.
- As portas P0 a P7 são usadas para entrada ou saída com uma carga máxima de 20 mA por porta em modo de entrada de corrente. Ou seja, um led com seu anodo ligado ao positivo e catodo ligado em série com um resistor de uns 180 ohms ao pino do CI. De forma contrária o pino ligado ao anodo do led mesmo sem o resistor, não supre a corrente mínima para ligar o led na sua máxima capacidade de condução, o que acarreta um brilho bem fraco no mesmo. Para um bom funcionamento nessa configuração é necessário usar um transistor (como driver) para aumentar a corrente de saída.
- Os pinos de energia são, pino 8 (GND) e 16 no (VCC). A tensão de entrada deve ser entre 2,5 V a 6 V.
- Os pinos de comunicação serial com o Arduino localizam-se no pinos 14 (SCL) e 15 (SDA).
- O pino 13 é usado para comunicação de interrupção que pode ser conectada com a saída de interrupção do microcontrolador (o Arduino no nosso caso).
- O Arduino pode suportar no máximo 16 PCF8574 o que expande o número de portas de entrada ou saída (input/output) para 128 portas usando apenas duas portas (A4 e A5).
- Um outro ponto a ser observado, é que as saídas são setada em forma binária do pino P7 ao pino P0, todas ao mesmo tempo, ou seja, se precisar setar somente o pino P2 como LOW (GND), será preciso setar todos os outros como HIGH (5 volts) como no exemplo: Wire.write (0b10111111).
- Os PCF8574 tem uma escala de endereços conforme a letra após o nome. Ex: PCF8574P e PCF8574AP tem endereços diferentes com a mesma ligação nos pinos de endereçamento. A maneira mais fácil de encontrar os endereços usados é usar o Scanner I2C .
Uso correto do PCF8574
- O LCD é utilizado para a construção do jogo é um de 16×2 . A diferença é que já vem acoplado um módulo I2C, e será controlado pela biblioteca Wire e a biblioteca LiquidCrystal_I2C. OBS: É preciso renomear a pasta como LiquidCrystal_I2C antes de colar na pasta libraries do seu Arduino.
- O display de 7 segmentos com anodo comum será ligado no sétimo PCF8574, que também será controlado pela biblioteca Wire do Arduino.
Código do jogo de campo minado e batalha naval no Arduino
#include <Wire.h> //Inclui a biblioteca Wire #include <LiquidCrystal_I2C.h> //Inclui a biblioteca LiquidCrystal_I2C - LCD int tempo = 300; //Seta o tempo como 1 - em teste - byte jogador = 0; //Variável inicial do jogador - conforme jogador terá o valor de 1 ou 2 byte sorteioDado = 0; //Variáel para o valor do dado byte coordenadasDado = 0; byte dado; //Valor inicial para o dado byte select = 0; int pontosVerde = 0; int pontosAzul = 0; byte nivel = 0; byte placar = 0; byte mina = 0; byte Pino1 = 3; // Saída para o buzzer byte Pino2 = 4; // byte Pino3 = 5; // byte Pino4 = 6; // Seta os pinos do Arduino do 3 ao 9 para os Botões byte Pino5 = 7; // byte Pino6 = 8; // byte Pino7 = 9; // byte Pino8 = 10;// byte Pino9 = 11;// byte estadoBotao1 = 0; //Seta o estado inicial das variáveis estadoBotao do 1 até o 7 como zero byte estadoBotao2 = 0; // byte estadoBotao3 = 0; // byte estadoBotao4 = 0; // byte estadoBotao5 = 0; // byte estadoBotao6 = 0; // byte estadoBotao7 = 0; // byte estadoBotao8 = 0; // byte posicaoVerde = 10; //Seta a posição inicial do peão 2(LED Verde) byte posicaoAzul = 6; //Seta a posição inicial do peão 1(LED Azul) byte posicaoMina = 0; byte posicaoMissel = 0; byte coordenadasVerde; //Inicia a variável coordenadasVerde para os Cases byte coordenadasAzul; //Inicia a variável coordenadasVerde para os Cases byte coordenadasMina; //Inicia a variável coordenadasMina para os Cases byte coordenadasMissel; //Inicia a variável coordenadasMina para os Cases byte niveis = 0; byte misseis = 0; byte missel = 0; LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); //Seta os parâmetros e endereço I2C do LCD void setup() { Wire.begin(); //Chama a biblioteca Wire Serial.begin(9600); //Inicia a velocidade da serial (usado para testes no programa) lcd.setBacklight(LOW); //Seta a luz de fundo do lcd como desligada lcd.clear(); //Zera as informações do LCD pinMode(Pino1, OUTPUT); //Seta como saída pinMode(Pino2, INPUT); //Seta como entrada pinMode(Pino3, INPUT); //Seta como entrada pinMode(Pino4, INPUT); //Seta como entrada pinMode(Pino5, INPUT); //Seta como entrada pinMode(Pino6, INPUT); //Seta como entrada pinMode(Pino7, INPUT); //Seta como entrada pinMode(Pino8, INPUT); //Seta como entrada pinMode(Pino9, INPUT_PULLUP); //Seta como entrada lcd.begin (16, 2); //Seta o LCD como 16 colunas e 2 linhas randomSeed(analogRead(0));// inicializa o gerador de números aleatórios. // um pino analógico desconectado irá retornar um // valor aleatório de tensão em analogRead() lcd.setCursor(0, 0); //seta o cursor na coluna zero e linha zero lcd.print ("== NOVO JOGO =="); //Escreve o que está entre aspas nas coordenadas acima delay(100); //tempo de 100 milisegundos para estabilizar o LCD lcd.setCursor(0, 1); //seta o cursor na coluna zero e linha 1 lcd.print ("NIVEIS de 1 a 4"); //Escreve o que está entre aspas nas coordenadas acima delay(100); //tempo de 100 milisegundos para estabilizar o LCD } void loop () { mina = random(1, 16); //Sorteia um númeo entre 1 e 15 para as coordenadas da mina missel = random(1, 16); //Sorteia um númeo entre 1 e 15 para as coordenadas do míssel misseis = random(100); //Sorteia um númeo entre 0 e 100 para a quantidade de mísseis estadoBotao1 = digitalRead(Pino2); //Registra os estados dos pinos 3 até 9 como HIGH ou LOW estadoBotao2 = digitalRead(Pino3); //nas variáveis estadoBotão estadoBotao3 = digitalRead(Pino4); // estadoBotao4 = digitalRead(Pino5); // estadoBotao5 = digitalRead(Pino6); // estadoBotao6 = digitalRead(Pino7); // estadoBotao7 = digitalRead(Pino8); // estadoBotao8 = digitalRead(Pino9); // // ==== INÍCIO DO JOGO ==== if (estadoBotao1 == LOW && select == 0) //Botão "SELECT" / "DADO" { tone(3, 440, 100); niveis += 1; delay(100); if (niveis == 5) { niveis = 1; } lcd.setCursor(0, 1); //seta o cursor na coluna zero e linha 1 lcd.print ("NIVEL = "); //Escreve o que está entre aspas nas coordenadasVerde acima lcd.setCursor(8, 1); lcd.print (niveis); delay(100); //tempo de 100 milisegundos para estabilizar o LCD } if (estadoBotao2 == LOW && jogador == 0 && niveis != 0) //Botão Start (Após pressionado, começa efetivamente o jogo { select = 1; for (byte f = 0; f <= 10; f++) { tone(3, 293, 100); delay(100); lcd.setBacklight(LOW); delay(50); lcd.setBacklight(LOW); } //==== Coordenadas iniciais dos peões Azul e Verde ==== coordenadasVerde = 10; coordenadasAzul = 6; jogador = 2; } //==== SORTEIO DADO ===== if (estadoBotao1 == LOW && select == 1) //Botão "SELECT" / "DADO" { dado = random(1, 7); //Sorteia um númeo entre 1 e 6 coordenadasDado = dado; } // ==== INVASÃO DO TERRITÓRIO INIMIGO AZUL ==== if (posicaoVerde == 1 && posicaoVerde != posicaoAzul) { delay(500); pontosVerde += 25; coordenadasVerde = 10; jogador = 2; placar = 1; } if (posicaoVerde == 6 && posicaoVerde != posicaoAzul) { delay(500); pontosVerde += 25; coordenadasVerde = 10; jogador = 2; placar = 1; } if (posicaoVerde == 11 && posicaoVerde != posicaoAzul) { delay(500); pontosVerde += 25; coordenadasVerde = 10; jogador = 2; placar = 1; } // ==== INVASÃO DO TERRITÓRIO INIMIGO VERDE ==== if (posicaoAzul == 5 && posicaoAzul != posicaoVerde) { delay(500); pontosAzul += 25; coordenadasAzul = 6; jogador = 1; placar = 1; } if (posicaoAzul == 10 && posicaoAzul != posicaoVerde) { delay(500); pontosAzul += 25; coordenadasAzul = 6; jogador = 1; placar = 1; } if (posicaoAzul == 15 && posicaoAzul != posicaoVerde) { delay(500); pontosAzul += 25; coordenadasAzul = 6; jogador = 1; placar = 1; } // ==== CONFRONTO COM O INIMIGO VERDE ==== if (posicaoAzul == posicaoVerde && jogador == 2) { pontosAzul -= 10; posicaoAzul = 6; for (byte f = 0; f <= 30; f++) { lcd.setCursor(0, 0); //seta o cursor na coluna zero e linha 1 lcd.print ("AZUL FOI FERIDO ");//Escreve o que está entre aspas nas coordenadasVerde acima lcd.setCursor(0, 1); lcd.print ("PERDEU 20 PONTOS"); } jogador = 1; coordenadasAzul = 6; placar = 1; delay(1000); } // ==== CONFRONTO COM O INIMIGO AZUL ==== if (posicaoVerde == posicaoAzul && jogador == 1) { pontosVerde -= 10; posicaoVerde = 10; for (byte f = 0; f <= 30; f++) { lcd.setCursor(0, 0); //seta o cursor na coluna zero e linha 1 lcd.print ("VERDE FOI FERIDO");//Escreve o que está entre aspas nas coordenadasVerde acima lcd.setCursor(0, 1); lcd.print ("PERDEU 20 PONTOS"); } jogador = 2; coordenadasVerde = 10; placar = 1; delay(1000); } ////////////////// //==== TIRO ====// ////////////////// if (estadoBotao8 == LOW && jogador == 2 && mina != 5 && mina != 10 && mina != 15) //Botão "Tiro" { jogador = 1; for (int a = 100; a >= 0; a--) // { // tone(3, 440 + a, 150); // Bomba caindo delay(20); // } coordenadasMina = mina; lcd.setCursor(0, 1); //seta o cursor na coluna zero e linha 1 lcd.print ("Coord. Mina: "); //Escreve o que está entre aspas nas coordenadasVerde acima lcd.setCursor(14, 1); lcd.print (mina); delay(100); //tempo de 100 milisegundos para estabilizar o LCD } if (estadoBotao7 == LOW && jogador == 1 && mina != 1 && mina != 6 && mina != 11) //Botão "Tiro" { jogador = 2; for (int a = 100; a >= 0; a--) // { // tone(3, 440 + a, 150); // Bomba caindo delay(20); // } coordenadasMina = mina; lcd.setCursor(0, 1); //seta o cursor na coluna zero e linha 1 lcd.print ("Coord. Mina: "); //Escreve o que está entre aspas nas coordenadas acima lcd.setCursor(14, 1); lcd.print (mina); delay(100); //tempo de 100 milisegundos para estabilizar o LCD } //Colisão da mina contra o peão Azul if (coordenadasMina == coordenadasAzul && jogador == 2) { lcd.setCursor(0, 0); //seta o cursor na coluna zero e linha 1 lcd.print (" AZUL ATINGIDO ");//Escreve o que está entre aspas nas coordenadas acima for (byte f = 0; f <= 30; f++) { lcd.setCursor(0, 1); lcd.print ("PERDEU 10 PONTOS"); tone(3, 300, 100); delay(50); lcd.setCursor(0, 1); lcd.print (" "); delay(50); } pontosAzul -= 20; placar = 1; coordenadasMina = 0; coordenadasAzul = 6; jogador = 1; } //Colisão da mina contra Peão Verde if (coordenadasMina == posicaoVerde && jogador == 1) { lcd.setCursor(0, 0); //seta o cursor na coluna zero e linha 1 lcd.print (" VERDE ATINGIDO ");//Escreve o que está entre aspas nas coordenadasVerde acima for (byte f = 0; f <= 30; f++) { lcd.setCursor(0, 1); lcd.print ("PERDEU 10 PONTOS"); tone(3, 300, 100); delay(50); //tempo de 1000 milisegundos para estabilizar o LCD lcd.setCursor(0, 1); lcd.print (" "); delay(50); } pontosVerde -= 20; placar = 1; coordenadasMina = 0; coordenadasVerde = 10; jogador = 2; } ///////////////////////////////////// // ==== LANÇAMENTO DO MÍSSEL ==== /// ///////////////////////////////////// if (select == 1 && (misseis == 30 || misseis == 60 || misseis == 90)) // misseis == 30 || misseis == 30 || { for (byte f = 0; f <= 15; f++) { lcd.clear(); //Zera as informações do LCD delay(200); lcd.setCursor(0, 0); lcd.print ("==== MISSEL ==="); lcd.setCursor(0, 1); lcd.print ("****************"); tone(3, 100, 200); delay(200); } coordenadasMina = missel; coordenadasMissel = 1; lcd.clear(); //Zera as informações do LCD placar = 1; } /////////////////////////////////////////////////////////// // ==== MOVIMENTOS POSSÍVEIS DO PEÃO VERDE ==== /////////// /////////////////////////////////////////////////////////// if (estadoBotao3 == LOW && posicaoVerde == 1 && jogador == 1) //Botão "Para baixo" { tone(3, 440, 100); coordenadasVerde = 6; } if (estadoBotao3 == LOW && posicaoVerde == 6 && jogador == 1) //Botão "Para baixo" { tone(3, 440, 100); coordenadasVerde = 11; } if (estadoBotao3 == LOW && posicaoVerde == 2 && jogador == 1) //Botão "Para baixo" { tone(3, 440, 100); coordenadasVerde = 7; } if (estadoBotao3 == LOW && posicaoVerde == 7 && jogador == 1) //Botão "Para baixo" { tone(3, 440, 100); coordenadasVerde = 12; } if (estadoBotao3 == LOW && posicaoVerde == 3 && jogador == 1) //Botão "Para baixo" { tone(3, 440, 100); coordenadasVerde = 8; } if (estadoBotao3 == LOW && posicaoVerde == 8 && jogador == 1) //Botão "Para baixo" { tone(3, 440, 100); coordenadasVerde = 13; } if (estadoBotao3 == LOW && posicaoVerde == 4 && jogador == 1) //Botão "Para baixo" { tone(3, 440, 100); coordenadasVerde = 9; } if (estadoBotao3 == LOW && posicaoVerde == 9 && jogador == 1) //Botão "Para baixo" { tone(3, 440, 100); coordenadasVerde = 14; } if (estadoBotao3 == LOW && posicaoVerde == 5 && jogador == 1) //Botão "Para baixo" { tone(3, 440, 100); coordenadasVerde = 10; } if (estadoBotao3 == LOW && posicaoVerde == 10 && jogador == 1) //Botão "Para baixo" { tone(3, 440, 100); coordenadasVerde = 15; } if (estadoBotao4 == LOW && posicaoVerde == 10 && jogador == 1) //Botão "Para esquerda" { tone(3, 440, 100); coordenadasVerde = 9; } if (estadoBotao4 == LOW && posicaoVerde == 9 && jogador == 1) //Botão "Para esquerda" { tone(3, 440, 100); coordenadasVerde = 8; } if (estadoBotao4 == LOW && posicaoVerde == 8 && jogador == 1) //Botão "Para esquerda" { tone(3, 440, 100); coordenadasVerde = 7; } if (estadoBotao4 == LOW && posicaoVerde == 7 && jogador == 1) //Botão "Para esquerda" { tone(3, 440, 100); coordenadasVerde = 6; } if (estadoBotao4 == LOW && posicaoVerde == 5 && jogador == 1) //Botão "Para esquerda" { tone(3, 440, 100); coordenadasVerde = 4; } if (estadoBotao4 == LOW && posicaoVerde == 4 && jogador == 1) //Botão "Para esquerda" { tone(3, 440, 100); coordenadasVerde = 3; } if (estadoBotao4 == LOW && posicaoVerde == 3 && jogador == 1) //Botão "Para esquerda" { tone(3, 440, 100); coordenadasVerde = 2; } if (estadoBotao4 == LOW && posicaoVerde == 2 && jogador == 1) //Botão "Para esquerda" { tone(3, 440, 100); coordenadasVerde = 1; } if (estadoBotao4 == LOW && posicaoVerde == 15 && jogador == 1) //Botão "Para esquerda" { tone(3, 440, 100); coordenadasVerde = 14; } if (estadoBotao4 == LOW && posicaoVerde == 14 && jogador == 1) //Botão "Para esquerda" { tone(3, 440, 100); coordenadasVerde = 13; } if (estadoBotao4 == LOW && posicaoVerde == 13 && jogador == 1) //Botão "Para esquerda" { tone(3, 440, 100); coordenadasVerde = 12; } if (estadoBotao4 == LOW && posicaoVerde == 12 && jogador == 1) //Botão "Para esquerda" { tone(3, 440, 100); coordenadasVerde = 11; } if (estadoBotao5 == LOW && posicaoVerde == 10 && jogador == 1) //Botão "Para Cima" { tone(3, 440, 100); coordenadasVerde = 5; } if (estadoBotao5 == LOW && posicaoVerde == 15 && jogador == 1) //Botão "Para Cima" { tone(3, 440, 100); coordenadasVerde = 10; } if (estadoBotao5 == LOW && posicaoVerde == 9 && jogador == 1) //Botão "Para Cima" { tone(3, 440, 100); coordenadasVerde = 4; } if (estadoBotao5 == LOW && posicaoVerde == 14 && jogador == 1) //Botão "Para Cima" { tone(3, 440, 100); coordenadasVerde = 9; } if (estadoBotao5 == LOW && posicaoVerde == 8 && jogador == 1) //Botão "Para Cima" { tone(3, 440, 100); coordenadasVerde = 3; } if (estadoBotao5 == LOW && posicaoVerde == 13 && jogador == 1) //Botão "Para Cima" { tone(3, 440, 100); coordenadasVerde = 8; } if (estadoBotao5 == LOW && posicaoVerde == 7 && jogador == 1) //Botão "Para Cima" { tone(3, 440, 100); coordenadasVerde = 2; } if (estadoBotao5 == LOW && posicaoVerde == 12 && jogador == 1) //Botão "Para Cima" { tone(3, 440, 100); coordenadasVerde = 7; } if (estadoBotao5 == LOW && posicaoVerde == 11 && jogador == 1) //Botão "Para Cima" { tone(3, 440, 100); coordenadasVerde = 6; } if (estadoBotao5 == LOW && posicaoVerde == 6 && jogador == 1) //Botão "Para Cima" { tone(3, 440, 100); coordenadasVerde = 1; } if (estadoBotao6 == LOW && posicaoVerde == 9 && jogador == 1) //Botão "Para Direita" { tone(3, 440, 100); coordenadasVerde = 10; } if (estadoBotao6 == LOW && posicaoVerde == 8 && jogador == 1) //Botão "Para Direita" { tone(3, 440, 100); coordenadasVerde = 9; } if (estadoBotao6 == LOW && posicaoVerde == 7 && jogador == 1) //Botão "Para Direita" { tone(3, 440, 100); coordenadasVerde = 8; } if (estadoBotao6 == LOW && posicaoVerde == 6 && jogador == 1) //Botão "Para Direita" { tone(3, 440, 100); coordenadasVerde = 7; } if (estadoBotao6 == LOW && posicaoVerde == 4 && jogador == 1) //Botão "Para Direita" { tone(3, 440, 100); coordenadasVerde = 5; } if (estadoBotao6 == LOW && posicaoVerde == 3 && jogador == 1) //Botão "Para Direita" { tone(3, 440, 100); coordenadasVerde = 4; } if (estadoBotao6 == LOW && posicaoVerde == 2 && jogador == 1) //Botão "Para Direita" { tone(3, 440, 100); coordenadasVerde = 3; } if (estadoBotao6 == LOW && posicaoVerde == 1 && jogador == 1) //Botão "Para Direita" { tone(3, 440, 100); coordenadasVerde = 2; } if (estadoBotao6 == LOW && posicaoVerde == 9 && jogador == 1) //Botão "Para Direita" { tone(3, 440, 100); coordenadasVerde = 10; } if (estadoBotao6 == LOW && posicaoVerde == 14 && jogador == 1) //Botão "Para Direita" { tone(3, 440, 100); coordenadasVerde = 15; } if (estadoBotao6 == LOW && posicaoVerde == 13 && jogador == 1) //Botão "Para Direita" { tone(3, 440, 100); coordenadasVerde = 14; } if (estadoBotao6 == LOW && posicaoVerde == 12 && jogador == 1) //Botão "Para Direita" { tone(3, 440, 100); coordenadasVerde = 13; } if (estadoBotao6 == LOW && posicaoVerde == 11 && jogador == 1) //Botão "Para Direita" { tone(3, 440, 100); coordenadasVerde = 12; } /////////////////////////////////////////////////////////// // ==== MOVIMENTOS POSSÍVEIS DO PEÃO AZUL ==== //////////// /////////////////////////////////////////////////////////// if (estadoBotao3 == LOW && posicaoAzul == 1 && jogador == 2) //Botão "Para baixo" { tone(3, 440, 100); coordenadasAzul = 6; } if (estadoBotao3 == LOW && posicaoAzul == 6 && jogador == 2) //Botão "Para baixo" { tone(3, 440, 100); coordenadasAzul = 11; } if (estadoBotao3 == LOW && posicaoAzul == 2 && jogador == 2) //Botão "Para baixo" { tone(3, 440, 100); coordenadasAzul = 7; } if (estadoBotao3 == LOW && posicaoAzul == 7 && jogador == 2) //Botão "Para baixo" { tone(3, 440, 100); coordenadasAzul = 12; } if (estadoBotao3 == LOW && posicaoAzul == 3 && jogador == 2) //Botão "Para baixo" { tone(3, 440, 100); coordenadasAzul = 8; } if (estadoBotao3 == LOW && posicaoAzul == 8 && jogador == 2) //Botão "Para baixo" { tone(3, 440, 100); coordenadasAzul = 13; } if (estadoBotao3 == LOW && posicaoAzul == 4 && jogador == 2) //Botão "Para baixo" { tone(3, 440, 100); coordenadasAzul = 9; } if (estadoBotao3 == LOW && posicaoAzul == 9 && jogador == 2) //Botão "Para baixo" { tone(3, 440, 100); coordenadasAzul = 14; } if (estadoBotao3 == LOW && posicaoAzul == 5 && jogador == 2) //Botão "Para baixo" { tone(3, 440, 100); coordenadasAzul = 10; } if (estadoBotao3 == LOW && posicaoAzul == 10 && jogador == 2) //Botão "Para baixo" { tone(3, 440, 100); coordenadasAzul = 15; } if (estadoBotao4 == LOW && posicaoAzul == 10 && jogador == 2) //Botão "Para esquerda" { tone(3, 440, 100); coordenadasAzul = 9; } if (estadoBotao4 == LOW && posicaoAzul == 9 && jogador == 2) //Botão "Para esquerda" { tone(3, 440, 100); coordenadasAzul = 8; } if (estadoBotao4 == LOW && posicaoAzul == 8 && jogador == 2) //Botão "Para esquerda" { tone(3, 440, 100); coordenadasAzul = 7; } if (estadoBotao4 == LOW && posicaoAzul == 7 && jogador == 2) //Botão "Para esquerda" { tone(3, 440, 100); coordenadasAzul = 6; } if (estadoBotao4 == LOW && posicaoAzul == 5 && jogador == 2) //Botão "Para esquerda" { tone(3, 440, 100); coordenadasAzul = 4; } if (estadoBotao4 == LOW && posicaoAzul == 4 && jogador == 2) //Botão "Para esquerda" { tone(3, 440, 100); coordenadasAzul = 3; } if (estadoBotao4 == LOW && posicaoAzul == 3 && jogador == 2) //Botão "Para esquerda" { tone(3, 440, 100); coordenadasAzul = 2; } if (estadoBotao4 == LOW && posicaoAzul == 2 && jogador == 2) //Botão "Para esquerda" { tone(3, 440, 100); coordenadasAzul = 1; } if (estadoBotao4 == LOW && posicaoAzul == 15 && jogador == 2) //Botão "Para esquerda" { tone(3, 440, 100); coordenadasAzul = 14; } if (estadoBotao4 == LOW && posicaoAzul == 14 && jogador == 2) //Botão "Para esquerda" { tone(3, 440, 100); coordenadasAzul = 13; } if (estadoBotao4 == LOW && posicaoAzul == 13 && jogador == 2) //Botão "Para esquerda" { tone(3, 440, 100); coordenadasAzul = 12; } if (estadoBotao4 == LOW && posicaoAzul == 12 && jogador == 2) //Botão "Para esquerda" { tone(3, 440, 100); coordenadasAzul = 11; } if (estadoBotao5 == LOW && posicaoAzul == 10 && jogador == 2) //Botão "Para Cima" { tone(3, 440, 100); coordenadasAzul = 5; } if (estadoBotao5 == LOW && posicaoAzul == 15 && jogador == 2) //Botão "Para Cima" { tone(3, 440, 100); coordenadasAzul = 10; } if (estadoBotao5 == LOW && posicaoAzul == 9 && jogador == 2) //Botão "Para Cima" { tone(3, 440, 100); coordenadasAzul = 4; } if (estadoBotao5 == LOW && posicaoAzul == 14 && jogador == 2) //Botão "Para Cima" { tone(3, 440, 100); coordenadasAzul = 9; } if (estadoBotao5 == LOW && posicaoAzul == 8 && jogador == 2) //Botão "Para Cima" { tone(3, 440, 100); coordenadasAzul = 3; } if (estadoBotao5 == LOW && posicaoAzul == 13 && jogador == 2) //Botão "Para Cima" { tone(3, 440, 100); coordenadasAzul = 8; } if (estadoBotao5 == LOW && posicaoAzul == 7 && jogador == 2) //Botão "Para Cima" { tone(3, 440, 100); coordenadasAzul = 2; } if (estadoBotao5 == LOW && posicaoAzul == 12 && jogador == 2) //Botão "Para Cima" { tone(3, 440, 100); coordenadasAzul = 7; } if (estadoBotao5 == LOW && posicaoAzul == 11 && jogador == 2) //Botão "Para Cima" { tone(3, 440, 100); coordenadasAzul = 6; } if (estadoBotao5 == LOW && posicaoAzul == 6 && jogador == 2) //Botão "Para Cima" { tone(3, 440, 100); coordenadasAzul = 1; } // if(estadoBotao6 == LOW && posicaoAzul == 9 && jogador == 2) //Botão "Para Direita" //{ //tone(3,440,100); //coordenadasAzul = 10; //} if (estadoBotao6 == LOW && posicaoAzul == 8 && jogador == 2) //Botão "Para Direita" { tone(3, 440, 100); coordenadasAzul = 9; } if (estadoBotao6 == LOW && posicaoAzul == 7 && jogador == 2) //Botão "Para Direita" { tone(3, 440, 100); coordenadasAzul = 8; } if (estadoBotao6 == LOW && posicaoAzul == 6 && jogador == 2) //Botão "Para Direita" { tone(3, 440, 100); coordenadasAzul = 7; } if (estadoBotao6 == LOW && posicaoAzul == 4 && jogador == 2) //Botão "Para Direita" { tone(3, 440, 100); coordenadasAzul = 5; } if (estadoBotao6 == LOW && posicaoAzul == 3 && jogador == 2) //Botão "Para Direita" { tone(3, 440, 100); coordenadasAzul = 4; } if (estadoBotao6 == LOW && posicaoAzul == 2 && jogador == 2) //Botão "Para Direita" { tone(3, 440, 100); coordenadasAzul = 3; } if (estadoBotao6 == LOW && posicaoAzul == 1 && jogador == 2) //Botão "Para Direita" { tone(3, 440, 100); coordenadasAzul = 2; } if (estadoBotao6 == LOW && posicaoAzul == 9 && jogador == 2) //Botão "Para Direita" { tone(3, 440, 100); coordenadasAzul = 10; } if (estadoBotao6 == LOW && posicaoAzul == 14 && jogador == 2) //Botão "Para Direita" { tone(3, 440, 100); coordenadasAzul = 15; } if (estadoBotao6 == LOW && posicaoAzul == 13 && jogador == 2) //Botão "Para Direita" { tone(3, 440, 100); coordenadasAzul = 14; } if (estadoBotao6 == LOW && posicaoAzul == 12 && jogador == 2) //Botão "Para Direita" { tone(3, 440, 100); coordenadasAzul = 13; } if (estadoBotao6 == LOW && posicaoAzul == 11 && jogador == 2) //Botão "Para Direita" { tone(3, 440, 100); coordenadasAzul = 12; } ////////////////////////////////////////////////// //==== POSIÇÕES POSSÍVEIS PARA O PEÃO VERDE ====// ////////////////////////////////////////////////// switch (coordenadasVerde) { case 1: Wire.beginTransmission(0x3E); Wire.write(0b11111110); Wire.endTransmission(); posicaoVerde = 1; // delay(tempo+100); break; case 2: Wire.beginTransmission(0x3E); Wire.write(0b11011111); Wire.endTransmission(); posicaoVerde = 2; // delay(tempo+100); break; case 3: Wire.beginTransmission(0x3E); Wire.write(0b10111111); Wire.endTransmission(); posicaoVerde = 3; // delay(tempo+100); break; case 4: Wire.beginTransmission(0x3A); Wire.write(0b11110111); Wire.endTransmission(); posicaoVerde = 4; // delay(tempo+100); break; case 5: Wire.beginTransmission(0x3A); Wire.write(0b11101111); Wire.endTransmission(); posicaoVerde = 5; // delay(tempo+100); break; case 6: Wire.beginTransmission(0x3E); Wire.write(0b11111101); Wire.endTransmission(); posicaoVerde = 6; // delay(tempo+100); break; case 7: Wire.beginTransmission(0x3E); Wire.write(0b11101111); Wire.endTransmission(); posicaoVerde = 7; // delay(tempo+100); break; case 8: Wire.beginTransmission(0x3E); Wire.write(0b01111111); Wire.endTransmission(); posicaoVerde = 8; // delay(tempo+100); break; case 9: Wire.beginTransmission(0x3A); Wire.write(0b11111011); Wire.endTransmission(); posicaoVerde = 9; // delay(tempo+100); break; case 10: //Posição inicial Wire.beginTransmission(0x3A); Wire.write(0b11011111); Wire.endTransmission(); posicaoVerde = 10; // delay(tempo+100); break; case 11: Wire.beginTransmission(0x3E); Wire.write(0b11111011); Wire.endTransmission(); posicaoVerde = 11; // delay(tempo+100); break; case 12: Wire.beginTransmission(0x3E); Wire.write(0b11110111); Wire.endTransmission(); posicaoVerde = 12; // delay(tempo+100); break; case 13: Wire.beginTransmission(0x3A); Wire.write(0b11111110); Wire.endTransmission(); posicaoVerde = 13; // delay(tempo+100); break; case 14: Wire.beginTransmission(0x3A); Wire.write(0b11111101); Wire.endTransmission(); posicaoVerde = 14; // delay(tempo+100); break; case 15: Wire.beginTransmission(0x3A); Wire.write(0b10111111); Wire.endTransmission(); posicaoVerde = 15; // delay(tempo+100); break; } //////////////////////////////////////////// //==== POSIÇÕES POSSÍVEIS PARA A MINA ====// //////////////////////////////////////////// switch (coordenadasMina) { case 1: Wire.beginTransmission(0x38); Wire.write(0b11111110); Wire.endTransmission(); delay(tempo); break; case 2: Wire.beginTransmission(0x38); Wire.write(0b11011111); Wire.endTransmission(); delay(tempo); break; case 3: Wire.beginTransmission(0x38); Wire.write(0b10111111); Wire.endTransmission(); delay(tempo); break; case 4: Wire.beginTransmission(0x3C); Wire.write(0b11110111); Wire.endTransmission(); delay(tempo); break; case 5: Wire.beginTransmission(0x3C); Wire.write(0b11101111); Wire.endTransmission(); delay(tempo); break; case 6: Wire.beginTransmission(0x38); Wire.write(0b11111101); Wire.endTransmission(); delay(tempo); break; case 7: Wire.beginTransmission(0x38); Wire.write(0b11101111); Wire.endTransmission(); delay(tempo); break; case 8: Wire.beginTransmission(0x38); Wire.write(0b01111111); Wire.endTransmission(); delay(tempo); break; case 9: Wire.beginTransmission(0x3C); Wire.write(0b11111011); Wire.endTransmission(); delay(tempo); break; case 10: Wire.beginTransmission(0x3C); Wire.write(0b11011111); Wire.endTransmission(); delay(tempo); break; case 11: Wire.beginTransmission(0x38); Wire.write(0b11111011); Wire.endTransmission(); delay(tempo); break; case 12: Wire.beginTransmission(0x38); Wire.write(0b11110111); Wire.endTransmission(); delay(tempo); break; case 13: Wire.beginTransmission(0x3C); Wire.write(0b11111110); Wire.endTransmission(); delay(tempo); break; case 14: Wire.beginTransmission(0x3C); Wire.write(0b11111101); Wire.endTransmission(); delay(tempo); break; case 15: Wire.beginTransmission(0x3C); Wire.write(0b10111111); Wire.endTransmission(); delay(tempo); break; } /////////////////////////////////////////// //==== VALORES POSSÍVEIS PARA O DADO ====// /////////////////////////////////////////// switch (coordenadasDado) { case 1: Wire.beginTransmission(0x3B); Wire.write(0b11111001); Wire.endTransmission(); break; case 2: Wire.beginTransmission(0x3B); Wire.write(0b11000100); Wire.endTransmission(); break; case 3: Wire.beginTransmission(0x3B); Wire.write(0b11010000); Wire.endTransmission(); break; case 4: Wire.beginTransmission(0x3B); Wire.write(0b10011001); Wire.endTransmission(); break; case 5: Wire.beginTransmission(0x3B); Wire.write(0b10010010); Wire.endTransmission(); break; case 6: Wire.beginTransmission(0x3B); Wire.write(0b10000010); Wire.endTransmission(); delay( tempo + 100 ); break; } ///////////////////////////////////////////////// //==== POSIÇÕES POSSÍVEIS PARA O PEÃO AZUL ====// ///////////////////////////////////////////////// switch (coordenadasAzul) { case 1: Wire.beginTransmission(0x3F); Wire.write(0b11111110); Wire.endTransmission(); posicaoAzul = 1; break; case 2: Wire.beginTransmission(0x3F); Wire.write(0b11011111); Wire.endTransmission(); posicaoAzul = 2; break; case 3: Wire.beginTransmission(0x3F); Wire.write(0b10111111); Wire.endTransmission(); posicaoAzul = 3; break; case 4: Wire.beginTransmission(0x39); Wire.write(0b11110111); Wire.endTransmission(); posicaoAzul = 4; break; case 5: Wire.beginTransmission(0x39); Wire.write(0b11101111); Wire.endTransmission(); posicaoAzul = 5; break; case 6: Wire.beginTransmission(0x3F); Wire.write(0b11111101); Wire.endTransmission(); posicaoAzul = 6; break; case 7: Wire.beginTransmission(0x3F); Wire.write(0b11101111); Wire.endTransmission(); posicaoAzul = 7; break; case 8: Wire.beginTransmission(0x3F); Wire.write(0b01111111); Wire.endTransmission(); posicaoAzul = 8; break; case 9: Wire.beginTransmission(0x39); Wire.write(0b11111011); Wire.endTransmission(); posicaoAzul = 9; break; case 10: Wire.beginTransmission(0x39); Wire.write(0b11011111); Wire.endTransmission(); posicaoAzul = 10; break; case 11: Wire.beginTransmission(0x3F); Wire.write(0b11111011); Wire.endTransmission(); posicaoAzul = 11; break; case 12: Wire.beginTransmission(0x3F); Wire.write(0b11110111); Wire.endTransmission(); posicaoAzul = 12; break; case 13: Wire.beginTransmission(0x39); Wire.write(0b11111110); Wire.endTransmission(); posicaoAzul = 13; break; case 14: Wire.beginTransmission(0x39); Wire.write(0b11111101); Wire.endTransmission(); posicaoAzul = 14; break; case 15: Wire.beginTransmission(0x39); Wire.write(0b10111111); Wire.endTransmission(); posicaoAzul = 15; break; } switch (placar) { case 1: lcd.clear(); //Zera as informações do LCD lcd.setCursor(0, 0); lcd.print ("PEAO VERDE="); lcd.setCursor(0, 1); //seta o cursor na coluna zero e linha zero lcd.print ("PEAO AZUL=");//Escreve o que está entre aspas nas coordenadas acima lcd.setCursor(12, 0); lcd.print (pontosVerde); lcd.setCursor(11, 1); lcd.print (pontosAzul); delay(200); break; } for (byte f = 0; f <= 2; f++) { //Apaga todas as portas dos PCF8574 Wire.beginTransmission(0x3A); // Wire.write(0b11111111); // VERDES Wire.endTransmission(); // Wire.beginTransmission(0x3E); // Wire.write(0b11111111); // VERDES Wire.endTransmission(); // Wire.beginTransmission(0x3C); // Wire.write(0b11111111); // VERMELHOS Wire.endTransmission(); // Wire.beginTransmission(0x38); // Wire.write(0b11111111); // VERMELHOS Wire.endTransmission(); // Wire.beginTransmission(0x39); // Wire.write(0b11111111); // AZUIS Wire.endTransmission(); // Wire.beginTransmission(0x3F); // Wire.write(0b11111111); // AZUIS Wire.endTransmission(); // delay(tempo - 250); Wire.beginTransmission(0x3B); // Wire.write(0b11111111); // DADO Wire.endTransmission(); // } switch (coordenadasMissel) { case1: { if (missel == posicaoVerde) { lcd.setCursor(0, 0); //seta o cursor na coluna zero e linha 1 lcd.print ("==== MORREU ==== ");//Escreve o que está entre aspas nas coordenadasVerde acima delay(2000); for (byte f = 0; f <= 30; f++) { lcd.setCursor(0, 1); lcd.print ("PERDEU 10 PONTOS"); tone(3, 300, 100); delay(50); //tempo de 1000 milisegundos para estabilizar o LCD lcd.setCursor(0, 1); lcd.print (" "); delay(50); } placar = 1; coordenadasVerde = 10; } if (missel == posicaoAzul) { lcd.setCursor(0, 0); //seta o cursor na coluna zero e linha 1 lcd.print ("==== MORREU ==== ");//Escreve o que está entre aspas nas coordenadasVerde acima delay(2000); for (byte f = 0; f <= 30; f++) { lcd.setCursor(0, 1); lcd.print ("PERDEU 10 PONTOS"); tone(3, 300, 100); delay(50); //tempo de 1000 milisegundos para estabilizar o LCD lcd.setCursor(0, 1); lcd.print (" "); delay(50); } placar = 1; coordenadasAzul = 6; } break; } } }
Conclusão
No decorrer deste projeto que foi “inventado” ele foi sendo adaptado conforme as possibilidades de programação do Arduino. Dessa forma aprendi novas maneiras de programação. Por exemplo, aprendi a usar a programação do PCF8574 diretamente em binário, o que facilitou a compreensão dos leds que queria ligar em dado momento, pois o digito binário “0” significa led acesso e dígito binário “1” led desligado.
Me deparei com muita repetição de códigos do tipo “IF” isso, “IF” aquilo, o que torna o código muito longo. Estou relendo o mesmo para tentar fazer rotinas com variáveis, para que o mesmo código conforme o valor da variável faça uma coisa ou outra. Estou fazendo vários testes para, por exemplo, retirar ao máximo a função “delay”. Ainda não sou craque em usar a função millis, mas estou estudando para usá-la.
Os sons testados até agora, não estão satisfazendo meus ouvidos, o legal seria uma caixinha, mesmo que xing ling, para que o jogo tenha efeitos sonoros. Usando o tutorial Módulo MP3 Arduino WTV020-SD, poderia ser carregado alguns efeitos sonoros que seriam chamados via programação (talvez isso seja demais para o joguinho em questão).
Gostou do jogo de campo minado e batalha naval no Arduino? deixe seu comentário logo abaixo. Se quiser acessar outros conteúdos como esse, visite o blog da MakerHero.
Abraços a todos!
Gostei. Fiz inscrição para fazer ocurso de Tenico de Eletronica, em abril será a seleção e o inicio em julho no Senai Anchieta – V. Mariana. Me diga se esse curso é bom e se dá para aprender bem. Abraço
Bom dia Jose Luiz, sim os cursos do Senai são os melhores, o material de uso prático é bem variado, normalmente é feita uma ou duas aulas teóricas e em seguida as práticas, além de aprender eletrônica
eles ainda disponibilizam vários pequenos cursos com diploma, vale muito a pena. Boa sorte e espero alguns bons projetos aqui na MakerHero no futuro, um abraço.