C++ тилиндеги консолдук roguelike

C++ тилиндеги консолдук roguelike

тааныштыруу

"Linux оюндар үчүн эмес!" - эскирген сөз айкашы: азыр бул сонун система үчүн көптөгөн сонун оюндар бар. Бирок, ошентсе да, кээде өзүңө ылайыктуу өзгөчө бир нерсени каалайсың... Анан мен бул өзгөчө нерсени жаратууну чечтим.

фундамент

Мен бүт кодду көрсөтпөйм жана айтып бербейм (бул абдан кызык эмес) - жөн гана негизги пункттар.

1.Карактер

Бардык каармандардын параметрлери бул жерде келтирилген (ден соолук, курал-жарак, тажрыйба, ж.б.) Кызыктуусу кыймылдын чийме жана багыты (учурда жок).

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.Менеджмент

Символду кантип жылдыруу мурунтан эле түшүнүктүү (x—++, y—++). Бирок клавиатураны иштетүү кызыктуураак:

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

Болгону "башкаруучу белгилерди" коюу гана калды. Сиз муну которгучту колдонсоңуз болот, бирок мен аны жек көрөм.

switch(...) case .. : ... ; break ушундай жакшыраак

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

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

Сулуулук! Функцияларды айлантып, экранды айланып чуркаңыз! Бирок негедир бир аз катаал... Жана курсор жаркылдап, тамгалар... Аны оңдойбуз!

//До цикла
  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! Бир пайыз даяр!

3.Бизди курчап турган дүйнө

Бул жерде биз дүйнөнүн x, y бөлүктөрүнө жана бөлүктөргө массивдерди жасайбыз (char o[N]), Желмогуздар жана бонустар үчүн бирдей.

Функция түзүү world(int objx[N] .... objy[N] ... obj[N], ... objcolor[N]) менен окшош hero(), бирок параметрлери жана массивди чыгаруу үчүн кошумча цикл менен... көңүл ачуу үчүн биз көрүү талаасында гана тартабыз (vis) (if (ox[k] < vis && oy[k]....))

Эми биз экранды дүйнөнүн бөлүкчөлөрү менен толтурабыз, алар үчүн жөнөкөй жана процедуралык түрдө оюп кеткен бөлмөлөрдү жана өтмөктөрдү колдонуп, ошол эле учурда биз душмандарга жана объекттерге киребиз, толук кокустук үчүн биз унутпайбыз. 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. Өз ара аракеттенүү

Эми биз кандайдыр бир жол менен дубалдардан жана желмогуздардан өтүп, буюмдардан бонустарды алышыбыз керек.

Биздин сүйүктүүлөр үчүн жана #аныктоо

#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.Меню

Биз жөн гана менюну көрсөтөбүз, нерселерди номерлейбиз жана оюнчунун тандоосун иштетүү үчүн getkey() колдонобуз. Биз каармандын статус тилкесин жазабыз, тегиздөө менюсун ишке ашырабыз, тарыхты жазабыз жана мен "Жер казынасы" деп атаган нерсени алабыз.

жыйынтыктоо

Бул ушуга окшош нерсе. Сиз аны ойной аласыз жүктөлүп алынган, таңгактан чыгаруу жана төмөнкүдөй иштетүү:

$ sudo chmod +x Subsoil-1.0/Subsoil

$ Subsoil-1.0/Subsoil

, же акыры шыктандырып, өзүңүзгө жаккан укмуштуу окуяны жазыңыз. Мен алдын ала эскертем: менин оюнум оңой эмес!

Шилтемелер

Процедуралык муун, шыктандыруучу.

Source: www.habr.com

Комментарий кошуу