Bảng điều khiển Roguelike trong C++

Bảng điều khiển Roguelike trong C++

Giới thiệu

“Linux không dành cho game!” - một cụm từ lỗi thời: hiện nay có rất nhiều trò chơi tuyệt vời dành riêng cho hệ thống tuyệt vời này. Tuy nhiên, đôi khi bạn muốn thứ gì đó đặc biệt phù hợp với mình... Và tôi quyết định tạo ra thứ đặc biệt này.

Cơ sở

Tôi sẽ không hiển thị và nói toàn bộ đoạn mã (nó không thú vị lắm) - chỉ những điểm chính.

1.Nhân vật

Tất cả các thông số của nhân vật đều được liệt kê ở đây (sức khỏe, áo giáp, kinh nghiệm, v.v.) Điều đáng quan tâm là hình vẽ và hướng di chuyển (hiện không có sẵn).

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.Quản lý

Cách di chuyển nhân vật đã rõ rồi (x—++, y—++). Nhưng việc xử lý bàn phím thú vị hơn:

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

Tất cả những gì còn lại là thiết lập “ký tự điều khiển”. Bạn có thể làm điều đó bằng cách sử dụng switch, nhưng tôi ghét nó.

switch(...) case .. : ... ; break tốt hơn như thế này

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

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

Sắc đẹp! Chức năng vòng lặp và chạy xung quanh màn hình! Nhưng không hiểu sao nó hơi gắt... Và con trỏ nhấp nháy, và các chữ cái... Chúng tôi sẽ sửa nó!

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

Ồ! Một phần trăm đã sẵn sàng!

3. Thế giới xung quanh chúng ta

Ở đây chúng ta tạo mảng cho các phần x, y của thế giới và chính các phần đó (char o[N]), tương tự đối với quái vật và tiền thưởng.

Tạo một chức năng world(int objx[N] .... objy[N] ... obj[N], ... objcolor[N]) bằng cách tương tự với hero(), nhưng với các tham số và một vòng lặp bổ sung để xuất mảng... để giải trí, chúng tôi chỉ vẽ trong trường nhìn (vis) (if (ox[k] < vis && oy[k]....))

Bây giờ, chúng tôi lấp đầy màn hình bằng các hạt của thế giới bằng cách sử dụng các phòng và lối đi đơn giản và theo thủ tục, đồng thời chúng tôi tiến vào kẻ thù và đồ vật, để hoàn toàn ngẫu nhiên, chúng tôi không quên 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.Tương tác

Bây giờ chúng ta cần bằng cách nào đó tránh đi xuyên qua các bức tường và quái vật và nhận tiền thưởng từ các vật phẩm.

Mục yêu thích của chúng tôi là dành cho và #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.Thực đơn

Chúng tôi chỉ cần hiển thị menu, đánh số các mục và sử dụng getkey() để xử lý lựa chọn của người chơi. Chúng tôi viết thanh trạng thái của nhân vật, triển khai menu thăng cấp, viết cốt truyện và chúng tôi nhận được cái mà tôi gọi là “Subsoil”.

Kết luận

Đây là một cái gì đó như thế này. Bạn có thể chơi nó đã tải xuống, giải nén và chạy như sau:

$ sudo chmod +x Subsoil-1.0/Subsoil

$ Subsoil-1.0/Subsoil

, hoặc cuối cùng được truyền cảm hứng, hãy viết cho mình một cuộc phiêu lưu theo ý thích của riêng bạn. Tôi cảnh báo trước với bạn: trò chơi của tôi không hề dễ dàng!

Liên kết

Tạo thủ tục, người khuyến khích.

Nguồn: www.habr.com

Thêm một lời nhận xét