[英]How can i create a one-dimensional array to hold several two-dimensional arrays?
我正在开发一款游戏。 这是一个基于文本的RPG冒险游戏。 我希望玩家可以使用简单的文本命令来浏览世界。 我进行了设置,以便将世界划分为“区域”或数组。 每个区域都是自定义数据类型Location,由二维数组组成。 我将使用两个变量来跟踪玩家的位置,它们实际上是“区域”网格上景点位置的两个索引值。 当玩家输入方向性命令(例如“北”,“南”,“东”或“西”)时,它将增加或减少这些值以“移动”玩家。 当它们到达过渡区域时,会将它们移到另一个“区域”。 我以为我可以拥有一个可以容纳所有区域的阵列。 过渡区域只会增加或降低主阵列的索引以“过渡”到下一个区域。 我当然希望过渡空间具有一个值来存储玩家最终将在下一个区域的网格上的位置。 我只是想知道如何制作此“主数组”来保存区域数组。 只是问我有没有做过什么;请解释不够好。 先感谢您。
struct Location
{
int type, destX, destY;
// 1 = battlefield
// areas where random encounters will at some future date occur
// 2 = town
// areas where hopefully the foolhardy adventurer will be able to speak
// to merchants and towns folk
// 3 = dungeon
// areas with long travel times and the promise of an end boss
// but more importantly really awesome loot
// 4 = transition points
//
string name, desc;
};
这就是我的设想。
银森林
[] [] []
[] [] []
[] [] []
^
过渡区将使用存储的值destX和destY将玩家移动到以下“区域”中的目的地
斯拉文
这个地方是目的地
V
[] [] [] [] []
[] [] [] [] []
[] [] [] [] []
[] [] [] [] []
就问题的标题而言,这是您在C ++中创建二维数组的一维数组:
std::vector<std::vector<std::vector<Entity>>> v;
这是多维的,每个子数组的大小可以彼此独立。
请注意,C ++还具有固定大小的数组(也是一维的):
std::array<std::array<std::array<int,16>,16,16>>
array_16_of_array_16_of_array_16_of_int;
通常,与直接阵列相比,更喜欢标准容器。 这为您打开了一个广阔的算法世界(例如, algorithm
标头)和辅助方法( .size()
)。
不幸的是,C ++没有内置的多维容器,但是有些库提供了它们,或者您可以自己制作。 基本实现可能如下所示:
template <typename T>
class surface {
public:
typedef size_t size_type;
surface(size_type w, size_type h) : width_(w), height_(h), data_(w*h) {}
size_type width() const { return width_; }
size_type height() const { return height_; }
size_type size() const { return width_*height_; }
// These are for when you need to loop over all elements
// without interest in coordinates.
T operator[] (size_type i) const { return data_[i]; }
T& operator[] (size_type i) { return data_[i]; }
T operator() (size_type x, size_type y) const { return data_[y*width_+x]; }
T& operator() (size_type x, size_type y) { return data_[y*width_+x]; }
T at(size_type i) const {
if (i>=size()) throw std::out_of_range(....);
return (*this)[i];
}
T& at(size_type i) {
if (i>=size()) throw std::out_of_range(....);
return (*this)[i];
}
T at(size_type x, size_type y) const {
if (x>=width_ || y>=height_) throw std::out_of_range(....);
return (*this)(x,y);
}
T& at(size_type x, size_type y) {
if (x>=width_ || y>=height_) throw std::out_of_range(....);
return (*this)(x,y);
}
private:
size_type width_, height_;
std::vector<T> data_;
};
...
surface<Foo> x(256,256);
x(16,12) = Foo();
x[16+12*256] = Foo();
根据数组的大小和访问顺序,您可以使用其他索引器(例如Morton / Z-Order索引)。
template <typename T, typename Indexer=LinearIndexer>
...
T operator() (size_type x, size_type y) const { return data_[Indexer()(x,y)]; }
...
surface<int, Morton> foo(102400, 102400);
甚至您甚至可以对容器进行模板化,以允许出现异常情况,例如可以及时从磁盘加载/保存到磁盘的容器。
3维数组就是答案。
int world[4][5][6];
4是区域的数量,5和6是2D数组。 如果您需要这些区域的大小可变,请使用指针并分配所需的数量。
您可以将所有矩阵简化为一个大的一维数组。 对于每个区域,您都知道其与数组的偏移量以及其宽度和高度。 区域内的导航非常简单,东/西为+/- 1
,南/北为+/- region_width
。 遍历区域边界时需要特殊代码,以防止区域跳转或跳转到另一个区域。
我建议您将世界从一堆矩阵变成一个图形。 图表中的位置将至少有4个(但可能更多)出口槽。 插槽将具有方向标识符(除了n,s,e,w之外,还可以包含“上”,“下”,“门”,“楼梯”以及您喜欢的任何东西),这些标识符可以是隐式的(已知于该插槽) )或显式(与广告位一起存储),以及此广告位通向的位置的标识符。 该标识符可以是“一个大一维数组”中位置的索引。 这种方法的缺点是簿记更多。 好处是您在创建自己的世界时有更多的自由。 该图在特殊情况下会发光。 您可能有4个以上的出口,单向通道或令人难以置信的区域(例如下水道),您认为自己会向北走,但它却使您向西走,等等。 CircleMUD和大多数其他MUD都使用该图形解决方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.