Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

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. :D 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 :

Hotová hra had v céčku - Zdrojákoviště jazyka C - Pokročilé konstrukce

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 782x (178.48 kB)
Aplikace je včetně zdrojových kódů v jazyce C

 

Všechny články v sekci
Zdrojákoviště jazyka C - Pokročilé konstrukce
Článek pro vás napsal Зайчик
Avatar
Uživatelské hodnocení:
4 hlasů
Коммунизм для нашего будущего!
Aktivity