Differences

This shows you the differences between two versions of the page.

Link to this comparison view

pm:prj2025:atoader:catalin.giuglan [2025/05/28 03:21]
catalin.giuglan [Software Design]
pm:prj2025:atoader:catalin.giuglan [2025/05/28 16:00] (current)
catalin.giuglan [Implementarea Hardware:]
Line 52: Line 52:
 </​note>​ </​note>​
  
-====== Implementarea Hardware: ======+{{:​pm:​prj2025:​atoader:​catalin_pong.jpg?​650|}}====== Implementarea Hardware: ====== 
  
  
-{{:​pm:​prj2025:​atoader:​catalin_pong.jpg?​650|}} 
 ===== Software Design ===== ===== Software Design =====
  
Line 71: Line 71:
 **Funcții:​** **Funcții:​**
  
- +  *void setup() ​- Inițializează componentele hardwareverifică fișierul muzical de pe SD și calibrează joystick-urile
-<​note>​ +  *void loop() - Gestionează logica joculuiredă muzica și actualizează ecranul și pozițiile elementelor în mod continuu
- +  ​*void drawFrame() - Desenează întreaga scenă de jocterenulscorulmingea și playerii
-void setup() ​+  ​*void resetGame() - Plasează mingea într-o poziție aleatorie și îi setează o direcție nouă de mișcare. 
-  Serial.begin(9600);​ +  ​*void drawCourt() ​- Desenează cadrul terenului de joc pe afișaj ​(un dreptunghi de 128x64 pixeli). 
-  pinMode(BEEPEROUTPUT); +  *void drawScore() ​- Afișează scorurile celor doi jucători pe ecran
-  tone(BEEPER,​ 440, 200); delay(250);​ +  ​*void gameOver() ​- Afișează ecranul de final și anunță jucătorul câștigătorapoi resetează scorurile și mingea
- +  ​*void updateBallPosition() - Calculează noua poziție a mingii și gestionează coliziunile cu pereții, playerii și dacă s-a marcat sau nu un punct. 
-  if (!sd.begin(chipSelect,​ SD_SCK_MHZ(10))) { +  *void updatePaddlePositions() - Citește pozițiile joystick-urilor și actualizează paletele în funcție de mișcare. 
-    Serial.println(F("​SD init failed!"​));​ +  ​*void constrainPaddlePosition(uint8_t &​paddle_y) ​- Asigură că playerul nu iese în afara ecranului. 
-  } else { +  ​*void soundBounce() - Redă un sunet scurt când mingea lovește un player sau marginea orizontală. 
-    Serial.println(F("​SD init OK."​));​ +  ​*void soundPoint() - Redă un sunet diferit când se marchează un punct. 
-  ​+  ​*void initMusic() ​- Deschide fișierul ​mario.txt ​de pe cardul SD dacă nu a fost deja deschis. 
- +  ​*void playMarioTheme() - Redă notele muzicale din fișierul mario.txtuna câte una.
-  wholenote = (60000L ​4) / marioTempo;​ +
- +
-  display.begin()+
-  display.setFont(u8g2_font_6x10_tf);​ +
-  display.firstPage();​ +
-  do { +
-    display.drawStr(010, "​Initializare..."​);​ +
-    display.drawStr(0,​ 20, sd.begin(chipSelect,​ SD_SCK_MHZ(10)) ? "SD OK" : "​Eroare SD"​);​ +
- +
-    char buf[12]; +
-    strcpy_P(buf,​ FILENAME);​ +
-    if (musicFile.open(buf,​ O_RDONLY)) { +
-      display.drawStr(0,​ 30, "​mario.txt OK"​);​ +
-      musicFile.close();​ +
-    } else { +
-      display.drawStr(0,​ 30, "​Fisier lipsa"​);​ +
-    } +
-  ​} while (display.nextPage()); +
- +
-  delay(3000);​ +
- +
-  pinMode(SW_pin,​ INPUT); +
-  pinMode(RESET_BUTTON,​ INPUT_PULLUP);​ +
-  digitalWrite(SW_pin,​ HIGH); +
- +
-  // Calibrare joystick-uri +
-  player1_center = analogRead(player1);​ +
-  player2_center = analogRead(player2);​ +
- +
-  ball_update = millis(); +
-  paddle_update = ball_update;​ +
-+
-</​note>​ +
- +
-<​note>​ +
- +
-void loop() { +
-  unsigned long now = millis(); +
-  bool update = false; +
- +
-  if (resetBall) { +
-    (player1Score == maxScore || player2Score == maxScore) ? gameOver() ​resetGame();​ +
-  } +
- +
-  if (now > ball_update) { +
-    updateBallPosition();​ +
-    update = true; +
-  } +
- +
-  if (now > paddle_update) { +
-    updatePaddlePositions();​ +
-    update = true; +
-  } +
- +
-  if (update) { +
-    drawFrame();​ +
-  } +
- +
-  playMarioTheme();​ +
-+
-</​note>​ +
-<​note>​ +
-void drawFrame() { +
-  display.firstPage();​ +
-  do { +
-    drawCourt();​ +
-    drawScore();​ +
-    display.drawPixel(ball_xball_y); +
-    display.drawVLine(PLAYER2_Xplayer2_y, PADDLE_HEIGHT);​ +
-    display.drawVLine(PLAYER_X,​ player1_y, PADDLE_HEIGHT);​ +
-  ​} while (display.nextPage());​ +
-+
-</​note>​ +
-<​note>​ +
-void resetGame() ​+
-  ball_x = random(45, 50); +
-  ball_y = random(23, 33); +
-  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; +
-+
-</​note>​ +
-<​note>​ +
-void drawCourt() ​+
-  display.drawFrame(0, 0, 128, 64)+
-+
- +
-void drawScore() ​+
-  char buf[4]; +
-  sprintf(buf,​ "​%d",​ player2Score);​ +
-  display.drawStr(45, 10, buf); +
-  ​sprintf(buf,​ "​%d",​ player1Score);​ +
-  display.drawStr(75,​ 10, buf); +
-+
-</​note>​ +
-<​note>​ +
-void gameOver() ​+
-  display.firstPage();​ +
-  do { +
-    display.drawStr(2025, (player1Score > player2Score) ? "​Player 1" : "​Player 2"); +
-    display.drawStr(40, 40, "​won"​);​ +
-  ​} while (display.nextPage());​ +
-  delay(2000);​ +
-  player1Score = player2Score = 0; +
-  resetBall = true; +
-  ball_update = paddle_update = millis(); +
-+
-</​note>​ +
-<​note>​ +
-void updateBallPosition() ​+
-  uint8_t new_x = ball_x + ball_dir_x;​ +
-  uint8_t new_y = ball_y + ball_dir_y;​ +
- +
-  if (new_x == 0 || new_x == 127) handleVerticalWallCollision(new_x);​ +
-  if (new_y == 0 || new_y == 63) { +
-    soundBounce();​ ball_dir_y = -ball_dir_y;​ +
-    new_y += ball_dir_y * 2; +
-  ​+
- +
-  if ((new_x == PLAYER2_X && new_y >= player2_y && new_y <= player2_y + PADDLE_HEIGHT) || +
-      (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 ​2; +
-  } +
- +
-  ball_x = new_x; +
-  ball_y = new_y; +
-  ball_update += BALL_RATE;​ +
-+
-</​note>​ +
-<​note>​ +
-void updatePaddlePositions() ​+
-  paddle_update += PADDLE_RATE;​ +
- +
-  int val2 = analogRead(player2);​ +
-  if (val2 < player2_center ​DEADZONE) player2_y--; +
-  ​if (val2 > player2_center + DEADZONE) player2_y++;​ +
-  constrainPaddlePosition(player2_y);​ +
- +
-  int val1 = analogRead(player1);​ +
-  if (val1 < player1_center - DEADZONE) player1_y--;​ +
-  if (val1 > player1_center + DEADZONE) player1_y++;​ +
-  constrainPaddlePosition(player1_y);​ +
-+
-</​note>​ +
-<​note>​ +
-void constrainPaddlePosition(uint8_t &​paddle_y) ​{ +
-  ​if (paddle_y < 1paddle_y = 1; +
-  ​if (paddle_y + PADDLE_HEIGHT > 63) paddle_y = 63 - PADDLE_HEIGHT;​ +
-+
- +
-void handleVerticalWallCollision(uint8_t new_x) { +
-  if (new_x == 0) { +
-    player1Score++; ​soundPoint(); resetBall = true; +
-  } else { +
-    player2Score++;​ soundPoint();​ resetBall = true; +
-  } +
-  ball_dir_x = -ball_dir_x; +
-+
-</​note>​ +
-<​note>​ +
-void soundBounce() { tone(BEEPER,​ 500, 50); } +
-void soundPoint() ​ { tone(BEEPER,​ 100, 50); } +
- +
-void initMusic() ​+
-  if (musicInitialized) return; +
-  char buf[12]; +
-  strcpy_P(buf,​ FILENAME);​ +
-  if (musicFile.open(buf,​ O_RDONLY)) { +
-    Serial.println(F("​Fisier ​mario.txt deschis.")); +
-  ​} else { +
-    Serial.println(F("​Eroare deschidere mario.txt"​));​ +
-  } +
-  musicInitialized = true; +
-+
-</​note>​ +
-<​note>​ +
-void playMarioTheme() ​+
-  if (!musicInitialized) { +
-    initMusic();​ +
-    return; +
-  } +
-  if (!musicFile.isOpen()) return; +
- +
-  unsigned long now = millis(); +
- +
-  if (!isNotePlaying && now noteStartTime >= pauseDuration) { +
-    if (!musicFile.available()) musicFile.rewind();​ +
- +
-    char line[20]; +
-    uint8_t idx = 0; +
-    char ch; +
-    while (musicFile.available() && idx < sizeof(line) - 1) { +
-      ch = musicFile.read();​ +
-      if (ch == '​\n'​) break; +
-      line[idx++] = ch; +
-    } +
-    line[idx] = '​\0';​ +
- +
-    char* commaPtr = strchr(line','​);​ +
-    if (commaPtr) { +
-      *commaPtr = '​\0';​ +
-      int freq = atoi(line);​ +
-      int dur  = atoi(commaPtr + 1); +
-      noteDuration = (dur > 0) ? (wholenote / dur) : ((wholenote / abs(dur)) * 1.5); +
-      if (freq != REST) tone(BEEPER,​ freq); +
-      isNotePlaying = true; +
-      noteStartTime = now; +
-    } +
-  } +
- +
-  if (isNotePlaying && now - noteStartTime >= noteDuration * 0.9) { +
-    noTone(BEEPER);​ +
-    isNotePlaying = false; +
-    pauseDuration = noteDuration * 0.1; +
-    noteStartTime = now; +
-  } +
-+
-</​note>​+
 </​note>​ </​note>​
  
Line 328: Line 109:
  
 <note warning> <note warning>
-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 şcopiere automată pe uC crează întotdeauna o impresie bună ;-). +Arhiva conține codul Arduino șvideoclipul demo de prezentare al proiectului{{:pm:prj2025:atoader:pong.zip|}}
- +
-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**.+
 </​note>​ </​note>​
- 
 ===== Jurnal ===== ===== Jurnal =====
  
pm/prj2025/atoader/catalin.giuglan.1748391662.txt.gz · Last modified: 2025/05/28 03:21 by catalin.giuglan
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