Snackino: O Jogo da Cobrinha Implementado no Arduino Uno
Bem-vindo a mais um projeto emocionante no DevMaker! Hoje, vamos explorar o "Snackino", uma implementação divertida do clássico jogo da cobrinha (Snake) usando hardware Arduino. Este projeto é perfeito para iniciantes em eletrônica e programação, pois combina controle de display gráfico, entrada de joystick e lógica de jogo simples. Usando um Arduino Uno R3, um joystick shield e um módulo display Nokia 5110 (NK5110), você pode recriar esse jogo icônico de forma portátil e interativa.
O objetivo do jogo é controlar a cobrinha para comer os "ovos" (alimentos) que aparecem na tela, crescendo em tamanho enquanto evita colidir com as bordas ou com o próprio corpo. O placar é atualizado em tempo real, e há um registro de recorde!

Materiais Necessários
Para montar o Snackino, você precisará dos seguintes componentes:
- Arduino Uno R3
- Joystick Shield (com botões para direções: up, down, left, right)
- Módulo Display NK5110 (baseado no PCD8544, o clássico Nokia 5110)
- Buzzer ou speaker pequeno (conectado ao pino A3 para sons de beep)
- Cabos jumper (se necessário para conexões personalizadas)
- Computador com Arduino IDE instalada
Passo a Passo
Configuração Inicial
- Baixe e instale a Arduino IDE, se ainda não tiver.
- Adicione as bibliotecas necessárias via Gerenciador de Bibliotecas na IDE:
- Adafruit_GFX
- Adafruit_PCD8544
- Conecte o joystick shield diretamente sobre o Arduino Uno R3 (ele se encaixa nos pinos).
- Conecte o display NK5110 aos pinos especificados:
- CLK: Pino 9
- DIN: Pino 10
- DC: Pino 11
- CE: Pino 13
- RST: Pino 12
- Conecte o speaker ao pino 17 (A3) e ao GND.
Código do Arduino
Aqui está o código completo para o jogo. Copie e cole na Arduino IDE, verifique e carregue para o board.
//Programa: Snake com Arduino Uno
//Alteracoes e adaptacoes: DevMaker
//
//Baseado no codigo original de Abhinav Faujdar *****/
#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>
#include <SPI.h>
// For LCD from DX.com (https://forum.arduino.cc/index.php?topic=322642.0)
#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>
// Pinos de conexão com o display
#define RST 12
#define CE 13
#define DC 11
#define DIN 10
#define CLK 9
// Inicializa o objeto do display
Adafruit_PCD8544 display = Adafruit_PCD8544(CLK, DIN, DC, CE, RST);
#define LEFT 5
#define DOWN 4
#define RIGHT 3
#define UP 2
#define speakerPin 17
//Verifica em qual direcao a cobra esta se movendo
boolean dl = false, dr = false, du = false, dd = false;
int x[50], y[50], i, slength, tempx = 10, tempy = 10, xx, yy;
unsigned int high;
uint8_t bh, bl;
int xegg, yegg;
int freq, tb;
int l, r, u, d, p;
unsigned long time = 280, beeptime = 50;
int score = 0, flag = 0;
void setup()
{
Serial.begin(9600);
display.begin();
//Informacoes iniciais display
display.setContrast(50);
display.clearDisplay();
display.drawRoundRect(0, 0, 84 , 25, 1, 2);
display.setTextSize(2);
display.setTextColor(BLACK);
display.setCursor(12, 6);
display.println("SNAKE");
display.setTextSize(1);
display.setTextColor(BLACK);
display.setCursor(12, 29);
display.println("DevMaker");
display.setCursor(13, 29);
display.println("DevMaker");
display.setCursor(0, 40);
display.println("devmaker.online");
display.display();
delay(2000);
pinMode(LEFT, INPUT);
pinMode(RIGHT, INPUT);
pinMode(UP, INPUT);
pinMode(DOWN, INPUT);
pinMode(speakerPin, OUTPUT);
digitalWrite(LEFT, HIGH);
digitalWrite(RIGHT, HIGH);
digitalWrite(UP, HIGH);
digitalWrite(DOWN, HIGH);
slength = 8;
xegg = (display.width()) / 2;
yegg = (display.height()) / 2;
display.clearDisplay();
display.drawRect(0, 0, 84, 48, 1);
display.setCursor(4, 2);
display.print("P: R:");
display.setCursor(22, 2);
display.print(score);
display.setCursor(64, 2);
display.print(high);
display.drawRect(0, 0, 84, 11, 1);
//Define coordenadas iniciais
for (i = 0; i <= slength; i++)
{
x[i] = 25 - 3 * i;
y[i] = 30;
}
for (i = 0; i < slength; i++) //Draw the snake
{
display.drawCircle(x[i], y[i], 1, BLACK);
}
display.display();
dr = true;
}
void loop()
{
movesnake();
}
void movesnake()
{
//Leitura do valor dos botoes
l = digitalRead(LEFT);
d = digitalRead(DOWN);
r = digitalRead(RIGHT);
u = digitalRead(UP);
if (flag == 0)
{
direct();
}
if (millis() % time == 0)
{
if (flag == 0)
{
if (dr == true) {
tempx = x[0] + 3;
tempy = y[0];
}
if (dl == true) {
tempx = x[0] - 3;
tempy = y[0];
}
if (du == true) {
tempy = y[0] - 3;
tempx = x[0];
}
if (dd == true) {
tempy = y[0] + 3;
tempx = x[0];
}
}
flag = 0;
//Verifica se a cobra esta nas mesmas coordenadas do ovo
checkgame();
checkegg();
//Altera as coordenadas de todos os pontos da cobra
for (i = 0; i <= slength; i++)
{
xx = x[i];
yy = y[i];
x[i] = tempx;
y[i] = tempy;
tempx = xx;
tempy = yy;
}
//Desenha a cobra e o ovo nas novas coordenadas
drawsnake();
}
}
void checkgame()
{
for (i = 1; i < slength; i++)
{
//Verifica se o recorde foi batido e
//mostra na tela o novo valor
high = (((0xff00 + bh) << 8) + bl);
if (score > high)
{
high = score;
bh = (high >> 8);
bl = high & 0xff;
display.fillRect(61, 1, 20, 9, 0);
display.setCursor(65, 2);
display.print(high);
}
//Verifica se tocou nas bordas
if ((x[0] <= 1 || x[0] >= 83) || (y[0] <= 12 || y[0] >= 47) || (x[i] == x[0] && y[i] == y[0]) )
{
//Jogo terminado. Mostra informacoes na tela
display.clearDisplay();
display.fillRoundRect(0, 0, 84 , 31, 1, 2);
display.setTextColor(WHITE);
display.setTextSize(2);
display.setCursor(18, 1);
display.print("GAME");
display.setCursor(18, 16);
display.print("OVER");
display.setTextColor(BLACK);
display.setTextSize(1);
display.setCursor(12, 33);
display.print("PLACAR");
display.setCursor(60, 33);
display.print(score);
display.setCursor(12, 41);
display.print("RECORDE");
display.setCursor(60, 41);
display.print(high);
display.display();
//Aguarda 5 segundos e reinicia o jogo
delay(5000);
//Apaga a tela
display.clearDisplay();
//Retorna aos valores iniciais
slength = 8;
score = 0;
time = 280;
redraw();
}
}
}
void checkegg() //Snake meets egg
{
//Verifica se a cobra está nas mesmas coordenadas do ovo
if (x[0] == xegg or x[0] == (xegg + 1) or x[0] == (xegg + 2) or x[0] == (xegg - 1))
{
if (y[0] == yegg or y[0] == (yegg + 1) or y[0] == (yegg + 2) or y[0] == (yegg - 1))
{
//Incrementa a cobra em uma posição, incrementa o placar e
//aumenta a velocidade do jogo, diminuindo o tempo
score += 1;
display.fillRect(21, 1, 20, 9, 0);
display.setCursor(22, 2);
display.print(score);
slength += 1;
if (time >= 90)
{
time -= 10;
}
display.fillRect(xegg, yegg, 3, 3, WHITE);
display.display();
beep(35, beeptime);
//Cria novo ovo em posicao aleatoria
xegg = random(2, 80);
yegg = random(15, 40);
}
}
}
void direct()
{
//Altera o movimento caso uma tecla tenha sido pressionada
if (l == LOW and dr == false)
{
dl = true; du = false; dd = false;
//Salva novas coordenadas em Tempx, Tempy
tempx = x[0] - 3;
tempy = y[0];
flag = 1;
}
else if (r == LOW and dl == false)
{
dr = true; du = false; dd = false;
tempx = x[0] + 3;
tempy = y[0];
flag = 1;
}
else if (u == LOW and dd == false)
{
du = true; dl = false; dr = false;
tempy = y[0] - 3;
tempx = x[0];
flag = 1;
}
else if (d == LOW and du == false)
{
dd = true; dl = false; dr = false;
tempy = y[0] + 3;
tempx = x[0];
flag = 1;
}
}
void drawsnake()
{
display.fillRect(xegg, yegg, 3, 3, BLACK);
display.drawCircle(x[0], y[0], 1, BLACK);
display.drawCircle(x[slength], y[slength], 1, WHITE);
display.display();
}
void redraw()
{
display.drawRect(0, 0, 84, 48, 1);
display.drawRect(0, 0, 84, 48, 1);
display.setCursor(4, 2);
display.print("P: R:");
display.drawRect(0, 0, 84, 11, 1);
display.fillRect(21, 1, 20, 9, 0);
display.setCursor(22, 2);
display.print(score);
display.fillRect(61, 1, 20, 9, 0);
display.setCursor(65, 2);
display.print(high);
xegg = (display.width()) / 2;
yegg = (display.height()) / 2;
dl = false, dr = false, du = false, dd = false;
dr = true;
display.setCursor(4, 2);
display.print("P: R:");
display.drawRect(0, 0, 84, 11, 1);
//Retorna as coordenadas iniciais
for (i = 0; i <= slength; i++)
{
x[i] = 25 - 3 * i;
y[i] = 30;
}
tempx = 33 - 3 * i;
tempy = 30;
display.display();
}
void beep (int freq, long tb)
{
int x;
long delayAmount = (long)(500 / freq);
long loopTime = (long)(tb / (delayAmount * 2));
for (x = 0; x < loopTime; x++)
{
digitalWrite(speakerPin, HIGH);
delay(delayAmount);
digitalWrite(speakerPin, LOW);
delay(delayAmount);
}
delay(2);
}
Explicação do Código
O código é baseado em uma adaptação do original de Abhinav Faujdar, com alterações para compatibilidade com o display e joystick.
- Bibliotecas e Definições: Inclui as bibliotecas Adafruit para gerenciar o display gráfico. Define os pinos para o display, joystick e speaker.
- Setup(): Inicializa o display, configura os pinos como inputs (com pull-up) e desenha a tela inicial com "SNAKE" e créditos. Define a cobrinha inicial com comprimento 8 e posiciona o primeiro ovo.
- Loop(): Chama a função
movesnake()continuamente para atualizar o jogo. - movesnake(): Lê os inputs do joystick, atualiza a direção, move a cobrinha a cada intervalo de tempo, verifica colisões e desenha na tela.
- checkgame(): Verifica se a cobrinha colidiu com bordas ou consigo mesma. Atualiza o recorde e reinicia o jogo após "GAME OVER".
- checkegg(): Detecta se a cobrinha comeu o ovo, incrementa o score, cresce a cobrinha, acelera o jogo e gera um novo ovo.
- direct(): Altera a direção da cobrinha com base nos botões pressionados, evitando movimentos reversos.
- drawsnake(): Desenha o ovo, a cabeça da cobrinha e apaga a cauda para simular movimento.
- redraw(): Reinicia a tela e posições iniciais após game over.
- beep(): Gera sons simples no speaker quando come o ovo.

Testando o Projeto
- Conecte o Arduino ao computador via USB.
- Abra a Arduino IDE, selecione a porta correta e carregue o código.
- Após o upload, o display mostrará a tela inicial "SNAKE".
- Use o joystick para mover a cobrinha (esquerda, direita, cima, baixo).
- Coma os ovos para aumentar o score e o tamanho. O jogo acelera conforme você pontua!
- Se colidir, verá "GAME OVER" com placar e recorde. Aguarde 5 segundos para reiniciar.
Divirta-se com o Snackino! Sinta-se à vontade para modificar o código, como adicionar níveis ou melhorar os gráficos. Se tiver dúvidas ou melhorias, compartilhe nos comentários abaixo. Fique ligado no DevMaker para mais projetos Arduino!
Comentários
Nenhum comentário ainda. Seja o primeiro a comentar!
Faça login para adicionar um comentário.