This is an old revision of the document!
Cu toate că acest tărâm fermecător este înconjurat de frumusețea florilor, el ascunde și un pericol teribil: un monstru care devorează totul în calea sa. Monstrul a distrus toate florile, lăsând în urmă doar pământ arid și dezolat. Împăratul, simțindu-se neputincios, a anunțat în întreaga țară că orice erou care va reuși să învingă bestia va primi mâna fiicei sale în căsătorie. Cu toate acestea, se spunea că Trandafirica era de o urâțenie rară, iar niciun voinic nu îndrăznise să se confrunte cu monstrul.
Oare care va fi primul jucător care își va pune viața în pericol indiferent de premiu? Cine știe, poate zvonurile sunt false și adevărata frumusețe a Trandafiricii se ascunde dincolo de povestea spusă de gurile rele.
Schemă bloc:
Funcționalități module proiect:
Matricea va fi de dimensiune 8×8, fiecare led reprezentând o poziție validă a jucătorului, una dintre poziții va fi ocupată de monstru și alta de cufărul cu arme necesar pentru a ucide bestia și a câștiga jocul.
În funcție de inputul dat de jucător joystick-ului, acesta se poate mișca pe orizontală și verticală pe hartă, iar folosind funcționalitatea de switch al joystick-ului el poate da hit monstrului. Pentru a da hit monstrului, jucătorul trebuie mai întâi să-l localizeze, să se afle pe o poziție de pe hartă alăturată lui pe axele ox sau oy îndreptat către el și să apese pe joystick.
Buzzer-ul va fi activat doar atunci când jucătorul este în apropierea monstrului pentru a contribui la localizarea acestuia. Acesta poate fi folosit și la redarea unor sunete când jucătorul pierde sau câștigă.
Ecranul OLED contribuie dpdv al graficii jocului, afișarea de mesaje și a unui timer. Scopul timer-ului este de a da un sentiment de survival și presiune, determinând jucătorul să învingă bestia într-un timp limitat.
Pentru a face proiectul portabil, folosesc o baterie de 9V pentru alimentarea microcontroller-ului ATmega328P, în loc să îl conectez la laptop prin USB. Placa va comunica cu ecranul oled prin I2C și cu matricea de led-uri prin SPI în funcție de inputul primit de la joystick. La rândul lui, joystick-ul va fi conectat la 2 pini analogici pentru deplasarea pe verticală și orizontală, și la 1 pin digital pentru un comportament asemănător unui buton. Buzzer-ul este conectat la un pin digital împreună cu un rezistor de 100Ω.
PIN13 de pe Arduino Uno este un pin SCK (Serial Data Clock) folosit pentru comunicarea prin SPI.
Pinul de DOUT de pe modulul matrice de leduri este pentru conectarea în lanț a mai multor matrice și nu-l voi folosi pentru proiect.
Al treilea pin nu se conectează la nimic.
În funcția de setup setez pinii, inițializez matricea de led-uri, ecranul OLED și creez harta - adică plasez monstrul și chest-ul într-o poziție random. Jucătorul va fi plasat la începutul fiecărui joc în colțul stânga jos.
Pentru funcția de switch al joystick-ului am creeat o întrerupere, care va avea loc de fiecare dată când apăs pe joystick.
Pentru timer configurez Timer0 al plăcuței pentru a funcționa în modul CTC (Clear Timer on Compare Match), setează un prescaler de 64 și configurează timerul pentru a genera o întrerupere la fiecare 1 milisecundă.
Pentru ca jucătorul să se deplaseze am definit funcția getDirection care primește inputul de la pinii VRX și VRY ai joystick-ului, și în funcție de valorile analogice primite întoarce una dintre direcțiile sus, jos, stânga, dreapta.
Funcția dangerZone() alertează jucătorul când se află în apropierea monstrului cu ajutorul buzzer-ului și al ecranului OLED.
Funcția chestZone() alertează jucătorul când se află în apropierea cufărului cu ajutorul buzzer-ului și al ecranului OLED.
Am definite niște variabile de tip bool și în funcție de valoarea lor, pe ecran va apărea o imagine cu eroul, prințesa (în cazul în care câștigă), cufărul (când se află în preajma lui), sabia (când deschide cufărul), monstrul (când se află în preajma lui) sau un mormânt (cănd eroul este mâncat de monstru). Imaginile pixelate au fost create în GIMP și după convertite în bitmap cu ajutorul site-ului
Eroul pierde jocul în următoarele situații
Eroul câștigă jocul dacă localizează mai întăi arma, iar odată localizat și monstrul va trebui să lovească în sensul și direcția lui. Pentru a ne da seama în ce sens lovește eroul, în cod reținem în variabila lastMove sensul din care vine jucătorul înspre monstru (de sus, de jos, din stânga sau din dreapta). Eroul trebuie să omoare monstrul în timpul alocat pentru a câștiga.
De fiecare dată când jucătorul pierde sau câștigă, jocul se resetează.
Proiectul ar putea fi puțin mai complex din punct de vedere al numărului de monștri sau prin adăugarea de animații pe ecranul OLED (asta ținând cont și de spațiul de stocare al programului (flash-ul) și de memoria dinamică folosită) - programul meu curent deja ocupând destul de mult:
De asemenea, am întâmpinat probleme din cauza folosirii timer-ului 0, pentru că nu am mai putut folosi funcția de delay() și nici millis(), de care aș fi avut nevoie la creearea sunetelor cu ajutorul buzzer-ului, la care am găsit o alternativă nu atât de bună (zic eu) - generam o anumită frecvență pe un interval determinat de valoarea contorului.
Cu toate acestea, chiar dacă am întâmpinat unele probleme, a fost plăcut să gasesc soluții la ele de una singură.
Fişierele se încarcă pe wiki folosind facilitatea Add Images or other files. Namespace-ul în care se încarcă fişierele este de tipul :pm:prj20??:c? sau :pm:prj20??:c?:nume_student (dacă este cazul). Exemplu: Dumitru Alin, 331CC → :pm:prj2009:cc:dumitru_alin.
Inspirație:
Resurse hardware:
Resurse software:
→ pentru a converti imagini în byte arrays
→ pentru implementare întreruperi
→ pentru implementare timer
→ pentru comunicare SPI
→ pentru comunicare I2C