Differences

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

Link to this comparison view

pm:prj2026:alexandru.jipa2803:andrei.preda0308 [2026/05/23 20:03]
andrei.preda0308
pm:prj2026:alexandru.jipa2803:andrei.preda0308 [2026/05/24 01:22] (current)
andrei.preda0308
Line 55: Line 55:
  
 **Interacțiunea cu componentele hardware:** **Interacțiunea cu componentele hardware:**
-  * **Joystick:​** Se inițializează ADC-ul pentru cei doi pini analogici, folosind VCC ca referință și prescaler de 128. La citirea valorii ADC, pentru a preveni zgomotul electric ca nava spațială să nu se miște de una singură, s-a impus o toleranță de 50 astfel încât orice valoare care se află în acea toleranță față de valoarea de mijloc (512) îi va corespunde viteza 0 pentru axa respectivă. De asemenea, pentru butonul joystick-ului,​ se inițializează și se activează întreruperea lui INT0 pe front descrescător. La fiecare apăsare, se va trata rutina lui INT0, care va seta o variabilă cu true, aceasta reprezentând că o cerere de apăsare a fost efectuată. Există o funcție care actualizează statusul apăsării joystick-ului,​ verificând dacă o cerere a existat. De asemenea, există funcții pentru a verifica dacă butonul a fost apăsat și pentru a dezactiva sau activa funcționalitatea butonului.+  * **Joystick:​** Se inițializează ADC-ul pentru cei doi pini analogici, folosind VCC ca referință și prescaler de 128. La citirea valorii ADC, pentru a preveni zgomotul electric ​și pentru ​ca nava spațială să nu se miște de una singură, s-a impus o toleranță de 50 astfel încât ​pentru ​orice valoare care se află în acea toleranță față de valoarea de mijloc (512) îi va corespunde viteza 0 pentru axa respectivă. De asemenea, pentru butonul joystick-ului,​ se inițializează ​pinul respectiv ca input și se activează întreruperea lui INT0 pe front descrescător. La fiecare apăsare, se va trata rutina lui INT0, care va seta o variabilă cu true, aceasta reprezentând că o cerere de apăsare a fost efectuată. Există o funcție care actualizează statusul apăsării joystick-ului,​ verificând dacă o cerere a existat. De asemenea, există funcții pentru a verifica dacă butonul a fost apăsat și pentru a dezactiva sau activa funcționalitatea butonului.
  
   * **Systime:​** Se folosește timer-ul 0 astfel încât la fiecare milisecundă,​ să se activeze o întrerupere de comparație care numără câte milisecunde au trecut de la pornirea plăcii. Numărul de milisecunde este folosit pentru calcularea valorii de delta time pentru mișcarea jucătorului și a asteroizilor independent de framerate și pentru timere software.   * **Systime:​** Se folosește timer-ul 0 astfel încât la fiecare milisecundă,​ să se activeze o întrerupere de comparație care numără câte milisecunde au trecut de la pornirea plăcii. Numărul de milisecunde este folosit pentru calcularea valorii de delta time pentru mișcarea jucătorului și a asteroizilor independent de framerate și pentru timere software.
  
-  * **RGB LED:** Se inițializează pinii led-ului ca output și timer-ul 1, dar oprit. Timer-ul acestuia este pornit în cazul în care se cere roșu intermitent. Întreruperea de comparație a acestuia va alterna starea logică a pinului corespunzător culorii roșii la fiecare 0.secunde. Stările valide ale led-ului sunt următoarele:​ GREEN, YELLOW, BLINKING RED, NONE. Starea NONE este folosit atunci când jucătorul nu mai are viață și ledul este stins.+  * **RGB LED:** Se inițializează pinii led-ului ca output și timer-ul 1, dar oprit. Timer-ul acestuia este pornit în cazul în care se cere roșu intermitent. Întreruperea de comparație a acestuia va alterna starea logică a pinului corespunzător culorii roșii la fiecare 0.25 secunde. Stările valide ale led-ului sunt următoarele:​ GREEN, YELLOW, BLINKING RED, NONE. Starea NONE este folosită atunci când jucătorul nu mai are viață și led-ul ​este stins.
  
   * **Buzzer:** Pentru a reda sunet, se folosește timer-ul 2, care va alterna rapid între HIGH și LOW pentru a reda frecvența specificată. De asemenea, avem funcționalitatea de a seta frecvența dorită și dacă să activăm sau nu buzzer-ul. Numărul de milisecunde de la systime este folosit pentru a verifica dacă mai trebuie să redea sunet în continuare sau să schimbe nota în cazul în care avem mai mult de o notă de redat, cum ar fi atunci când jucătorul a rămas fără vieți.   * **Buzzer:** Pentru a reda sunet, se folosește timer-ul 2, care va alterna rapid între HIGH și LOW pentru a reda frecvența specificată. De asemenea, avem funcționalitatea de a seta frecvența dorită și dacă să activăm sau nu buzzer-ul. Numărul de milisecunde de la systime este folosit pentru a verifica dacă mai trebuie să redea sunet în continuare sau să schimbe nota în cazul în care avem mai mult de o notă de redat, cum ar fi atunci când jucătorul a rămas fără vieți.
