Arnov Sharma
Published © MIT

Handheld PONG Console

Made a small DIY Pong Game console from scratch.

BeginnerFull instructions provided1 hour267
Handheld PONG Console

Things used in this project

Software apps and online services

Fusion
Autodesk Fusion

Hand tools and fabrication machines

3D Printer (generic)
3D Printer (generic)

Story

Read more

Custom parts and enclosures

STEP FILE

Schematics

SCH

Code

code

C/C++
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 32
#define OLED_RESET    -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

const int buttonUpPin = 1; // Pin for the up button
const int buttonDownPin = 0; // Pin for the down button

const int paddleHeight = 12;
const int paddleWidth = 3;
int playerPaddleY = (SCREEN_HEIGHT - paddleHeight) / 2;
int compPaddleY = (SCREEN_HEIGHT - paddleHeight) / 2;

int ballX = SCREEN_WIDTH / 2;
int ballY = SCREEN_HEIGHT / 2;
int ballVelocityX = 2;
int ballVelocityY = 2;

bool isGameOver = false;
bool playerWin = false;

void setup() {
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;);
  }
  // Clear the Adafruit splash screen
  display.clearDisplay();
  display.display();
  delay(2000);

  // Display the welcome screen
  display.setTextSize(2);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(10, 10);
  display.print("PONG PRO");
  display.display();
  delay(2000);

  pinMode(buttonUpPin, INPUT_PULLUP);
  pinMode(buttonDownPin, INPUT_PULLUP);
}

void loop() {
  if (isGameOver) {
    display.clearDisplay();
    display.setTextSize(2);
    display.setTextColor(SSD1306_WHITE);
    display.setCursor((SCREEN_WIDTH - 72) / 2, (SCREEN_HEIGHT - 16) / 2);
    if (playerWin) {
      display.print("You Win!");
    } else {
      display.print("You Lose!");
    }
    display.display();
    delay(3000);
    isGameOver = false;
    ballX = SCREEN_WIDTH / 2;
    ballY = SCREEN_HEIGHT / 2;
    playerPaddleY = (SCREEN_HEIGHT - paddleHeight) / 2;
    compPaddleY = (SCREEN_HEIGHT - paddleHeight) / 2;
    return;
  }

  // Update player paddle position
  if (digitalRead(buttonUpPin) == LOW) {
    playerPaddleY = max(playerPaddleY - 1, 0);
  }
  if (digitalRead(buttonDownPin) == LOW) {
    playerPaddleY = min(playerPaddleY + 1, SCREEN_HEIGHT - paddleHeight);
  }

  // Update computer paddle position
  if (ballY < compPaddleY + paddleHeight / 2) {
    compPaddleY = max(compPaddleY - 1, 0);
  }
  if (ballY > compPaddleY + paddleHeight / 2) {
    compPaddleY = min(compPaddleY + 1, SCREEN_HEIGHT - paddleHeight);
  }

  // Update ball position
  ballX += ballVelocityX;
  ballY += ballVelocityY;

  // Check ball collisions with top and bottom
  if (ballY <= 0 || ballY >= SCREEN_HEIGHT - 1) {
    ballVelocityY = -ballVelocityY;
  }

  // Check ball collision with player paddle
  if (ballX <= paddleWidth && ballY >= playerPaddleY && ballY <= playerPaddleY + paddleHeight) {
    ballVelocityX = -ballVelocityX;
  }

  // Check ball collision with computer paddle
  if (ballX >= SCREEN_WIDTH - paddleWidth - 1 && ballY >= compPaddleY && ballY <= compPaddleY + paddleHeight) {
    ballVelocityX = -ballVelocityX;
  }

  // Check ball out of bounds
  if (ballX <= 0) {
    isGameOver = true;
    playerWin = false;
  }
  if (ballX >= SCREEN_WIDTH - 1) {
    isGameOver = true;
    playerWin = true;
  }

  // Clear display
  display.clearDisplay();

  // Draw player paddle
  display.fillRect(0, playerPaddleY, paddleWidth, paddleHeight, SSD1306_WHITE);

  // Draw computer paddle
  display.fillRect(SCREEN_WIDTH - paddleWidth, compPaddleY, paddleWidth, paddleHeight, SSD1306_WHITE);

  // Draw ball
  display.fillRect(ballX, ballY, 1, 1, SSD1306_WHITE);

  // Update display
  display.display();

  delay(30);
}

Credits

Arnov Sharma
352 projects • 360 followers
I'm Arnov. I build, design, and experiment with tech—3D printing, PCB design, and retro consoles are my jam.

Comments