Введение
«Линукс не для игр!» — устаревшая фраза: сейчас появилось много замечательных игр специально для этой замечательной системы. Но всё же, иногда, хочется чего-то особенного, что подходило бы именно тебе… И я решил создать это особенное.
Основа
Я не стану показывать и рассказывать весь код (это не очень интересно) — только основные моменты.
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’a, но я ненавижу его.
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]....))
Сейчас заливаем экран частичками мира посредством незамысловатого for и процедурно выдалбливаем комнаты и проходы, заодно вписываем врагов и предметы, для полной рандомности не забываем про 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[00m\e[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.Взаимодействие
Теперь нам нужно как-то не проходить сквозь стены и монстров, получать бонусы от предметов.
Наши любимые for и #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() обрабатываем выбор игрока. Пишем статус-бар персонажа, реализуем меню прокачки, пишем предысторию, и получаем то, что я назвал «Subsoil»(«Недра»).
Заключение
Такое вот нечто. Вы можете поиграть в него, скачав, распаковав и запустив таким образом:
$ sudo chmod +x Subsoil-1.0/Subsoil
$ Subsoil-1.0/Subsoil
, или же, наконец воодушевившись, написать себе приключение по своему вкусу. Заранее предупреждаю: моя игра не из лёгких!
Ccылки
ссылка на оригинал статьи https://habr.com/ru/post/465625/
Добавить комментарий