我目前正在编写2d cmd冒险游戏的开始结构。如果您查看提供的代码,则将图块存储在结构中,并且将对撞机设为布尔值。

我最初的想法是在角色周围有4个“节点”,并且在以下move命令中将有一个if语句,用于检查节点的位置并查看是否存在对撞机块,以查看是否可以在此处移动。

我被卡住是因为我将图块存储为char“ barrier.type”,并且我只想读取“ barrier.type”而不是当前存储在其中的char数据“#”。我想到的唯一方法是将位置设为字符串,然后删除该位置的最后4个字母并添加对撞机,但是我不知道该怎么做,因为它们是两种不同的数据类型,除非我能以某种方式获取char转换为字符串。在那种情况下,我认为如果我将其转换为字符串,它将使“#”成为字符串。

如果有人对检查对撞机有更好的主意,或者如何提出我的原始主意,那么我当前的播放器和磁贴系统非常灵活,我愿意接受各种各样的细节。

码:

using namespace std;

void drawArea();
//void getInput();
void resizeWindow();

bool gameRunning = true;
int position[2] = { 8,10 };
//char character = '@';
int aboveNode[2] = { 9,10 };
int belowNode[2] = { 7,10 };
int leftNode[2] = { 8,9 };
int rightNode[2] = { 8,11 };

struct tileType
{
    enum class Tile { air, wallside, walltop, wallbottom, barrier, };
    Tile x;
    char type;
    bool collider;
};
//// tiles////
 tileType barrier = {
    tileType::Tile::barrier,
    '#',
    true,
};
 tileType air = {
    tileType::Tile::air,
    ' ',
    false,


 };
////player control////
class Player {
    public:

        char character = '@';

        int playerX = position[1];
        int playerY = position[0];



        void getInput() {
            if (GetAsyncKeyState(VK_UP)) {

                position [0] -= 1;
                aboveNode[0] -= 1;
                belowNode[0] -= 1;
                leftNode [0] -= 1;
                rightNode[0] -= 1;

            }
            else if (GetAsyncKeyState(VK_DOWN)) {
                position [0] += 1;
                aboveNode[0] += 1;
                belowNode[0] += 1;
                leftNode [0] += 1;
                rightNode[0] += 1;
            }
            else if (GetAsyncKeyState(VK_LEFT)) {
                position [1] -= 1;
                aboveNode[1] -= 1;
                belowNode[1] -= 1;
                leftNode [1] -= 1;
                rightNode[1] -= 1;

            }
            else if (GetAsyncKeyState(VK_RIGHT)) {
                position [1] += 1;
                aboveNode[1] += 1;
                belowNode[1] += 1;
                leftNode [1] += 1;
                rightNode[1] += 1;

            }
        }
    private:
        void checkNodeA() {
            //string mapData = map[aboveNode[0]][aboveNode[1]];

        }
        void checkNodeB() {
            //map[belowNode[0]][belowNode[1]];

        }
        void checkNodeL() {
            //map[leftNode[0]][leftNode[1]];

        }
        void checkNodeR() {
            //map[rightNode[0]][rightNode[1]];

        }
};




void setup() {


}








