Console roguelike sa C++

Console roguelike sa C++

Pasiuna

"Ang Linux dili alang sa mga dula!" - usa ka karaan nga hugpong sa mga pulong: karon adunay daghang nindot nga mga dula nga espesipiko alang niining talagsaon nga sistema. Apan sa gihapon, usahay gusto nimo ang usa ka espesyal nga butang nga mohaum kanimo... Ug nakahukom ko sa paghimo niining espesyal nga butang.

Basehan

Dili nako ipakita ug isulti ang tibuuk nga code (kini dili kaayo makapaikag) - ang panguna nga mga punto.

1. Kinaiya

Ang tanan nga mga parameter sa karakter gilista dinhi (panglawas, armadura, kasinatian, ug uban pa) Ang interes mao ang drowing ug direksyon sa paglihok (nga dili magamit karon).

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.Pagdumala

Ang paagi sa paglihok sa karakter klaro na (xβ€”++, yβ€”++). Apan ang pagproseso sa keyboard mas makapaikag:

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

Ang nahabilin mao ang pagtakda sa "kontrol nga mga karakter". Mahimo nimo kini gamit ang switch, apan gidumtan ko kini.

switch(...) case .. : ... ; break mas maayo nga ingon niini

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

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

Katahom! Loop function ug pagdagan sa palibot sa screen! Apan sa usa ka paagi kini medyo mapintas ... Ug ang cursor nagkidlap, ug ang mga letra ... Atong ayohon kini!

//Π”ΠΎ Ρ†ΠΈΠΊΠ»Π°
  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! Usa ka porsyento ang andam na!

3. Ang kalibutan sa atong palibot

Dinhi naghimo kami og mga arrays alang sa x, y nga mga piraso sa kalibutan ug ang mga piraso mismo (char o[N]), parehas sa mga monsters ug bonus.

Paghimo og function world(int objx[N] .... objy[N] ... obj[N], ... objcolor[N]) pinaagi sa analohiya sa hero(), apan adunay mga parametro ug usa ka dugang nga loop alang sa pag-output sa array... alang sa kalingawan, kami nagdrowing lamang sa natad sa panglantaw (vis) (if (ox[k] < vis && oy[k]....))

Karon gipuno namon ang screen sa mga partikulo sa kalibutan gamit ang usa ka yano ug pamaagi nga paghaw-as sa mga kwarto ug mga agianan, sa parehas nga oras nga gisulod namon ang mga kaaway ug mga butang, alang sa hingpit nga pagkabulag nga dili namo malimtan. 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

Karon kinahanglan naton nga likayan ang pag-agi sa mga dingding ug mga monsters ug makadawat mga bonus gikan sa mga butang.

Ang among mga paborito kay para ug #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

Gipakita lang namo ang menu, pag-numero sa mga butang, ug gamita ang getkey() aron maproseso ang pagpili sa magdudula. Gisulat namon ang status bar sa karakter, gipatuman ang leveling menu, gisulat ang backstory, ug nakuha namon ang gitawag nako nga "Subsoil".

konklusyon

Kini usa ka butang nga sama niini. Mahimo nimo kini dulaon nga na-download, pag-unpack ug pagdagan sama niini:

$ sudo chmod +x Subsoil-1.0/Subsoil

$ Subsoil-1.0/Subsoil

, o, sa katapusan nadasig, pagsulat sa imong kaugalingon nga usa ka adventure nga imong gusto. Gipasidan-an ko ikaw daan: ang akong dula dili sayon!

Mga link

Procedural nga henerasyon, Magdasig.

Source: www.habr.com

Idugang sa usa ka comment