Line 67: Line 67:
  
   * **Asteroid:​** Asteroidul este instanțiat inițial în afara ecranului, cât să atingă cercul de marginea hărții. Acesta se mișcă în linie dreaptă, viteza rămânând constantă, dacă nu este perturbat de un alt asteroid. Acesta se elimină în cazul în care ajunge din nou offscreen, după inițializare. În cazul în care există o coliziune între doi asteroizi, prima dată se modifică pozițiile înapoi în timp astfel încât cele două cercuri să fie tangente. Apoi, se aplică principiile coliziunii elastice pentru a modifica vitezele celor doi asteroizi. De asemenea, deoarece nu vrem să avem cercuri prea mari care ar suprasolicita comunicarea SPI, dar totuși să avem varietate, s-a decis ca fiecare asteroid să aibă una dintre cele trei raze: 7 pentru asteroid mic, 11 pentru asteroid mediu și 15 pentru asteroid mare. Încă un motiv pentru care s-a făcut acest lucru este menționat la partea de optimizări. Un edge case important de menționat este că atunci când se instanțiază un asteroid, este posibil ca acel asteroid care este offscreen să se ciocnească de un asteroid aproape de acesta și să devieze și să rămână offscreen mereu. Pentru a rezolva acest lucru, se pune un timer software scurt ca după primele 80 de milisecunde,​ dacă încă este offscreen, să se elimine.   * **Asteroid:​** Asteroidul este instanțiat inițial în afara ecranului, cât să atingă cercul de marginea hărții. Acesta se mișcă în linie dreaptă, viteza rămânând constantă, dacă nu este perturbat de un alt asteroid. Acesta se elimină în cazul în care ajunge din nou offscreen, după inițializare. În cazul în care există o coliziune între doi asteroizi, prima dată se modifică pozițiile înapoi în timp astfel încât cele două cercuri să fie tangente. Apoi, se aplică principiile coliziunii elastice pentru a modifica vitezele celor doi asteroizi. De asemenea, deoarece nu vrem să avem cercuri prea mari care ar suprasolicita comunicarea SPI, dar totuși să avem varietate, s-a decis ca fiecare asteroid să aibă una dintre cele trei raze: 7 pentru asteroid mic, 11 pentru asteroid mediu și 15 pentru asteroid mare. Încă un motiv pentru care s-a făcut acest lucru este menționat la partea de optimizări. Un edge case important de menționat este că atunci când se instanțiază un asteroid, este posibil ca acel asteroid care este offscreen să se ciocnească de un asteroid aproape de acesta și să devieze și să rămână offscreen mereu. Pentru a rezolva acest lucru, se pune un timer software scurt ca după primele 80 de milisecunde,​ dacă încă este offscreen, să se elimine.
 +
 +  * **Asteroid spawner:** Entitatea care se ocupă de a instanția asteroizi offscreen într-un mod random. Ea menține în memorie numărul mediu și deviația in milisecunde de așteptare pentru a lansa un asteroid, precum și viteza minimă și maximă pe care o poate avea. Are implementat și un sistem de ponderi pentru alegerea tipului de rază. Cu cât ponderea este mai mare față de restul, cu atât cresc șansele ca acea rază să fie selectată. De asemenea, se aleg valorile vitezei astfel încât tot cercul, la un moment dat, să fie vizibil pe ecran, neavând situații de a arunca un asteroid și mai adânc offscreen sau să apară foarte puțin într-un colț. La fiecare 10 secunde, se actualizează variabilele astfel încât să se spawneze mai des, asteroizi să fie mai rapid și să avem asteroizi cu raze mai mari. Deoarece mulți asteroizi mari (cei cu raza 15) cu viteză mare ar rezulta în multe actualizări ale ecranului, pe măsură ce trece timpul, șansele să lanseze asteroizi mari scad. Pentru asteroizii mici, șansele scad mai repede. Astfel, jocul favorizează în late-game asteroizii de dimensiune medie. Numărul de actualizări de făcut a fost limitat la 20.
 +
 +  * **UI bar manager:** Este un manager care actualizează datele din bara de UI. În stânga, se afișează numărul de vieți pe care jucătorul le mai are. În dreapta, sunt afișate câte scuturi mai pot fi folosite, fiecare pătrățel reprezentând un scut.
 +
 +**Bucla de joc:**
 +
 +Prima dată se actualizează starea de apăsare a joystick-ului. După aceea, se verifică buzzer-ul, pentru a-l opri după un timp scurt dacă jucătorul a luat damage, sau pentru a alterna notele dacă rulează melodia de game over de 3 note. Dacă jucătorul a rămas fără vieți, starea jocului devine game over și se desenează ecranul de final. Aici se calculează timpul supraviețuit și se verifică în EEPROM dacă s-a bătut recordul de timp supraviețuit anterior, actualizându-se dacă este cazul. De asemenea, se pornește și muzica de final. În acest caz, se așteaptă apăsarea joystick-ului pentru a reseta jocul. Dacă jocul rulează în continuare, se calculează delta time (diferența dintre milisecunda actuală și milisecunda de la frame-ul anterior convertită în secunde). Se actualizează spawner-ul de asteroizi, iar apoi se actualizează poziția jucătorului,​ invincibilitatea,​ scutul și coliziunile acestuia cu marginile hărții, iar la final și poziția asteroizilor. Apoi, se verifică coliziunile între asteroizi, iar la final coliziunile asteroizilor cu jucătorul. Dacă jucătorul a fost lovit și mai are vieți, se pornește buzzer-ul pentru a reda sunetul de hit. La finalul buclei se face desenarea. Se desenează jucătorul, apoi asteroizii. În cazul în care un asteroid poate fi distrus pentru că a ieșit din ecran, el este eliminat din memorie prin copierea ultimului asteroid din vectorul de asteroizi în locul lui. În final, se actualizează datele din bara de UI și se desenează pe ecran.
  
 **Optimizări:​** **Optimizări:​**
