Autor: Gheorghe Mara, 333CD
Proiectul este o consola portabila cu joc de labirint controlat prin rotirea dispozitivului. Scopul jocului este ca o bila sa ajunga de la “start” la “finish” in labirint, ea fiind afectata doar de gravitatie, fara interventie directa. Labirintul se roteste odata cu dispozitivul, astfel fiind controlata, indirect, deplasarea bilei. Sunt 2 moduri principale de joc, in care labirintul este fie prestabilit, fie generat pe masura ce bila avanseaza.
Ideea mi-a venit de la jocuri similare pe telefon. Consider ca un astfel de joc se preteaza foarte bine pe un dispozitiv hand-held dedicat, mult mai bine decat jocurile clasice unde actiunea e controlata doar prin butoane.
Mediul de joc constă într-o grilă în care bila trebuie să ajungă la puncte de tip “Finish” marcate prin pătrate de 2×2. Proiectul utilizează un accelerometru MPU6050 cu un filtru trece-jos (low-pass filter) pentru a izola vectorul gravitațional, eliminând zgomotul cauzat de tremurul mâinilor, fără a necesita calibrarea giroscopului.
Moduri de joc:
Set Level: Labirint delimitat, obiectivul este atingerea unui scor prestabilit (5 puncte).
Endless Mode: Labirint generat live in partea dreapta, pe măsură ce bila avansează. Cand bila depaseste marginea ecranului, se genereaza o noua sectiune de labirint. Jucatorul se poate intoarce la ecranul anterior, dar nu poate da inapoi mai mult de o sectiune de labirint. Nu se poate “castiga”, jocul ruleaza la infinit.
Funcționalități:
Start/Cancel Game: Buton roșu.
Change Gamemode: Buton galben.
Feedback Vizual:
Unitatea de Procesare (placa Arduino Nano): Este dotata cu microprocesor ATmega328P. Acesta ruleaza codul principal, primeste date de la modulul MPU6050, gestioneaza comunicarea cu perifericele (ecran, butoane) si proceseaza algoritmii de joc.
Senzorul Inertial (MPU6050): Masoara acceleratia pe 3 axe. Detecteaza inclinarea consolei in timp real si trimite datele catre microcontroller prin protocolul I2C.
Modulul de Afisare (OLED SSD1306): Functioneaza prin interfata I2C. Ofera feedback vizual utilizatorului. Afiseaza labirintul, bila, obiectivele si ecrane informationale privind starea jocului.
Modulul de incarcare TP4056: Permite incarcarea bateriei prin USB-C.
Acumulator LiPo: Necesar pentru un dispozitiv portabil. Are capacitate de 1000mAh, permitand cateva ore de functionare pana a avea nevoie de reincarcare. Functioneazza la 3.7V si prezinta protectie PCM si NTC.
MT3608 (Step-up): Ridica tensiunea de la 3.7V (baterie) la 5V constant pentru a asigura functionarea stabila a celorlaltor componente.
Butoane: Ofera optiuni de “start/restart level”, “change gamemode” si “look down”
LED-uri controlate prin PWN: Cele 4 LED-uri albe se aprind atunci cand bila face contact cu peretii de labirint corespunzatori. Cele 3 LED-uri verzi se vor aprinde unul cate unul pe masura ce utilizatorul progreseaza in joc.
| Denumire Piesa | Schema electrica |
|---|---|
| Placa de dezvoltare cu microprocesor ATmega328p | https://www.arduino.cc/en/uploads/Main/ArduinoNano30Schematic.pdf |
| Modul Accelerometru si Giroscop cu 3 Axe MPU6050 | https://www.researchgate.net/figure/Circuit-diagram-of-MPU6050_fig5_378433285 |
| Modul incarcare LiPo TP4056 | https://www.sunrom.com/media/content/86/tp4056-schematic-app.gif |
| Modul tensiune MT3608 | https://bit.ly/mt3608-schem |
| Afisaj grafic OLED 128×64 GMEI12864-19 cu driver SSD1306 | http://wiki.sunfounder.cc/index.php?title=OLED-SSD1306_Module |
Alte componente:
Codul aplicației este dezvoltat “bare-metal” în limbajul C, utilizând direct regiștrii microcontrolerului ATmega328P pentru a asigura o execuție rapidă și o gestionare eficientă a memoriei, aspecte esențiale pentru un joc care rulează la 30 FPS.
Sistemul determină înclinarea consolei folosind exclusiv datele de la accelerometru. Pentru a stabiliza mișcarea bilei și a elimina efectul de tremur al mâinilor, se aplică un Filtru Trece-Jos (Low-Pass Filter) care ignoră variațiile bruște. Pe baza acestor date “netezite”, se calculează direct forța și direcția în care trebuie să cadă bila pe ecran. Am renunțat complet la giroscop pentru a evita acumularea de erori în timp (“gyro drift”), obținând astfel un control constant și precis pe termen nelimitat.
Labirintul este stocat într-o matrice bidimensională. Lățimea dublă a matricii permite stocarea simultană a două secțiuni de ecran, facilitând scrolling-ul fluid în “Endless Mode”. Generarea se face prin algoritmul “Drunkard's Walk” (Mersul Bețivului): * Întreaga secțiune este umplută inițial cu pereți (blocuri pline). * Un generator virtual (“cârtița”) pornește dintr-un punct valid și “sapă” tuneluri. * La fiecare pas, alege aleatoriu o direcție, o lățime a tunelului și o distanță, transformând pereții în zone libere. * În modul infinit, când bila ajunge la capătul din dreapta, jumătatea dreaptă a matricii este mutată în stânga, iar o nouă jumătate este generată pe loc în dreapta.
Coliziunile sunt separate pe axele X și Y, decizie care permite bilei să “alunece” fluid de-a lungul unui perete. Dacă se detectează o coliziune doar pe axa X, viteza orizontală este anulată, dar viteza pe Y rămâne intactă, lăsând gravitația să tragă bila în jos de-a lungul obstacolului. Pentru a optimiza verificările și a nu scana tot ecranul, coordonatele în pixeli ale bilei sunt pur și simplu împărțite la dimensiunea unui bloc, aflând astfel exact indicii celulei curente din matricea labirintului.
Ecranul OLED comunică prin protocolul I2C. Datorită resurselor limitate de memorie RAM, nu folosim un ecran virtual complet (“frame buffer”) în memorie. În schimb, desenarea se face citind direct matricea labirintului: * Se desenează pătrate solide pentru fiecare celulă de tip perete. * Se randează markere grafice pentru destinațiile de tip “Finish”. * La final, se desenează poziția curentă a bilei peste labirint. Această abordare este rulată sincronizat cu un Timer Hardware setat precis pentru a reîmprospăta ecranul de 30 de ori pe secundă, oferind o mișcare vizuală perfect cursivă.
Un joculet care te poate tine ocupat macar 5 minute, ce reacționează suficient de repede la mișcare si care incape intr-o carcasa de dimensiuni mici
Demonstratie video (mod de joc Endless Maze): https://youtu.be/hDFpc9VpoJU
7 Mai: au fost livrate componentele comandate.
13 Mai: am conectat ecranul si giroscopul la arduino. Am descoperit ca de fapt ecranul are zone fixe de culoare; vor trebui modificate aspecte ale jocului
17 Mai: am deschis repository pe GitHub cu codul 'bare-metal' necesar interactiunii cu MPU6050 si cu ecranul
18 Mai: lipituri pentru tot circuitul de alimentare: baterie, modul de incarcare, convertor de tensiune si intrerupator
25-26 Mai: finalizare proiect