Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Manufacturing Technology >> Processo de manufatura

Crie o Clássico Jogo Asteroids com Arduino Mega e Matriz LED MAX72XX

Componentes Necessários

Componente Quantidade
Arduino Mega 2560 1
Maxim Integrated MAXREFDES99# MAX7219 Display Driver Shield 1
Chave Pushbutton 12mm (SparkFun) 2
Buzzer Ativo 1
Protoboard (genérica) 1

Sobre o Projeto

Este é um jogo simples usando a Matriz LED MAX72XX como display, dois micro switches como botões e um buzzer ativo para efeito sonoro.

Você controla uma nave espacial e deve evitar o contato com asteroides caindo. O jogo acelera com o tempo. No final, uma pontuação é exibida mostrando quanto tempo você sobreviveu.

Código do Jogo


/*********************************************************
 * Jogo Asteroids simples com Matriz LED MAX72XX
 * Você é uma nave e deve evitar asteroides caindo.
 * (c) 2018 by Joshua Weßner
 *******************************************************/

#include "LedControl.h"

// Pinos: DataIn=12, CLK=11, LOAD=10, 1 dispositivo MAX72XX
LedControl lc = LedControl(12, 11, 10, 1);

// Variáveis Globais
unsigned long delaytime = 1000; // delay entre updates do display
String scoreString;
int score = 0;
int hundreds = 0;
String scoreStr;
String scoreArr[3] = {"", "", ""};

int pinLeft = 2;
int pinRight = 3;
volatile unsigned long buttonPressed = 0;
int buttonDelay = 150; // debounce
volatile bool gameOver = false;

int tick = 300; // "ritmo" do jogo em ms
int tickCounter = 1;
unsigned long now = 0;

int ship = 3; // posição inicial da nave (coluna 3)
int columns[8] = {0,0,0,0,0,0,0,0}; // 8 colunas, cada int = linha 1-8
int randomInt;

void setup() {
  gameOver = false;
  hundreds = 0;
  scoreArr[0] = scoreArr[1] = scoreArr[2] = "";
  score = 0;
  tick = 300;
  tickCounter = 1;
  ship = 3;
  now = millis();
  buttonPressed = millis();
  randomSeed(analogRead(15)); // melhor aleatoriedade
  for (int i = 0; i < 8; i++) columns[i] = 0;

  // Serial.begin(9600); // debug

  lc.shutdown(0, false); // wakeup MAX72XX
  lc.setIntensity(0, 1); // brilho médio
  lc.clearDisplay(0);

  pinMode(pinLeft, INPUT_PULLUP);
  pinMode(pinRight, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(pinLeft), left, FALLING);
  attachInterrupt(digitalPinToInterrupt(pinRight), right, FALLING);
}

// Botão ESQUERDA
void left() {
  if (millis() - buttonPressed > buttonDelay) {
    if (ship != 0) ship--; else ship = 7;
    lc.clearDisplay(0);
    buttonPressed = millis();
  }
  if (gameOver) { gameOver = false; setup(); }
}

// Botão DIREITA
void right() {
  if (millis() - buttonPressed > buttonDelay) {
    if (ship != 7) ship++; else ship = 0;
    lc.clearDisplay(0);
    buttonPressed = millis();
  }
  if (gameOver) { gameOver = false; setup(); }
}

void loop() {
  if (millis() - now > tick) {
    score++; // pontuação = ticks sobrevividos
    now = millis();

    if (tickCounter == 1) { // a cada 4 ticks
      tick = tick / 1.02; // jogo acelera gradualmente
      randomInt = random(0, 8);
      if (columns[randomInt] == 0) columns[randomInt] = 1; // novo asteroide no topo
    }
    if (tickCounter != 4) tickCounter++; else tickCounter = 1;

    // mover asteroides para baixo
    for (int i = 0; i < 8; i++) {
      if (columns[i] == 10) columns[i] = 0; // saiu do display
      if (columns[i] != 0) columns[i]++;
    }
    lc.clearDisplay(0);
  }

  // Desenhar nave (linha 7 = inferior)
  lc.setLed(0, 7, ship, true);

  // Desenhar asteroides (2 LEDs cada para melhor visualização)
  for (int i = 0; i < 8; i++) {
    if (columns[i] > 0) {
      lc.setLed(0, columns[i] - 2, i, true);
      lc.setLed(0, columns[i] - 3, i, true);
    }
  }

  // Detectar colisão
  if (columns[ship] == 10 || columns[ship] == 9) {
    lc.clearDisplay(0);
    // Animação de explosão
    for (int i = 0; i < 4; i++) {
      lc.setLed(0, 7, ship + i, true);
      lc.setLed(0, 7, ship - i, true);
      lc.setLed(0, 7 - i, ship + i, true);
      lc.setLed(0, 7 - i, ship - i, true);
      lc.setLed(0, 7 - 1.5 * i, ship, true);
      // Som explosão
      unsigned long time = millis();
      int randomSound = 1000;
      while (millis() - time <= 250) {
        randomSound--;
        tone(9, random(randomSound, 1000));
      }
      lc.clearDisplay(0);
      noTone(9);
    }
    delay(500);

    // Exibir pontuação
    scoreStr = String(score);
    scoreArr[0] = String(scoreStr.charAt(0));
    scoreArr[1] = String(scoreStr.charAt(1));
    scoreArr[2] = String(scoreStr.charAt(2));

    if (score < 100) {
      for (int i = 0; i < 2; i++) {
        drawDigit(scoreArr[i], 1 + i * 4);
      }
    } else {
      // > 99: mostra apenas 2 últimos dígitos
      for (int i = 1; i < 3; i++) {
        drawDigit(scoreArr[i], 1 + (i - 1) * 4);
      }
      // Centenas mostradas como pontos na linha superior
      for (int i = 1; i < 10; i++) {
        if (scoreArr[0] == String(i)) hundreds = i;
      }
      for (int i = 1; i <= hundreds; i++) {
        lc.setLed(0, 0, i - 1, true);
        lc.setLed(0, 1, i - 1, true);
        delay(200);
      }
    }
    gameOver = true;
    while (gameOver) { /* aguarda botão para reiniciar */ }
  }
}

