Konzolni rogalič na C++

Konzolni rogalič na C++

Uvod

„Linux nije za igre!“ — zastarela fraza: sada postoji mnogo divnih igara posebno za ovaj divan sistem. No, ponekad, ipak, želimo nešto posebno, što bi odgovaralo baš nama... I odlučio sam da stvorim to posebno.

Osnova

Neću prikazivati i pričati ceo kod (to nije baš zanimljivo) — samo osnovne tačke.

1. Lik

Ovde su navedeni svi parametri lika (zdravlje, oklop, iskustvo itd) zanimljivo je crtanje i pravac kretanja (koji trenutno ne postoji).

int x = 5, y = 5;
    hp = 100,
    maxhp = 100,
    dm    = 20,
    armor = 0,
    xp    = 0,
    level = 0,
    diff  = 10, // težina
    pos   = 0; // pravac

bool reg = 0,
       Mdm = 0, // bonusi
       ght = 0;

string color; // boja će se koristiti kao indikator stanja junaka

void hero() // ovde se dešava pomeranje junaka na koordinate (x ; y)
{
  cout << "e[u " << "e[0;0H"; // obnavljanje pozicije kursora, brisanje razmakom
  for (int i = 0; i <= x; i++)
    cout << RIGHT;              // makro "e[1C"
  for (int i = 0; i <= y; i++)
    cout << DOWN;             // makro "e[1B"
  cout << "e[s" << color << "╬"; // čuvanje pozicije kursora
}

2. Upravљење

Kako pomerati lika je jasna (x—++, y—++). Ali obrada tastature je zanimljivija:

char key;
char getkey()
{
  system("stty raw");
  key = getchar();
  system("stty cooked");
  return key;
}

Samo treba da definišemo „kontrolne simbole“. Može se uraditi koristeći switch, ali ja ga ne volim.

switch(...) case .. : ... ; break bolje ovako

#define KEY if (key ==
#define I ){
#define J ;}else

void keys()
{
  getkey();
    KEY 'a' I x-- ; pos = 1 J
    KEY......
}

Lepota! Cikličimo funkcije i trčimo po ekranu! Ali nekako je naglo… I kursor treperi, i slova… Ispravićemo!

//До цикла
  cout << "e[?25l"; //отключаем отображение курсора
  system("stty -echo"); //отключаем эхо-ввод
  system("xset r rate 120 10"); // изменяем задержку на более плавную
//После цикла
//-------Return_normal_system_settings--------
  cout << "e[00m";
  system("reset");
  system("xset r rate 200 20");

Uh-huh! Jedan procenat gotov!

3. Okruženje

Ovde pravimo nizove za x, y delove sveta i same delove (char o[N]), isto važi za čudovišta i bonuse.

Pravim funkciju world(int objx[N] .... objy[N] ... obj[N], ... objcolor[N]) po analogiji sa hero(), ali sa parametrima i dodatnom petljom za iscrtavanje niza… radi interesa crtamo samo u vidnom polju (vis) (if (ox[k] < vis && oy[k]....))

Sada punimo ekran delićima sveta pomoću jednostavnog for i proceduralno oblikujemo sobe i prolaze, pritom dodajući neprijatelje i predmete, za potpunu nasumičnost ne zaboravljamo na srand(time(NULL));

//------------------GENERATION---------------
void rooms()
{
  for (int i = 0; i <= 50; i++)
  {
    px[i] = rand() % 115 + 2;
    py[i] = rand() % 34 + 2;
    pl[i] = rand() % 5 + 5;
    ph[i] = rand() % 5 +  5;

    if (px[i] + pl[i] > 117) px[i] = 50 - pl[i] / 2; else
    if (px[i] < 2)           px[i] = 50 - pl[i] / 2; else
    if (py[i] < 1)           py[i] = 15 - ph[i] / 2; else
    if (py[i] + ph[i] > 37)  py[i] = 15 - ph[i] / 2;

    for (int j = 0; j <= i; j++)
    {
      while (px[i] > px[j] && px[i] < px[j] + pl[j])
        (px[i]+pl[i]/2 >= 55) ? px[i]++ : px[i]-- ;

      while (py[i] > py[j] && py[i] < py[j] + ph[j])
        (py[i]+ph[i]/2 >= 18) ? py[i]++ : py[i]-- ;

      while (px[i]+pl[i] > px[j] && px[i]+pl[i] < px[j] + pl[j])
        (px[i]+pl[i]/2 >= 55) ? px[i]++ : px[i]-- ;

      while (py[i]+ph[i] > py[j] && py[i]+ph[i] < py[j] + ph[j])
        (py[i]+ph[i]/2 >= 18) ? py[i]++ : py[i]-- ;
    }

    for (int j = 0; j <= i; j++)
    {
      while (px[j] + pl[j] >= 116) px[j]-- ;
      while (px[j] < 2)            px[j]++ ;
      while (py[j] < 1)            py[j]++ ;
      while (py[j] + ph[j] >= 37)  py[j]-- ;
    }
    tx[i] = px[i]+10; ty[i] = py[i]-3;

    if (i <= diff)
    {
      ex[i]  = px[i];
      ey[i]  = py[i];
      while (ex[i] < 10){ ex[i]++ ; epos[i] = 3 ;}
      while (ey[i] < 10){ ey[i]++ ; epos[i] = 1 ;}
      e[i]   = evar[pl[i]];
      ecolor[i] = "e[00me[31m";

      edm[i] = edmvar[pl[i]];
      ehp[i] = ehpvar[pl[i]];
      exp[i] = expvar[pl[i]];
    }
    rect(px[i], py[i], pl[i], ph[i]);
  }
}

