0

すべてのコードについてお詫び申し上げますが、何をしようとしているのかを説明するのに苦労しました。タイル マップの 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];
        }
    }
}
4

0 に答える 0