This shows you the differences between two versions of the page.
pm:prj2025:vstoica:horia.moroianu3101 [2025/05/28 13:10] horia.moroianu3101 Restructurare pagina |
pm:prj2025:vstoica:horia.moroianu3101 [2025/05/30 04:34] (current) horia.moroianu3101 [Software Design] |
||
---|---|---|---|
Line 83: | Line 83: | ||
**Implementare**: | **Implementare**: | ||
+ | |||
+ | Codul este împărțit în 5 fișiere ce vor fi prezentate mai jos, ținând cont de funcționalitățile moduleleor. Deși acestea nu conțin particularități ale limbajului ''C++'', am ales sa folosesc acest limbaj pentru compatibilitatea cu bibliotecile externe. | ||
+ | |||
+ | **//main.cpp / main.h//**: conține implementarea principală a jocului. | ||
+ | |||
+ | Programul este structurat sub forma unui atutomat cu 3 stări: | ||
+ | *''START'': Inițializează jocul și așteaptă comanda START. La primirea ei, resetează scorul și viețile, pornește timerul, setează seed-ul random și trece la GAME_PLAYING. | ||
+ | *''GAME_PLAYING'': Gestionează jocul activ — aprinde LED-uri, așteaptă răspuns IR și actualizează scorul sau viețile. Dacă timpul expiră sau răspunsul e greșit, scade o viață. Dacă viețile ajung la 0 sau se apasă START, trece la GAME_OVER. | ||
+ | *''GAME_OVER'': Oprește LED-urile, afișează scorul final și redă un sunet în funcție de performanță. Așteaptă comanda START pentru a reveni la GAME_START. | ||
+ | |||
+ | Variabile globale folosite: | ||
+ | * ''game_state'' – stare actuală a jocului | ||
+ | * ''valid_ir'' – flag pentru semnal IR valid | ||
+ | * ''led_timeout'' – flag dacă timpul LED-ului a expirat | ||
+ | * ''score, high_score, lives'' – folosite pentru a urmari progresul jucatorului | ||
+ | |||
+ | **//timers.cpp / timers.h//**: realizează controlul duratei de aprindere a LED-urilor, generarea de sunete prin buzzer și extragerea unui seed pentru randomizare. | ||
+ | |||
+ | |||
+ | Timer1 - Folosit pentru a controla cât timp rămâne aprins un LED. | ||
+ | *''initLedTimer()'' – setează Timer1 în mod CTC, cu prescaler 1024 și OCR corespunzător MAX_LED_DELAY (2s). | ||
+ | *''startLedTimer()'' – pornește cronometrarea si resetează TCNT1. | ||
+ | *''stopLedTimer()'' – oprește timerul. | ||
+ | *''decreaseLedDelay()'' – reduce treptat durata LED-ului (până la MIN_LED_DELAY), pentru a crește dificultatea jocului. | ||
+ | *ISR ''TIMER1_COMPA_vect'' – semnalează timeout-ul LED-ului în main.cpp (led_timeout = true). | ||
+ | |||
+ | Timer0 - Folosit pentru a genera tonuri audio la frecvențe date. | ||
+ | *''initBuzz()'' – configurează Timer0 în mod CTC pentru ieșire pe pinul PD6 (OC0A). | ||
+ | *''buzz(freq, duration)'' – redă un sunet la frecvența și durata cerută. Folosește ''timer_freq_prescale()'' pentru a calcula automat prescalerul și OCR-ul necesar si controlează durata folosind întreruperea ''TIMER0_COMPA_vect''. (//Cod inspirat din [[https://pcarduino.blogspot.com/2013/10/generating-tones-with-timers.html|acest]] articol.//) | ||
+ | |||
+ | Random seed: ''extractTimers()'' – combină valorile din TCNT0, TCNT1 și TCNT2 într-un uint32_t pentru a genera un seed aleator folosit la alegerea LED-urilor. | ||
+ | |||
+ | **//lcd.cpp / lcd.h//**: gestionează afișajul LCD al jocului (mesaje de început, de final, scor, și vieți). | ||
+ | * vectorul ''heart'' reprezintă un caracter personalizat (o inimă stilizată), folosită pentru a reprezenta viețile jucătorului. | ||
+ | *''initLCD()'' — inițializează LCD-ul și configurează simbolul inimă pentru afișare. | ||
+ | *''displayStart()'' — afișează instrucțiunile inițiale pentru a porni jocul și controlul LED-urilor. | ||
+ | *''displayScore(lives, score)'' — arată numărul de vieți rămase și scorul curent pe ecran. | ||
+ | *''displayGameOver(score, high_score)'' — prezintă scorul final și high score-ul la încheierea jocului. | ||
+ | |||
+ | **//sounds.cpp / sounds.h//**: se ocupă de redarea melodiilor și sunetelor pentru stările jocului. | ||
+ | *''playStart()'' — melodie scurtă de început pentru startul jocului. | ||
+ | *''playWin()'' — melodie de victorie la obținerea unui high score. | ||
+ | *''playFail()'' — melodie de eșec/skip. | ||
+ | |||
+ | **//random.cpp / random.h//**: modul de generare a numerelor pseudo-aleatoare, optimizat pentru microcontrolere. | ||
+ | *''setSeed(seed)'' — inițializează generatorul cu o valoare externă pentru diversificarea secvenței de numere aleatoare. | ||
+ | *''nextRand()'' — returnează un număr pseudo-aleator pe 8 biți folosind algoritmul ''xorshift32'' usor modificat. Acesta lucreaza doar cu operații bitwise și produce rapid valori pe 8 biți, folosite ulterior pentru selectarea celor 4 LED-uri. | ||
+ | |||
===== Rezultate Obţinute ===== | ===== Rezultate Obţinute ===== | ||
+ | {{:pm:prj2025:vstoica:horia.moroianu3101:infracatch.jpg?700|}} | ||
+ | {{:pm:prj2025:vstoica:horia.moroianu3101:start.jpg?700|}} | ||
+ | {{:pm:prj2025:vstoica:horia.moroianu3101:running.jpg?700|}} | ||
+ | {{:pm:prj2025:vstoica:horia.moroianu3101:gameover.jpg?700|}} | ||
+ | |||
+ | ===== Demo ===== | ||
+ | Un scurt demo al proiectului poate fi găsit [[https://www.youtube.com/watch?v=qQdRE64-_nE|aici]]. | ||
- | {{:pm:prj2025:vstoica:horia.moroianu3101:hardware-demo.jpeg?600|}} | + | <html> |
+ | <iframe width="700" height="400" | ||
+ | src="https://www.youtube.com/embed/qQdRE64-_nE" | ||
+ | title="InfraCatch - a reflex game" frameborder="0" | ||
+ | allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" | ||
+ | referrerpolicy="strict-origin-when-cross-origin" | ||
+ | allowfullscreen></iframe> | ||
+ | </html> | ||
===== Download ===== | ===== Download ===== |