Κονσόλα roguelike σε C++

Κονσόλα roguelike σε C++

Εισαγωγή

"Το 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

#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

Προσθέστε ένα σχόλιο