Jogo de Arco e Flecha no Arduino com LCD 16x2
Jogo de Arco e Flecha no Arduino com LCD 16x2
Introdução
Neste artigo, vamos explorar como criar um jogo de arco e flecha simples usando Arduino e um display LCD 16x2, baseado no projeto disponível no Arduino Project Hub. Este projeto é uma ótima maneira de aprender sobre programação de jogos simples, manipulação de displays LCD e uso de botões como controles.
Materiais Necessários
1 Arduino Uno (ou similar)
1 Display LCD 16x2 com módulo I2C
2 botões push-button
1 Potenciômetro 10kΩ (para ajuste de contraste do LCD)
Resistores de 10kΩ (para os botões)
Protoboard e jumpers
Circuito do Projeto
O circuito é relativamente simples:
Conecte o display LCD ao Arduino via interface I2C (GND-GND, VCC-5V, SDA-A4, SCL-A5)
Conecte dois botões aos pinos digitais (por exemplo, D2 e D6) com resistores pull-down
Explicação do Código
O jogo consiste em controlar um arqueiro na parte inferior da tela que atira flechas para atingir alvos que aparecem aleatoriamente na parte superior.
} #include <LiquidCrystal.h> const int buttonPin1 = 6; const int buttonPin2 = 1; int button1state = 0; int button2state = 0; int arrowRow = 0; int newRow = 0; int sameRowCounter = 0; LiquidCrystal lcd(12, 11, 5, 4, 3, 2); byte weakblock[] = { B01100, B01100, B01100, B01100, B01100, B01100, B01100, B01100 }; byte strongblock[] = { B00000, B00000, B11111, B11111, B11111, B11111, B11111, B00000 }; byte bow[] = { B00000, B00110, B01110, B10010, B11111, B10010, B01110, B00110 }; byte bow2[] = { B00100, B00110, B00110, B00101, B00101, B00110, B00110, B00100 }; byte arrow[] = { B00000, B00000, B00100, B00010, B11111, B00010, B00100, B00000 }; byte superarrow[] = { B00000, B01000, B00100, B00110, B11111, B00110, B00100, B01000 }; struct OneBlock { int row; int col; int type; }; OneBlock blocks[15]; int counter; int score; int scoreCol; unsigned long prevScoreMillis = 0; unsigned long prevBlockMillis = 0; unsigned long prevArrowMillis = 0; unsigned long prevSuperMillis = 0; bool gameOver = false; bool superArrow = false; void setup() { pinMode(buttonPin1, INPUT); pinMode(buttonPin2, INPUT); lcd.begin(16, 2); lcd.createChar(0, weakblock); lcd.createChar(1, strongblock); lcd.createChar(2, bow); lcd.createChar(3, bow2); lcd.createChar(4, arrow); lcd.createChar(5, superarrow); randomSeed(analogRead(0)); arrowRow = 0; superArrow = false; score = 0; counter = 0; blocks[0].row = random(0, 2); blocks[0].col = 15; for (int i = 0; i < 15; ++i) blocks[i].row = -1; } void EndGame() { lcd.clear(); lcd.setCursor(3, 0); lcd.print("Game Over"); lcd.setCursor(3, 1); lcd.print("Score:"); lcd.setCursor(9, 1); lcd.print(score); gameOver = true; } void IncrementScore() { score++; if (score > 9999) scoreCol = 11; else if (score > 999) scoreCol = 12; else if (score > 99) scoreCol = 13; else if (score > 9) scoreCol = 14; else scoreCol = 15; } void loop() { if (gameOver) { button1state = digitalRead(buttonPin1); button2state = digitalRead(buttonPin2); if (button1state == HIGH || button2state == HIGH) { gameOver = false; delay(1000); setup(); } else return; } unsigned long currentMillis = millis(); button1state = digitalRead(buttonPin1); button2state = digitalRead(buttonPin2); if (currentMillis - prevArrowMillis >= 450) { if (button1state == HIGH && !superArrow) { lcd.setCursor(1, arrowRow); lcd.print(" "); if (arrowRow == 0) { arrowRow = 1; prevArrowMillis = currentMillis; } else if (arrowRow == 1) { arrowRow = 0; prevArrowMillis = currentMillis; } } } if (currentMillis - prevSuperMillis >= 450) { if (button2state == HIGH) { superArrow = !superArrow; prevSuperMillis = currentMillis; } } if (currentMillis - prevScoreMillis >= 1000) { prevScoreMillis = currentMillis; IncrementScore(); } bool redraw = false; if (score > 9999 && currentMillis - prevBlockMillis >= 1) { prevBlockMillis = currentMillis; redraw = true; } else if (score > 500 && currentMillis - prevBlockMillis >= 200) { prevBlockMillis = currentMillis; redraw = true; } else if (score > 99 && currentMillis - prevBlockMillis >= 350) { prevBlockMillis = currentMillis; redraw = true; } else if (score > 9 && currentMillis - prevBlockMillis >= 450) { prevBlockMillis = currentMillis; redraw = true; } else if (currentMillis - prevBlockMillis >= 500) { prevBlockMillis = currentMillis; redraw = true; } if (score > 0) { lcd.setCursor(scoreCol, 0); lcd.print(score); } if (score >= 5) { lcd.setCursor(1, arrowRow); if (superArrow) lcd.write(byte(5)); else lcd.write(byte(4)); } if (score < 5) { lcd.setCursor(0, 0); lcd.write(byte(2)); } if (score == 10) { lcd.setCursor(0, 0); lcd.print(" "); } if (score < 10 && score >= 5) { lcd.setCursor(0, 0); lcd.write(byte(3)); } if (!redraw) return; lcd.clear(); for (int i = 0; i < 15; ++i) { if (blocks[i].row != -1) { lcd.setCursor(blocks[i].col, blocks[i].row); lcd.write(byte(blocks[i].type)); blocks[i].col--; if (blocks[i].col < 0) { if (arrowRow == blocks[i].row) { if (!superArrow || superArrow && blocks[i].type == 1) { EndGame(); return; } } blocks[i].row = -1; } if (superArrow && arrowRow == blocks[i].row && blocks[i].col == 1 && blocks[i].type == 0) { IncrementScore(); blocks[i].row = -1; } } } if (sameRowCounter > 0) { counter++; if (counter == 15) counter = 0; blocks[counter].row = newRow; blocks[counter].col = 15; blocks[counter].type = random(0, 2); sameRowCounter--; } else { sameRowCounter = random(1, 5); if (newRow == 1) newRow = 0; else newRow = 1; } }
Funcionamento do Jogo
Controles:
Mecânicas:
O alvo aparece aleatoriamente na linha superior
O jogador deve posicionar o arqueiro e atirar para acertar o alvo
Cada acerto aumenta a pontuação
O jogo termina quando o jogador erra um certo número de vezes (não implementado neste exemplo básico)
Melhorias Possíveis
Adicionar vidas/limite de erros
Implementar diferentes níveis de dificuldade
Adicionar múltiplos alvos simultâneos
Incluir animações mais elaboradas
Armazenar a pontuação máxima na EEPROM
Adicionar um menu inicial
Conclusão
Este projeto demonstra como criar um jogo simples mas divertido usando componentes básicos com Arduino. Ele combina conceitos importantes como leitura de entradas digitais, controle de displays LCD e lógica de jogos. É um excelente ponto de partida para quem quer aprender desenvolvimento de jogos em hardware embarcado.
Para versões mais avançadas, você pode considerar adicionar um display gráfico ou mesmo componentes físicos como um sensor de flexão para simular o movimento de puxar o arco.
Comentários
Postar um comentário