Я пытался создать свою игру с roguelike для C++, используя библиотеку ncurses. После нескольких различных учебников я могу создать персонаж игрока, карту, код, чтобы предотвратить прохождение Игрока через стены и случайные движения для персонажа Монстра.Как заставить игрока взаимодействовать с монстром с помощью библиотеки ncurses?
Следующая проблема, с которой я сталкиваюсь, реализует логическое значение, поэтому всякий раз, когда персонаж игрока взаимодействует с персонажем Монстра, игра прекращается (как и игры с рогейлей). Однако я не могу заставить его функционировать так, как я хотел. Я думаю, что это связано с координатами, которые я установил для Игрока и Монстра, но я все еще не уверен. Может ли кто-нибудь помочь мне, пожалуйста?
Вот код:
#include <iostream>
#include <ncurses.h>
#define MAP_WIDTH 22
#define MAP_HEIGHT 15
#define TILE_FLOOR 0
#define TILE_WALL 1
int PlayerX, PlayerY;
void erase (int y, int x) {
mvaddch(y, x, '.');
}
int nMapArray[MAP_HEIGHT][MAP_WIDTH] = {
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 },
{ 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1 },
{ 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
};
bool IsPassable (int nMapX, int nMapY) { //prevents from walking into walls
if (nMapX < 0 || nMapX >= MAP_WIDTH || nMapY < 0 || nMapY >= MAP_HEIGHT)
return false;
int nTileValue = nMapArray[nMapY][nMapX];
if(nTileValue == TILE_FLOOR) {
return true;
}
return false;
}
class Monster {
public:
void Appearance(char monster) {
this->Monster = monster;
}
void SetPos(int x, int y) {
this->PosX = x;
this->PosY = y;
}
void Movement(int &MonsX, int &MonsY) {
int x = (rand() % 3 - 1);
int y = (rand() % 3 - 1);
if (IsPassable(this->PosX+x, this->PosY+y)) {
erase(PosY, PosX);
MonsX = this->PosX += x;
mvaddch(this->PosY, MonsX, this->Monster);
refresh();
erase(PosY, PosX);
MonsY = this->PosY += y;
mvaddch(MonsY, this->PosX, this->Monster);
refresh();
}
}
protected:
int PosX;
int PosY;
char Monster;
};
bool MonsterContact (int nMapY, int nMapX, int x, int y) {
if (nMapArray[nMapY][nMapX] == nMapArray[y][x]) {
return true;
}
return false;
}
void map() {
for (int y = 0; y < MAP_HEIGHT; y++) { //loops to print the map
move(y,0);
for (int x = 0; x < MAP_WIDTH; x++) {
switch (nMapArray[y][x]) {
case TILE_FLOOR:
printw(".");
break;
case TILE_WALL:
printw("#");
break;
}
}
}
};
void init() { //starts the ncurses screen.
initscr();
clear();
noecho();
raw();
keypad(stdscr, TRUE);
curs_set(0);
}
void game_loop (char Player, int row, int col, int ch) {
Monster npc;
npc.SetPos(7, 8);
npc.Appearance('g');
int MonsX,MonsY;
mvaddch(row,col, Player); //player movement
refresh();
while(true) {
npc.Movement(MonsX, MonsY);
ch = getch();
switch (ch) {
case 'w':
if (IsPassable(col, row-1)) {
erase(row,col);
row = row - 1;
mvaddch(row, col, Player);
refresh();
}
if (MonsterContact(col, row, MonsX, MonsY)) {
return();
}
break;
case 's':
if (IsPassable(col, row+1)) {
erase(row, col);
row = row + 1;
mvaddch(row, col, Player);
refresh();
}
if (MonsterContact(col, row, MonsX, MonsY)) {
return();
}
break;
case 'a':
if (IsPassable(col-1, row)) {
erase(row,col);
col = col - 1;
mvaddch(row, col, Player);
refresh();
}
if (MonsterContact(col, row, MonsX, MonsY)) {
return();
}
break;
case 'd':
if (IsPassable(col+1, row)) {
erase(row,col);
col = col + 1;
mvaddch(row,col, Player);
refresh();
}
if (MonsterContact(col, row, MonsX, MonsY)) {
return();
}
break;
case 'q':
return;
default:
break;
}
}
}
int main(int argc, const char * argv[]) {
PlayerX = 2, PlayerY = 1; //Player initial position.
char Player = '@';
init(); //starts the ncurses screen.
printw("Press any key to start the game");
int ch = getch();
clear();
map();
game_loop(Player, PlayerY, PlayerX, ch);
endwin();
return 0;
}
Я заметил, что вы определяете 'MonsterContact' с параметрами, принимающими' mapy' перед 'mapx', но' IsPassable' берет 'mapx' перед' mapy', но когда вы вызываете их друг рядом друг с другом, вы 'передают 'col' и' row' в том же порядке. Это может быть причиной проблемы. Вы должны позаботиться о том, чтобы все ваши функции определяли координаты в одном и том же порядке (возможно, соответствующие порядку, который принимает ncurses), поэтому такого рода путаницу можно избежать. – jonhopkins