#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);
// Bitmap dimensions
#define BITMAP_WIDTH 16
#define BITMAP_HEIGHT 16
struct cordinates{
int x;
int y;
};
struct score{
int red;
int blue;
};
struct cordinates pl1 = {0,24};
struct cordinates pl2 = {124,24};
struct cordinates ball {60,32};
int sign= -1;
bool upBall = false;
bool downBall = false;
int speed = 2;
bool movingUp;
bool movingDown;
struct score gameScore;
// Bitmap data
unsigned char epd_bitmap_Sprite_s002[] = {
0xff, 0xff, 0xff, 0xff, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xcc, 0x63, 0xcc, 0x63, 0xc0, 0x03,
0xc0, 0x03, 0xc7, 0xc3, 0xc7, 0xc3, 0xc7, 0xc3, 0xc0, 0x03, 0xc0, 0x03, 0xff, 0xff, 0xff, 0xff
};
unsigned char epd_bitmap_ball [] = {
0xf0, 0x90, 0x90, 0xf0
};
unsigned char epd_bitmap_pl [] = {
0xf0, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0xf0
};
void setup() {
pinMode(12, INPUT);
pinMode(13, INPUT);
// initialize with the I2C addr 0x3C (for the 128x64)
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;);
}
UpdatePos();
}
void loop() {
ballPhysics();
movePlayer1();
movePlayer2AI();
}
void movePlayer1(){
if(digitalRead(13) == LOW){
if(pl1.y>0){
pl1.y-=6;
UpdatePos();
delay(100);
}
}
else if (digitalRead(12) == LOW){
if(pl1.y<48){
pl1.y+=6;
UpdatePos();
delay(100);
}
}
}
unsigned long lastUpdateTime = 0;
unsigned long aiReactionDelay = 300; // Adjust the delay time as needed
int aiRange = 20; // Adjust the range within which the AI reacts to the ball
void movePlayer2AI() {
unsigned long currentTime = millis();
// Check if enough time has passed since the last update
if (currentTime - lastUpdateTime >= aiReactionDelay) {
// Update the last update time
lastUpdateTime = currentTime;
// Calculate the difference between the y-coordinate of the ball and player 2
int yDiff = ball.y - pl2.y;
// Set the speed at which player 2 moves
int aiSpeed = 2;
// Determine the direction towards the ball
int direction = 0; // 0 for stationary
if (abs(yDiff) <= aiRange) {
direction = yDiff > 0 ? 1 : -1;
}
// Move towards the ball if it's within range
if (direction != 0) {
pl2.y += aiSpeed * direction; // Move towards the ball
movingUp = direction < 0;
movingDown = direction > 0;
}
// Update the display
UpdatePos();
}
}
void UpdatePos(){
display.clearDisplay();
display.drawBitmap(pl1.x, pl1.y, epd_bitmap_pl, 4,16, SSD1306_WHITE);
display.drawBitmap(ball.x, ball.y, epd_bitmap_ball, 4,4, SSD1306_WHITE);
display.drawBitmap(pl2.x, pl2.y, epd_bitmap_pl, 4,16, SSD1306_WHITE);
display.setTextSize(1); // Normal 1:1 pixel scale
display.setTextColor(SSD1306_WHITE); // White text
// Set cursor position (in pixels)
display.setCursor(56, 0);
display.print(gameScore.red);
display.print(":");
display.print(gameScore.blue);
display.display();
delay(1);
}
void ballPhysics(){
ball.x +=speed*sign;
if(upBall){
ball.y-=speed;
}
else if(downBall){
ball.y+=speed;
}
if(ball.y <=0){
upBall = false;
downBall = true;
if(speed >2){
speed--;
}
}
else if(ball.y >=60){
upBall = true;
downBall = false;
if(speed >2){
speed--;
}
}
if(ball.x<0){
ball.x = 60;
ball.y = 32;
upBall = false;
downBall = false;
speed =2;
gameScore.blue++;
}
else if(ball.x>128){
ball.x = 60;
ball.y = 32;
upBall = false;
downBall = false;
speed = 2;
gameScore.red++;
}
UpdatePos();
checkHits();
delay(5);
}
void checkHits(){
if(ball.x < pl1.x+8 && ball.y>= pl1.y && ball.y<= pl1.y+16){
sign = 1;
if(speed<=3){
speed += 1;
}
if( digitalRead(13) == LOW ){
upBall = true;
downBall = false;
speed+=1;
}
else if(digitalRead(12) == LOW ){
upBall = false;
downBall = true;
speed+=1;
}
else{
upBall = false;
downBall = false;
}
}
else if(ball.x > pl2.x-8 && ball.y>= pl2.y && ball.y<= pl2.y+16 ){
sign = -1;
if(speed<=3){
speed += 1;
}
if( movingUp ){
upBall = true;
downBall = false;
speed+=1;
}
else if(movingDown){
upBall = false;
downBall = true;
speed+=1;
}
else{
upBall = false;
downBall = false;
}
}
delay(20);
}