Console roguelike sa C++

Console roguelike sa C++

Pagpapakilala

"Ang Linux ay hindi para sa mga laro!" - isang hindi napapanahong parirala: ngayon ay maraming magagandang laro na partikular para sa napakagandang sistemang ito. Ngunit gayon pa man, minsan gusto mo ng isang espesyal na bagay na babagay sa iyo... At nagpasya akong likhain ang espesyal na bagay na ito.

Batayan

Hindi ko ipapakita at sasabihin ang buong code (ito ay hindi masyadong kawili-wili) - ang mga pangunahing punto lamang.

1.Tauhan

Ang lahat ng mga parameter ng character ay nakalista dito (kalusugan, baluti, karanasan, atbp.) Ang interes ay ang pagguhit at direksyon ng paggalaw (na hindi magagamit sa kasalukuyan).

int x = 5, y = 5;
    hp = 100,
    maxhp = 100,
    dm    = 20,
    armor = 0,
    xp    = 0,
    level = 0,
    diff  = 10, // сложность
    pos   = 0; // направление

bool reg = 0,
       Mdm = 0, // бонусы
       ght = 0;

string color; // цвет будет использован в качестве индикатора состаяния героя

void hero()  // здесь происходит перемещение героя на координаты (x ; y)
{
  cout << "e[u " << "e[0;0H"; // восстановление позиции курсора, затирание пробелом
  for (int i = 0; i <= x; i++)
    cout << RIGHT;              // макрос "e[1C"
  for (int i = 0; i <= y; i++)
    cout << DOWN;             // макрос "e[1B"
  cout << "e[s" << color << "╬"; // сохранение позиции курсора
}

2.Pamamahala

Malinaw na kung paano ilipat ang karakter (x—++, y—++). Ngunit ang pagproseso ng keyboard ay mas kawili-wili:

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

Ang natitira na lang ay itakda ang "mga control character". Magagawa mo ito gamit ang switch, ngunit kinasusuklaman ko ito.

switch(...) case .. : ... ; break mas maganda ang ganito

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

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

kagandahan! Loop function at tumakbo sa paligid ng screen! Ngunit sa paanuman ito ay medyo malupit... At ang cursor ay kumikislap, at ang mga titik... Aayusin namin ito!

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

Wow! Isang porsyento ay handa na!

3. Ang mundo sa paligid natin

Dito kami gumagawa ng mga array para sa x, y na mga piraso ng mundo at ang mga piraso mismo (char o[N]), pareho para sa mga halimaw at mga bonus.

Lumikha ng isang function world(int objx[N] .... objy[N] ... obj[N], ... objcolor[N]) sa pamamagitan ng pagkakatulad sa hero(), ngunit may mga parameter at karagdagang loop para sa pag-output ng array... para masaya, gumuhit lang kami sa field of view (vis) (if (ox[k] < vis && oy[k]....))

Ngayon ay pinupuno namin ang screen ng mga particle ng mundo gamit ang isang simple para sa at pamamaraan na guwang ang mga silid at mga sipi, sa parehong oras na pinapasok namin ang mga kaaway at mga bagay, para sa kumpletong randomness hindi namin nalilimutan ang tungkol sa 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. Interaksyon

Ngayon kailangan nating iwasan ang pagdaan sa mga pader at halimaw at makatanggap ng mga bonus mula sa mga item.

Ang aming mga paborito ay para sa at #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.Menu

Ipapakita lang namin ang menu, binibilang ang mga item, at ginagamit ang getkey() upang iproseso ang pinili ng player. Sinusulat namin ang status bar ng character, ipinatupad ang leveling menu, isinulat ang backstory, at nakuha namin ang tinatawag kong "Subsoil".

Konklusyon

Ito ay isang bagay tulad nito. Maaari mo itong laruin pagka-download, pag-unpack at pagpapatakbo tulad nito:

$ sudo chmod +x Subsoil-1.0/Subsoil

$ Subsoil-1.0/Subsoil

, o, sa wakas ay inspirasyon, isulat ang iyong sarili ng isang pakikipagsapalaran na gusto mo. Binabalaan kita nang maaga: ang aking laro ay hindi madali!

Mga link

Pagbuo ng pamamaraan, Tagapagpalakas ng loob.

Pinagmulan: www.habr.com

Magdagdag ng komento