这是我第一次使用Boost,我试图创建类块的多数组,它存储在类Chunk中。所以每个Chunk由(BLOCKS_PER_CHUNK x BLOCKS_PER_CHUNK x BLOCKS_PER_CHUNK)数量的block组成,本质上与Minecraft的方式相同。目前,我正在尝试使用两个不同的构造函数初始化这个数组,一个将stl向量作为输入,另一个使用"C风格向量"。
Block只有一个布尔值来检查它是否处于活动状态(默认值为false),一个Block类型(基本上是一个enum)以及变量的getter和setter。
Chunk的报头如下:
#pragma once
#include "Block.h"
#include <vector>
#include "Block.h"
#include "boost/multi_array.hpp" // Multi dimensional array
#define BLOCKS_PER_CHUNK 16
class Chunk
{
public:
Chunk();
Chunk(std::vector<Block>& blocks);
Chunk(Block* blocks); // Assumes you have a vector of the correct size
virtual ~Chunk();
void Update(float timeSinceLastUpdate);
private:
//BlockVec3D blocks;
//BlockArray blocks;
typedef boost::multi_array<Block, BLOCKS_PER_CHUNK> blockArray;
typedef blockArray::index blockArrayIndex;
blockArray m_blocks;
};
问题函数如下:
Chunk::Chunk(std::vector<Block>& blocks):
m_blocks(boost::extents[BLOCKS_PER_CHUNK][BLOCKS_PER_CHUNK][BLOCKS_PER_CHUNK])
{
assert(blocks.size() == BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK && "Number of blocks and size of the chunk do not match");
for(unsigned i = 0; i < BLOCKS_PER_CHUNK; ++i)
{
for(unsigned j = 0; j < BLOCKS_PER_CHUNK; ++j)
{
for( unsigned k = 0; k < BLOCKS_PER_CHUNK; ++k)
{
m_blocks[i][j][k] = blocks[i + BLOCKS_PER_CHUNK * (j + BLOCKS_PER_CHUNK * k) ];
}
}
}
}
Chunk::Chunk(Block* blocks)
{
for(unsigned i = 0; i < BLOCKS_PER_CHUNK; ++i)
{
for(unsigned j = 0; j < BLOCKS_PER_CHUNK; ++j)
{
for( unsigned k = 0; k < BLOCKS_PER_CHUNK; ++k)
{
m_blocks[i][j][k] = blocks[i + BLOCKS_PER_CHUNK * (j + BLOCKS_PER_CHUNK * k) ];
}
}
}
}
在尝试编译这段代码时,我收到错误,例如shape, num_dimensions, begin和end不是Block的成员。boost似乎有自己的静态断言风格,它检查必需的字段,当没有找到这些字段时,它会创建编译错误。显然,boost试图将输入值视为一维子数组,当它无法找到其完整性检查所需的字段(例如两个"子数组"具有相同的维数)时,它会触发错误。
容器的手册似乎没有解决这个特定的问题,我不相信我意外地创建了一个多数组视图。另外,将左侧的索引转换为boost::multi_array<Block, BLOCKS_PER_CHUNK>::index
似乎没有产生任何差异。正如我所提到的,我仍然是一个新手。正确的方法是什么呢?
m_blocks初始化时出现错误。您指定BLOCKS_PER_CHUNK值为16,但只将其初始化为三维数组。
#include <iostream>
#include <vector>
#include <boost/multi_array.hpp>
#include <cassert>
#define BLOCKS_PER_CHUNK 3
struct Block{
};
struct Chunk{
typedef boost::multi_array<Block, BLOCKS_PER_CHUNK> array_type;
typedef array_type::index index;
array_type m_blocks;
Chunk(std::vector<Block>& blocks):
m_blocks(boost::extents[BLOCKS_PER_CHUNK][BLOCKS_PER_CHUNK][BLOCKS_PER_CHUNK])
{
assert(blocks.size() == BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK && "Number of
blocks and size of the chunk do not match");
for(unsigned i = 0; i < BLOCKS_PER_CHUNK; ++i)
{
for(unsigned j = 0; j < BLOCKS_PER_CHUNK; ++j)
{
for( unsigned k = 0; k < BLOCKS_PER_CHUNK; ++k)
{
m_blocks[i][j][k] = blocks[i + BLOCKS_PER_CHUNK * (j + BLOCKS_PER_CHUNK * k) ];
}
}
}
}
Chunk(Block* blocks)
{
for(unsigned i = 0; i < BLOCKS_PER_CHUNK; ++i)
{
for(unsigned j = 0; j < BLOCKS_PER_CHUNK; ++j)
{
for( unsigned k = 0; k < BLOCKS_PER_CHUNK; ++k)
{
m_blocks[i][j][k] = blocks[i + BLOCKS_PER_CHUNK * (j + BLOCKS_PER_CHUNK * k) ];
}
}
}
}
};
int main(){
return 0;
}
上面的例子编译正确,因为BLOCKS_PER_CHUNK和m_blocks初始化匹配。例如,BLOCKS_PER_CHUNK定义为4,那么m_blocks应该初始化为:
#define BLOCKS_PER_CHUNK 4
struct Block{
};
struct Chunk{
typedef boost::multi_array<Block, BLOCKS_PER_CHUNK> array_type;
typedef array_type::index index;
array_type m_blocks;
Chunk(std::vector<Block>& blocks):
//initialization has to change if BLOCKS_PER_CHUNK changes
m_blocks(
boost::extents[BLOCKS_PER_CHUNK][BLOCKS_PER_CHUNK][BLOCKS_PER_CHUNK][BLOCKS_PER_CHUNK])
{
assert(blocks.size() == BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK && "Number of blocks and size of the chunk do not match");
for(unsigned i = 0; i < BLOCKS_PER_CHUNK; ++i)
{
for(unsigned j = 0; j < BLOCKS_PER_CHUNK; ++j)
{
for( unsigned k = 0; k < BLOCKS_PER_CHUNK; ++k)
{
//correct value assignment has to be taken care when BLOCKS_PER_CHUNK change
m_blocks[i][j][k][k] = blocks[i + BLOCKS_PER_CHUNK * (j + BLOCKS_PER_CHUNK * k) ];
}
}
}
}
};
如果你想要16宽,16高,16深的块集合,那么代码应该像这样:
#define BLOCKS_PER_CHUNK 16
#define DIMENSION 3
struct Block{
};
struct Chunk{
typedef boost::multi_array<Block, DIMENSION> array_type;
typedef array_type::index index;
array_type m_blocks;
Chunk(std::vector<Block>& blocks):
//initialization has to change if BLOCKS_PER_CHUNK changes
m_blocks(
boost::extents[BLOCKS_PER_CHUNK][BLOCKS_PER_CHUNK][BLOCKS_PER_CHUNK])
{
assert(blocks.size() == BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK && "Number of blocks and size of the chunk do not match");
for(unsigned i = 0; i < BLOCKS_PER_CHUNK; ++i)
{
for(unsigned j = 0; j < BLOCKS_PER_CHUNK; ++j)
{
for( unsigned k = 0; k < BLOCKS_PER_CHUNK; ++k)
{
//correct value assignment has to be taken care when BLOCKS_PER_CHUNK change
m_blocks[i][j][k] = blocks[i + BLOCKS_PER_CHUNK * (j + BLOCKS_PER_CHUNK * k) ];
}
}
}
}
};
array_type typepedef中的第二个参数指定了数组的维度,如果你想要它是3,那么typedef应该修改为:
typedef boost::multi_array<Block, DIMENSION> array_type; //where DIMENSION is 3