Differences

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

Link to this comparison view

pm:prj2025:rnedelcu:ioan_alexandru.popa [2025/05/13 20:49]
ioan_alexandru.popa [Introducere]
pm:prj2025:rnedelcu:ioan_alexandru.popa [2025/05/28 17:05] (current)
ioan_alexandru.popa
Line 64: Line 64:
   * (etapa 3) surse şi funcţii implementate   * (etapa 3) surse şi funcţii implementate
 </​note>​ </​note>​
 +
 +Codul este disponibil la [[https://​github.com/​ALEX11BR/​proiect-pm/​tree/​main/​cod-rpipico|https://​github.com/​ALEX11BR/​proiect-pm/​tree/​main/​cod-rpipico]].
 +
 +==== Mediu de dezvoltare ====
 +
 +Pentru dezvoltarea codului am folosit Visual Studio Code cu extensia PlatformIO.
 +
 +==== Bibloiteci folosite ====
 +
 +Ca biblioteci terțe folosite avem:
 +  * [[https://​github.com/​Bodmer/​TFT_eSPI|Biblioteca Bodmer/​TFT_eSPI folosită fentru LCD]]
 +  * [[https://​duktape.org|Duktape - interpretor JavaScript]]
 +  * PlatformIO cu [[https://​github.com/​maxgerhardt/​platform-raspberrypi|platforma lui maxgerhardt pentru Raspberry Pi]]
 +  * [[https://​github.com/​earlephilhower/​arduino-pico|Arduino-Pico]]
 +  * [[https://​www.raspberrypi.com/​documentation/​pico-sdk/​|SDK-ul Raspberry Pi Pico]] imclus în Arduino-Pico
 +
 +Las mai jos argumentele pentru folosirea bibliotecilor folosite:
 +  * Implementarea de la 0 a comunicării cu LCD-ul am considerat că depășește scopul proiectului,​ așa că am căutat o bibloiotecă care să implementeze randarea pe LCD, una care să poată suporta modelul meu de LCD ce //pare// a fi ST7735. ''​Bodmer/​TFT_eSPI''​ este exact ce căutam.
 +  * ''​Bodmer/​TFT_eSPI''​ folosește API-urile Arduino, așa că se impunea ca proiectul meu să le folosească,​ prin intermediul implementării pentru Pi Pico - Arduino-Pico
 +  * Simpla folosire a Arduino IDE și a convențiilor sale de compilare mi se părea un regres mare, fiind obișnuit cu mediile de dezvoltare software unde dependențele pot fi specificate clar într-un fișier aferent, fără să te bazezi pe un mecanism de forma //alege biblioteca cutare din interfața IDE-ului și descarc-o într-un folder global tuturor proiectelor//​.
 +  * La un moment dat al dezvoltării proiectului s-a manifestat o eroare a platformei implicite PlatformIO pentru Raspberry Pi Pico ce m-a chinuit mult timp (mi se tot apelau interrupt-urile dacă dădeam ''​analogWrite''​ sau ceva de genul), până când am încercat platforma lui maxgerhardt și m-am convins că ea e de folosit cănd folosim PlatformIO pe Raspberry Pi Pico.
 +  * Pentru ideea de scriere a jocurilor într-un limbaj dinamic am încercat inițial cu [[https://​github.com/​lua/​lua|Lua]],​ dar inegrarea bibliotecii în proiect era dificilă. Am găsit Duktape ca bibliotecă ușor integrabilă (am pus fișierul (unul singur) ''​.c''​ și cele ''​.h''​ în directorul ''​lib''​ al codului sursă); într-adevăr,​ pentru JavaScript - [[https://​compat-table.github.io/​compat-table/​es6/​|o versiune mai veche a limbajului]] fără anumite caracteristici moderne cu care eram obișnuit din lucrul meu anterior cu JavaScript (''​let'',​ arrow functions), dar pentru scopul proiectului este suficient.
 +  * Aveam dorința de a scrie codul JavaScript al jocurilor în fișiere ''​.js'',​ care să fie incluse ulterior în codul C++ ca șiruri de caractere și încărcate în interpretor. Am găsit ca soluție pentru acest lucru funcționalitatea PlatformIO de imagini ale sistemului de fișiere LittleFS cu fișierele aflate în directorul ''​data'',​ unde am pus fișierele ''​.js''​ cu logica jocurilor. Un dezavantaj al acestei abordări este că încărcarea codului pe plăcuță se face în 2 pași (în funcție de ce parte de cod s-a actualizat):​
 +    * ''​Upload''​ pentru încărcarea codului C++ compilat
 +    * ''​Upload filesystem''​ pentru încărcarea logicii JavaScript a jocurilor
 +  * Anumite caracteristici ale Raspberry Pi Pico sunt accesibile doar prin API-urile specifice Raspberry Pi Pico SDK (timere, watchdog, restart forțat, alarme).
 +
 +==== Jocuri Implementate ====
 +
 +  * Snake
 +    * 4 vieți
 +    * Controlează șarpele cu joystick-ul în direcția pe care vrei să o ia
 +      * Se ignoră comenzile de înapoi
 +    * Cu butonul acțiune se merge mai departe în direcția capului
 +    * Șarpele se mișcă automat după ce jucătorul l-a mutat manual o dată
 +    * Șarpele crește când mănâncă mâncarea disponibilă în nivel, moment în care se generează un nou punct cu mâncarea
 +    * Șarpele moare când se lovește de margini sau de el însuși
 +  * Drive
 +    * 4 vieți
 +    * Controlezi o mașinuță ce trebuie să se ferească de zidurile de pe marginile drumului
 +      * Stânga-dreapta
 +    * Mașinuța merge înainte la un interval de timp sau la joystick înainte
 +    * Zidurile se schimbă periodic
 +
 +Meniul principal este, de asemenea implementat ca script JavaScript.
 +
 +==== Interfața JavaScript ====
 +
 +Jocurile au acces la 2 ecrane virtuale, cu celule indexate de la 0:
 +  * Principal de 10x20 (pentru acțiunea jocului)
 +  * Secundar de 4x4 (pentru afișarea unor detalii suplimentare,​ ex. numărul de vieți)
 +
 +Ecranele au 3 culori:
 +  * 0 = stins
 +  * 1 = aprins (negru)
 +  * 2 = parțial aprins (gri)
 +
 +Există un sistem de tick-uri care se execută după fiecare ''​TICK_TIME''​ (500) milisecunde
 +
 +Runtime-ul implementează următoarele funcții:
 +  * ''​brickVibrate(intensity:​ number, duration: number)''​ - Motorul cu vibrații va vibra la intensitatea ''​intensity''​ (număr între 0 și 255; 255 = maxim, 180 = valoare intermediară bună) timp de ''​duration''​ milisecunde.
 +  * ''​brickMainDraw(x:​ number, y: number, color: number)''​ - desenează pe ecranul principal la celula specificată (linia ''​y'',​ coloana ''​x''​) culoarea specificată
 +  * ''​brickSecondaryDraw(x:​ number, y: number, color: number)''​ - desenează pe ecranul principal la celula specificată (linia ''​y'',​ coloana ''​x''​) culoarea specificată
 +  * ''​brickTickReset()''​ - nu se va mai executa tick-ul următor, se va executa peste ''​TICK_TIME''​ milisecunde (dacă nu se mai apelează ''​brickTickReset()''​ încă o dată până atunci)
 +  * ''​brickGameOver(x:​ number, y: number, noRestart: boolean)''​ - inițializează ecranul de game over cu „X”-ul în punctul specificat (linia ''​y'',​ coloana ''​x''​) și vibrație maximă. După un timp se ve reporni jocul în același context (variabilele globale sunt păstrate, dar se va rula ''​handleInit()''​) dacă ''​noRestart''​ e ''​false'',​ altfel se va reseta consola la meniul principal.
 +  * ''​brickLoad(gamePath:​ string)''​ - încarcă jocul din calea specificată din sistemul de fișiere LittelFS încărcat pe plăcuță, resetând contextul JavaScript. Un API „intern”,​ nu e intenționată folosirea lui în jocuri, doar în meniul de start.
 +
 +Jocurile trebuie să implementeze următoarele funcții, ce se apelează în cardul unor evenimente relevante în joc:
 +
 +  * ''​handleInit()''​ - se apelează inițializarea jocului la pornire sau după o pierdere de viață prin ''​brickGameOver(x,​ y, false)''​. Aici se inițializează variabilele ce indică starea vieții curente. Inițializarea numărului de vieți sau alte chestii ce se păstrează de-a lungul vieților se face direct în corpul scriptului.
 +  * ''​handleTick()''​ - se apelează la fiecare tick - bun pentru aplicarea mișcărilor automate etc.
 +  * ''​handleAction()''​ - se apelează la apăsarea butonului acțiune (cel mai din dreapta).
 +  * ''​handleUp()''​ - se apelează la deplasarea în sus a joystick-ului.
 +  * ''​handleLeft()''​ - se apelează la deplasarea în stânga a joystick-ului.
 +  * ''​handleRight()''​ - se apelează la deplasarea în dreapta a joystick-ului.
 +  * ''​handleDown()''​ - se apelează la deplasarea în jos a joystick-ului.
 +
 +Aceste funcții nu trebuie să dureze mult, doar cât trebuie pentru a administra evenimentul în cauză.
 +Pentru a încuraja bunele practici, există un watchdog ce nu poate fi resetat de codul Javascript, doar de alte timere interne, care să reseteze consola dacă JavaScriptul durează prea mult.
  
 ===== Rezultate Obţinute ===== ===== Rezultate Obţinute =====
Line 81: Line 160:
 {{:​pm:​prj2025:​rnedelcu:​ioan_alexandru.popa:​hardwarebun1.jpg?​400|}} {{:​pm:​prj2025:​rnedelcu:​ioan_alexandru.popa:​hardwarebun1.jpg?​400|}}
 {{:​pm:​prj2025:​rnedelcu:​ioan_alexandru.popa:​hardwarebun2.jpg?​400|}} {{:​pm:​prj2025:​rnedelcu:​ioan_alexandru.popa:​hardwarebun2.jpg?​400|}}
 +
 +==== Software ====
 +{{:​pm:​prj2025:​rnedelcu:​ioan_alexandru.popa:​20250528_165839.jpg?​400|}}
 +{{:​pm:​prj2025:​rnedelcu:​ioan_alexandru.popa:​20250528_165833.jpg?​400|}}
 +{{:​pm:​prj2025:​rnedelcu:​ioan_alexandru.popa:​20250528_165851.jpg?​400|}}
 +{{:​pm:​prj2025:​rnedelcu:​ioan_alexandru.popa:​20250528_165854.jpg?​400|}}
 +{{:​pm:​prj2025:​rnedelcu:​ioan_alexandru.popa:​20250528_165921.jpg?​400|}}
 ===== Concluzii ===== ===== Concluzii =====
 +
 +A fost o perioadă chinuitoare pentru mine, plină de burn-out, și nu am putut implementa toate jocurile ce le-aș fi dorit, dar am eliminat cam toate obstacolele în implementarea unor jocuri noi.
 +Am reușit să îmi evoluez visul meu de a avea o clonă a acelor console Brick 9999 games cu jocuri implementabile într-un limbaj dinamic, venind cu un API complet pentru scrierea în limbaj dinamic a jocurilor; într-adevăr,​ optimizat pentru un mediu cu randare lentă a ecranului.
  
 ===== Download ===== ===== Download =====
Line 105: Line 194:
  
 ==== Resurse Hardware ==== ==== Resurse Hardware ====
 +  * [[https://​datasheets.raspberrypi.com/​rp2040/​rp2040-datasheet.pdf|Datasheet RP2040]]
   * [[https://​datasheets.raspberrypi.com/​picow/​PicoW-A4-Pinout.pdf|Pinout Raspberry Pi Pico W]]   * [[https://​datasheets.raspberrypi.com/​picow/​PicoW-A4-Pinout.pdf|Pinout Raspberry Pi Pico W]]
   * [[https://​helloraspberrypi.blogspot.com/​2021/​07/​rpi-pico-arduino-framework-128x160.html|Exemplu de conectare și cod pentru cuplarea LCD-ului la Raspberry Pi Pico]]   * [[https://​helloraspberrypi.blogspot.com/​2021/​07/​rpi-pico-arduino-framework-128x160.html|Exemplu de conectare și cod pentru cuplarea LCD-ului la Raspberry Pi Pico]]
Line 111: Line 201:
 ==== Resurse Software ==== ==== Resurse Software ====
   * [[https://​github.com/​Bodmer/​TFT_eSPI|Biblioteca Bodmer/​TFT_eSPI folosită fentru LCD]]   * [[https://​github.com/​Bodmer/​TFT_eSPI|Biblioteca Bodmer/​TFT_eSPI folosită fentru LCD]]
-  * [[https://​github.com/​r-lyeh/​single_file_libs|LIstă de biblioteci C/C++ cu puține fișiere, deci integrabile ușor]]+  * [[https://​github.com/​r-lyeh/​single_file_libs|Listă de biblioteci C/C++ cu puține fișiere, deci integrabile ușor]]
   * [[https://​duktape.org/​api|Documentație Duktape]]   * [[https://​duktape.org/​api|Documentație Duktape]]
 +  * [[https://​docs.arduino.cc/​learn/​programming/​reference/​|Documentație API Arduino]]
 +  * [[https://​arduino-pico.readthedocs.io/​en/​latest/​|Documentație API Arduino Pico]]
 +  * [[https://​www.raspberrypi.com/​documentation/​pico-sdk/​|Documentație Raspberry Pi Pico SDK]]
  
 <​html><​a class="​media mediafile mf_pdf"​ href="?​do=export_pdf">​Export to PDF</​a></​html>​ <​html><​a class="​media mediafile mf_pdf"​ href="?​do=export_pdf">​Export to PDF</​a></​html>​
  
pm/prj2025/rnedelcu/ioan_alexandru.popa.1747158565.txt.gz · Last modified: 2025/05/13 20:49 by ioan_alexandru.popa
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