Table of Contents

Adrian-Petru CRISTEA (87677) - Chicken Scream

Autorul poate fi contactat la adresa: Login pentru adresa

Introducere

Ai avut vreodata minunata oportunitate de a te juca Chicken Scream ? Daca nu, si banuiesc ca nu, ca sa fiu cat mai succint este un Flappy Bird. Doar ca nu apesi pe ecran ca sa sara, ci va trebui sa tipi.

Descriere generală

Modul de functionare:

  • Prin informatiile obtinute de la modulul de microfon KY038 cu amplificator se detecteaza prezenta sunetului pentru a pune in miscare caracterul.
  • Metoda 2 - la apasarea unui buton
  • Cu informatiile primite se va afisa pe display.

Hardware Design

Componente folosite :

  • Display LCD ILI9341 - Optimus Digital
  • Microfon KY038 - Arduino Shop
  • Cablaj de test 140x90mm - Optimus Digital
  • LP2950ACZ-3.3G STABILIZATOR DE TENSIUNE LDO NEREGLABIL 3.3V 0.1A - ElectronicLight
  • Condensator Electrolitic de 10 uF la 63 V - Optimus Digital
  • 1 buton
  • 30 fire Mama-Mama
  • 20 Headere

Software Design

Am incercat sa fac programul cat mai simplu:

Am inceput prin generarea nivelului. Ca un prim pas mi-am creat prefabricatele (pereti, apa, lava) intr-o structura care le va tine pe toate. Urmatorul pas a fost ca sa ordonez aceste prefabricate. Am impartit ecranul in 8 diviziuni a cate 40 de pixeli pe latime acestea corespunzand fiecare unui obiect. Apoi cu ajutorul unui vector am retinut ordinea prefabricatelor pe ecran. De asemenea, am avut grija ca primul si ultimul obiect sa fie pereti pentru a face mai usor jocul. Ordonarea obiectelor random a fost prima problema reala deoarece:

Folosind random() nu puteam sa setez seed-ul. Astfel a trebuit cumva sa generez o secventa de numere aleator. Am ales sa folosesc un timer care va fi initializat la inceputul jocului si folosind valoarea acestuia se vor ordona prefabricatele pe ecran pentru creearea unui nivel. Dupa crearea acelui nivel timer-ul va fi resetat. Astfel la trecerea in partea dreapta a ecranului se va genera un alt nivel aleator obtinandu-se o mapa infinita.

NU ESTE COMPLET RANDOM ci mai degraba se foloseste de timpul necesar completarii unui nivel in implementarea mea but.. it works quite fine :)

Toata treaba asta si desenarea pasarii, a inimilor si chenarului pentru vieti mi-a luat cam o zi. Ceea ce urmeaza a durat ceva mai mult. Dar stiti cum se zice toate lucrurile la inceput sunt frumoase :)).

Urmatorul pas au fost coliziunile.. si de aici a devenit interesant. Pentru ca felul in care eu afisam pe ecran era putin.. ciudat. Mai exact, axele x si y erau inversate. Si de aici m-am chinuit putin sa ma folosesc de algoritmii de detectie de pe net (aabb collision detection) sau de suma Minkowski intre cele 2 dreptunghiuri - pasarea si obiectul. Ca orice om care face coliziuni de la 0, faci greseli, este pur si simplu natural, doar ca eu am facut mai multe. Si de asta am pierdut undeva la 17 ore ca sa imi dau seama ca mai bine iau pe foaie totul si fac dupa propria mea logica. Logica mea a fost ca sa detectez cu ce parte a obstacolului are loc coliziunea, detectarea in sine a coliziunii a fost folosind aabb collision detection. Logica mea.. una barbara, daca ma intrebi pe mine pentru ca pur si simplu compar laturile si in functie de pozitia lor imi dau seama ce parte a lovit.

Ultimul pas a fost logica jocului. Ideea de ansamblu a fost ca la detectarea de sunet sau la apasarea butonului pasarea sa sara. Si am facut asta. Problema a fost ca trebuia sa si cada. Aici devine putin tricky.. deoarece ajungi cu intrebarile :

Cat sare? Cand trebuie sa cada?

Ei bine, am facut sa sara pana velocity-ul pe care il obtine la apasarea/detectarea de sunet ajunge la 0 prin scaderi succesive la fiecare iteratie. Cat despre cazut, mi s-a parut cel mai logic sa o fac sa cada daca nu detecteaza nimic.

Cat despre Conectarea Hardware:

LCD-ul ILI9341 este conectat prin SPI la placuta. Am gasit librariile pentru font-uri si afisare pe lcd la un coleg din anii trecuti si spre surprinderea mea au mers cu brio.

Microfonul KY-038. Quite the deal. Pacat ca este foarte greu de initializat cum trebuie :(. De ce ? Este simplu.. are un potentiometru a carui piulita trebuie invartita pentru a creste/scade sensibilitatea acestuia. Cum interpretezi asta in cod? Nu asa de simplu. Trebuie sa te foloseste de un ADC (la mine pus pe A0, cu prescaler de 8 - mai mic mai accurate) care va primii Analog Output de la microfon.

De ce nu folosesti Digital Output ? Pentru ca in functie de cat ai rotit acel potentiomentru este setat la LOW sau la HIGH iar la detectarea sunetului se INVERSEAZA dar nu se si intoarce la valoarea initiala, decat la o alta detectare de sunet. Deci NU este nici usor, nici practic de folosit. Pentru ca nu vei stii intensitatea sunetului si nici nu vei putea detecta cu precizie cand este destul sunet si cand nu.

Revenim la ADC si potentiometru. Am facut in asa fel incat pentru calibrare sa imi afiseze in mod constant pe LCD valorile ADC-ului astfel am putut sa imi dau seama care este setarea de care are nevoie, respectiv trebuie rotit de potentiometru pana cand ADC-ul iti va da o valoarea ~= 2.5V. De aici semnalul poate varia foarte usor si in sus pana la 5V si in jos pana la 0V. Tot ce mai e de facut este ca la initializarea programului sa iti iei un treshold pentru ADC pe care il vei compara cu valoarea obtinuta la o iteratie.

Diferenta dintre treshold si valoarea curenta depinde de mediul in care este microfonul pentru o detectie optima.

  20 - Liniste
  100 - PM FAIR

Rezultate Obţinute

Concluzii

In primul rand a fost un proiect care mi-a mancat nervii timp de o saptamana. TOTUSI ma simt mandru ca am reusit sa fac asa ceva. Este primul proiect pe care pot sa il arat oricui si nu doar sa inteleaga ci sa si fie putin uimit macar. De asemenea, este unul din proiectele din facultate care iti da un sens de implinire avand o dovada fizica cum ca ai reusit sa faci ceva.

Download

cristeaadrianpetru332cbpmchickenscream.zip

Jurnal

Data Activitatea
18.05.2019 Am inceput si terminat de lipit toate componentele
19.05.2019 Am inceput sa lucrez la cod, in mare parte m-am jucat cu LCD-ul.
20.05.2019 Am creat prefabricatele pentru nivel si am incercat sa inteleg de ce nu pot sa ma folosesc de random().
21.05.2019 Am realizat ca trebuie sa folosesc un timer intern pentru a genera nivele random si am terminat tot ce tine de partea de grafica si afisare.
22.05.2019 Am inceput sa lucrez la coliziuni. Speram sa termin in acceasi zi.. dar nu am avut atat noroc :-).
23.05.2019 Am terminat coliziunile. Am inceput sa inteleg cum functioneaza ADC-ul si microfonul.
24.05.2019 Am deslusit si microfonul si am terminat logica jocului.