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 ===== | ||