Konsoles roguelike uz C++

Konsoles roguelike uz C++

Ievads

ā€žLinux nav paredzēts spēlēm!ā€ — novecojusi frāze: tagad ir daudz brÄ«niŔķīgu spēļu, kas izveidotas tieÅ”i Å”ai izcilajai operētājsistēmai. Bet tomēr, dažreiz, gribas kaut ko Ä«paÅ”u, kas bÅ«tu piemērots tieÅ”i tev... Un es nolēmu izveidot Å”o Ä«paÅ”o.

Pamats

Es nerādīŔu un neizstāstīŔu visu kodu (tas nav pārāk interesanti) — tikai galvenās detaļas.

1. Varonis

Å eit ir uzskaitÄ«ti visi varoņa parametri (veselÄ«ba, bruņas, pieredze utt.), interesants ir zÄ«mējums un kustÄ«bas virziens (kā Å”obrÄ«d nav).

int x = 5, y = 5;
    hp = 100,
    maxhp = 100,
    dm    = 20,
    armor = 0,
    xp    = 0,
    level = 0,
    diff  = 10, // grūtības pakāpe
    pos   = 0; // virziens

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

string color; // krāsa tiks izmantota kā varoņa stāvokļa indikators

void hero() // Å”eit notiek varoņa pārvietoÅ”ana uz koordinātēm (x ; y)
{
  cout << "e[u " << "e[0;0H"; // kursoru pozÄ«cijas atjaunoÅ”ana, izdzēŔana ar tukÅ”o
  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 << "╬"; // kursoru pozÄ«cijas saglabāŔana
}

2. Vadība

Kā pārvietot varoni ir skaidrs (x—++, y—++). Bet tastatÅ«ras apstrāde ir interesantāka:

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

Viss, kas jāizdara, ir jānostāda ā€žvadÄ«bas simboliā€. To var izdarÄ«t, izmantojot switch, bet es to ienÄ«stu.

switch(...) case .. : ... ; break labāk Ŕādi

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

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

Skaistums! Ciklu funkcijas un skrienam pa ekrānu! Bet kaut kā karsti... un kursoru mirgo, un burti... Izlabosim!

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

Uhh! Viens procents ir gatavs!

3. Apkārtējā pasaule

Šeit veidojam masīvus x, y pasaules gabaliem un paŔiem gabaliem (char o[N]), tas pats attiecībā uz monstriem un bonusiem.

Veidojam funkciju world(int objx[N] .... objy[N] ... obj[N], ... objcolor[N]) pēc analogijas ar hero(), bet ar parametriem un papildu ciklu masÄ«va izvadīŔanai... kā interesantuma dēļ zÄ«mējam tikai redzamajā sfērā (vis) (if (ox[k] < vis && oy[k]....))

Tagad mēs pārklājam ekrānu ar pasaules daļiņām, izmantojot vienkārÅ”u for un procedurāli izveidojam istabas un ejas, nepārliekot pretiniekus un priekÅ”metus, lai nodroÅ”inātu pilnÄ«gu nejauŔību, neaizmirstam par 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. Sadarbība

Tagad mums kaut kā jāsaglabā gumijas pāriem un monstriem, gūstot bonusus no priekŔmetiem.

Mūsu mīļie for un #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. Izvērst

Meniu vienkārÅ”i attēlojam ekrānā, numurējot punktus, ar getkey() apstrādājam spēlētāja izvēli. Rakstām varoņa statusa joslu, Ä«stenojam attÄ«stÄ«bas izvēlni, rakstām fona stāstu un iegÅ«stam to, ko es nosaucu par ā€žSubsoilā€ (ā€žZemes dzÄ«lesā€).

Secinājums

Tāda nu ir. JÅ«s varat tajā spēlēt, lejupielādējot, izpakojot un palaist Ŕādā veidā:

$ sudo chmod +x Subsoil-1.0/Subsoil

$ Subsoil-1.0/Subsoil

, vai, iedvesmojoties, uzrakstÄ«t sev piedzÄ«vojumu pēc savas gaumes. IepriekÅ” brÄ«dināju: mana spēle nav viegla!

Saites

Procedurālā Ä£enerēŔana, Iedvesmotājs.

Avots: habr.com

Iegādājieties uzticamu tÄ«mekļa hostingu ar DDoS aizsardzÄ«bu, VPS VDS serveriem šŸ”„ Iegādājieties uzticamu tÄ«mekļa hostingu ar DDoS aizsardzÄ«bu, VPS VDS serveriem | ProHoster