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");

Апыр-ай! Бір пайыз дайын!

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

, немесе, сайып келгенде, шабыттанып, өзіңізге ұнайтын шытырман оқиғаны жазыңыз. Мен сізге алдын ала ескертемін: менің ойыным оңай емес!

Сілтемелер

Процедуралық генерация, Ынталандырушы.

Ақпарат көзі: www.habr.com

пікір қалдыру