C++-da roguelike konsolu

C++-da roguelike konsolu

Giriş

"Linux oyunlar üçün deyil!" - köhnəlmiş bir ifadə: indi bu gözəl sistem üçün xüsusi olaraq çox gözəl oyunlar var. Amma yenə də bəzən özünə uyğun gələn xüsusi bir şey istəyirsən... Və mən bu xüsusi şeyi yaratmağa qərar verdim.

təməl

Bütün kodu göstərməyəcəyəm və deməyəcəyəm (çox maraqlı deyil) - yalnız əsas məqamlar.

1. Xarakter

Bütün xarakter parametrləri burada verilmişdir (sağlamlıq, zireh, təcrübə və s.) Maraqlı olan rəsm və hərəkət istiqamətidir (hazırda mövcud deyil).

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. İdarəetmə

Simvolun necə hərəkət etdirilməsi artıq aydındır (x—++, y—++). Ancaq klaviatura emalı daha maraqlıdır:

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

Qalan şey "nəzarət simvollarını" təyin etməkdir. Bunu keçiddən istifadə edərək edə bilərsiniz, amma mən buna nifrət edirəm.

switch(...) case .. : ... ; break belə daha yaxşı

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

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

Gözəllik! Funksiyaları çevirin və ekranın ətrafında qaçın! Amma nədənsə bir az sərtdir... Və kursor yanıb-sönür və hərflər... Biz bunu düzəldəcəyik!

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

Heyrət! Vay! Bir faiz hazırdır!

3.Ətrafımızdakı dünya

Burada dünyanın x, y parçaları və parçaların özləri üçün massivlər düzəldirik (char o[N]), canavarlar və bonuslar üçün eyni.

Funksiya yaradın world(int objx[N] .... objy[N] ... obj[N], ... objcolor[N]) ilə bənzətmə ilə hero(), lakin parametrlərlə və massivi çıxarmaq üçün əlavə döngə ilə... əylənmək üçün biz yalnız görünüş sahəsində çəkirik (vis) (if (ox[k] < vis && oy[k]....))

İndi biz otaqları və keçidləri sadə və prosedur olaraq boşaldan istifadə edərək ekranı dünyanın hissəcikləri ilə doldururuq, eyni zamanda düşmənlərə və obyektlərə daxil oluruq, tam təsadüfiliyi unutmamalıyıq. 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. Qarşılıqlı əlaqə

İndi birtəhər divarlardan və canavarlardan keçməkdən çəkinməli və əşyalardan bonuslar almalıyıq.

Sevimlilərimiz üçün və #müəyyən edir

#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.Menyu

Biz sadəcə menyunu nümayiş etdiririk, elementləri nömrələyirik və oyunçunun seçimini emal etmək üçün getkey() istifadə edirik. Biz personajın status panelini yazırıq, tənzimləmə menyusunu həyata keçiririk, arxa planı yazırıq və mən “Subsoil” adlandırdığımı əldə edirik.

Nəticə

Bu belə bir şeydir. Siz oynaya bilərsiniz yüklədikdən sonra, qablaşdırmadan çıxarmaq və bu şəkildə işləmək:

$ sudo chmod +x Subsoil-1.0/Subsoil

$ Subsoil-1.0/Subsoil

, və ya, nəhayət, ilham alaraq, özünüzə xoşunuza gələn bir macəra yazın. Sizi əvvəlcədən xəbərdar edirəm: mənim oyunum asan deyil!

Linklər

Prosessual nəsil, Həvəsləndirici.

Mənbə: www.habr.com

Добавить комментарий