Industrial manufacturing
Industrial Internet of Things | Industrial materials | Equipment Maintenance and Repair | Industrial programming |
home  MfgRobots >> Industrial manufacturing >  >> Manufacturing Technology >> Manufacturing process

NeoPixel Matrix Pong on Arduino Nano: Build a Neon Pong Game

Components and supplies

NeoPixel Matrix Pong on Arduino Nano: Build a Neon Pong Game
NeoPixel strip
×1
NeoPixel Matrix Pong on Arduino Nano: Build a Neon Pong Game
Jumper wires (generic)
×1
NeoPixel Matrix Pong on Arduino Nano: Build a Neon Pong Game
Arduino Nano R3
×1
NeoPixel Matrix Pong on Arduino Nano: Build a Neon Pong Game
Female Header 8 Position 1 Row (0.1")
×1
NeoPixel Matrix Pong on Arduino Nano: Build a Neon Pong Game
Perma-Proto Breadboard Half Size
×1
Analog joystick (Generic)
×1
NeoPixel Matrix Pong on Arduino Nano: Build a Neon Pong Game
Rotary potentiometer (generic)
×1

Necessary tools and machines

NeoPixel Matrix Pong on Arduino Nano: Build a Neon Pong Game
Soldering iron (generic)

Apps and online services

NeoPixel Matrix Pong on Arduino Nano: Build a Neon Pong Game
Arduino IDE

About this project

The Matrix

No, not the movie, the NeoPixel matrix! To make a matrix, just buy one strip of individually addressable NeoPixel LEDs. Uncoil the strip, and take note of the arrows on it. You can only attach them in ONE DIRECTION, you could ruin them if the orientation is wrong.

NeoPixel Matrix Pong on Arduino Nano: Build a Neon Pong Game

I used a 30 led/m 5m strip and cut them into strips of ten LEDs each. I then started laying down the strips on a piece of cardstock, alternating orientations. I then cut wires to the correct lengths and soldered them to the NeoPixel terminals. After doing that 14 times, my matrix was finally done! Next, I checked with a multimeter to ensure that there were no short-circuits, as a short-circuit will fry the Nano, the matrix, and maybe your USB port (I know from experience). Upload the neomatrix test sketch with the "NEO_BOTTOM + NEO_LEFT + NEO_COLUMNS + NEO_ZIGZAG" parameters. If it scroll "howdy" across the display, you're done with the display part!

NeoPixel Matrix Pong on Arduino Nano: Build a Neon Pong Game

The Logic

A pong game has several objects: the paddle, walls, and the ball. The code has ball X and ball Y variables, which keep track of the ball's position. The ball's direction is handled by either a 1 or -1 being assigned to the direction variables. The paddle is a rectangle that is controlled via a potentiometer being mapped to 0 through 15. The paddle's Y won't change, so a variable for mapping it isn't needed. At the start of a game, the ball starts at 1,1 and the player must allow the ball to bounce once to begin. The physics take into account the ball's direction and where it hit on the paddle.

Fun time!

Now, just hook up the NeoPixel matrix your Arduino Nano, the +5V on the joystick to 5v, the GND to Arduino GND, and finally the X axis to A0. Have fun with your new pong game! Try adding more players and better physics for a challenge!

Code

  • The Arduino Code
  • Arduino Code
The Arduino CodeC/C++
#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include <Adafruit_NeoPixel.h>

#define PIN 6

Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(15, 10, PIN,
  NEO_MATRIX_BOTTOM     + NEO_MATRIX_LEFT +
  NEO_MATRIX_COLUMNS + NEO_MATRIX_ZIGZAG,
  NEO_GRB            + NEO_KHZ800);

// variables for the position of the ball and paddle
int paddleX = 0;
int paddleY = 0;
int oldPaddleX, oldPaddleY;
int ballDirectionX = 1;
int ballDirectionY = 1;
int score = 0;

int ballSpeed = 10; // lower numbers are faster

int ballX, ballY, oldBallX, oldBallY;

void setup() {
  Serial.begin(9600);
  // initialize the display
  matrix.begin();
  // black background
  matrix.fillScreen(0);
  matrix.setTextColor(matrix.Color(0,255,0));
  matrix.print("GO");
  matrix.show();
  delay(2000);
  matrix.fillScreen(0);
  matrix.show();
}

void loop() {

  // save the width and height of the screen
  int myWidth = matrix.width();
  int myHeight = matrix.height();

  // map the paddle's location to the position of the potentiometers
  paddleX = map(analogRead(A0), 0, 1023, 0, 12);
  paddleY = 8;
  
  // set the fill color to black and erase the previous
  // position of the paddle if different from present

  if (oldPaddleX != paddleX || oldPaddleY != paddleY) {
    matrix.fillRect(oldPaddleX, oldPaddleY, 4, 1,matrix.Color(0,0,0));
  }

  // draw the paddle on screen, save the current position
  // as the previous.
//if(paddleX >= 0 && paddleX <= 11){
  matrix.fillRect(paddleX, paddleY, 4, 1,matrix.Color(0,0,255));
//}
//else if(paddleX < 0){
  //paddleX = 0;
  //matrix.fillRect(paddleX, paddleY, 3, 1,matrix.Color(0,0,255));
//}
//else if(paddleX >= 13){
  
//}
  oldPaddleX = paddleX;
  oldPaddleY = paddleY;
  matrix.show();

  // update the ball's position and draw it on screen
  if (millis() % ballSpeed < 2) {
    moveBall();
  }
  matrix.show();
  if(ballY > 8 && (millis() > 10000)){
    score += 1;
    matrix.fillScreen(0);
    matrix.setTextColor(matrix.Color(255,0,0));
    matrix.setCursor(0,2);
    matrix.print(String(score));
    matrix.show();
    delay(4000);
    ballX = random(3,11);
    ballY = random(1,1);
    matrix.fillScreen(0);
    matrix.show();
    delay(1000);
  }
  delay(5);
}

// this function determines the ball's position on screen
void moveBall() {
  // if the ball goes offscreen, reverse the direction:
  if (ballX > matrix.width() - 1 || ballX < 0) {
    ballDirectionX = -ballDirectionX;
  }

  if (ballY > matrix.height() || ballY < 0) {
    ballDirectionY = -ballDirectionY;
  }

  // check if the ball and the paddle occupy the same space on screen
  if (inPaddle(ballX, ballY, paddleX, paddleY, 4, 1)) {
    if(ballX == paddleX && ballY == paddleY){
    ballDirectionX = -ballDirectionX;
    ballDirectionY = -ballDirectionY;
    }
    else if(ballX == paddleX + 3 && ballY == paddleY){
      ballDirectionX = ballDirectionX;
      ballDirectionY = -ballDirectionY;
    }
    else if(ballX == paddleX + 1 && ballY == paddleY){
      ballDirectionX = -ballDirectionX;
      ballDirectionY = -ballDirectionY;
    }
    else if(ballX == paddleX + 2 && ballY == paddleY){
      ballDirectionX = ballDirectionX;
      ballDirectionY = -ballDirectionY;
    }
  }

  // update the ball's position
  ballX += ballDirectionX;
  ballY += ballDirectionY;

  // erase the ball's previous position

  if (oldBallX != ballX || oldBallY != ballY) {
    matrix.drawPixel(oldBallX, oldBallY,matrix.Color(0,0,0));
  }


  // draw the ball's current position
  matrix.drawPixel(ballX, ballY,matrix.Color(150,150,0));

  oldBallX = ballX;
  oldBallY = ballY;

}

// this function checks the position of the ball
// to see if it intersects with the paddle
boolean inPaddle(int x, int y, int rectX, int rectY, int rectWidth, int rectHeight) {
  boolean result = false;

  if ((x >= rectX && x <= (rectX + rectWidth)) &&
      (y >= rectY && y <= (rectY + rectHeight))) {
    result = true;
  }

  return result;
}
Arduino CodeC/C++
#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include <Adafruit_NeoPixel.h>

#define PIN 6

Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(15, 10, PIN,
  NEO_MATRIX_BOTTOM     + NEO_MATRIX_LEFT +
  NEO_MATRIX_COLUMNS + NEO_MATRIX_ZIGZAG,
  NEO_GRB            + NEO_KHZ800);

// variables for the position of the ball and paddle
int paddleX = 0;
int paddleY = 0;
int oldPaddleX, oldPaddleY;
int ballDirectionX = 1;
int ballDirectionY = 1;
int score = 0;

int ballSpeed = 10; // lower numbers are faster

int ballX, ballY, oldBallX, oldBallY;

void setup() {
  Serial.begin(9600);
  // initialize the display
  matrix.begin();
  // black background
  matrix.fillScreen(0);
  matrix.setTextColor(matrix.Color(0,255,0));
  matrix.print("GO");
  matrix.show();
  delay(2000);
  matrix.fillScreen(0);
  matrix.show();
}

void loop() {

  // save the width and height of the screen
  int myWidth = matrix.width();
  int myHeight = matrix.height();

  // map the paddle's location to the position of the potentiometers
  paddleX = map(analogRead(A0), 0, 1023, 0, 12);
  paddleY = 8;
  
  // set the fill color to black and erase the previous
  // position of the paddle if different from present

  if (oldPaddleX != paddleX || oldPaddleY != paddleY) {
    matrix.fillRect(oldPaddleX, oldPaddleY, 4, 1,matrix.Color(0,0,0));
  }

  // draw the paddle on screen, save the current position
  // as the previous.
//if(paddleX >= 0 && paddleX <= 11){
  matrix.fillRect(paddleX, paddleY, 4, 1,matrix.Color(0,0,255));
//}
//else if(paddleX < 0){
  //paddleX = 0;
  //matrix.fillRect(paddleX, paddleY, 3, 1,matrix.Color(0,0,255));
//}
//else if(paddleX >= 13){
  
//}
  oldPaddleX = paddleX;
  oldPaddleY = paddleY;
  matrix.show();

  // update the ball's position and draw it on screen
  if (millis() % ballSpeed < 2) {
    moveBall();
  }
  matrix.show();
  if(ballY > 8 && (millis() > 10000)){
    score += 1;
    matrix.fillScreen(0);
    matrix.setTextColor(matrix.Color(255,0,0));
    matrix.setCursor(0,2);
    matrix.print(String(score));
    matrix.show();
    delay(4000);
    ballX = random(3,11);
    ballY = random(1,1);
    matrix.fillScreen(0);
    matrix.show();
    delay(1000);
  }
  delay(5);
}

// this function determines the ball's position on screen
void moveBall() {
  // if the ball goes offscreen, reverse the direction:
  if (ballX > matrix.width() - 1 || ballX < 0) {
    ballDirectionX = -ballDirectionX;
  }

  if (ballY > matrix.height() || ballY < 0) {
    ballDirectionY = -ballDirectionY;
  }

  // check if the ball and the paddle occupy the same space on screen
  if (inPaddle(ballX, ballY, paddleX, paddleY, 4, 1)) {
    if(ballX == paddleX && ballY == paddleY){
    ballDirectionX = -ballDirectionX;
    ballDirectionY = -ballDirectionY;
    }
    else if(ballX == paddleX + 3 && ballY == paddleY){
      ballDirectionX = ballDirectionX;
      ballDirectionY = -ballDirectionY;
    }
    else if(ballX == paddleX + 1 && ballY == paddleY){
      ballDirectionX = -ballDirectionX;
      ballDirectionY = -ballDirectionY;
    }
    else if(ballX == paddleX + 2 && ballY == paddleY){
      ballDirectionX = ballDirectionX;
      ballDirectionY = -ballDirectionY;
    }
  }

  // update the ball's position
  ballX += ballDirectionX;
  ballY += ballDirectionY;

  // erase the ball's previous position

  if (oldBallX != ballX || oldBallY != ballY) {
    matrix.drawPixel(oldBallX, oldBallY,matrix.Color(0,0,0));
  }


  // draw the ball's current position
  matrix.drawPixel(ballX, ballY,matrix.Color(150,150,0));

  oldBallX = ballX;
  oldBallY = ballY;

}

// this function checks the position of the ball
// to see if it intersects with the paddle
boolean inPaddle(int x, int y, int rectX, int rectY, int rectWidth, int rectHeight) {
  boolean result = false;

  if ((x >= rectX && x <= (rectX + rectWidth)) &&
      (y >= rectY && y <= (rectY + rectHeight))) {
    result = true;
  }

  return result;
}

Schematics

NeoPixel Matrix Pong on Arduino Nano: Build a Neon Pong Game

Manufacturing process

  1. TinyML Language Detector with Edge Impulse on Arduino Nano 33 BLE Sense
  2. Build a Real-Time Gyroscope Game with Arduino Nano & MPU-6050 Sensor
  3. Arduino Digital Dice Project: Build Your Own LCD-based Random Number Generator
  4. Find Me: Smart Item Locator with Arduino and Bluetooth
  5. Arduino-Powered Security System: Smart Motion Detection & Alert
  6. Build a Classic Arduino LCD Arcade Game with Buzzer and Joystick
  7. Arduino Tennis Game – Build a Virtual Racquet Experience with NeoPixel, Sensors, and Bluetooth
  8. Build a Smart Weather Station with Arduino UNO and AWS Integration
  9. Arduino Marble Maze Labyrinth – Build an Exciting Cardboard Board Game
  10. Build an Interactive LCD Game with Arduino UNO