
Introduktion
«Linux is not for gaming!» — an outdated phrase; there are now many wonderful games specifically designed for this remarkable system. Still, sometimes, you crave something special that suits you… And I decided to create that special thing.
Basis
I won't show and explain all the code (that's not very interesting) — only the main points.
1.Character
All character parameters (health, armor, experience, etc.) are listed here; rendering and movement direction (which is currently absent) are of interest.
int x = 5, y = 5;
hp = 100,
maxhp = 100,
dm = 20,
armor = 0,
xp = 0,
level = 0,
diff = 10, // difficulty
pos = 0; // direction
bool reg = 0,
Mdm = 0, // bonuses
ght = 0;
string color; // color will be used as an indicator of the hero's state
void hero() // this is where the hero moves to the coordinates (x ; y)
{
cout << "e[u " << "e[0;0H"; // restore cursor position, erase with space
for (int i = 0; i <= x; i++)
cout << RIGHT; // macro "e[1C"
for (int i = 0; i <= y; i++)
cout << DOWN; // macro "e[1B"
cout << "e[s" << color << "╬"; // save cursor position
}
2.Control
How to move the character is clear (x—++, y—++). But keyboard handling is more interesting:
char key;
char getkey()
{
system("stty raw");
key = getchar();
system("stty cooked");
return key;
}
Now, we just need to define the "control characters". You can do it with a switch, but I hate it.
switch(...) case .. : ... ; break better like this
#define KEY if (key ==
#define I ){
#define J ;}else
void keys()
{
getkey();
KEY 'a' I x-- ; pos = 1 J
KEY......
}
Beauty! We loop the functions and run around the screen! But somehow it's too abrupt… The cursor flickers, and the letters… Let's fix it!
//До цикла
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");
Yay! One percent done!
3.The Surrounding World
Here we create arrays for x, y pieces of the world and the pieces themselves. (char o[N]), the same for monsters and bonuses.
We create a function world(int objx[N] .... objy[N] ... obj[N], ... objcolor[N]) analogous to hero(), but with parameters and an additional loop for array output… for fun, we only draw in the field of view (vis) (if (ox[k] < vis && oy[k]....))
Now we flood the screen with pieces of the world using a simple for loop and procedurally carve out rooms and passages, while embedding enemies and items; for complete randomness, don't forget about 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.Interaction
Now we need to somehow not pass through walls and monsters, and collect bonuses from items.
Our favorite for and #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.Menu
Vi viser bare menuen på skærmen, nummererer punkterne og behandler spillerens valg ved hjælp af getkey(). Vi skriver statusbjælken for figuren, implementerer opgraderingsmenuen, skriver baggrundshistorien, og får det, jeg har kaldt „Subsoil“ („Underglæde“).
Konklusion
Dette er noget. Du kan spille det, , udpakkes og startes sådan her:
$ sudo chmod +x Subsoil-1.0/Subsoil$ Subsoil-1.0/Subsoil, eller, hvis du føler dig inspireret, skrive et eventyr efter eget valg. Jeg advarer på forhånd: mit spil er ikke let!
Links
, .
Kilde: habr.com
