Components and supplies
USB-A to B Cable
Analog joystick (Generic)
Solderless Breadboard Full Size
Jumper wires (generic)
Gravity I2C OLED-2864 Display
Male/Female Jumper Wires
Buzzer
Arduino UNO
Apps and platforms
Arduino IDE
Project description
Code
Game Code
c_cpp
Code made using Arduino IDE
1/* 2 A simple Pong game: 3 Original game, project and code at: 4 https://create.arduino.cc/projecthub/wotblitza/pong-with-oled-ssd1306-joystick-and-buzzer-58c423 5*/ 6 7#include <SPI.h> 8#include <Wire.h> 9#include <Adafruit_GFX.h> 10#include <Adafruit_SSD1306.h> 11 12const int SW_pin = 4; // digital pin connected to switch output 13const int player1 = A1; // analog pin connected to Y output 14const int player2 = A0; // analog pin connected to Y output 15 16const unsigned long PADDLE_RATE = 45; 17const unsigned long BALL_RATE = 0; 18const uint8_t PADDLE_HEIGHT = 12; 19int player1Score = 0; 20int player2Score = 0; 21int maxScore = 8; 22int BEEPER = 12; 23bool resetBall = false; 24#define SCREEN_WIDTH 128 // OLED display width, in pixels 25#define SCREEN_HEIGHT 64 // OLED display height, in pixels 26#define RESET_BUTTON 3 27// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins) 28#define OLED_RESET 4 // Reset pin # (or -1 if sharing Arduino reset pin) 29Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); 30 31void drawCourt(); 32void drawScore(); 33 34uint8_t ball_x = 64, ball_y = 32; 35uint8_t ball_dir_x = 1, ball_dir_y = 1; 36unsigned long ball_update; 37 38unsigned long paddle_update; 39const uint8_t PLAYER2_X = 22; 40uint8_t player2_y = 26; 41 42const uint8_t PLAYER_X = 105; 43uint8_t player1_y = 26; 44 45void setup() { 46 display.begin(SSD1306_SWITCHCAPVCC, 0x3C); 47 display.display(); 48 unsigned long start = millis(); 49 pinMode(BEEPER, OUTPUT); 50 pinMode(SW_pin, INPUT); 51 pinMode(RESET_BUTTON, INPUT_PULLUP); 52 digitalWrite(SW_pin, HIGH); 53 display.clearDisplay(); 54 drawCourt(); 55 drawScore(); 56 while (millis() - start < 2000); 57 58 display.display(); 59 60 ball_update = millis(); 61 paddle_update = ball_update; 62} 63 64void loop() { 65 bool update = false; 66 unsigned long time = millis(); 67 68 static bool up_state = false; 69 static bool down_state = false; 70 71 72 if (resetBall) 73 { 74 if (player1Score == maxScore || player2Score == maxScore) 75 { 76 gameOver(); 77 } 78 else { 79 display.fillScreen(BLACK); 80 drawScore(); 81 drawCourt(); 82 ball_x = random(45, 50); 83 ball_y = random(23, 33); 84 do 85 { 86 ball_dir_x = random(-1, 2); 87 } while (ball_dir_x == 0); 88 89 do 90 { 91 ball_dir_y = random(-1, 2); 92 } while (ball_dir_y == 0); 93 94 95 resetBall = false; 96 } 97 } 98 99 100 //up_state |= (digitalRead(UP_BUTTON) == LOW); 101 // down_state |= (digitalRead(DOWN_BUTTON) == LOW); 102 103 if (time > ball_update) { 104 uint8_t new_x = ball_x + ball_dir_x; 105 uint8_t new_y = ball_y + ball_dir_y; 106 107 // Check if we hit the vertical walls 108 if (new_x == 0 || new_x == 127) { 109 110 if (new_x == 0) { 111 player1Score += 1; 112 display.fillScreen(BLACK); 113 soundPoint(); 114 resetBall = true; 115 116 } 117 else if (new_x == 127) { 118 player2Score += 1; 119 display.fillScreen(BLACK); 120 soundPoint(); 121 resetBall = true; 122 } 123 ball_dir_x = -ball_dir_x; 124 new_x += ball_dir_x + ball_dir_x; 125 } 126 127 // Check if we hit the horizontal walls. 128 if (new_y == 0 || new_y == 63) { 129 soundBounce(); 130 ball_dir_y = -ball_dir_y; 131 new_y += ball_dir_y + ball_dir_y; 132 } 133 134 // Check if we hit the player 2 paddle 135 if (new_x == PLAYER2_X && new_y >= player2_y && new_y <= player2_y + PADDLE_HEIGHT) { 136 soundBounce(); 137 ball_dir_x = -ball_dir_x; 138 new_x += ball_dir_x + ball_dir_x; 139 } 140 141 // Check if we hit the player 1 paddle 142 if (new_x == PLAYER_X && new_y >= player1_y && new_y <= player1_y + PADDLE_HEIGHT) { 143 soundBounce(); 144 ball_dir_x = -ball_dir_x; 145 new_x += ball_dir_x + ball_dir_x; 146 } 147 148 display.drawPixel(ball_x, ball_y, BLACK); 149 display.drawPixel(new_x, new_y, WHITE); 150 ball_x = new_x; 151 ball_y = new_y; 152 153 ball_update += BALL_RATE; 154 155 update = true; 156 } 157 158 if (time > paddle_update) { 159 paddle_update += PADDLE_RATE; 160 161 //Player 2 paddle 162 display.drawFastVLine(PLAYER2_X, player2_y, PADDLE_HEIGHT, BLACK); 163 const uint8_t half_paddle = PADDLE_HEIGHT >> 1; 164 if (analogRead(player2) < 475) { 165 player2_y -= 1; 166 } 167 if (analogRead(player2) > 550) { 168 player2_y += 1; 169 } 170 if (player2_y < 1) player2_y = 1; 171 if (player2_y + PADDLE_HEIGHT > 63) player2_y = 63 - PADDLE_HEIGHT; 172 display.drawFastVLine(PLAYER2_X, player2_y, PADDLE_HEIGHT, WHITE); 173 174 // Player 1 paddle 175 display.drawFastVLine(PLAYER_X, player1_y, PADDLE_HEIGHT, BLACK); 176 if (analogRead(player1) < 475) { 177 player1_y -= 1; 178 } 179 if (analogRead(player1) > 550) { 180 player1_y += 1; 181 } 182 up_state = down_state = false; 183 if (player1_y < 1) player1_y = 1; 184 if (player1_y + PADDLE_HEIGHT > 63) player1_y = 63 - PADDLE_HEIGHT; 185 display.drawFastVLine(PLAYER_X, player1_y, PADDLE_HEIGHT, WHITE); 186 } 187 update = true; 188 189 if (update) { 190 drawScore(); 191 display.display(); 192 if (digitalRead(SW_pin) == 0) //Player pressed button to stop the game 193 { 194 gameOver(); 195 } 196 } 197} 198 199void drawCourt() { 200 display.drawRect(0, 0, 128, 64, WHITE); 201} 202void drawScore() { 203 // draw players scores 204 display.setTextSize(2); 205 display.setTextColor(WHITE); 206 display.setCursor(45, 0); 207 display.println(player2Score); 208 display.setCursor(75, 0); 209 display.println(player1Score); 210} 211 212void gameOver() { 213 display.fillScreen(BLACK); 214 if (player1Score > player2Score) 215 { 216 display.setCursor(20, 15); 217 display.setTextColor(WHITE); 218 display.setTextSize(2); 219 display.print("Player 1"); 220 display.setCursor(40, 35); 221 display.print("won"); 222 } 223 else 224 { 225 display.setCursor(20, 15); 226 display.setTextColor(WHITE); 227 display.setTextSize(2); 228 display.print("Player 2"); 229 display.setCursor(40, 35); 230 display.print("won"); 231 } 232 delay(100); 233 display.display(); 234 delay(2000); 235 player2Score = player1Score = 0; 236 237 unsigned long start = millis(); 238 while (millis() - start < 2000); 239 ball_update = millis(); 240 paddle_update = ball_update; 241 resetBall = true; 242} 243//Sound of ball hitting wall and paddles 244void soundBounce() 245{ 246 tone(BEEPER, 500, 50); 247} 248//Sound of point scored 249void soundPoint() 250{ 251 tone(BEEPER, 100, 50); 252}
Downloadable files
Schematics
Schematics for pong game, using Fritzing.
Schematics
Comments
Only logged in users can leave comments