C++'da roguelike konsol

C++'da roguelike konsol

Giriş

“Linux oyunlar için değil!” - modası geçmiş bir ifade: artık bu harika sistem için özel olarak birçok harika oyun var. Ama yine de bazen kendinize yakışacak özel bir şey istersiniz... Ben de bu özel şeyi yaratmaya karar verdim.

Основа

Kodun tamamını gösterip anlatmayacağım (çok ilginç değil) - sadece ana noktaları.

1.Karakter

Tüm karakter parametreleri burada listelenmiştir (sağlık, zırh, deneyim vb.). İlgi çekici olan, çizim ve hareket yönüdür (şu anda mevcut değildir).

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.Yönetim

Karakterin nasıl hareket ettirileceği zaten açıktır (x—++, y—++). Ancak klavyenin işlenmesi daha ilginç:

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

Geriye kalan tek şey “kontrol karakterlerini” ayarlamaktır. Bunu anahtarı kullanarak yapabilirsiniz, ancak bundan nefret ediyorum.

switch(...) case .. : ... ; break böyle daha iyi

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

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

Güzellik! Döngü işlevleri ve ekranın etrafında koşun! Ama nedense biraz sert... Ve imleç yanıp sönüyor, harfler... Düzelteceğiz!

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

Vay! Yüzde biri hazır!

3. Çevremizdeki dünya

Burada dünyanın x, y parçaları ve parçaların kendileri için diziler yapıyoruz (char o[N])canavarlar ve bonuslar için de aynısı geçerlidir.

Bir işlev oluşturun world(int objx[N] .... objy[N] ... obj[N], ... objcolor[N]) benzeterek hero(), ancak parametreler ve dizinin çıktısını almak için ek bir döngü ile... eğlence için, yalnızca görüş alanında çizim yaparız (vis) (if (ox[k] < vis && oy[k]....))

Artık ekranı basit bir yöntem kullanarak ve prosedürel olarak odaları ve geçitleri oyarak dünyanın parçacıklarıyla dolduruyoruz, aynı zamanda düşmanlara ve nesnelere giriyoruz, tam bir rastgelelik için unutmuyoruz 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.Etkileşim

Artık bir şekilde duvarların ve canavarların içinden geçip eşyalardan bonus almamız gerekiyor.

Favorilerimiz for ve #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.Menü

Basitçe menüyü görüntülüyoruz, öğeleri numaralandırıyoruz ve oyuncunun seçimini işlemek için getkey() işlevini kullanıyoruz. Karakterin durum çubuğunu yazıyoruz, seviyelendirme menüsünü uyguluyoruz, arka hikayeyi yazıyoruz ve benim "Subsoil" dediğim şeyi elde ediyoruz.

Sonuç

Bu da bunun gibi bir şey. Oynayabilirsin indirerek, paketi aç ve şu şekilde çalıştır:

$ sudo chmod +x Subsoil-1.0/Subsoil

$ Subsoil-1.0/Subsoil

ya da sonunda ilham alarak kendinize hoşunuza giden bir macera yazın. Sizi şimdiden uyarıyorum: Oyunum kolay değil!

Bağlantılar

Prosedürel nesil, Teşvik Edici.

Kaynak: habr.com

Yorum ekle