Létající písmenka
Využijte znalosti dvourozměrných polí, řetězců a argumentů programu pro vytvoření následující animace:
-
Vytvoříme si strukturu reprezentující vykreslovací plochu
typedef struct { char *content; // rows x cols "pixelu" int rows; int cols; } Board; -
Naimplementujeme si funkci pro vytvoření nové vykreslovací plochy o předaných rozměrech
Board* board_new(int rows, int cols) { // dynamická alokace paměti pro strukturu složenou z pointeru na obsah a dvou proměnných udávající rozměry // dynamická alokace paměti pro rows*cols pixelů typu char a uložení do pointeru content // uložení rows a cols do struktury a vrácení }Nesmíme také zapomenout ošetřovat různé chybové stavy - alokace paměti nemusí být vždy úspěšná a musíme provést kontrolu, zda navrácená paměť není
NULL. K této funkci je také vhodné doimplementovat funkci pro uvolnění pixelů a poté samostatné struktury:void board_delete(Board* b); -
Funkce pro vykreslení pixelu / znaku
Pro jednoduší a čitelnější kód si naimplementujeme funkci, která nám vykreslí znak
cna řádekrowa sloupeccol. Funkce by také měla zkontrolovat, zda souřadnice není před nultým či posledním řádkem a sloupcem, aby nedocházelo k pádu programu nebo k vykreslování jinam.void board_draw_pixel(Board *b, int row, int col, char c);Přepočet 2D souřadnice
[row, col]na 1D index můžeme podle následujícího obrázku: -
Vykreslení rámečku
Kolem okrajů vykreslíme rámeček pomocí funkce
board_draw_pixel. Pro vykreslování rámečku NENÍ potřeba procházet vnitřek - stačí dvě smyčky za sebou. První smyčka bude procházet všechny řádky a kreslit na nultý a poslední sloupec. Obdobně druhá smyčka bude procházet sloupce a kreslit na nultý a poslední řádek. Procházením vnitřku plochy se může znatelně zpomalit např. při rozlišení 8k.################# # # # # # # # # # # # # ################# -
Reprezentace písmenka a jeho vykreslování
Písmenko budeme reprezentovat pomocí struktury složené ze znaku, pozice a rychlost pohybu:
typedef struct { int row; int col; } Coord; typedef struct { char c; Coord position; Coord speed; } Letter;Rychlost pohybu
speedbude nabývat hodnot-1pro směr vlevo v případě sloupcové souřadnice nebo směr nahoru v případě řádkové souřadnice. Hodnota1pak bude znamenat směr doprava respektive dolů.Následně si vytvoříme funkci pro jeho vykreslení do plochy:
void letter_render(Letter *letter, Board *board); -
Pohyb písmenka s odrážením od stěn
Vytvoříme si funkci simulující jeden pohyb písmenka:
void letter_step(Letter *letter, Board *board);K aktuální pozici písmenka v řádku a sloupci přičteme rychlost
speedz odpovídající souřadnice. Poté zkontrolujeme, zda je nová pozice na prvním řádku/sloupci či předposledním řádku/sloupci. Pokud ano, tak změníme směr písmenka a tím dojde v příštím kroku k odrazu. -
Hlavní smyčka
Pro otestování odrazu je opět vhodné si udělat hlavní vykreslovací smyčku:
Board *b = board_new(20, 50); Letter l; l.c = 'O'; l.position.row = b->rows / 2; l.position.col = b->cols / 2; l.speed.row = 1; l.speed.col = -1; for(;;) { // smazani terminalu printf("\e[1;1H\e[2J"); // vykresleni ramecku board_draw_border(b); // jeden krok pismenka letter_step(&l, b); // vykresleni pismenka letter_render(&l, b); // uspani na 500 ms usleep(500 * 1000); } -
Více písmenek
Textový řetězec si převedeme na pole létajících písmenek pomocí funkce:
typedef struct { Letter *letters; int count; } Sentence; Sentence* sentence_new(const char* sentence) { // dynamická alokace struktury sentence // dynamická alokace pole pro písmenka letters // v cyklu projdeme řetězec sentence a nastavíme písmenka v letters, tak aby následovala za sebou a měla náhodnou rychlost // vrátíme ukazatel na strukturu }Vykreslovací smyčku poté upravíme, aby uměla pracovat s celou větou a ne jenom s jediným písmenkem - prakticky půjde pouze o doplnění cyklu přes všechna písmenka.