# Dynamic Tilemap size changer

I have started coding this project using the library SFML a few months ago.

I have implemented a random map generation everytime I load the game thanks to Biome and the Perlin noise Algorithm.

I wish i could increase the TileMap size on the border of the map according to the player position (Chunk system in minecraft) .

I have managed to do it on the bottom and the right of the map :

But this isn't dynamic. There is a snap of my code where i add a new "chunck" :

void TileMap::AddChunckToTileSet(sf::Vector2i PlayerTile, char * direction)
{
int previousWidth = _width;
int previousHeight = _height;

_height = _height + 24;
_width = _width + 24;
m_vertices.resize(_width * _height * 4);

int tileNumber = 384; // ToDO

// on en déduit sa position dans la texture du tileset
int tu = tileNumber % (m_tileset.getSize().x / _tileSize.x);
int tv = tileNumber / (m_tileset.getSize().x / _tileSize.x);

if (direction == "Down")
{

for (int i = previousWidth; i < _width; ++i)
{
for (int j = previousHeight; j < _height; ++j)
{
// on récupère un pointeur vers le quad à définir dans le tableau de vertex
sf::Vertex* quad = &m_vertices[(i + j * _width) * 4];

// on définit ses quatre coins
quad[0].position = sf::Vector2f((i - previousWidth) + PlayerTile.x * _tileSize.x, j * _tileSize.y);
quad[1].position = sf::Vector2f(((i - previousWidth) + PlayerTile.x + 1) * _tileSize.x, j * _tileSize.y);
quad[2].position = sf::Vector2f(((i - previousWidth) + PlayerTile.x + 1) * _tileSize.x, (j + 1) * _tileSize.y);
quad[3].position = sf::Vector2f((i - previousWidth) + PlayerTile.x * _tileSize.x, (j + 1) * _tileSize.y);

// on définit ses quatre coordonnées de texture
quad[0].texCoords = sf::Vector2f(tu * _tileSize.x, tv * _tileSize.y);
quad[1].texCoords = sf::Vector2f((tu + 1) * _tileSize.x, tv * _tileSize.y);
quad[2].texCoords = sf::Vector2f((tu + 1) * _tileSize.x, (tv + 1) * _tileSize.y);
quad[3].texCoords = sf::Vector2f(tu * _tileSize.x, (tv + 1) * _tileSize.y);

}
}
}
}


I call the function AddChunckToTileSet like this :

void TileMap::Update(sf::Vector2i PlayerTile)
{

if (PlayerTile.y + 15 > _height)
{
// Increase map on Down according to our X
}

}


Do you have any hints on how I could achieve this correctly ?

• Please explain what you mean by dynamic. You update the chunks based on your players y position, which seems dynamic to me. Are you referring to the entire region being filled in? Your for loops on i and j only capture a small portion of the area that needs to be updated. – Kyy13 Mar 2 '18 at 14:29
• By dynamic i mean, How could i check for the next chunk to update. not only on the "Down" Axis . Like on the second picture, i can add more and more chunck towards the bottom of the map. But how could i achieve this on the Left / Right of the current chunck I added . – paul b Mar 2 '18 at 14:34

1

The first thing you need to do is develop a method of expanding your m_vertices array in the negative x and y direction.

One option is to pad it with an offset. As the array expands update the offset, so no value is ever less than 0. This will require you to first expand the array and move the previous data. You would access your tiles like this:

Tile(i, j) = &m_vertices[(i+offsetx + (j+offsety) * _width) * 4]


Another method would be to use 4 arrays in each quadrant and rotate them, so they expand away from each other.

2

The second thing you need to do is loop over all the tiles that need to be updated. And expand where needed. An example using offset method would look something like this...

min_j = min(min_j, playerTile.y-16);
max_j = max(max_j, playerTile.y+16);

if (min_j + offsety < 0) expandTileMap();
if (max_j - min_j + 1 > _height) expandTileMap();

for ( i = min_i; i <= max_i; ++i )
{
// up
for ( j = min_j-1; j > playerTile.y-16; --j )
{
doSomething(i, j);
}
// down
for ( j = max_j+1; j < playerTile.y+16; ++j )
{
doSomething(i, j);
}
}

min_i = min(min_i, playerTile.x-16);
max_i = max(max_i, playerTile.x+16);

if (min_i + offsetx < 0) expandTileMap();
if (max_i - min_i + 1 > _width) expandTileMap();

for ( j = min_j; j < max_j; ++j )
{
// left
for ( i = min_i; i < playerTile.x+16; ++i )
{
doSomething(i, j);
}
// right
for ( i = max_i; i < playerTile.y+16; ++i )
{
doSomething(i, j);
}
}