2016-11-30 6 views
0

Я пытался создать свою игру с 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; 
} 
+0

Я заметил, что вы определяете 'MonsterContact' с параметрами, принимающими' mapy' перед 'mapx', но' IsPassable' берет 'mapx' перед' mapy', но когда вы вызываете их друг рядом друг с другом, вы 'передают 'col' и' row' в том же порядке. Это может быть причиной проблемы. Вы должны позаботиться о том, чтобы все ваши функции определяли координаты в одном и том же порядке (возможно, соответствующие порядку, который принимает ncurses), поэтому такого рода путаницу можно избежать. – jonhopkins

ответ

1

Я подытожить, что jonhopkins прокомментировал.

Это по существу результат несогласованности. Ваш код передает аргументы в различных порядках в различных функций (первый х, то у в isPassable, а наоборот в MonsterContact), и использует разные названия для одних и тех же вещей (строки и х одинаковы.)

Ваша проблема вызванный тем, что вы прошли col, row в MonsterContact, когда вы должны были пройти row, col. Возможно, вы подсознательно скопировали порядок аргументов, когда вы написали isPassable немного раньше, забыв, что порядок аргументов отменен. Или вы на мгновение ошибочно подумали, что col означает y, а row означает x.

Всегда помните, чтобы ваш код был как можно более последовательным, и вы можете избежать подобных ошибок в будущем.

 Смежные вопросы

  • Нет связанных вопросов^_^