/*
Jogo Pong (1 Player) utilizando Arduino Mega 2560, 1 Potenciômetro de 10K Ohms, Buzzer e Matriz de LED 8x8 (MAX7219)
Versão 1.0 - Versão inicial com Jogo Simples de bola rebatendo e som de quique da bola. Muda de fase a cada 20 rebatidas, alterando velocidade
* * Criado por Cleber Borges - FunBots - @cleber.funbots * *
Instagram: https://www.instagram.com/cleber.funbots/
Facebook: https://www.facebook.com/cleber.funbots
YouTube: https://www.youtube.com/channel/UCKs2l5weIqgJQxiLj0A6Atw
*/
// Definição dos pinos da Matriz de Led 8x8
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define numPixels 256
int ledPin = 10;
Adafruit_NeoPixel strip(numPixels, ledPin, NEO_GRB + NEO_KHZ800);
// Definição de variáveis que acendem os Leds
uint16_t mascaraBola = 0b0000000000000100; // Máscara que acende bola
uint16_t mascaraPlataforma = 0b0000000000011111; // Máscara que acende plataforma do jogador
uint16_t zero = 0b0000000000000000; // Máscara para apagar leds
uint16_t b1[16] = {
0b0000000000000000, // Leds todos apagados 1
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000};
uint16_t b2[16] = {
0b1111111111111111, // Leds todos acesos
0b1111111111111111,
0b1111111111111111,
0b1111111111111111,
0b1111111111111111,
0b1111111111111111,
0b1111111111111111,
0b1111111111111111,
0b1111111111111111,
0b1111111111111111,
0b1111111111111111,
0b1111111111111111,
0b1111111111111111,
0b1111111111111111,
0b1111111111111111,
0b1111111111111111};
uint16_t b3[16] = {
0b0000000000000000, // Leds todos apagados 2
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000};
// Variáveis de posição da bola
int l = 2; // Linha atual
int c = 3; // Coluna atual
// Variáveis de direção da bola
int v = 0; // 0 pra baixo, 1 pra cima
int h = 0; // 1 pra direita, 0 pra esquerda
// Pinos do Buzzer e Potenciômetro
#define buzzer 12
#define pinoPot A0
// Variáveis da plataforma do jogador
int posPlataforma = 1; // Posição da plataforma do jogador
int potenciometro; // Variável que recebe valor do potenciômetro
// Variáveis de Jogo
int tempoJogo = 50; // Tempo de loop, diminui conforme passa de fase
int fase = 0; // Fase de jogo, aumenta frequencia do som da bola
int pontos = 0; // pontos conquistados
/*
SETUP
*/
void setup()
{
// Configura e inicializa a Matriz de Led
Serial.begin(9600); // Serial para debug, se necessário
strip.begin();
pinMode(buzzer, OUTPUT); // Configura pino do Buzzer como saída
randomSeed(analogRead(A1)); // Deixa posição inicial da bola aleatória
resetJogo(); // Função para resetar variáveis do Jogo
}
/*
LOOP
*/
void loop()
{
leituraControle(); // Faz leitura do Potenciômetro
// Verifica posição/direção da bola versus posição da plataforma
if (l == 15 && ((posPlataforma == (c + 1) && h == 0) || (posPlataforma == (c - 5) && h == 1)))
{ // Quicou na Quina
quicaBolaQuina();
printTela();
}
else
{
if (l == 15 && (c >= (posPlataforma + 5) || c <= (posPlataforma - 1)))
{ // Não acertou plataforma, perdeu o jogo
perdeuJogo();
resetJogo();
}
else
{
moveBola(); // Quicou nas bordas ou no meio da plataforma
printTela();
}
}
// Checa quantos pontos já fez
if (pontos > 10)
{
tempoJogo -= 5; // Se chegou a 20, diminui tempo do loop e incrementa fase
pontos = 0;
fase++;
}
delay(tempoJogo);
}
/****** FUNÇÕES *******/
void printTela()
{
b1[(l - 1)] = mascaraBola;
b1[15] = mascaraPlataforma;
printByte(b1);
}
void printByte(uint16_t caracter[])
{
strip.clear();
for (int i = 0; i < 16; i++)
{
for (int j = 0; j < 16; j++)
{
int ledIndex;
if (j % 2 == 0)
{
ledIndex = j * 16 + i;
}
else
{
ledIndex = j * 16 - i + 15;
}
if ((caracter[i] & (1 << j)) != 0)
{
strip.setPixelColor(ledIndex, strip.Color(255, 0, 0));
}
}
}
strip.show();
}
void quicaBolaQuina()
{
// Move na coluna
if (16 > c && c > 1 && h == 0)
{
mascaraBola >>= 1;
c--;
}
else
{
if (16 > c && c > 1 && h == 1)
{
mascaraBola <<= 1;
c++;
}
else
{
if (c == 1 && h == 1)
{
mascaraBola <<= 1;
c++;
h = 0;
}
else
{
if (c == 16 && h == 0)
{
mascaraBola >>= 1;
c--;
h = 1;
}
}
}
}
b1[14] = zero;
l = 6;
v = 1;
if (h == 0)
{
h = 1;
}
else
{
h = 0;
}
// incrementa pontos e executa som
pontos++;
somBola2();
}
void leituraControle()
{
// Faz leitura analógica do potênciometro
potenciometro = analogRead(pinoPot);
int valorInicial = 100;
int intervalo = 80;
// Verifica qual valor do potenciômetro e ajusta posição da plataforma conforme giro dele
uint16_t mascaraPlataformaTemporaria = 0b0000000000011111;
if (potenciometro < valorInicial)
{
mascaraPlataforma = mascaraPlataformaTemporaria;
posPlataforma = 1;
}
else if (potenciometro >= valorInicial && potenciometro < valorInicial + intervalo)
{
mascaraPlataforma = mascaraPlataformaTemporaria << 1;
posPlataforma = 2;
}
else if (potenciometro >= valorInicial + intervalo && potenciometro < valorInicial + intervalo * 2)
{
mascaraPlataforma = mascaraPlataformaTemporaria << 2;
posPlataforma = 3;
}
else if (potenciometro >= valorInicial + intervalo * 2 && potenciometro < valorInicial + intervalo * 3)
{
mascaraPlataforma = mascaraPlataformaTemporaria << 3;
posPlataforma = 4;
}
else if (potenciometro >= valorInicial + intervalo * 3 && potenciometro < valorInicial + intervalo * 4)
{
mascaraPlataforma = mascaraPlataformaTemporaria << 4;
posPlataforma = 5;
}
else if (potenciometro >= valorInicial + intervalo * 4 && potenciometro < valorInicial + intervalo * 5)
{
mascaraPlataforma = mascaraPlataformaTemporaria << 5;
posPlataforma = 6;
}
else if (potenciometro >= valorInicial + intervalo * 5 && potenciometro < valorInicial + intervalo * 6)
{
mascaraPlataforma = mascaraPlataformaTemporaria << 6;
posPlataforma = 7;
}
else if (potenciometro >= valorInicial + intervalo * 6 && potenciometro < valorInicial + intervalo * 7)
{
mascaraPlataforma = mascaraPlataformaTemporaria << 7;
posPlataforma = 8;
}
else if (potenciometro >= valorInicial + intervalo * 7 && potenciometro < valorInicial + intervalo * 8)
{
mascaraPlataforma = mascaraPlataformaTemporaria << 8;
posPlataforma = 9;
}
else if (potenciometro >= valorInicial + intervalo * 8 && potenciometro < valorInicial + intervalo * 9)
{
mascaraPlataforma = mascaraPlataformaTemporaria << 9;
posPlataforma = 10;
}
else if (potenciometro >= valorInicial + intervalo * 9 && potenciometro < valorInicial + intervalo * 10)
{
mascaraPlataforma = mascaraPlataformaTemporaria << 10;
posPlataforma = 11;
}
else if (potenciometro >= valorInicial + intervalo * 10)
{
mascaraPlataforma = mascaraPlataformaTemporaria << 11;
posPlataforma = 12;
}
}
void moveBola()
{
// Move na coluna
if (16 > c && c > 1 && h == 0)
{
mascaraBola <<= 1;
c++;
}
else
{
if (16 > c && c > 1 && h == 1)
{
mascaraBola >>= 1;
c--;
}
else
{
if (c == 1 && h == 1)
{
mascaraBola <<= 1;
c++;
h = 0;
somBola();
}
else
{
if (c == 16 && h == 0)
{
mascaraBola >>= 1;
c--;
h = 1;
somBola();
}
}
}
}
// Move na linha
if (15 > l && l > 1 && v == 0)
{
b1[(l - 1)] = zero;
l++;
}
else
{
if (15 > l && l > 1 && v == 1)
{
b1[(l - 1)] = zero;
l--;
}
else
{
if (l == 1 && v == 1)
{
b1[(l - 1)] = zero;
l++;
v = 0;
somBola();
}
else
{
if (l == 15 && v == 0)
{
b1[(l - 1)] = zero;
l--;
v = 1;
pontos++;
somBola2();
}
}
}
}
}
void perdeuJogo()
{
// Coloca bola na ultiam linha
if (h == 0)
{
mascaraBola <<= 1;
}
else
{
mascaraBola >>= 1;
}
mascaraBola |= mascaraPlataforma;
b1[14] = zero;
b1[15] = mascaraBola;
printByte(b1);
delay(4000); // Atraso de 4 segundos
// Faz piscar a tela e barulho diferente
for (int i = 0; i < 10; i++)
{
printByte(b2);
tone(buzzer, 1500); // Som de 1.5KHz...
delay(100);
printByte(b3);
tone(buzzer, 200); // Som de 200Hz...
delay(100);
}
noTone(buzzer);
// Zera variáveis de Jogo
pontos = 0;
fase = 0;
tempoJogo = 200;
}
void resetJogo()
{
// Ajusta todas variáveis para inicio do jogo
c = random(2, 16); // sorteia coluna
uint16_t mascaraBolaTemporaria = 0b0000000000000001;
mascaraBola = mascaraBolaTemporaria << (c - 1);
h = random(0, 2); // sorteia direção lateral (1 pra direita, 0 pra esquerda)
v = 0; // fixo, semrpre inicia com 0 pra baixo (1 é pra cima)
l = 2; // fixo, sempre inicia na linha 2
for (int i = 0; i < 16; i++)
{
b1[i] = zero;
}
}
void somBola()
{
tone(buzzer, (700 + fase * 15)); // Som 850 Hz, fica mais agudo conforme passa de fase
delay(20); // duração de 20 mseg
noTone(buzzer); // Termina som
}
void somBola2()
{
tone(buzzer, (200 + fase * 15)); // Som de 200 Hz, fica mais agudo conforme passa de fase
delay(30); // duração de 30 mseg
noTone(buzzer); // Termina som
}