This is an old revision of the document!


Pong recreation

PONG Remastered

Introducere

Proiectul ales consta in reproducerea jocului Pong prin intermediul a 2 joystickuri pentru controale , a unui buzzer pentru a semnaliza marcarea unui punct.

Descriere generală

Jucatorii sunt reprezentati prin 2 linii trase pe orizontala pe ecran, aproape lipite de margini Mingea este reprezentata de un pixel de culoare alba care se misca pe ecran Fiecare jucator isi controleaza linia prin cate un joystick La inscrierea unui punct, buzzerul scoate un zgomot scurt

Hardware Design

*Arduino UNO *breadboard * 2 joystickuri * ecarn OLED * buzzer arduino_pong.pdf

Software Design

#include <SPI.h> #include <Wire.h> #include <LiquidCrystal_I2C.h>

const int SW_pin = 9; digital pin connected to switch output const int leftJoystick = A0; analog pin connected to Y output of the left joystick const int rightJoystick = A2; analog pin connected to Y output of the right joystick const unsigned long PADDLE_RATE = 45; const unsigned long BALL_RATE = 0; const uint8_t PADDLE_HEIGHT = 12; int player1Score = 0; int player2Score = 0; int maxScore = 8; int buzzerPin = 9; bool resetBall = false; LiquidCrystal_I2C lcd(0x27, 16, 2); Set LCD address and dimensions accordingly

void drawCourt(); void drawScore();

uint8_t ball_x = 7, ball_y = 1; uint8_t ball_dir_x = 1, ball_dir_y = 1; unsigned long ball_update;

unsigned long paddle_update; const uint8_t PLAYER2_X = 13; uint8_t player2_y = 1;

const uint8_t PLAYER_X = 0; uint8_t player1_y = 1;

void setup() {

lcd.begin(16, 2);
lcd.clear();
unsigned long start = millis();
pinMode(buzzerPin, OUTPUT);
pinMode(SW_pin, INPUT);
digitalWrite(SW_pin, HIGH);
drawCourt();
drawScore();
while (millis() - start < 2000);
ball_update = millis();
paddle_update = ball_update;

}

void loop() {

bool update = false;
unsigned long time = millis();
if (resetBall) {
  if (player1Score == maxScore || player2Score == maxScore) {
    gameOver();
  } else {
    lcd.clear();
    ball_x = random(2, 15);
    ball_y = random(1, 2);
    do {
      ball_dir_x = random(-1, 2);
    } while (ball_dir_x == 0);
    do {
      ball_dir_y = random(-1, 2);
    } while (ball_dir_y == 0);
    resetBall = false;
  }
}
if (time > ball_update) {
  uint8_t new_x = ball_x + ball_dir_x;
  uint8_t new_y = ball_y + ball_dir_y;
  // Check if we hit the vertical walls
  if (new_x == 0 || new_x == 15) {
    if (new_x == 0) {
      player1Score += 1;
      lcd.clear();
      soundPoint();
      resetBall = true;
    } else if (new_x == 15) {
      player2Score += 1;
      lcd.clear();
      soundPoint();
      resetBall = true;
    }
    ball_dir_x = -ball_dir_x;
    new_x += ball_dir_x + ball_dir_x;
  }
  // Check if we hit the horizontal walls.
  if (new_y == 0 || new_y == 1) {
    soundBounce();
    ball_dir_y = -ball_dir_y;
    new_y += ball_dir_y + ball_dir_y;
  }
  // Check if we hit the player 2 paddle
  if (new_x == PLAYER2_X && new_y >= player2_y && new_y <= player2_y + PADDLE_HEIGHT) {
    soundBounce();
    ball_dir_x = -ball_dir_x;
    new_x += ball_dir_x + ball_dir_x;
  }
  // Check if we hit the player 1 paddle
  if (new_x == PLAYER_X && new_y >= player1_y && new_y <= player1_y + PADDLE_HEIGHT) {
    soundBounce();
    ball_dir_x = -ball_dir_x;
    new_x += ball_dir_x + ball_dir_x;
  }
  lcd.setCursor(ball_x, ball_y);
  lcd.print(' ');
  lcd.setCursor(new_x, new_y);
  lcd.print('*');
  ball_x = new_x;
  ball_y = new_y;
  ball_update += BALL_RATE;
  update = true;
}
if (time > paddle_update) {
  paddle_update += PADDLE_RATE;
  // Player 2 paddle
  lcd.setCursor(PLAYER2_X, player2_y);
  lcd.write(0b11111); // Custom character for paddle
  if (analogRead(rightJoystick) < 475) {
    player2_y -= 1;
  }
  if (analogRead(rightJoystick) > 550) {
    player2_y += 1;
  }
  if (player2_y < 1) player2_y = 1;
  if (player2_y + PADDLE_HEIGHT > 2) player2_y = 2 - PADDLE_HEIGHT;
  // Player 1 paddle
  lcd.setCursor(PLAYER_X, player1_y);
  lcd.write(0b11111); // Custom character for paddle
  if (analogRead(leftJoystick) < 475) {
    player1_y -= 1;
  }
  if (analogRead(leftJoystick) > 550) {
    player1_y += 1;
  }
  if (player1_y < 1) player1_y = 1;
  if (player1_y + PADDLE_HEIGHT > 2) player1_y = 2 - PADDLE_HEIGHT;
  update = true;
}
if (update) {
  if (player1Score > 0 || player2Score > 0) {
    drawScore();
  }
  if (player1Score == maxScore || player2Score == maxScore) {
    gameOver();
  }
}

}

void drawCourt() {

lcd.setCursor(0, 0);
lcd.print("|");
lcd.setCursor(0, 1);
lcd.print("|");
lcd.setCursor(15, 0);
lcd.print("|");
lcd.setCursor(15, 1);
lcd.print("|");

}

void drawScore() {

lcd.setCursor(6, 0);
lcd.print(player2Score);
lcd.setCursor(9, 0);
lcd.print("-");
lcd.setCursor(12, 0);
lcd.print(player1Score);

}

void gameOver() {

lcd.clear();
if (player1Score > player2Score) {
  lcd.setCursor(2, 0);
  lcd.print("Player 1 won");
} else {
  lcd.setCursor(2, 0);
  lcd.print("Player 2 won");
}
delay(2000);
player2Score = player1Score = 0;
unsigned long start = millis();
while (millis() - start < 2000);
ball_update = millis();
paddle_update = ball_update;
resetBall = true;

}

void soundBounce() {

tone(buzzerPin, 1000, 20);

}

void soundPoint() {

tone(buzzerPin, 1500, 200);
delay(200);
tone(buzzerPin, 2000, 200);
delay(200);
tone(buzzerPin, 2500, 200);
delay(200);

}

Rezultate Obţinute

WIP

Concluzii

Download

O arhivă (sau mai multe dacă este cazul) cu fişierele obţinute în urma realizării proiectului: surse, scheme, etc. Un fişier README, un ChangeLog, un script de compilare şi copiere automată pe uC crează întotdeauna o impresie bună ;-).

Fişierele se încarcă pe wiki folosind facilitatea Add Images or other files. Namespace-ul în care se încarcă fişierele este de tipul :pm:prj20??:c? sau :pm:prj20??:c?:nume_student (dacă este cazul). Exemplu: Dumitru Alin, 331CC → :pm:prj2009:cc:dumitru_alin.

Jurnal

WIP

Bibliografie/Resurse

pm/prj2023/tmiu/pongrecreation.1685403321.txt.gz · Last modified: 2023/05/30 02:35 by Ovidiu.istrate0211
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0