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/28 15:41]
ioan_alexandru.popa
pm:prj2025:rnedelcu:ioan_alexandru.popa [2025/05/28 17:05] (current)
ioan_alexandru.popa
Line 85: Line 85:
   * 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//​.   * 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.   * 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.+  * 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):​   * 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''​ pentru încărcarea codului C++ compilat
Line 94: Line 94:
  
   * Snake   * 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   * 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 ==== ==== Interfața JavaScript ====
  
-Jocurile trebuie să implementeze următoarele funcții, ce se apelează în cardul unor evenimente relevante în joc.+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 116: 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 =====
  
pm/prj2025/rnedelcu/ioan_alexandru.popa.1748436073.txt.gz · Last modified: 2025/05/28 15:41 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