#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
int paddle1Y = 32; // Initial Y position of player 1 paddle
int paddle2Y = 32; // Initial Y position of player 2 (AI) paddle
int ballX = 62; // Initial X position of the ball
int ballY = 32; // Initial Y position of the ball
int ballSpeedX = 1; // Ball speed along X-axis
int ballSpeedY = 1; // Ball speed along Y-axis
int score1 = 0; // Score of player 1
int score2 = 0; // Score of player 2
int buzzerPin = 8; // Buzzer pin
void setup() {
Serial.begin(9600);
pinMode(buzzerPin, OUTPUT);
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;);
}
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
display.setTextSize(1);
display.setCursor(45, 0);
display.println("Score");
display.setCursor(45, 9);
display.println("0 : 0");
display.fillCircle(ballX, ballY, 1, 1);
display.display();
}
void loop() {
// Read joystick input
int joystickY = analogRead(A1);
// Move paddles based on joystick input
movePaddle(joystickY);
// Move AI paddle
moveAI();
// Move ball
moveBall();
// Update display
updateDisplay();
}
void movePaddle(int joystickY) {
static int direction = 0; // 0 for no movement, 1 for up, -1 for down
// Determine the direction based on the joystick input
if (joystickY > 600) { // Adjust this threshold as needed
direction = 1; // Move paddle up
} else if (joystickY < 400) { // Adjust this threshold as needed
direction = -1; // Move paddle down
} else {
direction = 0; // No movement
}
// Update paddle position based on the direction
if (direction == 1 && paddle1Y > 0) {
paddle1Y--; // Move paddle up
} else if (direction == -1 && paddle1Y < SCREEN_HEIGHT - 10) {
paddle1Y++; // Move paddle down
}
}
void moveAI() {
// AI follows the ball vertically
if (paddle2Y + 5 < ballY) {
paddle2Y++;
} else if (paddle2Y + 5 > ballY) {
paddle2Y--;
}
}
void moveBall() {
// Update ball position
ballX += ballSpeedX;
ballY += ballSpeedY;
// Check collision with paddles
if (ballX == 2 && ballY >= paddle1Y && ballY <= paddle1Y + 10) {
// Randomize vertical direction upon collision with player paddle
ballSpeedY = random(-1, 2); // Random number between -1 and 1
ballSpeedX = 1; // Bounce back from player paddle
playBuzzer(490); // Activate buzzer with higher frequency
} else if (ballX == 125 && ballY >= paddle2Y && ballY <= paddle2Y + 10) {
// Randomize vertical direction upon collision with AI paddle
ballSpeedY = random(-1, 2); // Random number between -1 and 1
ballSpeedX = -1; // Bounce back from AI paddle
playBuzzer(490); // Activate buzzer with lower frequency
}
// Check collision with top and bottom walls
if (ballY <= 1 || ballY >= SCREEN_HEIGHT - 2) {
ballSpeedY = -ballSpeedY; // Bounce back from top or bottom wall
playBuzzer(200); // Activate buzzer with intermediate frequency
}
// Check if ball is out of bounds (score point)
if (ballX <= 0) {
score2++; // Increase score of player 2
resetBall();
} else if (ballX >= SCREEN_WIDTH - 1) {
score1++; // Increase score of player 1
resetBall();
}
}
void playBuzzer(int frequency) {
tone(buzzerPin, frequency); // Play a tone at the specified frequency
delay(50); // Buzz for 50 milliseconds
noTone(buzzerPin); // Turn off the buzzer
}
void resetBall() {
ballX = 62; // Reset ball position
ballY = 32;
ballSpeedX *= -1; // Reverse ball direction
ballSpeedY = 1;
}
void updateDisplay() {
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
display.setTextSize(1);
display.setCursor(45, 0);
display.println("Score");
display.setCursor(45, 9);
display.print(score1);
display.print(" : ");
display.println(score2);
display.fillCircle(ballX, ballY, 1, 1); // Draw ball
display.fillRect(0, paddle1Y, 2, 10, SSD1306_WHITE); // Draw player paddle
display.fillRect(127, paddle2Y, 2, 10, SSD1306_WHITE); // Draw AI paddle
display.display();
}