Hackster is hosting Hackster Holidays, Finale: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Tuesday!Stream Hackster Holidays, Finale on Tuesday!
Mirko Pavleski
Published © GPL3+

OSU! Catch the Beat Game on Homemade 8x8 Matrix

This is a simplified version of "Osu! Catch the Beat" game which is played on an 8 to 8 LED matrix.

BeginnerFull instructions provided2,181
OSU! Catch the Beat Game on Homemade 8x8 Matrix

Things used in this project

Hardware components

Arduino Nano R3
Arduino Nano R3
×1
LED (generic)
LED (generic)
×64
Buzzer
Buzzer
×1
Rotary potentiometer (generic)
Rotary potentiometer (generic)
×1

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)
Solder Wire, Lead Free
Solder Wire, Lead Free

Story

Read more

Schematics

Schematic

Code

Arduino Code

C/C++
int row[] = {12, 11, 10, 9, 8, 7, 6, 5};
int col[] = {4, 3, 2, A0, A1, A2, A3, A4};
int joystick = A6; //it is a simple potentiometer
int lastUpdate;
int puntos = 0;
int vidas = 10; //number of lives
int speakerPin = 13;
int SPEED = 0;
bool updatedAsteroid = false, updatedPlayer = true;

typedef struct coordenada {
  int x; //column coordinate
  int y; //row coordinate
}COORD;

COORD asteroid, jugador;

void setup() {
  // put your setup code here, to run once:
  
  for (int i = 0; i < 8; i++)
  {
    pinMode(row[i], OUTPUT);
    pinMode(col[i], OUTPUT);
    digitalWrite(col[i], HIGH);
    digitalWrite(row[i], LOW);
  }
  pinMode(speakerPin, OUTPUT);
  initGame();
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  for(int i = 0; i < 2; i++)
  {
    clearScreen(); //clean the led matrix
    if(lastUpdate == 1) {
      movePlayer();
    }
    if(lastUpdate == 0) {
      asteroidFall();
      //Serial.print ("The asteroid changes position !! \ n");
    }
    lastUpdate = Update(); //update the array of LEDs according to movePlayer () and asteroidFall ()
    delay(SPEED);
  }
  puntuacion(); //calculates the score and increases one life per point, when the player runs out of lives it goes to gameover () to restart the game
  if (asteroid.y == 8 || asteroid.y > 8) {
    initasteroid(); //initialize a new asteroid when the previous one has already dropped
  }
}

void initGame() {
  vidas = 10;
  puntos = 0; //points
  SPEED = 25;
  initplayer();
  initasteroid();
  return;
}

void initplayer() {
  jugador.x = 3;
  jugador.y = 7;
  digitalWrite(col[jugador.y], HIGH);
  digitalWrite(row[jugador.x], LOW);
  return;
}

void initasteroid() {
  asteroid.x = random(0, 7);
  asteroid.y = -1; //so that asteroid Fall () starts at 0 as soon as it is executed
  digitalWrite(col[asteroid.x], LOW);
  digitalWrite(row[asteroid.y], HIGH);
  return;
}

void movePlayer() {
  int value = analogRead(joystick);
  value = map(value, 0, 1023, 0, 7);
  value = constrain(value, 0, 7);
  //Serial.print("joystickX: ");
  //Serial.print(jugador.x);
  //Serial.print("\n");
  if(value >= 0 && value <= 7) {
    jugador.x = value;
  }
  return;
}

void asteroidFall() {
  asteroid.y++;
  //Serial.print("AsteroidY: ");
  //Serial.print(asteroid.y);
  //Serial.print("\n");
  return;
}

void clearScreen() {
  for (int led = 0; led < 8; led++)
  {
    digitalWrite(col[led], HIGH);
    digitalWrite(row[led], LOW);
  }
  return;
}

int Update() {
  if(updatedAsteroid == true && updatedPlayer == false) {
    digitalWrite(col[jugador.x], LOW);
    digitalWrite(row[jugador.y], HIGH);
    updatedAsteroid = false;
    updatedPlayer = true;
    //Serial.print("Player Updated !! \ n");
    return 0; //returns that the player has been updated
  } else {
    digitalWrite(col[asteroid.x], LOW);
    digitalWrite(row[asteroid.y], HIGH);
    updatedAsteroid = true;
    updatedPlayer = false;
    //Serial.print ("Asteroid Updated !! \ n");
    return 1; //returns that the asteroid has been updated
  }
}

void puntuacion() {
  if(asteroid.y == jugador.y && asteroid.x == jugador.x) {
      digitalWrite(speakerPin, HIGH);
      puntos++;
      delay(100);
      digitalWrite(speakerPin, LOW);
      vidas += 2;
      if(SPEED > 9 && puntos >= 4) {
        SPEED--; //SPEED up the game (new level)
        puntos = 0; //We restart the punctuation when we go to the next level
      }
      Serial.print("Points: ");
      Serial.print(puntos);
      Serial.print("\n");
  } 
  if(asteroid.y == jugador.y && asteroid.x != jugador.x) {
      vidas--;
      Serial.print("Vidas: ");
      Serial.print(vidas);
      Serial.print("\n");
      if(vidas == 0) {
        gameover();
      }
  }
  return;
}

void gameover() {
  //animation when you lose the game
  for(int y = 0; y < 5; y++)
  {
    //Serial.print("Animacion: ");
    //Serial.print(y);
    //Serial.print("\n");
    //loop that turns off all LEDs in the matrix
    digitalWrite(speakerPin, HIGH);
    for(int i = 0; i < 8; i++)
    {
      digitalWrite(col[i], HIGH);
      digitalWrite(row[i], LOW);
    }
    delay(500);
    //loop that turns on all the LEDs of the matrix
    for(int i = 0; i < 8; i++)
    {
      digitalWrite(col[i], LOW);
      digitalWrite(row[i], HIGH);
    }
    digitalWrite(speakerPin, LOW);
    delay(500);
  }
  delay(3000);
  initGame(); //initialize a new game
  return;
}

Credits

Mirko Pavleski
155 projects • 1305 followers

Comments