Table of Contents

Asteroid Avoider

Introducere

Proiectul reprezintă un joc arcade în care utilizatorul pilotează o navă spațială cu ajutorul unui joystick, având ca scop evitarea asteroizilor. Nivelul de dificultate crește dinamic în timp, iar numărul de vieți rămase este indicat vizual printr-un LED RGB (verde, galben sau roșu intermitent). Jucătorul poate activa un scut temporar cu utilizări limitate prin apăsarea joystick-ului, iar un buzzer pasiv oferă feedback auditiv, emițând semnale sonore la coliziunea cu un asteroid și în momentul de game over. La finalizarea sesiunii, se afișează timpul petrecut în joc și cel mai bun timp obținut, fiind actualizat când este cazul. Scopul jocului pentru utilizator este testarea reflexelor și obținerea unui timp de supraviețuire cât mai lung pentru a stabili un nou record.

Descriere generală

Diagrama hardware

Hardware Design

Listă de componente:

Componentă Descriere
ATmega328P Xplained Mini Microcontrollerul principal care se ocupă de periferice și logica jocului. Cel mai bun timp va fi stocat în memoria EEPROM a acestuia.
Display TFT LCD 3.2 (Controller ILI9341) Ecranul unde se afișează jocul prin protocolul SPI
Joystick HW-504 Modul principal de controlare a navei spațiale
LED RGB Folosit pentru status de viață: 3 vieți - verde, 2 vieți - galben, 1 viață - roșu intermitent
Buzzer pasiv Redă sunet în momentul coliziunii navei cu un asteroid sau la game over
Rezistențe Folosite pentru limitarea curentului prin LED și pentru divizori de tensiune

Schema electrică:

Schema electrică

Pinii nefolosiți sunt marcați cu un X.

Pentru comunicarea prin protocolul SPI cu ecranul LCD, se folosesc următorii pini:

Deoarece nu se vor citi niciodată date de la ecran, nu se folosește pinul D12 (MISO). Având în vedere că ecranul efectuează comunicarea SPI la 3.3V, iar pinii au un output de 5V, se folosește un divizor de tensiune pentru fiecare pin, utilizând rezistențe de 1K și 2K pentru a coborî tensiunea de la 5V la 3.33V. De asemenea, se folosește pinul 3V3 (LED) al plăcii pentru a alimenta backlight-ul ecranului.

Pentru joystick, se folosesc următorii pini:

Pentru LED-ul RGB, se folosesc pinii digitali D5 (R) și D6 (G) pentru a controla culoarea roșie, respectiv culoarea verde, folosind rezistențe de 330Ω pentru a limita curentul prin acesta. Deoarece avem nevoie numai de culorile roșu, verde și galben (roșu + verde), nu este necesară culoarea albastră, pinul aferent acesteia rămânând neconectat. Pentru situația în care jucătorul mai are o singură viață, se va folosi un timer care va alterna între HIGH și LOW pentru culoarea roșie.

Buzzerul pasiv va fi controlat de pinul digital D7 (BUZZER), alternând între stările HIGH și LOW folosind timere pentru a reda sunetul.

Conectare componente + testare ecran LCD și LED RGB:

Conectare componente

Nava spațială este afișată corect pe ecranul LCD, ceea ce validează comunicarea prin protocolul SPI. LED-ul RGB este funcțional, fiind activat pe culoarea verde, demonstrând configurarea corectă a pinilor de ieșire.

Software Design

Mediu de dezvoltare: Visual Studio Code + PlatformIO

Librăria folosită: https://github.com/lexus2k/ssd1306, care are suport și pentru ILI9341, folosit pentru desenarea pe ecran și funcționalitățile protocolului SPI. S-a ales această librărie, deoarece se poate folosi fără ecosistemul Arduino, folosește cât mai puține resurse și are implementări performante, fiind important pentru a actualiza ecranul cât mai repede posibil pentru un framerate cât mai bun.

Interacțiunea cu componentele hardware:

Componente software:

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:

Rezultate Obţinute

Link Youtube: Asteroid Avoider - Proiect PM 2026

Se poate observa în videoclip că, într-o sesiune de joc, toate componentele hardware și software menționate funcționează.

Concluzii

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.

Download

Link GitHub: https://github.com/PredaAndrei3/AsteroidAvoider

Bibliografie/Resurse

Resurse Hardware:

Manual utilizare Display TFT LCD 3.2

ATmega328P Datasheet

Resurse Software:

SSD1306 Library

Coliziune elastică

Export to PDF