Note: I may be misunderstanding what you are saying. It sounds like you want to get an element (a tile) out of a 3 dimensional array, and your X,Y,Z relative to the center of the array (That is, the position 0,0,0 is in the center of the array in every dimension).
This is easy enough to do, once you realize that even though you are
pretending it's a 3D array, the computer's memory isn't 3D, nor is it 2D, it's only 1D, and so your 3D array is actually
only a 1D array. So let's treat it like one.
Let's simplify this first, by doing it one dimension at a time. If you have a tile array, called oneDimensionalArray, and you want to get the tile 'x' out of it, you do it like this:
oneDimensionalArray[ x ]
Easy!
For two dimensions, we need to also take into account the width of the array, because the array
is not stored like this:
It's actually stored like this: (spaces between rows added for easier reading - in actual memory, there are no gaps between the rows)
So to access the two dimensional array, all we really need to do is still use the same method as before (
oneDimensionalArray[ x ] ), but offset it by the width of the array multiplied by the row we want to access.
twoDimensionalArray[ (y * width) + x ]
For example, to access the third row (y = 2 since it starts at 0), and the 3rd column, we get
twoDimensionalArray[ (1 * width) + 2 ], which gets us:
[hr]
So let's move on to the third dimension.
For the first dimension when we use 'X', think of this as
X times the size of the cell, which in your case, each cell is 1, so we just exclude that multiplication.
First dimension, to get the cell:
X times size of Cell
Second dimension, to get the row:
Y times size of Row
Third dimension, to get the layer:
Z times size of Layer
So we have:
threeDimensionalArray[ (z * width * height) + (y * width) + x ]
Or to simplify through additional variables:
threeDimensionalArray[ (Layer * LayerSize) + (Row * RowSize) + (Cell * CellSize)]
Where the variables are:
Layer = Z, Row = Y, and Cell = X
LayerSize = Width * Height
RowSize = Width
CellSize = 1
And since we can omit the cell size (since X times 1 is still X):
threeDimensionalArray[ (Layer * LayerSize) + (Row * RowSize) + Cell]
This scales up to however many dimensions you want, whether it be three dimensions or three hundred.
[hr]
Since you start at the center of the array, you can just resolve the actual position before getting the index of the array:
Tile &GetTile(int x, int y, int z)
{
//Convert the position from the center of the map to the upperleft corner, like it's stored in memory.
int realX = (MapWidth / 2) + x;
int realY = (MapHeight / 2) + x;
int realZ = (MapDepth / 2) + x;
int tileIndex = (realZ * MapWidth * MapHeight) + (realY * MapWidth) + realX;
return map[ tileIndex ];
}
[hr]
Note: For the formulas I showed you to work, DO NOT have C++ create a Three-Dimensional array. Have C++ create a One-Dimensional array, and treat it like a 3D one. Because C++ might think the data is being stored one way (for example, row first and then column) and you might think it's being stored another way (for example,. column first and then row).
Don't do this:
MyArray = new Tile[Depth] [Height] [Width];
Do this:
MyArray = new Tile[ (Width * Height * Depth) ];
[hr]
Ofcourse, when you are
looping over the entire array you don't want to waste time with the function call overhead, for every iteration of the loop, so for actual looping, you do it all in one run:
//The outer loops go: z, y, x, instead of x, y, z, because I prefer the game to loop over
//the tiles in the same order that I mentally think of the tiles. If you take a moment
//and think about the difference between the inner loop being 'x', you'll see what I mean.
for(int z = 0; z < MapDepth; z++)
{
for(int y = 0; y < MapHeight; y++)
{
for(int x = 0; x < MapWidth; x++)
{
int tileIndex = (z * MapWidth * MapHeight) + (y * MapWidth) + x;
Tile &tile = map[ tileIndex ];
tile.Draw(...);
}
}
}
This can even be further optimized by avoiding the resolving of the index of the array on every loop (all the multiplications), by doing pointer arithmetic. But we don't need to do that, because now I'll tell you an even cooler secret: Remember that our array is actually just a 1-dimensional array
pretending to be a 3-dimensional array? Well, for hard loops, we can just treat it like a one-dimensional array. Observe:
int TotalSize = (MapDepth * MapHeight * MapWidth);
for(int index = 0; index < TotalSize; index++)
{
Tile &tile = map[ index ];
tile.Draw(...);
}
Because after all, it
is just an array,