Line 75: Line 83:
 ===== Rezultate Obţinute ===== ===== Rezultate Obţinute =====
  
-<note tip> +**Link Youtube:** [[https://​www.youtube.com/​watch?​v=R3XNV3BAYq4|Asteroid Avoider - Proiect PM 2026]] 
-Care au fost rezultatele obţinute ​în urma realizării proiectului vostru. + 
-</​note>​+Se poate observa ​în videoclip că, într-o sesiune de joc, toate componentele hardware și software menționate funcționează.
  
 ===== Concluzii ===== ===== Concluzii =====
  
-===== Download =====+Realizarea acestui proiect a fost o experiență foarte interesantă,​ dar și destul de provocatoare,​ mai ales când a venit vorba de partea grafică. Cea mai mare problemă a fost să implementez logica prin care să se șteargă și să se redeseneze strict porțiunile de pe ecran unde s-au mișcat obiectele de la un frame la altul, dar după ce am reușit să fac jocul să ruleze fluid, rezultatul a meritat tot efortul.
  
-<note warning>​ +===== 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**. +
-</​note>​+
  
 **Link GitHub:** https://​github.com/​PredaAndrei3/​AsteroidAvoider **Link GitHub:** https://​github.com/​PredaAndrei3/​AsteroidAvoider
- 
-===== Jurnal ===== 
- 
-<note tip> 
-Puteți avea și o secțiune de jurnal în care să poată urmări asistentul de proiect progresul proiectului. 
-</​note>​ 
  
 ===== Bibliografie/​Resurse ===== ===== Bibliografie/​Resurse =====
- 
-<​note>​ 
-Listă cu documente, datasheet-uri,​ resurse Internet folosite, eventual grupate pe **Resurse Software** şi **Resurse Hardware**. 
-</​note>​ 
  
 **Resurse Hardware:** **Resurse Hardware:**
pm/prj2026/alexandru.jipa2803/andrei.preda0308.1779555801.txt.gz · Last modified: 2026/05/23 20:03 by andrei.preda0308
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