Tvoříme hru had v jazyce C - 2.Díl
Tak z minulého tutoriálu o vytvoření hada v céčku bychom měli mít soubory main.c, funkce.h a had.h. Ve funkcích by měly být barvičky, delay, MyGetch, Vymaz a funkce gotoxy. V souboru had.h mělo být následující.
#include "funkce.h" #define START_DELKA_HADA 4 /* velikost hada pri vykresleni */ #define START_X 25 /* startovni souradnice hada na ose X */ #define START_Y 12 /* startovni souradnice hada na ose Y */ #define RADKY 25 /* pocet radku v hracim poli */ #define SLOUPECKY 80 /* pocet sloupecku v hracim poli */ void RAM_ZED(); void vykresli_hada_start(void); void pohybuj_hada(); void vykresli_hlavicku(void); void smaz_posledni(void); void posun_hodnoty(void); void bodiky(); void vypis_bodiky(); void novy_mysky(void); void konec(int udalost); void exit_fce(void);
Teď si v souboru had.h vytvoříme struktury :
typedef struct { int x; int y; } Souradnice_hada; struct { int x; int y; } mysky;
Pro souřadnice hada a myšek, které budeme žrát.
Dále...
Souradnice_hada *alokuj_delku_hada(void); Souradnice_hada *realokuj_delku_hada(void); int hraci_pole[RADKY][SLOUPECKY],body,hadova_rychlost,i,j,mezernik = 0,start; short n = START_DELKA_HADA; /* Delka hada pri vykresleni na startu */ short pauza,barva_hada; char pocatecni_smer; Souradnice_hada *sou_had; konecprosdraca = 1;
To je alokace hada a nějaké globální proměnné, které by být v
programu ideálně neměly, ale již jsem to nechtěl předělávat. (K funkci pro alokaci se dostaneme
dále v kódu).
void RAM_ZED() { /* Vyplni hraci pole v okrajich */ for(i = 0; i < 80; i++) { hraci_pole[0][i] = 1; hraci_pole[24][i] = 1; } for(j = 0; j < 25; j++) { hraci_pole[j][0] = 1; hraci_pole[j][79] = 1; } /* Vykresli zed */ for(i = 0; i < 25; i++) { barva(2); gotoxy(0,i); putc('1',stdout); gotoxy(79,i); putc('1',stdout); } for(i = 0; i < 80; i++) { barva(2); gotoxy(i,0); putc('1',stdout); gotoxy(i,24); putc('1',stdout); } }
Vykreslíme si rámeček jak v dvourozměrném poli, tak jen tak "barvičkově" trošku drastickým způsobem. (Mám to takhle, protože když jsem nacpal víc cyklů dohromady, tak to bylo značně pomalejší).
Souradnice_hada *alokuj_delku_hada(void) { Souradnice_hada *sou_had_start; sou_had_start = (Souradnice_hada *) malloc((START_DELKA_HADA+1) * sizeof(Souradnice_hada)); if (sou_had_start == NULL) { printf("Nelze provest alokaci hada!"); exit(1); } return sou_had_start; } Souradnice_hada *realokuj_delku_hada(void) { Souradnice_hada *sou_had_zvetsen; sou_had_zvetsen = (Souradnice_hada *) realloc(sou_had, (n+1) * (sizeof(Souradnice_hada))); if (sou_had_zvetsen == NULL) { printf("Nelze provest alokaci hada!"); exit(1); } return sou_had_zvetsen; }
Alokace a realokace paměti hada... není co dodat kdo se v tom nevyzná tak šup do
mého tutoriálu o alikaci
paměti.
void vykresli_hada_start(void) { for(i = START_X; i < (START_DELKA_HADA+START_X); i++) { barva(barva_hada); sou_had[i-START_X].x = i; sou_had[i-START_X].y = START_Y; gotoxy(i,START_Y); putc('0', stdout); } }
Funkce pro vykreslení hada v poli. Teď trošku delší funkce pro pohyb našeho hada.
void pohybuj_hada() { while (konecprosdraca > 0) { do { /* Nastavi hlavicku na smer XY */ switch(pocatecni_smer) { case 'u' : sou_had[n].x = sou_had[n-1].x; sou_had[n].y = sou_had[n-1].y-1; break; case 'd' : sou_had[n].x = sou_had[n-1].x; sou_had[n].y = sou_had[n-1].y+1; break; case 'r' : sou_had[n].x = sou_had[n-1].x+1; sou_had[n].y = sou_had[n-1].y; break; case 'l' : sou_had[n].x = sou_had[n-1].x-1; sou_had[n].y = sou_had[n-1].y; break; } /* Kontrola narazu do zdi */ if (hraci_pole[sou_had[n].y][sou_had[n].x]) konec(2); /* kontrola kousnuti */ for(i = 0; i < n-3; i++) if ((sou_had[n].x == sou_had[i].x) && (sou_had[n].y == sou_had[i].y)) konec(1); vykresli_hlavicku(); /* Kdyz had sezere mysku */ if ((sou_had[n].x == mysky.x) && (sou_had[n].y == mysky.y)) bodiky(); else /* had nesezral mysku */ { smaz_posledni(); posun_hodnoty(); } delay(hadova_rychlost); } while (!kbhit()); int key; key = MyGetch(); if (key) { switch (key) { case 27: // escape konecprosdraca = 0; break; case 328:/* sipka nahoru */ if (pocatecni_smer != 'd') pocatecni_smer = 'u'; break; case 336:/* sipka dolu */ if (pocatecni_smer != 'u') pocatecni_smer = 'd'; break; case 333: /* sipka vpravo*/ if (pocatecni_smer != 'l') pocatecni_smer = 'r'; break; case 331:/* sipka vlevo */ if (pocatecni_smer != 'r') pocatecni_smer = 'l'; break; case 32: if (!pauza) { pauza = 1; do{} while (!kbhit()); } else pauza = 0; break; case 13: break; default: continue; } } } }
Není co dodat, určuje směr pohybu hada a co se stane, když zmáčknu
nějakou klávesu. Exkluzivně pro Sdraca jsem upravil nekonečný cyklus, za
který by mě sežral za živa. a A proto :
while (konecprosdraca > 0)
No a nyní zbytek našich funkcí :
void smaz_posledni(void) { gotoxy(sou_had[0].x,sou_had[0].y); barva(-1); putc(219, stdout); } void posun_hodnoty(void) { for(i = 0; i < n; i++) { sou_had[i].x = sou_had[i+1].x; sou_had[i].y = sou_had[i+1].y; } } void vykresli_hlavicku(void) { barva(barva_hada); gotoxy(sou_had[n].x,sou_had[n].y); putc('0', stdout); } void vypis_bodiky() { barva(1); gotoxy(77,0); printf("%d", body); } void bodiky() { barva(1); body++; gotoxy(77,0); printf("%d", body); n++; /* delka hada ++ */ sou_had = realokuj_delku_hada(); novy_mysky(); } void novy_mysky(void) { mysky.x = (rand() % 79) + 1; mysky.y = (rand() % 24) + 1; /* kdyz se mysky obevi v prekazce nebo v hadovi tak se vykesli nove */ for(i = 0; i < (n-1); i++) if (((sou_had[i].x == mysky.x) && (sou_had[i].y == mysky.y)) || (hraci_pole[mysky.y][mysky.x])) novy_mysky(); gotoxy(mysky.x,mysky.y); barva(0); putc('0', stdout); } void konec(int udalost) { if (udalost == 1) { barva(0); gotoxy(36,12); printf("Hryznul ses!"); getchar(); } else { barva(0); gotoxy(30,12); printf("Narazil si do zdi!"); getchar(); } body = 0; main(); } void exit_fce(void) { free((void *) sou_had); }
Smazat poslední hodnotu, posunout hada, vykreslit hlavičku a tak déle. ( nepopisuji to podrobně, protože to už má každý umět z tutoriálů (ne umět) ale vyznat se v tom co co dělá).
No a nyní už jen upravíme soubor main.c následovně.
#include "had.h" int main(void) { SetConsoleTitle( "Snake v1.0" ); hadova_rychlost = 70; /* 70 ms */ barva_hada = 0; /* barva hada je bila */ n = START_DELKA_HADA; /* Delka hada pri vykresleni */ pocatecni_smer = 'r'; /* smer hada je vpravo */ if (start == 1) /* Pokud zacne nova hra vynuluje se skore */ { body = 0; } vymaz(); /* vymaze obraz */ srand((unsigned int) time(NULL)); RAM_ZED(); sou_had = alokuj_delku_hada(); vypis_bodiky(); vykresli_hada_start(); novy_mysky(); pohybuj_hada(); }
A po kompilaci by měl výsledek vypadat nějak takto :

Tak doufám že se to všem povedlo! Pro případ, že ne, přidávám zdrojový kód k článku.
Stáhnout
Stažením následujícího souboru souhlasíš s licenčními podmínkami
Staženo 793x (178.48 kB)
Aplikace je včetně zdrojových kódů v jazyce C