// Funções para desenhar dígitos 0-9 na matriz (cada dígito = 3 colunas)
void drawDigit(String digit, int pos) {
  if (digit == "0") draw0(pos);
  else if (digit == "1") draw1(pos);
  else if (digit == "2") draw2(pos);
  else if (digit == "3") draw3(pos);
  else if (digit == "4") draw4(pos);
  else if (digit == "5") draw5(pos);
  else if (digit == "6") draw6(pos);
  else if (digit == "7") draw7(pos);
  else if (digit == "8") draw8(pos);
  else if (digit == "9") draw9(pos);
}

void draw1(int p) { lc.setColumn(0, 0+p, B00001000); lc.setColumn(0, 1+p, B00011111); }
void draw2(int p) { lc.setColumn(0, 0+p, B00010111); lc.setColumn(0, 1+p, B00010101); lc.setColumn(0, 2+p, B00011101); }
void draw3(int p) { lc.setColumn(0, 0+p, B00010001); lc.setColumn(0, 1+p, B00010101); lc.setColumn(0, 2+p, B00011111); }
void draw4(int p) { lc.setColumn(0, 0+p, B00011100); lc.setColumn(0, 1+p, B00000100); lc.setColumn(0, 2+p, B00011111); }
void draw5(int p) { lc.setColumn(0, 0+p, B00011101); lc.setColumn(0, 1+p, B00010101); lc.setColumn(0, 2+p, B00010111); }
void draw6(int p) { lc.setColumn(0, 0+p, B00011111); lc.setColumn(0, 1+p, B00010101); lc.setColumn(0, 2+p, B00010111); }
void draw7(int p) { lc.setColumn(0, 0+p, B00010000); lc.setColumn(0, 1+p, B00010011); lc.setColumn(0, 2+p, B00011100); }
void draw8(int p) { lc.setColumn(0, 0+p, B00011111); lc.setColumn(0, 1+p, B00010101); lc.setColumn(0, 2+p, B00011111); }
void draw9(int p) { lc.setColumn(0, 0+p, B00011101); lc.setColumn(0, 1+p, B00010101); lc.setColumn(0, 2+p, B00011111); }
void draw0(int p) { lc.setColumn(0, 0+p, B00011111); lc.setColumn(0, 1+p, B00010001); lc.setColumn(0, 2+p, B00011111); }

Esquemático

Consulte o diagrama de fiação no projeto original (conexão do shield MAX7219, botões nos pinos 2 e 3 com pull-up interno, buzzer no pino 9).

Biblioteca Necessária

LedControl por Eberhard Fahle: https://wayoda.github.io/LedControl/

Processo de manufatura

  1. Xadrez: Das Origens Antigas à Fabricação Moderna — Visão de Especialista
  2. Pinball: História, Design e Fabricação de um Clássico dos Fliperamas
  3. A Evolução e Artesanato do Futebol Americano: De Jogos Antigos aos Padrões Modernos da NFL
  4. Construa o Clássico Jogo Pong no Arduino UNO com Display OLED – Tutorial Passo a Passo
  5. Construa Seu Próprio Jogo de Roleta com 37 LEDs e Arduino Nano
  6. Construa um Console Pong 24×16 LED com Arduino Nano e MAX7219
  7. Construa um Jogo Tetris com Arduino Nano em Matriz LED 16×8 DIY
  8. Jogo Interativo com Joystick e Arduino – Feedback com LEDs
  9. Display Interativo de Matriz LED na Porta com Sensor PIR – Saudação de Férias Arduino
  10. Display de Luz com 8 LEDs Ativado por Som