Skip to content

Instantly share code, notes, and snippets.

/TileMap.cpp Secret

Created September 17, 2016 18:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/f9ddbf24f684d0552d7fee31f4063155 to your computer and use it in GitHub Desktop.
Save anonymous/f9ddbf24f684d0552d7fee31f4063155 to your computer and use it in GitHub Desktop.
#include "TileMap.h"
TileMap::TileMap() {}
bool TileMap::load(const char* xmlDocument)
{
// Read Level from XML
if (!readXML(xmlDocument))
return false;
// Load the tileset texture
if (!tileSheet.loadFromFile(filepath))
return false;
// Get size of a tile
const unsigned int tileWidth = tileSheet.getSize().x / sheetColumns;
const unsigned int tileHeight = tileSheet.getSize().y / sheetRows;
// Resize the vertex array to fit the level size
vertexArray.setPrimitiveType(sf::Quads);
vertexArray.resize(worldWidth * worldHeight * 4);
// Populate the vertex array, with one quad per tile
for (unsigned int i = 0; i < worldWidth; i++)
{
for (unsigned int j = 0; j < worldHeight; j++)
{
// Get the current tile number (Does 1 column at a time)
int tileNumber = map[i + j * worldWidth];
// Find its position in the tileset texture
int tileRow = tileNumber / (tileSheet.getSize().x / tileWidth);
int tileCol = tileNumber % (tileSheet.getSize().x / tileWidth);
// Get a pointer to the current tile's quad
sf::Vertex* quad = &vertexArray[(i + j * worldWidth) * 4];
/*\
|*| Define its 4 corners
|*|
|*| 0 ----- 1 This takes care of where and how the quad will
|*| | | appear in the world. Adding or subtracting in the
|*| | | X or Y will change the size/shape.
|*| 3 ----- 2
\*/
quad[0].position = sf::Vector2f((float) (i * tileWidth), (float) (j * tileHeight));
quad[1].position = sf::Vector2f((float) ((i + 1) * tileWidth), (float) (j * tileHeight));
quad[2].position = sf::Vector2f((float) ((i + 1) * tileWidth), (float) ((j + 1) * tileHeight));
quad[3].position = sf::Vector2f((float) (i * tileWidth), (float) ((j + 1) * tileHeight));
/*\
|*| Define its 4 texture coordinates
|*|
|*| 0 ------- 1 Offsets => Top(T), Right(R), Bottom(B), Left(L)
|*| | T |
|*| | L R | Offsets will be subtracted from the texture.
|*| | B | They are not required if you want the whole texture.
|*| 3 ------- 2
\*/
quad[0].texCoords = sf::Vector2f((float) ((tileCol * tileWidth) - leftOffset), (float) ((tileRow * tileHeight) - topOffset));
quad[1].texCoords = sf::Vector2f((float) (((tileCol + 1) * tileWidth) - rightOffset), (float) ((tileRow * tileHeight) - topOffset));
quad[2].texCoords = sf::Vector2f((float) (((tileCol + 1) * tileWidth) - rightOffset), (float) (((tileRow + 1) * tileHeight) - bottomOffset));
quad[3].texCoords = sf::Vector2f((float) ((tileCol * tileWidth) - leftOffset), (float) (((tileRow + 1) * tileHeight) - bottomOffset));
}
}
// Tilemap loaded successfully
return true;
}
bool TileMap::readXML(const char* xmlDocument)
{
// Used for tokenizing the level array
char *token, *nextToken;
// Clear the vector for reloading
map.clear();
// Load the xml file
pugi::xml_parse_result result = document.load_file(xmlDocument);
// Check if loaded correctly
if (!result)
return false;
// Get the filepath
filepath = document.first_element_by_path("Level/Tileset", '/').text().as_string();
// Get sheet rows and columns
sheetRows = document.first_element_by_path("Level/SheetRows", '/').text().as_uint();
sheetColumns = document.first_element_by_path("Level/SheetColumns", '/').text().as_uint();
// Get world size
worldWidth = document.first_element_by_path("Level/WorldWidth", '/').text().as_uint();
worldHeight = document.first_element_by_path("Level/WorldHeight", '/').text().as_uint();
// Get the offsets
topOffset = document.first_element_by_path("Level/TopOffset", '/').text().as_float();
bottomOffset = document.first_element_by_path("Level/BottomOffset", '/').text().as_float();
leftOffset = document.first_element_by_path("Level/LeftOffset", '/').text().as_float();
rightOffset = document.first_element_by_path("Level/RightOffset", '/').text().as_float();
// Get all the children of <Map>
pugi::xml_node rows = document.first_element_by_path("Level/Map", '/');
// Loop through the rows and get the tile numbers
for each (pugi::xml_node row in rows.children())
{
// Tokenize the row
token = strtok_s((char*)row.text().as_string(), " ", &nextToken);
while (token)
{
// Add number to array then get next token
map.push_back(std::stoi(token));
token = strtok_s(NULL, " ", &nextToken);
}
}
// XML file read successfully
return true;
}
void TileMap::draw(sf::RenderTarget& target, sf::RenderStates states) const
{
// Apply the transforms
states.transform *= getTransform();
// Apply the tileset texture
states.texture = &tileSheet;
// Draw the vertex array
target.draw(vertexArray, states);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment