• Create Account

# 2D Sorting map tiles into map chunks

Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

2 replies to this topic

### #1BlueSin  Members   -  Reputation: 142

Like
0Likes
Like

Posted 26 December 2013 - 02:59 PM

So I am having a ridiculous problem I cannot seem to wrap my head around.  I have been working at it for days, and I know the solution is simple I just cannot see it, so I need an outside opinion.  I am working on procedural map generator.  When I generate the map, the first thing I am doing is initializing map chunks.  These chunks will contain several tiles each and will be used to only draw the chunks that are currently on the screen.  All other chunks will not be drawn.

So I begin by creating chunks:

// Creates map chunks
private static Map CreateChunks(Map map)
{
// Initialize map chunk rows
map.Chunks = new MapChunk[map.GetMapWidth / MAP_CHUNK_WIDTH][];

// Traverse chunk rows
for (int chunkX = 0; chunkX < map.Chunks.Length; chunkX++)
{
// Initialize chunk column
map.Chunks[chunkX] = new MapChunk[map.GetMapHeight / MAP_CHUNK_HEIGHT];

// Traverse chunk columns
for (int chunkY = 0; chunkY < map.Chunks[chunkX].Length; chunkY++)
{
// Initialize chunk
map.Chunks[chunkX][chunkY] = new MapChunk(MAP_CHUNK_WIDTH, MAP_CHUNK_HEIGHT);
}
}

// Return map
return map;
}


Then I create tiles within those chunks:

// Create map tiles
private static Map CreateTiles(Map map)
{
// The current X position of the map
float mapX = 0;
// The current Y position of the map
float mapY = 0;

// Traverse chunk rows
for (int chunkX = 0; chunkX < map.Chunks.Length; chunkX++)
{
// Traverse chunk columns
for (int chunkY = 0; chunkY < map.Chunks[chunkX].Length; chunkY++)
{
// Initialize tile rows
map.Chunks[chunkX][chunkY].Tiles = new MapTile[MAP_CHUNK_WIDTH][];

// Traverse chunk rows
for (int tileX = 0; tileX < map.Chunks[chunkX][chunkY].Tiles.Length; tileX++)
{
// Initialize tile columns
map.Chunks[chunkX][chunkY].Tiles[tileX] = new MapTile[MAP_CHUNK_HEIGHT];

// Traverse tile columns
for (int tileY = 0; tileY < map.Chunks[chunkX][chunkY].Tiles[tileX].Length; tileY++)
{
// initialize this tile
map.Chunks[chunkX][chunkY].Tiles[tileX][tileY] = new MapTile(
0, null, new Rectangle(
(int)mapX * map.GetTileWidth,
(int)mapY * map.GetTileHeight,
map.GetTileWidth, map.GetTileHeight
),
Noise.GetNoise(mapX * 0.1f, mapY * 0.1f, map.GetSeed));

// Increase mapY
mapY++;
}

// Increase mapX
mapX++;
// Reset map Y
mapY = 0f;
}
}
}

// Return map
return map;
}


So, in theory Chunk[0][0].Tile[0][0] should be positioned at Vector (0,0).  Which it is.  And in theory the second tile in the row Chunk[0][0].Tile[1][0] should be positioned at Vector (24, 0) (tiles are 24 x 24).  Which it is. The first tile in the second row Chunk[0][0].Tile[0][1] should be at Vector (0, 24).  Which it is.  All of that works fine.

The problem comes when we move on to the next chunk.  Chunk [1][0] is to the right of Chunk[0][0].  Chunk [0][1] should be below Chunk[0][0].  However the vector of Chunk[1][0].Tile[0][0] is  (18432, 0).  Chunk[0][1].Tile[0][0] has a Vector (0, 2304).  Which means they are reversed, in theory Chunk[1][0] should be Vector (2328, 0) (I need to increase mapX/mapY between chunk changes.  But given the way it stands now Chunk[0][1] is where Chunk[1][0] should be.  Chunk[1][0] current vector is just messed up.  I know I need to play around with the increase of mapX/mapY and reset of mapX/mapY to change it.  But I have tried every imaginable combination and it just isn't working.  Any help?

### #2Postie  Members   -  Reputation: 726

Like
0Likes
Like

Posted 26 December 2013 - 03:55 PM

Personally, I avoid 2d arrays as I find them confusing. I'm building a game currently that has a similar design with tiles and zones, and I used 1-dimensional arrays as they make more sense to me.

Try doing something like this in your chunk and tile creator:

int offset;
for (int chunkX = 0; chunkX < map.Chunks.Length; chunkX++)
{
// Traverse chunk columns
for (int chunkY = 0; chunkY < map.Chunks[chunkX].Length; chunkY++)
{
offset = (chunkY * MAP_CHUNK_WIDTH) + chunkX;
map.Chunks[offset] = new MapChunk(MAP_CHUNK_WIDTH, MAP_CHUNK_HEIGHT);
}
}


On a related note, I find it's not good to use functions as part of the loop condition in a for statement, eg: map.Chunks.Length. If there's a chance that could change, the code will re-evaluate that value every loop. If you know its fixed, you can assign it to a variable outside the loop first.

Currently working on an open world survival RPG - For info check out my Development blog:

### #3BlueSin  Members   -  Reputation: 142

Like
0Likes
Like

Posted 26 December 2013 - 04:14 PM

Thanks so much for your tips Postie, I really appreciate it!  Before checking this though I actually was able to get it resolved by modifying the Create Tiles code to this:

// Create map tiles
private static Map CreateTiles(Map map)
{
// The current X position of the map
float mapX = 0;
// The current Y position of the map
float mapY = 0;

// Traverse chunk rows
for (int chunkX = 0; chunkX < map.Chunks.Length; chunkX++)
{
// Traverse chunk columns
for (int chunkY = 0; chunkY < map.Chunks[chunkX].Length; chunkY++)
{
// Initialize tile rows
map.Chunks[chunkX][chunkY].Tiles = new MapTile[MAP_CHUNK_WIDTH][];

// Traverse tile rows
for (int tileX = 0; tileX < map.Chunks[chunkX][chunkY].Tiles.Length; tileX++)
{
// Initialize tile columns
map.Chunks[chunkX][chunkY].Tiles[tileX] = new MapTile[MAP_CHUNK_HEIGHT];

// Traverse tile columns
for (int tileY = 0; tileY < map.Chunks[chunkX][chunkY].Tiles[tileX].Length; tileY++)
{
int chunkStartX = (int)chunkX * (map.GetTileWidth * MAP_CHUNK_WIDTH);
int chunkStartY = (int)chunkY * (map.GetTileHeight * MAP_CHUNK_HEIGHT);

// initialize this tile
map.Chunks[chunkX][chunkY].Tiles[tileX][tileY] = new MapTile(
0, null, new Rectangle(
(int)(chunkStartX + (mapX * map.GetTileWidth)),
(int)(chunkStartY + (mapY * map.GetTileHeight)),
map.GetTileWidth, map.GetTileHeight
),
Noise.GetNoise(mapX * 0.1f, mapY * 0.1f, map.GetSeed));

// Increase mapY
mapY++;
}

// Increase mapX
mapX++;
// Reset mapY
mapY = 0f;
}
// Reset mapY
mapX = 0f;
}
}

// Return map
return map;
}


I just need to optimize it in this case.  But I fully agree with your advice on using .Length.  However, the map is generated once and once generated it is static.  The map size and chunk size can never be changed, nor will this code block ever run again (unless a new map is created).  Thanks again!

Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

PARTNERS