我目前正在编写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;
时