简体   繁体   English

如何使用2d数组在cmd中为cd中的地图添加cmd中的冒险游戏对撞机?

[英]How can I add colliders for my adventure game in cmd with 2d array defining the map in c++?

I am currently writing the beginning structure of a 2d cmd adventure game. 我目前正在编写2d cmd冒险游戏的开始结构。 If you look at the provided code, I have my tiles stored in a struct, and I have a bool for the collider. 如果您查看提供的代码,则将我的图块存储在一个结构中,并且对撞机有一个布尔值。

My original idea is to have 4 'nodes' around the character and there will be an if statement in the following move commands checking the position of the node and seeing if there is a collider tile to see if you can move there or not. 我最初的想法是在角色周围有4个“节点”,并且在以下move命令中将有一个if语句,用于检查节点的位置并查看是否有对撞机块,以查看是否可以在此处移动。

I'm stuck because I am storing the tiles as a char "barrier.type", and I want to only read "barrier.type" not the char data "#" that is currently being stored in it. 我被卡住是因为我将图块存储为char“ barrier.type”字符,并且我只想读取“ barrier.type”而不是当前存储在其中的char数据“#”。 The only way I thought of doing this is making the position a string and then deleting the last 4 letters of it and adding collider, but I don't know how that will work because they are two different data types unless I can somehow get a char to a string. 我想到的唯一方法是将位置设为字符串,然后删除该位置的最后4个字母并添加对撞机,但是我不知道该怎么做,因为它们是两种不同的数据类型,除非我能以某种方式获取char转换为字符串。 In that case I think if I got it to turn into a string it would make "#" a string. 在那种情况下,我认为如果我将其转换为字符串,它将使“#”成为字符串。

If someone has a better idea for checking colliders or how to make my original idea my current player and tile system is very flexible and I am open to a wide variety of details. 如果某人有一个更好的想法来检查对撞机或如何使我的原始想法成为现实,那么我当前的播放器和磁贴系统非常灵活,我愿意接受各种各样的细节。

Code: 码:

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;

    }

}

Personally, I would try and encapsulate the tiles behind a class. 就个人而言,我会尝试将瓦片封装在类的后面。 For instance (details missing for brevity): 例如(为简洁起见,细节缺失):

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)
{
    // ...
}

This way, you don't need to try and keep track of the state around the character as it's moving around, you can just query it as needed. 这样,您无需在角色移动时尝试跟踪其周围的状态,只需根据需要查询它。 ie. 即。 if the character tries to move left, you could say: 如果角色试图向左移动,您可以说:

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

Edit: I see you still want an instance per tile, you can do a similar thing as above, but with a slight change: 编辑:我看到您仍然希望每个图块都有一个实例,您可以执行与上述类似的操作,但是要稍作更改:

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
}

I also wouldn't use map as a variable name, especially when you have using namespace std; 我也不会使用map作为变量名,特别是当您using namespace std;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM