Konsolipõhine roguelike C++-is

Konsolipõhine roguelike C++-is

Sissejuhatus

„Linux ei ole mängude jaoks!“ – vananenud ütlus: nüüd on saadaval palju suurepäraseid mänge, mis on loodud just selle imelise süsteemi jaoks. Kuid vahel tahaks midagi erilist, mis sobiks just sulle... Ja ma otsustasin luua selle erilise.

Alus

Ma ei hakka näitama ja rääkima kogu koodist (see pole eriti huvitav) — ainult peamised punktid.

1. Isik

Siin on loetletud kõik isiku parameetrid (tervis, kaitse, kogemus jne), huvitav on joonistamine ja liikumise suund (mida praegu pole).

int x = 5, y = 5;
    hp = 100,
    maxhp = 100,
    dm    = 20,
    armor = 0,
    xp    = 0,
    level = 0,
    diff  = 10, // raskus
    pos   = 0; // suund

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

string color; // värv kasutatakse kangelase oleku näitajana

void hero() // siin toimub kangelase liikumine koordinaatidel (x ; y)
{
  cout << "e[u " << "e[0;0H"; // taastatakse kursoripositsioon, kustutamine tühikutega
  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 << "╬"; // kursoripositsiooni salvestamine
}

2. Juhtimine

Kuidas isikut liigutada on selge (x—++, y—++). Aga klaviatuuri töötlemine on põnevam:

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

Ainult „juhtivate sümbolite“ määramine on jäänud. Seda saab teha switch’iga, aga ma vihkan seda.

switch(...) case .. : ... ; break parem on nii

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

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

Ilu! Tsüklime funktsioone ja jookseme ringi ekraanil! Aga kuidagi teravalt… Ja kursor vilgub, ja tähed… Parandame!

//До цикла
  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");

Oh-h-h! Üks protsent valmis!

3. Ümbritsev maailm

Siin loome massiivid x, y maailma tükkide jaoks ja ise tükkide jaoks (char o[N]), sama ka koletiste ja boonuste jaoks.

Loome funktsiooni world(int objx[N] .... objy[N] ... obj[N], ... objcolor[N]) analoogiliselt hero(), aga parameetritega ja täiendava tsükliga massiivi kuvamiseks… huvituseks joonistame ainult nähtavuses (vis) (if (ox[k] < vis && oy[k]....))

Praegu valame ekraani maailma tükkidega, kasutades lihtsat for ja protseduuriliselt lõhkumise ruume ja käike, lisades samal ajal vaenlasi ja esemeid, et täieliku juhuslikkuse jaoks ei unustaks 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. Koostöö

Nüüd peame kuidagi mitte läbima seinte ja koletiste, saamaks boonuseid esemetelt.

Meie lemmikud for ja #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. Menüüs

Menüü lihtsalt kuvame ekraanile, numbrides punkte, valime mängija valikut getkey() abil. Kirjutame tegelase staatuse baari, rakendame arengumenüü, kirjutame taustaloost ja saame selle, mida nimetasime "Subsoil" ("Alus").

Kokkuvõte

Selline asi. Te saate seda mängida, laadides alla, välja pakkides ja käivitades järgmiselt:

$ sudo chmod +x Subsoil-1.0/Subsoil

$ Subsoil-1.0/Subsoil

, või lõpuks innustunult kirjutades endale seikluse vastavalt oma maitsele. Eelnevalt hoiatuseks: minu mäng ei ole kergete killast!

Lingid

Protseduuriline genereerimine, Inspireerija.

Allikas: habr.com

Osta usaldusväärne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid 🔥 Osta usaldusväärne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid | ProHoster