2016-11-30 6 views
0

나는 ncurses 라이브러리를 사용하여 C++ 용 로거 타입 게임을 만들려고 노력해 왔습니다. 많은 다른 튜토리얼을 따른 후에 플레이어 캐릭터, 맵, 플레이어가 벽을 통과하지 못하도록하는 코드 및 몬스터 캐릭터의 무작위 움직임을 만들 수 있습니다.플레이어가 ncurses 라이브러리를 사용하여 Monster와 상호 작용하는 방법?

내가 만나는 다음 문제는 부울을 구현하는 것이므로 플레이어 캐릭터가 몬스터 캐릭터와 상호 작용할 때마다 게임이 종료됩니다 (대부분의 게임과 유사). 그러나, 나는 그것이 원하는 방식으로 기능을 발휘할 수없는 것 같습니다. 나는 그것이 플레이어와 몬스터를 위해 설정 한 좌표와 관련이 있다고 생각하지만 여전히 확실하지 않습니다. 누구든지 나를 도울 수 있습니까?

#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

나는'mapx' 전에'mapy'를 취하는 매개 변수로'MonsterContact'를 정의했지만'IsPassable'는'mapy' 전에'mapx'를 취 합니다만, 당신이 서로 옆에 두 개를 호출하면, 'col'과'row'를 같은 순서로 전달합니다. 이것은 문제의 원인 일 수 있습니다. 이런 순서로 혼란을 피할 수 있도록 모든 순서로 좌표를 취하도록 모든 함수를 정의해야합니다 (아마도 ncurses가 취하는 순서와 일치 할 것입니다). – jonhopkins

답변

1

나에 댓글을 달았습니다 jonhopkins 무엇을 요약합니다 : 여기

는 코드입니다.

이것은 근본적으로 불일치의 결과입니다. 코드에 따라 다른 함수 (다른 함수의 다른 순서로 인수가 전달되고 isPassable은 y이지만 MonsterContact은 같은 이름의 다른 이름을 사용합니다 (행과 x는 동일합니다).

문제는 다음과 같습니다. 너가 row, col를 건네 줬음에 너가 MonsterContact로 col, row를 통과했다는 사실에 기인 한. 어쩌면 당신은 무의식적으로 인수의 순서가 바뀌 었음을 잊어 버린 채 조금 늦은 isPassable을 작성했을 때부터 인수의 순서를 복사했을 것입니다. 아니면 당신이 실수로 실수로 그 칼은 y를 의미하고 행은 x를 의미한다고 생각했습니다.

가능한 한 코드를 일관되게 유지해야하며 앞으로 이러한 종류의 실수를 피할 수 있습니다.