char map[33][34] = { { barrier.type,barrier.type, barrier.type, barrier.type, barrier.type,barrier.type, barrier.type,barrier.type,barrier.type, barrier.type,barrier.type, barrier.type, barrier.type, '#', '#','#', '#','#','#', '#', '#', '#', '#', '#', '#','#', '#','#','#', '#', '#', '#', '#', '#' },
{ '#', '|', '-', '-', '-','-', '|',' ',' ', ' ',' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', '#' },
{ '#', '|', ' ', ' ', ' ',' ', '|',' ',' ', ' ',' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', '#' },
{ '#', '|', '[', ']', ' ',' ', '|',' ',' ', ' ',' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', '#' },
{ '#', '|', '_', '_', '_','_', '|',' ',' ', ' ',' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', '#' },
{ '#', ' ', ' ', '|', '|',' ', ' ',' ',' ', ' ',' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', '#' },
{ '#', ' ', ' ', '-', '-',' ', ' ',' ',' ', ' ',' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', '#' },
{ '#', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ',' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', '#' },
{ '#', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ',' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', '#' },
{ '#', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ',' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', '#' },
{ '#', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ',' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', '#' },
{ '#', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ',' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', '#' },
{ '#', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ',' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', '#' },
{ '#', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ',' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', '#' },
{ '#', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ',' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', '#' },
{ '#', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ',' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', '#' },
{ '#', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ',' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', '#' },
{ '#', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ',' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', '#' },
{ '#', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ',' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', '#' },
{ '#', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ',' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', '#' },
{ '#', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ',' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', '#' },
{ '#', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ',' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', '#' },
{ '#', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ',' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', '#' },
{ '#', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ',' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', '#' },
{ '#', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ',' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', '#' },
{ '#', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ',' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', '#' },
{ '#', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ',' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', '#' },
{ '#', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ',' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', '#' },
{ '#', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ',' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', '#' },
{ '#', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ',' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', '#' },
{ '#', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ',' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', '#' },
{ '#', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ',' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', ' ', ' ',' ', ' ',' ',' ', ' ', ' ', ' ', ' ', '#' },
{ '#', '#', '#', '#', '#','#', '#','#','#', '#','#', '#', '#', '#', '#','#', '#','#','#', '#', '#', '#', '#', '#', '#','#', '#','#','#', '#', '#', '#', '#', '#' } };

void drawArea() {
    Player player;
    for (int y = 0; y < 33; y++) {
        for (int x = 0; x < 34; x++) {
            if (y == player.playerY && x == player.playerX) {
                cout << player.character;
            }

            else {
                cout << map[y][x];
            }

        }
        cout << endl;

    }

}

最佳答案

就个人而言,我会尝试将瓦片封装在类的后面。例如(为简洁起见,细节缺失):

struct Tile
{
    enum class Type { air, wallside, walltop, wallbottom, barrier, };
    Type type;
    bool collider;
};

class GameMap
{
private:
    std::map<char, Type> tiles_;
public:
    GameMap(std::vector<std::string> myMap)
    {
    // Probably sanity check that all strings are the same size, and record the length of that string
    // Maybe even validate the contents of the strings, so invalid characters throw an error.

       tiles_[' '] = Tile { Tile::Type::air, false };
       tiles_['#'] = Tile { Tile::Type::barrier, false };
       // ...
    }

    Tile getTile(size_t xPos, size_t yPos)
    {
        if (xPos >= stringLength || yPos > myMap.size()
            throw runtime_error("Out of bounds");

        char tileMarker = myMap[yPos][xPos];

        auto tile = tiles.find(c);
        if (tile != tiles.end())
        {
            throw runtime_error("Invalid tile marker");
        }

        return *tile;
    }
};


// ...

std::vector<std::string> rawMapData = {
"###############################",
"#  [   ]                       ",
"#  [ _ ]                       ",
"#              etc...          ",
};

GameMap gameMap = GameMap(rawMapData);


Tile tile = gameMap.getTile(3, 5);
if (tile.collider)
{
    // ...
}


这样,您就无需在角色移动时尝试跟踪其周围的状态,只需根据需要查询它。即。如果角色试图向左移动,您可以说:

if (! gameMap.getTile(playerX - 1, playerY).collider)
{
     // Move the character
}


编辑:我看到您仍然希望每个图块都有一个实例,您可以执行与上述类似的操作,但是要稍作更改:

class GameMap
{
private:
std::vector<std::vector<Tile>> tiles_;
public:
GameMap(std::vector<std::string> myMap)
{
    std::map<char, Tile> tileTypes;
    tileTypes[' '] = Tile { Tile::Type::air, false };
    tileTypes['#'] = Tile { Tile::Type::barrier, false };
    // ...

    for (const auto& row : myMap)
    {
        std::vector<Tile> tileRow;
        for (char c : row)
        {
            auto tile = tileTypes.find(c);
            if (tile != tileTypes.end())
            {
                throw runtime_error("Invalid tile marker");
            }

            tileRow.emplace_back(tile);
        }

        tiles_.emplace_back(std::move(tileRow));
    }
}

Tile getTile(int x, int y)
{
    // return tile.  Return reference if it might change
}


我也不会使用map作为变量名,尤其是当您使用using namespace std;

10-07 12:30