void corrs()
{
  int pc, px, py;
  for (int i = 0; i <= 4; i++)
  {
    if (i < 2){
      px = 3;
      py = rand() % 33 + 3;
      pc = 110;
      line(px, py, pc, true);
      line(px, py+1, pc, true);
    } else {
      px = rand() % 100 + 3;
      py = 3;
      pc = 33;
      line(px, py, pc, false);
      line(px+1, py, pc, false);
    }
  }
}

4. Interakcija

Sada nam je potrebno da nekako ne prolazimo kroz zidove i čudovišta, i dobijemo bonuse od predmeta.

Naši omiljeni for i #define

#define TOUCH if (x == ox[i] && y == oy[i] && pos ==
#define HIT   x == ex[i] && y == ey[i] && pos ==
 for (int i = 0; i <= n; i++)
  {
    if (i <= diff)
    {
     if (Mdm) ehp[i]-=2 ; // если бонус "массовый урон" включен
     epos[i] = 0;

     if (ex[i] < x+5 && ex[i] > x-5 &&
         ey[i] < y+5 && ey[i] > y-5  )
     {
       edel(i); // функция переписывающая предыдущее положение противника
       if (ex[i] < x I ex[i]++ ; epos[i] = 1 J
       if (ex[i] > x I ex[i]-- ; epos[i] = 2 J
       if (ey[i] < y I ey[i]++ ; epos[i] = 3 J
       if (ey[i] > y I ey[i]-- ; epos[i] = 4 ;}
     }
   for (int j = 0; j <= n; j++) // столкновение моба со стенками
       while (ex[i] == ox[j] && ey[i] == oy[j] || ex[i] == ex[j] && ey[i] == ey[j] && j != i)
       {
         if (epos[i] == 1) ex[i]-- ; else
         if (epos[i] == 2) ex[i]++ ; else
         if (epos[i] == 3) ey[i]-- ; else
         if (epos[i] == 4) ey[i]++ ;
       }

     if (x == ex[i] && y == ey[i]) //  "битва"
      {
       if (ehp[i] > 1)
       {
         ehp[i] -= dm;
         (edm[i] < armor) ?
         hp -= 0 :
         hp -= edm[i]-armor;
       } else {
         ex[i] = ey[i] = -1;
         xp += exp[i];
         ehp[i] = 12;
       }
     }
     if (!ght) // если не призрак проверять столкновение игрока с врагами
     {
       if (HIT 1) y++ ;else
       if (HIT 2) x-- ;else
       if (HIT 3) y-- ;else
       if (HIT 4) x++ ;
     }
    }
    if (!ght) // то же, но со стенами
    {
      TOUCH 1 I y++ J
      TOUCH 2 I x-- J
      TOUCH 3 I y-- J
      TOUCH 4 ) x++ ;
    }
  }

5. Meni

Izpisujemo meni na zaslon z numeracijo točk, s pomočjo getkey() obdelujemo izbiro igralca. Napišemo statusno vrstico lika, uresničimo meni za nadgradnjo, napišemo zgodovino in dobimo tisto, kar sem poimenoval «Subsoil» («Nadre»).

Zaključek

Takšna stvar. Igrate lahko to igro, tako da prenesete, razpakirate in zaženete na ta način:

$ sudo chmod +x Subsoil-1.0/Subsoil

$ Subsoil-1.0/Subsoil

, ali pa, navdihnjeni, napišete pustolovščino po svojem okusu. Vnaprej opozarjam: moja igra ni enostavna!

Povezave

Postopek generacije, Navdihovalec.

Izvor: habr.com

Kupite zanesljivo gostovanje za spletne strani z zaščito pred DDoS, VPS VDS strežniki 🔥 Kupite zanesljivo gostovanje za spletne strani z zaščito pred DDoS, VPS VDS strežniki | ProHoster