すべてのコードについてお詫び申し上げますが、何をしようとしているのかを説明するのに苦労しました。タイル マップの 2D グリッドを作成しています。タイル (ブロック) は、チャンクと呼ばれる 10x10 の正方形のタイルに分割され、チャンクは 10x10 の正方形を形成して領域を形成し、10x10 の正方形の領域が世界を形成します。正方形の辺の寸法は blockSize です。
すべての座標は [X,Y]、0,0 は左上、すべて左から右、次に上から下にスキャンします。
大きいものから小さいものへ: ワールド -> リージョン -> チャンク -> ブロック。
この画像は、ブロックサイズが 2x2 のワールドがどのようにレイアウトされるかを示しています。
「大規模」アドレスは、サブユニットに分割されるのではなく、単一の巨大な配列にある場合の各ブロック アドレスがどうなるかを示しています。
この投稿の最後に、私が既に作業しているコードのクリフ ノート バージョンを示します。すべての構造を作成できます。各レベルがそれよりも低いレベルのみを反復できるように、反復子を設定しました (最後のコードを参照)。私のコードは次のことができます:
// Create a world of 10x10 regions, each made up of 10x10 chunks, each made up of 10x10 tiles
World world = new World(blockSize);
// Address the upper left hand corner of the world. The first region's first chunk's first block.
Block block = World.Regions[0,0].Chunks[0,0].Blocks[0,0];
// Address a random chunk
Chunk chunk = World.Regions[1,2].Chunks[6,2];
// Iterate over the Block[,] grid of the given chunk from left to right, up to down
// This will give us every block in Region 1,2 Chunk 6,2
foreach (Block block in chunk) {}
// Address a random region
Region region = World.Regions[4,5];
// Iterate over the Chunk[,] grid of the given region from left to right, up to down
// This will give us every Chunk in Region 4,5
foreach (Chunk chunk in region) {}
// In World, iterate over the Region[,] grid from left to right, up to down
// This will give us every Region in the World
foreach (Region region in World.regions) {}
...
私が望むのは、イテレーターがデータの 2 つのレベルを反復できるようにすることです。たとえば、リージョンが与えられた場合、そのリージョン内のすべてのチャンクをスキャンして、全体のすべてのブロックのリストを取得します。または、与えられた世界で、世界のすべてのチャンクを取得します。または、世界全体のすべてのブロックの膨大なリスト。
...
// Given a region, return all chunks in that region
foreach (Chunk chunk in region) {}
// Given a region, return all blocks in all chunks in that region
foreach (Block block in region.GetAllBlocks)
{
// Scan the chunks from left to right.
// In each chunk, scan the blocks from left to right.
// Cover every block in the region.
}
// Given a world, return all the regions
Region regionArray = World.region; // For clarity
foreach (Region region in regionArray ) {}
// Given a world, return all the chunks in all the regions
Region regionArray = World.region; // For clarity
foreach (Chunk chunk in regionArray.GetAllChunks)
{
// Scan the regions from left to right, up to down.
// In each region, scan the chunks from left to right, up to down.
}
// Given a world, return all the blocks in all the chunks in all the regions
Region regionArray = World.region; // For clarity
foreach (Block block in regionArray.GetAllBlocks)
{
// Scan the regions from left to right, up to down.
// In each region, scan the chunks from left to right, up to down.
// In each chunk, scan the blocks from left to right, up to down.
}
...
必要なリストを生成するためにイテレータ コードを作成するにはどうすればよいですか? イテレータで複雑なことをしたのはこれが初めてで、その方法を理解するのに苦労しています。この種のことを試してみるのは良い考えですか?効率的/非効率的ですか?
これは、私が作業していることを示すために、私のコードがどのように見えるかを縮小したバージョンです。
/* **************************************** */
class Block
{
int blockX, blockY; // Grid X/Y of this block in it's chunk
public Block(blockX, blockY)
{
this.blockX = blockX;
this.blockY = blockY;
}
} // Block Class
/* **************************************** */
class Chunk : IEnumerator, IENumerable
{
int chunkX, chunkY; // X/Y of the chunk in it's region
int blockSize;
int containsBlocks;
public Block[,] blocks;
int enumeratorIndex = -1;
public Chunk(int chunkX, int chunkY, int blockSize)
{
this.chunkX = chunkX;
this.chunkY = chunkY;
this.blockSize = blockSize;
this.containsBlocks = blockSize * blockSize;
blocks = new Block[blockSize, blockSize];
for (int x = 0; x < blockSize; ++x)
{
for (int y = 0; y < blockSize; ++y)
{
blocks[x, y] = new Block(x, y);
}
}
} // constructor
public IEnumerator GetEnumerator()
{
return (IEnumerator)this;
}
public bool MoveNext()
{
enumeratorIndex++;
return (enumeratorIndex < this.containsBlocks);
}
public void Reset() { enumeratorIndex = 0; }
public object Current
{
get
{
int y = enumeratorIndex / blockSize;
int x = enumeratorIndex % blockSize;
return blocks[x, y];
}
}
} // Chunk Class
/* **************************************** */
class Region : IEnumerator, IENumerable
{
int regionX, int regionY; // X/Y of region in the world
int blockSize;
int containsBlocks;
public Chunks[,] chunks;
int enumeratorIndex = -1;
...
Same kind of constructor to setup the Chunks[,] array, but this time the iterator is
...
public object Current
{
get
{
int y = enumeratorIndex / blockSize;
int x = enumeratorIndex % blockSize;
return Chunks[x, y];
}
}
} // Region Class
/* **************************************** */
class World : IEnumerator, IENumerable
{
public Region[,] regions; // There is only one world, here are it's regions
int blockSize;
...
etc
...
public object Current
{
get
{
int y = enumeratorIndex / blockSize;
int x = enumeratorIndex % blockSize;
return Region[x, y];
}
}
}