C++ 在C+;中为游戏地图使用2D数组+;
软件:Visual Studio 2017社区 大家好, 我正在用C++制作一个简单的2D控制台游戏(如果你知道的话,它很简化的矮人要塞)。 我想在控制台中用ASCII显示地图 大概是这样的: 我在头文件中声明了一个WorldMap类(简化版)。 我在里面声明了一个2d数组C++ 在C+;中为游戏地图使用2D数组+;,c++,arrays,oop,visual-c++,C++,Arrays,Oop,Visual C++,软件:Visual Studio 2017社区 大家好, 我正在用C++制作一个简单的2D控制台游戏(如果你知道的话,它很简化的矮人要塞)。 我想在控制台中用ASCII显示地图 大概是这样的: 我在头文件中声明了一个WorldMap类(简化版)。 我在里面声明了一个2d数组 #pragma once #include <iostream> class WorldMap { public: WorldMap(); virtual ~WorldMap(); priv
#pragma once
#include <iostream>
class WorldMap
{
public:
WorldMap();
virtual ~WorldMap();
private:
int worldWidth;
int worldHeight;
char worldMap; // Declare a variable that will hold all the characters for the map
};
char worldMap[]然后将其定义为worldMap[50][50]代码>
error C2109: subscript requires array or pointer type
error C2087: 'worldMap': missing subscript
warning C4200: nonstandard extension used: zero-sized array in struct/union
message : This member will be ignored by a defaulted constructor or copy/move assignment operator
error C2327: 'WorldMap::worldWidth': is not a type name, static, or enumerator
error C2065: 'worldWidth': undeclared identifier
error C2327: 'WorldMap::worldHeight': is not a type name, static, or enumerator
error C2065: 'worldHeight': undeclared identifier
char worldMap[worldWidth][worldWidth]代码>,期望在创建对象时,首先定义宽度和高度变量,然后定义数组
error C2109: subscript requires array or pointer type
error C2087: 'worldMap': missing subscript
warning C4200: nonstandard extension used: zero-sized array in struct/union
message : This member will be ignored by a defaulted constructor or copy/move assignment operator
error C2327: 'WorldMap::worldWidth': is not a type name, static, or enumerator
error C2065: 'worldWidth': undeclared identifier
error C2327: 'WorldMap::worldHeight': is not a type name, static, or enumerator
error C2065: 'worldHeight': undeclared identifier
char*worldMap
和char**worldMap
,但到目前为止,我甚至无法理解双指针是如何工作的,然而char*worldMap
实际上可以在1D数组中正常工作,直到我开始访问数组中元素的值为止谢谢你的阅读。我真的很感激任何帮助,即使只是一些想法和建议也可能会把我推向正确的方向:)没有最好的方法做任何事情*。这是最适合你的 据我所知,你想制作一个动态2D数组来保存你的世界地图字符。你有很多选择来做这件事。你可以有一个worldMap类,这没什么错。如果您想要动态2D数组,只需使用这种逻辑生成函数即可
#包括
#包括
int main(){
int H=10,W=20;
char**map=NULL;//这将放在您的类中。H
//创建一个函数来分配2D数组
map=新字符*[H];
对于(int i=0;i为类声明2d数组并在对象中定义它的最佳方式是什么
为这样的游戏机存储地图的最佳方式是什么?(不一定使用数组)
这不是“最好的方法”,但这是一种方法
- 创建一个
类
包装一个1Dstd::vector
- 添加
operator()
s以访问各个元素
- 向
类添加其他支持函数,如save()
和restore()
我已经使用了你的类
作为基础,并试图记录它在代码中所做的工作:如果我使用的某些函数不熟悉,我建议查找它们,这是一个很好的wiki,其中经常有如何使用你读到的特定函数的示例
#include <algorithm> // std::copy, std::copy_n
#include <filesystem> // std::filesystem::path
#include <fstream> // std::ifstream, std::ofstream
#include <iostream> // std::cin, std::cout
#include <iterator> // std::ostreambuf_iterator, std::istreambuf_iterator
#include <vector> // std::vector
class WorldMap {
public:
WorldMap(unsigned h = 5, unsigned w = 5) : // colon starts the initializer list
worldHeight(h), // initialize worldHeight with the value in h
worldWidth(w), // initialize worldWidth with the value in w
worldMap(h * w, '.') // initialize the vector, size h*w and filled with dots.
{}
// Don't make the destructor virtual unless you use polymorphism
// In fact, you should probably not create a user-defined destructor at all for this.
//virtual ~WorldMap(); // removed
unsigned getHeight() const { return worldHeight; }
unsigned getWidth() const { return worldWidth; }
// Define operators to give both const and non-const access to the
// positions in the map.
char operator()(unsigned y, unsigned x) const { return worldMap[y*worldWidth + x]; }
char& operator()(unsigned y, unsigned x) { return worldMap[y*worldWidth + x]; }
// A function to print the map on screen - or to some other ostream if that's needed
void print(std::ostream& os = std::cout) const {
for(unsigned y = 0; y < getHeight(); ++y) {
for(unsigned x = 0; x < getWidth(); ++x)
os << (*this)(y, x); // dereference "this" to call the const operator()
os << '\n';
}
os << '\n';
}
// functions to save and restore the map
std::ostream& save(std::ostream& os) const {
os << worldHeight << '\n' << worldWidth << '\n'; // save the dimensions
// copy the map out to the stream
std::copy(worldMap.begin(), worldMap.end(),
std::ostreambuf_iterator<char>(os));
return os;
}
std::istream& restore(std::istream& is) {
is >> worldHeight >> worldWidth; // read the dimensions
is.ignore(2, '\n'); // ignore the newline
worldMap.clear(); // empty the map
worldMap.reserve(worldHeight * worldWidth); // reserve space for the new map
// copy the map from the stream
std::copy_n(std::istreambuf_iterator<char>(is),
worldHeight * worldWidth, std::back_inserter(worldMap));
return is;
}
// functions to save/restore using a filename
bool save(const std::filesystem::path& filename) const {
if(std::ofstream ofs(filename); ofs) {
return static_cast<bool>(save(ofs)); // true if it suceeded
}
return false;
}
bool restore(const std::filesystem::path& filename) {
if(std::ifstream ifs(filename); ifs) {
return static_cast<bool>(restore(ifs)); // true if it succeeded
}
return false;
}
private:
unsigned worldHeight;
unsigned worldWidth;
// Declare a variable that will hold all the characters for the map
std::vector<char> worldMap;
};
<代码> >包含在编译时未知大小的数组的< /p>。使用动态内存分配。在C++中,您不需要做太多的事情,因为标准库给了您<代码> STD::vector < /代码>。它已经为您做了所有的复杂工作。在了解此特性之后,您可能会认为<代码> STD::向量< /代码>可能是WH。至少,您正在搜索。这是可行的,但在性能方面并不理想。为了获得最佳性能,人们通常使用词典索引(例如,idx=y*width+x
)这和你自己的建议差不多。然后可以将其包装到类或函数中。@TedLyngmo抱歉,我已经删除了该注释,因为该部分可能会被解释为具有构造函数的参数,该参数可能仍然是静态的。但我想这有点牵强……这正是PaulG所说的-我提到的性能注意事项的深度。最后,您的尝试不起作用的原因:1.WorldMap
是一个char
而不是一个char数组。这永远不会起作用。2.char数组[num\u元素]
声明仅在编译时已知num_元素的情况下在标准C/C++中有效。有些编译器(gcc)允许您以不同的方式使用它(甚至可能像您尝试过的那样,我不知道),这意味着“非标准扩展”.3.从指针开始是向动态内存方向迈出的一步,但您仍然需要为其分配内存。但是使用“原始”像这样的指针是C的工作方式。哇!非常感谢!至少考虑到我是初学者,这看起来像是一个非常专业的代码。它非常复杂,但非常清楚。我花了几个小时来分析它,从中我学到了很多。我的代码中已经实现了这个修改版本。所以这是超级有用:)我唯一没有找到的信息是(*this)(y,x)
。具体来说,为什么*this
用括号括起来?也许这种使用括号的方法有一个独特的名字?@YamikoHikari我很高兴它能帮上忙,欢迎你!你可以编写(*this)(y,x)
操作符()(y,x)而不是;
-这只是访问用户定义的操作符()
(s)的一种方式。括号是因为。没有括号,它将与*(this(y,x))
(尝试将this
指针作为函数调用(然后取消引用结果),而不是world m