How I made a game console

I recently started messing around with an Arduino. I have had previous experience with a Raspberry Pi, and I wanted to see what I could make with this. After some work I ended up with this, the ultimate modern gaming console.

The Hardware

I used an Arduino Uno, two 8×8 Dot-Matrix displays, a buzzer and a joystick to make this. Every modern gaming console uses joysticks, so this is state-of-the-art. The dot-matrix display uses individually lit LEDs, just like cutting-edge OLED TVs that all serious modern gamers use. The two displays sit next to each other to make a 16×8 widescreen display (I couldn’t deny players the modern widescreen experience!)

The Game

Now where this console really shines is its game. Like all modern consoles, it has no disc-drive, and stores its game digitally! The game it plays is Space Invaders, one of the highest-grossing video games of all time.

When you push the joystick left, it shoots a lethal projectile from your spaceship, murdering any pesky aliens in its way. You have three lives in this game, and you lose one each time your spaceship gets hit or an alien evades you. There are five levels, and you need to murder eight aliens to progress. The levels increase in difficulty. The bar in the bottom left shows kills, and the bar in the top left shows lives. Once you beat the final fifth level, the buzzer plays a jingle.

The code

I programmed and built the entire console myself. Here is the code:

#include <MaxMatrix.h>
#define STICK_X A0
#define STICK_Y A1
#define STICK_BUTTON 2
#define BUZZER 3
#define MATRIX_DIN 7
#define MATRIX_CS 6
#define MATRIX_CLK 5
#define NUM_OF_MATRIXES 2
#define MAXALIENS 5
#define FPS 5
int lives = 3;
MaxMatrix m(MATRIX_DIN, MATRIX_CS, MATRIX_CLK, NUM_OF_MATRIXES);
int playerX = 0;
int playerY = 3;
int laserX = 0;
int laserY = 0;
int aliens[MAXALIENS][2];
int numOfAliens = 0;
unsigned long int aliensTimer = 0;
void setup() {
  for (int i = 0; i < MAXALIENS; i++) {
    aliens[i][0] = -1;
    aliens[i][1] = -1;
  }
  pinMode(BUZZER, OUTPUT);
  m.init();
  m.setIntensity(8);
  Serial.begin(9600);
}
void loop() {
  unsigned long int loop_start = millis();
  int x = analogRead(STICK_X);
  int y = analogRead(STICK_Y);
  char joystickInput = ' ';
  aliensTimer++;
  if (x > 700 && y < x && y > 300) {
    joystickInput = 'L';
  }
  else if (x < 300 && y > x && y < 700) {
    joystickInput = 'R';
  }
  else if (y > 700 && y > x && x > 300) {
    joystickInput = 'U';
  }
  else if (y < 300 && y < x && x < 700) {
    joystickInput = 'D';
  }
  switch (joystickInput) {
    case 'L':
      //playerX++;
      if (laserX == 0) {
        laserX = 1;
        laserY = playerY;
        noTone(BUZZER);
        tone(BUZZER, 261.6256, 1000 / FPS);
      }
      break;
    case 'R':
      //playerX--;
      break;
    case 'U':
      playerY++;
      break;
    case 'D':
      playerY--;
      break;
  }
  if (playerY > 6) {
    playerY = 6;
  }
  if (playerY < 1) {
    playerY = 1;
  }
  if (laserX > 0) {
    laserX++;
  }
  if (laserX > (NUM_OF_MATRIXES * 8 - 1)) {
    laserX = 0;
    laserY = 0;
  }
  for (int i = 0; i < numOfAliens; i++) {
    aliens[i][0]--;
    if ((aliens[i][0] == laserX || aliens[i][0] == laserX + 1 || aliens[i][0] == laserX - 1) && aliens[i][1] == laserY) {
      noTone(BUZZER);
      tone(BUZZER, 523.2511, 1000 / FPS);
      removeAlien(i);
      laserX = 0;
      laserY = 0;
    }
    if (aliens[i][0] == playerX && aliens[i][1] == playerY) {
      removeAlien(i);
      loseLife();
      loop_start = millis();
    }
    if (aliens[i][0] == -1) {
      removeAlien(i);
    }
  }
  if (aliensTimer % (30 - MAXALIENS * 4) == 0) {
    numOfAliens++;
    aliens[numOfAliens - 1][0] = (NUM_OF_MATRIXES * 8 - 1);
    aliens[numOfAliens - 1][1] = random(1, 7);
  }
  m.clear();
  m.setDot(playerX, playerY, true);
  m.setDot(playerX, playerY+1, true);
  m.setDot(playerX, playerY-1, true);
  m.setDot(playerX+1, playerY, true);
  if (laserX > 0) {
    m.setDot(laserX, laserY, true);
  }
  for (int i = 0; i < numOfAliens; i++) {
    m.setDot(aliens[i][0], aliens[i][1], true);
  }
  for (int i = 0; i < lives; i++) {
    m.setDot((NUM_OF_MATRIXES * 8 - 1) - i, 7, true);
  }
  delay((1000 / FPS) - (millis() - loop_start));
}
void endGame() {
  bool flash = true;
  noTone(BUZZER);
  int count = 0;
  while (true) {
    if (count < 3) {
      count++;
      noTone(BUZZER);
      tone(BUZZER, 130.8128, (1000 / FPS) / 2);
    }
    m.clear();
    if (flash) {
      m.setDot(playerX, playerY, true);
      m.setDot(playerX, playerY+1, true);
      m.setDot(playerX, playerY-1, true);
      m.setDot(playerX+1, playerY, true);
    }
    flash = !flash;
    delay(1000 / FPS);
  }
}
void loseLife() {
  lives--;
  if (lives) {
    bool flash = true;
    noTone(BUZZER);
    tone(BUZZER, 130.8128, 1000 / FPS);
    for (int i = 0; i < 6; i++) {
      m.clear();
      if (flash) {
        m.setDot(playerX, playerY, true);
        m.setDot(playerX, playerY+1, true);
        m.setDot(playerX, playerY-1, true);
        m.setDot(playerX+1, playerY, true);
        m.setDot((NUM_OF_MATRIXES * 8 - 1) - lives, 7, true);
      }
      if (laserX > 0) {
        m.setDot(laserX, laserY, true);
      }
      for (int i = 0; i < numOfAliens; i++) {
        m.setDot(aliens[i][0], aliens[i][1], true);
      }
      for (int i = 0; i < lives; i++) {
        m.setDot((NUM_OF_MATRIXES * 8 - 1) - i, 7, true);
      }
      flash = !flash;
      delay(1000 / FPS);
    }
    return millis();
  }
  else {
    endGame();
  }
}
void removeAlien(int alien) {
  for (int j = alien + 1; j < numOfAliens; j++) {
    aliens[j - 1][0] = aliens[j][0];
    aliens[j - 1][1] = aliens[j][1];
  }
  for (int j = numOfAliens; j < MAXALIENS; j++) {
    aliens[j][0] = -1;
    aliens[j][1] = -1;
  }
  numOfAliens--;
}

The code makes use of the MaxMatrix library. You can set the pin numbers for the various components at the top, and how many 8×8 matrix displays you have.

Leave a comment