Tiled Map - Multiplayer Indie Game - Gether

Tiled Map - Multiplayer Indie Game - Gether

The game world!

After we have realized the character that can move freely, we still need something to replace the black background. One level, one map, one world.

For Gether we use tiled, probably the most popular 2D level editor. Tiled has a very simple interface. You just have to add a spritesheet with all tiles to get started.

Very simple spritesheet consisting of 3 tiles.

After it has been loaded by tiled, a map can already be created. Once you are reasonably satisfied, you can save or export the map in many different formats. Among others in CSV format, which is probably the simplest format and the format we will work with.

Example Map

To export a map in CSV format, you have to select "CSV files (*.csv)" as file type under tiled File -> Export -> Export.

load a tiled map with C++

Now we have a CSV file in which the level data is available in a simple format.

CSV file - Looks wilder than it is.

Each number represents a tile. The number -1 stands for "no tile". The tiles in the spritesheet are numbered in order, starting at the top left from 0 to x.

.

load content into a string

With this knowledge it is very easy to implement a method to load this file. I recommend to pack the complete content of the file into a string.

std::ifstream file("path/to/map.csv");
std::string content((std::istreambuf_iterator<char>(file)), (std::istreambuf_iterator<char>()));

Numbers parse

Once we have the content in a string, we can iterate through any character and put numbers together (if the number is > 9).

std::string number = "";

for(int i = 0; i < content.length(); ++i)
{
// Isn't it a comma and a line break?
if(content.at(i) != ',' && content.at(i) != '\n')
{
// Then it's a digit
number += content.at(i);
}
else
{
// It was a comma or a line break
// So now comes the next number (the next tile)
number = "";
}
}

Use container

To have all numbers in a list, we take a STL Vector.

Vielleicht auch interessant
Der Charakter - Multiplayer Indie Game - Gether
Der Charakter - Multiplayer Indie Game - Gether

Weiter geht es mit dem Hauptcharakter für Gether.

std::vector<int> tiles;

// ...
// STOI => String to Integer
tiles.push_back(std::stoi(number));
number = "";

Now we only have to consider the case line break. If there is a line break, we will later add a tile height to the Y coordinate.

// ...
// Is the current character a line break?
if(content.at(i) == '\n')
{
tiles.push_back(-2);
}

Load the matching tiles

Now that we have all tile IDs in one list, we can interpret them, create the sprites and position them.

int px = 0;
int py = 0;
int tileSize = 32;
	
for(auto it = tiles.begin(); it != tiles.end(); ++it)
{
if(*it != -1)
{
// ... Create tile

if(*it != -2)
{
// Spritesheet width, not the tile width!
int textureWidth = tile->getTexture()->getSize().x;

// Number of tiles in a row (in spritesheet)
int tilesPerRow = std::floor(textureWidth / tileSize);
int index = (*it);
int row = 0;

// Is the Tile ID in the first row?
if(index+1 > tilesPerRow)
{
// No, so calculate the correct index
// Example: 5 tiles per line in the spritesheet. A total of 2 rows.
// The searched index: 7
// 7 / 5 = 1,4 => rounded => 1
// 7 % 5 = 2
// = row 1, the second tile
row = std::floor(index / tilesPerRow);
index %= tilesPerRow;
}

tile->setTextureRect(sf::IntRect(index*tileSize, row*tileSize, tileSize, tileSize));
tile->setPosition(px, py);
m_objects.push_back(tile);

px += tileSize;
}
else
{
// Da -2 => new line
// X Reset coordinate to 0 and add to Y tile height
px = 0;
py += tileSize;
}
}
}
Next article
Coop Modus - Multiplayer Indie Game - Gether
Leave a like or comment (~‾▿‾)~
Name Text