![](/media/cache/group/default_image.jpg.50x50_q85.jpg)
Igra u kojoj se nasumično uključuju i isključuju LED, a korisnik mora ponoviti redoslijed kojim su se uključivale. Redoslijed paljenja bira se preko potenciometra za označavanje željene LED i tipkala za potvrdu odabira. Povratne informacije o igri (poraz/nova razina/pobjeda) su napravljene uz pomoć prikladnih svjetlosnih i zvučnih efekata.
Dependencies: mbed zvucniEfekti
main.cpp
- Committer:
- nikola_cancer
- Date:
- 2021-12-01
- Revision:
- 0:f1138da8bd35
File content as of revision 0:f1138da8bd35:
/* mbed Microcontroller Library * Copyright (c) 2019 ARM Limited * SPDX-License-Identifier: Apache-2.0 */ #include "mbed.h" #include "zvucniEfekti.h" #define MAX_BROJ_SEKVENCE 10 #define SAMPLEFREQ 8000 InterruptIn tipkaloFlipLED(D12); DigitalOut ledZaProvjeru(D6); Ticker sampleRate; AnalogOut zvucnik(PA_5); AnalogIn potenciometar(A0); DigitalIn tipkalo(D9); int kontrolaZvuka; // globalna varijabla za odabir koji zvuk se pušta (u // funkciji sviraj) na piezo class Igra { private: int brojLedica; DigitalOut *ledice; float vrijednostiZaPotenciometar[10]; public: Igra(DigitalOut *led, int brLED) { ledice = led; brojLedica = brLED; float korak = 1. / brojLedica; for (int i = 0; i < brojLedica + 1; i++) { if (i == 0) { vrijednostiZaPotenciometar[i] = 0; } else { vrijednostiZaPotenciometar[i] = vrijednostiZaPotenciometar[i - 1] + korak; } } tipkalo.mode(PullUp); srand(time(0)); } /* globalna varijabla kontrolaZvuka: 0 -> gameStart 1 -> nextLevel 2 -> finalLevel 3 -> gameWon 4 -> gameOver */ void sviraj() { static int i = 0; switch (kontrolaZvuka) { case 0: zvucnik.write_u16(zvukGameStart[i] << 8); i++; if (i == brojSamplovaZvukGameStart) { i = 0; zvucnik.write_u16(0); sampleRate.detach(); } break; case 1: zvucnik.write_u16(zvukNextLevel[i] << 8); i++; if (i == brojSamplovaZvukNextLevel) { i = 0; zvucnik.write_u16(0); sampleRate.detach(); } break; case 2: zvucnik.write_u16(zvukFinalLevel[i] << 8); i++; if (i == brojSamplovaZvukFinalLevel) { i = 0; zvucnik.write_u16(0); sampleRate.detach(); } break; case 3: zvucnik.write_u16(zvukGameWon[i] << 8); i++; if (i == brojSamplovaZvukGameWon) { i = 0; zvucnik.write_u16(0); sampleRate.detach(); } break; case 4: zvucnik.write_u16(zvukGameOver[i] << 8); i++; if (i == brojSamplovaZvukGameOver) { i = 0; zvucnik.write_u16(0); sampleRate.detach(); } break; } } void generirajRandomSekvencu(int brojUzoraka, int *sekvenca) { ugasiSveLED(); for (int i = 0; i < brojUzoraka; i++) { int num = (rand() % brojLedica); // random broj između 0 i brLED sekvenca[i] = num; // spremi u sekvencu zbog kasnije usporedbe generiranog // i pogađanog // upali i ugasi random LED wait_ms(500); ledice[num] = 1; wait_ms(500); ledice[num] = 0; wait_ms(500); } wait(2); } void spremiUnosKorisnika(int brojUzoraka, int *sekvenca) { for (int k = 0; k < brojUzoraka; k++) { for (;;) { for (int i = 0; i < brojLedica; i++) { if (potenciometar >= vrijednostiZaPotenciometar[i] && potenciometar < vrijednostiZaPotenciometar[i + 1]) { ledice[i] = 1; } else { ledice[i] = 0; } } if (tipkalo == 0) { wait_ms(50); // debounce if (tipkalo == 0) { for (int j = 0; j < brojLedica; j++) { if (ledice[j].read() == 1) { sekvenca[k] = j; // da korisnih ima feedback da je ucitan njegov odabir ledice[j] = 0; wait_ms(500); ledice[j] = 1; } } // cekaj dok tipkalo ne ode u jedan (radi ko rising edge) // da ove beskonacne petlje nema bi spremil 4x istu vrijednost u // array (jer radi brzo) do { } while (tipkalo.read() == 0); break; } } } } } /* funkcija vraca 0 za razlicite arraye, a 1 za iste */ int provjeriSekvence(int *generiranaSekvenca, int *unesenaSekvenca, int brojUzorakaSekvence) { int i = 0; for (i = 0; i < brojUzorakaSekvence; i++) { if (generiranaSekvenca[i] != unesenaSekvenca[i]) { return 0; // poraz } } return 1; // sljedeca razina/pobjeda } void ugasiSveLED() { for (int i = 0; i < brojLedica; i++) { ledice[i] = 0; } } void sljedecaRazina(int finalniLevel) { ugasiSveLED(); if (finalniLevel != 0) { kontrolaZvuka = 2; } else { kontrolaZvuka = 1; } sampleRate.attach(this, &Igra::sviraj, 1.0 / SAMPLEFREQ); for (int i = 0; i < brojLedica; i++) { ledice[i] = 1; wait_us(100000); ledice[i] = 0; } wait_us(100000); } void novaIgra() { kontrolaZvuka = 0; sampleRate.attach(this, &Igra::sviraj, 1.0 / SAMPLEFREQ); wait(2); } void pobjeda() { ugasiSveLED(); kontrolaZvuka = 3; sampleRate.attach(this, &Igra::sviraj, 1.0 / SAMPLEFREQ); // chaser effekt 5x sim tam int i = 0; do { for (int j = 0; j < brojLedica; j++) { ledice[j] = 1; wait_us(60000); ledice[j] = 0; } for (int j = brojLedica - 1; j >= 0; j--) // -1 jer sizeof(arr) za arr[20] npr daje 20 a zadnji element je // 19 { ledice[j] = 1; wait_us(60000); ledice[j] = 0; } i++; } while (i < 10); wait(2); } void poraz() { ugasiSveLED(); kontrolaZvuka = 4; sampleRate.attach(this, &Igra::sviraj, 1.0 / SAMPLEFREQ); int i = 0; do { for (int j = 0; j < brojLedica; j++) { ledice[j] = 1; } wait_us(500000); ugasiSveLED(); wait_us(500000); i++; } while (i < 3); wait(2); } }; void flipLED() { ledZaProvjeru = !ledZaProvjeru; } int main() { wait(1); tipkaloFlipLED.mode(PullUp); tipkaloFlipLED.rise(&flipLED); // inicijalizacija pinova za igru DigitalOut led[] = {D2, D4, D7, D8, D10, D11}; int brojLedica = sizeof(led) / sizeof(led[0]); // spremanje generiranih i unesenih vrijednosti int generiranaSekvenca[MAX_BROJ_SEKVENCE] = {0}; int unosKorisnika[MAX_BROJ_SEKVENCE] = {0}; // postavke i logika igre int brojUzorakaSekvence = 3; // kolko puta se LED pale/gase int pobjedaPorazZastavica; int trenutniLevel = 0; int finalniLevel = 2; Igra igra(led, brojLedica); while (true) { if (trenutniLevel == 0) { igra.novaIgra(); } igra.generirajRandomSekvencu(brojUzorakaSekvence, generiranaSekvenca); igra.spremiUnosKorisnika(brojUzorakaSekvence, unosKorisnika); pobjedaPorazZastavica = igra.provjeriSekvence( generiranaSekvenca, unosKorisnika, brojUzorakaSekvence); switch (pobjedaPorazZastavica) { case 0: igra.poraz(); brojUzorakaSekvence = 3; trenutniLevel = 0; break; case 1: if (trenutniLevel == finalniLevel - 1) { igra.sljedecaRazina(1); // 1 -> šalji zvuk finalLevel brojUzorakaSekvence++; trenutniLevel++; } else if (trenutniLevel == finalniLevel) { igra.pobjeda(); brojUzorakaSekvence = 3; trenutniLevel = 0; } else { igra.sljedecaRazina(0); // 0 -> šalji zvuk nextLevel brojUzorakaSekvence++; trenutniLevel++; } break; } } }