This was school project with LED matrix with special shield. Unfortunately, comments are in czech language but I think the program is quite easy to understand. It´s unusable without the shield, but the basis can be used esewhere.
main.cpp
- Committer:
- xtypov00
- Date:
- 2017-01-13
- Revision:
- 0:b4a961ac4a97
File content as of revision 0:b4a961ac4a97:
#include "mbed.h" #include "MMA8451Q.h" //knihovna akcelerometru #define MMA8451_I2C_ADDRESS (0x1d<<1) //definice pro akcelerometr MMA8451Q acc(PTE25, PTE24, MMA8451_I2C_ADDRESS); //obsluha akcelerometru void AdresRadku(int line); //adresování řádků void Zobraz(void); //funkce zprostředkující zobrazení void Inicializace(void); //inicalizace počáteční polohy svodidel a auta hráče void SvodidlaPohyb(void); //samostatný pohyb svodidel void AutaPohyb(void); //generování a pohyb aut počítače void Pohyb(void); //ovládání pozice auta hráče pomocí akcelerometru void Kolize(void); //detekce kolize auta hráče s auty počítače void Reset(void); //restart hry Ticker disptick; //definice časovače pro volání funkce zobrazení Ticker tick; //definice časovače pro volání funkce pohybu svodidel - 1px/s Ticker tick2; //definice časovače pro volání funkce pohybu aut počítače - 1px/0.25s int randVector[] = {0,1,0,1,0,1,1,0,1,0,1,1,0,1,0,0,1,0,0,0,1,0,1,1}; //vektor náhodných čísel int pocitadlo = 0; //pomocná proměnná pro vyber z náhodného vektoru int rowAuto = 0; int pomAuto; int pomAuto2; int poloha = 4; float ay; float prah; int kolize; //definování pinů pro zelenou barvu DigitalOut zelena0(PTC7); DigitalOut zelena1(PTC6); DigitalOut zelena2(PTC5); DigitalOut zelena3(PTC4); DigitalOut zelena4(PTC3); DigitalOut zelena5(PTC2); DigitalOut zelena6(PTC1); DigitalOut zelena7(PTC0); //definování pinů pro červenou barvu DigitalOut cervena0(PTC17); DigitalOut cervena1(PTC16); DigitalOut cervena2(PTC13); DigitalOut cervena3(PTC12); DigitalOut cervena4(PTC11); DigitalOut cervena5(PTC10); DigitalOut cervena6(PTC9); DigitalOut cervena7(PTC8); //definování pinů pro adresování řádků DigitalOut ln0(PTB0); DigitalOut ln1(PTB1); DigitalOut ln2(PTB2); //2^3 = 8...8 radku kodovany binar. hodnotama // pracovní pole pro matici čerevných LED // |0||1||2||3||4||5||6||7| int poleCerveny[8][8] = { {0, 0, 0, 0, 0, 0, 0, 0}, //0 {0, 0, 0, 0, 0, 0, 0, 0}, //1 {0, 0, 0, 0, 0, 0, 0, 0}, //2 {0, 0, 0, 0, 0, 0, 0, 0}, //3 {0, 0, 0, 0, 0, 0, 0, 0}, //4 {0, 0, 0, 0, 0, 0, 0, 0}, //5 {0, 0, 0, 0, 0, 0, 0, 0}, //6 {0, 0, 0, 0, 0, 0, 0, 0}, };//7 // pracovní pole pro matici zelených LED int poleZeleny[8][8] = { {0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0}, }; /*----------------------------------------------------------------------------*/ // MAIN // /*----------------------------------------------------------------------------*/ int main() { Inicializace(); //inicalizace počáteční polohy oranžových svodidel a zeleného auta hráče disptick.attach(&Zobraz, 0.002); //nastavení časovače pro rozsvicování displeye tick.attach(&SvodidlaPohyb, 1); //nastavení časovače pro volání funkce zabezpečující pohyb svodidel tick2.attach(&AutaPohyb, 0.25); //nastavení časovače pro volání funkce zabezpečující pohyb aut počítače while(1) { Pohyb(); //ovládání pozice auta hráče pomocí akcelerometru Kolize(); //detekce kolize auta hráče s auty počítače } } /*----------------------------------------------------------------------------*/ // // /*----------------------------------------------------------------------------*/ /*---------------------------------Zobraz-------------------------------------*/ //rozsvicování matice na základě stavu pracovních polí v aktuálním kroku void Zobraz(void) { static int line = 0; //proměná inicializující prnví řádek AdresRadku(line); //adresování řádků pomocí funkce AdresRadku() //Rozsvicování LEDek je zajištěno jejich uzeměním - tedy, když je na řídící vstup přivedena 0. //Z důvodu lepší oirentace při práci bylo využito negace, aby v následujícím algoritmu rozsvícení LEDek //způsobovalo číslo 1. //rozsvicování zelených LED zelena0 =! poleZeleny[line][0]; zelena1 =! poleZeleny[line][1]; zelena2 =! poleZeleny[line][2]; zelena3 =! poleZeleny[line][3]; zelena4 =! poleZeleny[line][4]; zelena5 =! poleZeleny[line][5]; zelena6 =! poleZeleny[line][6]; zelena7 =! poleZeleny[line][7]; //rozsvícení červených LED cervena0 =! poleCerveny[line][0]; cervena1 =! poleCerveny[line][1]; cervena2 =! poleCerveny[line][2]; cervena3 =! poleCerveny[line][3]; cervena4 =! poleCerveny[line][4]; cervena5 =! poleCerveny[line][5]; cervena6 =! poleCerveny[line][6]; cervena7 =! poleCerveny[line][7]; //v případě, že na stejné pozici svící obě LEDky, je barva oranžová wait(0.001); //zpožděni-aby se to stihlo rozsvitit line++; //přepis proměnné na další řádek if(line == 8) //v případě,že dojde na konec,jede se od zacatku { line = 0; } } /*--------------------------------AdresRadku----------------------------------*/ //adresování řádků void AdresRadku(int line) { switch(line) { case 0: ln0 = 0; ln1 = 0; ln2 = 0; break; case 1: ln0 = 1; ln1 = 0; ln2 = 0; break; case 2: ln0 = 0; ln1 = 1; ln2 = 0; break; case 3: ln0 = 1; ln1 = 1; ln2 = 0; break; case 4: ln0 = 0; ln1 = 0; ln2 = 1; break; case 5: ln0 = 1; ln1 = 0; ln2 = 1; break; case 6: ln0 = 0; ln1 = 1; ln2 = 1; break; case 7: ln0 = 1; ln1 = 1; ln2 = 1; break; default: break; } } /*--------------------------------Inicializace--------------------------------*/ void Inicializace(void){ int col; int row; /*------------inicializace svodidel--------------*/ for(col=0;col < 8; col = col+7) { for(row = 0; row < 8; row++) { if(row == 0 ||row == 4) { poleCerveny[row][col]=0; poleZeleny[row][col]=0; } else { poleCerveny[row][col]=1; poleZeleny[row][col]=1; } } } /*----inicializace auta hráče - pozice napravo---*/ poleZeleny[4][4] = 1; poleZeleny[5][4] = 1; poleZeleny[6][4] = 1; poleZeleny[4][5] = 1; poleZeleny[5][5] = 1; poleZeleny[6][5] = 1; } /*--------------------------------SvodidlaPohyb-------------------------------*/ void SvodidlaPohyb(void) { int col; int row; int pom1; //pomocná proměnná pom1 = poleCerveny[7][0]; //uloží hodnotu v poslendím 8. radku //posune svodidla o 1 pozici směrem dolu při každém zavolání funkce for(col=0;col < 8; col = col+7) //pracuje pouze v 1. a v posledním sloupci { for(row = 7; row > 0; row--) //7. až 1. řádek přepíše na 8. až 2. { poleCerveny[row][col] = poleCerveny[row-1][col]; poleZeleny[row][col] = poleZeleny[row-1][col]; } } //poslední řádek přepíše jako 1. poleCerveny[0][0] = pom1; poleCerveny[0][7] = pom1; poleZeleny[0][0] = pom1; poleZeleny[0][7] = pom1; } /*--------------------------------AutaPohyb-----------------------------------*/ void AutaPohyb(void) { int col2; //sloupec, ve kterém se auto počítače nachází - mění se podle hodnot randVectoru //"pocitadlo" = pozice v randVectoru; začíná se od počáteční pozice 0 //"rowAuto" - zajišťuje posun aut; počáteční hodnota je 0, ale 1. auto se objeví až po zavolání funkce if(randVector[pocitadlo] == 1) //když bude aktuální hodnota randVectoru rovna 1, auto počítače bude nalevo { col2 = 2; //levý (3.) sloupec poleCerveny[rowAuto][col2] = 1; poleCerveny[rowAuto][col2+1] = 1; } else //při hodnotě 0 bude auto počítače napravo { col2 = 4; //pravý (5.) sloupec poleCerveny[rowAuto][col2] = 1; poleCerveny[rowAuto][col2+1] = 1; } rowAuto++; //zvýší hodnotu o 1, aby se v náseledující iteraci auto počítače objevilo na dalším čádku //----zhasínání LEDek, kterými prošlo auto počítače----// if(rowAuto > 3) { poleCerveny[rowAuto-4][col2] =! 1; poleCerveny[rowAuto-4][col2+1] =! 1; } else if(rowAuto > 4) { poleCerveny[rowAuto-5][col2] =! 1; poleCerveny[rowAuto-5][col2+1] =! 1; } else if(rowAuto > 5) { poleCerveny[rowAuto-6][col2] =! 1; poleCerveny[rowAuto-6][col2+1] =! 1; } else if(rowAuto > 6) { poleCerveny[rowAuto-7][col2] =! 1; poleCerveny[rowAuto-7][col2+1] =! 1; } else if(rowAuto > 7) { poleCerveny[rowAuto-8][col2] =! 1; poleCerveny[rowAuto-8][col2+1] =! 1; } else if(rowAuto == 1) { poleCerveny[5][pomAuto] =! 1; poleCerveny[5][pomAuto+1] =! 1; } else if(rowAuto == 2) { poleCerveny[6][pomAuto2] =! 1; poleCerveny[6][pomAuto2+1] =! 1; } else if(rowAuto == 3) { poleCerveny[7][2] =! 1; poleCerveny[7][4] =! 1; poleCerveny[7][3] =! 1; poleCerveny[7][5] =! 1; } //----opakovaní cyklu + další pohola auta počítače----// if(rowAuto > 7) //jakmile řádky dojedou na konec, jede se od začátku { rowAuto = 0; pocitadlo++; //zvýšení proměnné o 1, aby aktualizovala pozice nového auta počítače } //pokud cyklus dojede na konec randVectoru, jede se opět od začátku int n = sizeof(randVector) / sizeof(randVector[0]); if(pocitadlo > n-1) //n =10, ale indexuju max do 9 { pocitadlo = 0; } // pomocné proměnné, které si pamatují, v jaké pozici bylo auto počítače v předchozím cyklu // z důvodu postupného smazání tohoto starého auta pomAuto2=pomAuto; //pozice starého auta v před-předposlední pozici pomAuto = col2; //pozice starého auta v předposlední pozici } /*-----------------------------------Pohyb------------------------------------*/ void Pohyb(void) { prah = 0.3; //nastavení prahu, vymezující úhel detekce ay = float(acc.getAccY()); //odečítání Y-ové osy akcelerometru if((ay > prah)) //náklon vpravo { poloha =4; //pravý (5.) sloupec //rožnout auto hráče napravo poleZeleny[4][poloha] = 1; poleZeleny[5][poloha] = 1; poleZeleny[6][poloha] = 1; poleZeleny[4][poloha+1] = 1; poleZeleny[5][poloha+1] = 1; poleZeleny[6][poloha+1] = 1; //zhasnout auto hráče vlevo poleZeleny[4][poloha-2] =! 1; poleZeleny[5][poloha-2] =! 1; poleZeleny[6][poloha-2] =! 1; poleZeleny[4][poloha-1] =! 1; poleZeleny[5][poloha-1] =! 1; poleZeleny[6][poloha-1] =! 1; } else if((ay < -prah)) //náklon vlevo { poloha =2; //levý (3.) sloupec //rožnout auto hráče vlevo poleZeleny[4][poloha] = 1; poleZeleny[5][poloha] = 1; poleZeleny[6][poloha] = 1; poleZeleny[4][poloha+1] = 1; poleZeleny[5][poloha+1] = 1; poleZeleny[6][poloha+1] = 1; //zhasnout auto hráče vpravo poleZeleny[4][poloha+2] =! 1; poleZeleny[5][poloha+2] =! 1; poleZeleny[6][poloha+2] =! 1; poleZeleny[4][poloha+3] =! 1; poleZeleny[5][poloha+3] =! 1; poleZeleny[6][poloha+3] =! 1; } } /*-----------------------------------Kolize-----------------------------------*/ void Kolize(void) { //detekování překryvu matice červených LEDek a matice zelených LEDek //detekce probíha pouze ve dvou krajních bodech, ktere dostatečně pokrývají všechny možné kolize //poloha těchto bodů je závislá pouze na proměnné "poloha", která určuje, zda jsou vpravo či v levo if (poleZeleny[4][poloha] == poleCerveny[4][poloha] || poleZeleny[6][poloha] == poleCerveny[6][poloha]) { //při detekci kolize dojde ke zmražení všech pohybů tick.detach(); tick2.detach(); //-----zobrazí se oranžový vrak auta-----// poleZeleny[4][poloha-1] = 1; poleZeleny[5][poloha] = 1; poleZeleny[6][poloha-1] = 1; poleZeleny[4][poloha+2] = 1; poleZeleny[5][poloha+1] = 1; poleZeleny[6][poloha+2] = 1; poleCerveny[4][poloha-1] = 1; poleCerveny[5][poloha] = 1; poleCerveny[6][poloha-1] = 1; poleCerveny[4][poloha+2] = 1; poleCerveny[5][poloha+1] = 1; poleCerveny[6][poloha+2] = 1; //prosvitalo puvodni zeleny auto poleZeleny[4][poloha] =! 1; poleZeleny[4][poloha+1] =! 1; poleZeleny[6][poloha] =! 1; poleZeleny[6][poloha+1] =! 1; wait(2); //zachování tohoto statického obrazu na dobu 2s Reset(); // zavolá funkci reset } } /*-----------------------------------Kolize-----------------------------------*/ void Reset(void) { int col; int row; //---na 2s se zobrazí pouze červené LED na celé ploše matice---// for(col = 0; col < 8; col++) { for(row = 0; row < 8; row++) { poleZeleny[row][col]=0; poleCerveny[row][col]=1; } } wait(2); //--------proběhne resetovací fáze--------// //zhasnutí celé LED matice for(col = 0; col < 8; col++) { for(row = 0; row < 8; row++) { poleCerveny[row][col]=0; } } //re-inicializace Inicializace(); pocitadlo = 0; rowAuto = 0; poloha =4; //zrušení zmražení všech pohybů tick.attach(&SvodidlaPohyb, 1); tick2.attach(&AutaPohyb, 0.25); }