4

プログラム メモリに無限の 3D ラスター マップを実装する必要があります。マップは [0;0;0] から始まる場合とそうでない場合があります。マップの Y 座標は 255 に制限されており、他の座標は無限である可能性があります。(はい、これは Minecraft のマップだと思われるかもしれません)シンプルなメソッド
を持つクラスを作成する必要があります。つまり、データの読み取りと書き込みの両方ができる必要があります。また、ブロックを削除てメモリを解放できるようにしたいと考えています。 この目的のために何を使用する必要がありますか? 最良の解決策は、そのような構造を持つテーブルになると思います:McMap::getBlock(int x, short y, int z)McMap::setBlock(int x, short y, int z)

int x|short y|int z|int block id|other values...
-----+-------+-----+------------+---------------
   55|     21|  666|           1|

しかし、実際の MySql を使用せずに C++ でこれを実装するにはどうすればよいでしょうか (これはやり過ぎです)。また、プログラムの終了時にマップを保持したくないため、データをプログラムのメモリ内に配置したいと考えています。
もう一度、マップは無限であるため、座標はでもよいと考えてください。また、非常に離れたポイントがマッピングされる可能性があることも忘れないでください。
また、注意すべき非常に重要なこと: X、Y、および Z 座標でブロックを取得する効果的な方法が必要です。すべてのブロックを調べて、そのうちの 1 つを見つける必要はありません。ライブラリ
は既に含まれています。

4

2 に答える 2

3

マインクラフトのように、マップをチャンクに分解できます。各チャンクはW * H * L (xyz) ブロックです。したがって、チャンクは単なる 3 次元配列です。最善の方法は、それを 1 次元配列にラップすることです。

BlockType* chunk = new BlockType[W * H * L];
BlockType block = chunk[x + z * W + y * W * H];

これは、適切なメモリ管理を行うためです (可能なマップ全体を配列に格納するよりもはるかに優れています)。チャンク内のブロックへのアクセスは O(1) であり、ここでは非常に高速であることに注意してください。

次に、チャンクを保存できます。各チャンクには、その ID である 2D 座標が与えられます。最速 (アクセス用) は std::map である必要があります。

std::map<ChunkCoord, ChunkType*> map;

ブロックへのアクセスは高速です。チャンクを取得する必要があり (除算により、ポイント座標からチャンク座標が得られるはずです)、次にブロックを取得します。チャンクへのアクセスは O(log(numChunks)) にあります。

チャンクを作成すると、メモリが割り当てられ、マップに新しいアイテムが作成されます。コンピュータのメモリ量によって制限されます (無限はこの世界の一部ではありません...)。そのため、マインクラフトのようなゲームでは未使用のチャンクがディスクに保存されることがよくあります。ディスクに保存することが、ほぼ無限のマップを持つ唯一の方法です。

注意が必要なのは、 WH、およびLの適切な値を見つけることです。このためには、多くのテストと測定が必要になると思います...

: この考え方を拡張すると、四分木につながります。それらを使用することはできますが、メモリ オーバーヘッドが大きすぎる可能性があります。

于 2013-03-30T16:27:17.260 に答える