#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
//DEFINE UP AND DOWN BUTTON FOR PLAYER PADDLE
#define UP_BUTTON 2
#define DOWN_BUTTON 3
int previousballx = 0;
//DEFINE PADDLE SPEED AND PADDLE RATE FOR PLAYER PADDLE
const unsigned long PADDLE_RATE = 5;
const uint8_t PADDLE_SPEED = 2;
//DEFINE PLAYER PADDLE STARTING POSITION(X,Y) AND WIDTH AND HEIGHT (X+W,Y+H)
const uint8_t PLAYER_X = 7;
uint8_t PLAYER_Y = 10;
const uint8_t PLAYER_W = 3;
const uint8_t PLAYER_H = 15;
//DEFINE BALL WIDTH/RADIUS , BALL(X,Y), AND BALL DIRECTIONAL SPEED
int BALLX = 64;
int BALLY = 32;
const uint8_t BALL_W = 2;
int BALLDX = 1;
int BALLDY = 1;
//DEFINE CPU PADDLE STARTING POSITION(X,Y) AND WIDTH AND HEIGHT(X+W,Y+H)
const uint8_t CPU_X = 120;
uint8_t CPU_Y = 10;
const uint8_t CPU_W = 3;
const uint8_t CPU_H = 15;
// DEFINE PLAYER AND CPU SCORE
int PLAYERSCORE = 0;
int CPUSCORE = 0;
//DEFINE SCREEN HEIGHT AND WIDTH
const uint8_t SCREEN_H = 64;
const uint8_t SCREEN_W = 128;
const int DISPLAY_RST = -1;
//INITIALIZE DISPLAY
Adafruit_SSD1306 display(SCREEN_W,SCREEN_H,&Wire,DISPLAY_RST);
//DRAWING SCORE FUNCTION
void drawScore(int PLAYERSCORE,int CPUSCORE);
long randNumber;
void setup()
{
display.begin(SSD1306_SWITCHCAPVCC,0x3C);
display.display();
Serial.begin(115200);
pinMode(A0, INPUT);
unsigned long start = millis();
pinMode(UP_BUTTON, INPUT_PULLUP);
pinMode(DOWN_BUTTON,INPUT_PULLUP);
pinMode(5, OUTPUT);
randomSeed(analogRead(A0));
while(millis() - start < 2000);
display.clearDisplay();
}
void loop()
{
float random_num = random(7);
display.clearDisplay();
//READING UP AND DOWN BUTTON FOR PLAYER PADDLE
int UP_STATE = digitalRead(UP_BUTTON);
int DOWN_STATE = digitalRead(DOWN_BUTTON);
//DRAW RECTANGLE AROUND THE SCREEN
display.drawRect(0,0,128,64,WHITE);
if(DOWN_STATE == LOW && (PLAYER_Y+PLAYER_H) < 62)
{
PLAYER_Y = PLAYER_Y + PADDLE_RATE;
}
if(UP_STATE == LOW && PLAYER_Y > 2)
{
PLAYER_Y = PLAYER_Y - PADDLE_RATE;
}
if (random_num < 3)
{
if(previousballx < BALLX && previousballx > 64)
{
if(BALLY > (CPU_Y+CPU_H/2)) {
if((CPU_Y+CPU_H) < 62) {
CPU_Y += PADDLE_SPEED;
}
}
else if(BALLY < (CPU_Y + CPU_H/2)) {
if(CPU_Y > 2) {
CPU_Y -= PADDLE_SPEED;
}
}
}
}
// IF THE RANDOM NUMBER IS GREATER THAN OR EQUAL TO 0.5, DON'T MOVE THE CPU PADDLE
previousballx = BALLX;
if(BALLY <= BALL_W || BALLY >= (64-BALL_W))
{
BALLDY = BALLDY * (-1);
soundBouncec();
}
if(BALLX <= BALL_W)
{
CPUSCORE = CPUSCORE + 1;
soundPoint();
delay(50);
BALLX = SCREEN_W/2;
BALLY = SCREEN_H/2;
BALLDX = 1;
BALLDY = 1;
}
if(BALLX >= (128-BALL_W))
{
PLAYERSCORE = PLAYERSCORE + 1;
soundPoint();
delay(50);
BALLX = 64;
BALLY = 32;
BALLDX = -1;
BALLDY = 1;
}
if (BALLDX < 0 && BALLX <= PLAYER_X + BALL_W + PLAYER_W && BALLY >= PLAYER_Y && BALLY <= PLAYER_Y + PLAYER_H + BALL_W)
{
Serial.print("changing BALLDX 1"); Serial.print(" ");
Serial.println("");
BALLDX = 1; // not toggle, just make it go the other way.
soundBounce();
}
if (BALLDX > 0 && BALLX >= CPU_X - BALL_W && BALLY >= CPU_Y && BALLY <= CPU_Y + CPU_H + BALL_W)
{
Serial.print("changing BALLDX 2"); Serial.print(" ");
Serial.println("");
BALLDX = -1;
soundBounce();
}
BALLX = BALLX + BALLDX;
BALLY = BALLY + BALLDY;
display.drawRect(PLAYER_X,PLAYER_Y,PLAYER_W,PLAYER_H,WHITE);
display.drawRect(CPU_X,CPU_Y,CPU_W,CPU_H,WHITE);
display.drawCircle(BALLX,BALLY,BALL_W,WHITE);
//Draw Line middle of the court
for (int i=0; i<SCREEN_H; i+=4) {
display.drawFastVLine(SCREEN_W/2, i, 2, WHITE);
}
drawScore(PLAYERSCORE,CPUSCORE);
display.display();
delay(10);
}
void drawScore(int PLAYERSCORE, int CPUSCORE) {
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(2, 2);
display.print(PLAYERSCORE);
display.setCursor(122, 2);
display.print(CPUSCORE);
}
void soundBounce()
{
tone(5, 500, 10);
}
void soundBouncec()
{
tone(5, 400, 10);
}
void soundPoint()
{
tone(5, 150, 150);
}