void LevelParser::parseTileLayer(TiXmlElement* pTileElement, std::vector<Layer*> *pLayers, const std::vector<Tileset>* pTilesets, std::vector<TileLayer*> *m_CollisionsLayer) { TileLayer* pTileLayer = new TileLayer(m_tileSizew, m_tileSizeh, *pTilesets); bool collidable = false; std::vector<std::vector<int>> data; std::string decodedIDs; TiXmlElement* pDataNode; for (TiXmlElement* e = pTileElement->FirstChildElement(); e != NULL; e = e->NextSiblingElement()) { if (e->Value() == std::string("properties")) { for (TiXmlElement* property = e->FirstChildElement(); property != NULL; property = property->NextSiblingElement()) { if (property->Value() == std::string("property")) { if (property->Attribute("name") == std::string("collidable")) { collidable = true; } } } } if (e->Value() == std::string("data")) { pDataNode = e; } } for (TiXmlNode* e = pDataNode->FirstChild(); e != NULL; e = e->NextSibling()) { TiXmlText* text = e->ToText(); std::string t = text->Value(); decodedIDs = base64_decode(t); } uLongf numGids = m_width * m_height * sizeof(int); std::vector<unsigned> gids(numGids); uncompress((Bytef*)&gids[0], &numGids, (const Bytef*)decodedIDs.c_str(), decodedIDs.size()); std::vector<int> layerRow(m_width); for (int j = 0; j < m_height; j++) { data.push_back(layerRow); } for (int rows = 0; rows < m_height; rows++) { for (int cols = 0; cols < m_width; cols++) { data[rows][cols] = gids[rows * m_width + cols]; } } if (collidable) { m_CollisionsLayer->push_back(pTileLayer); } pTileLayer->setTileIDs(data); pLayers->push_back(pTileLayer); }
void LevelParser::parseTileLayer(TiXmlElement* pTileElement, std::vector<Layer*> *pLayers, const std::vector<Tileset>* pTilesets) { TileLayer* pTileLayer = new TileLayer(m_tileSize, *pTilesets); // tile data std::vector<std::vector<int>> data; std::string decodedIDs; TiXmlElement* pDataNode = NULL; for (TiXmlElement* e = pTileElement->FirstChildElement(); e != NULL; e = e->NextSiblingElement()) { if (e->Value() == std::string("data")) { pDataNode = e; } } for (TiXmlNode* e = pDataNode->FirstChild(); e != NULL; e = e->NextSibling()) { TiXmlText* text = e->ToText(); std::string t = text->Value(); decodedIDs = base64_decode(t); } // uncompress zlib compression uLongf numGids = m_width * m_height * sizeof(int); std::vector<unsigned> gids(numGids); uncompress((Bytef*)&gids[0], &numGids, (const Bytef*)decodedIDs.c_str(), decodedIDs.size()); std::vector<int> layerRow(m_width); for (int j = 0; j < m_height; j++) { data.push_back(layerRow); } for (int rows = 0; rows < m_height; rows++) { for (int cols = 0; cols < m_width; cols++) { data[rows][cols] = gids[rows * m_width + cols]; } } pTileLayer->setTileIDs(data); pLayers->push_back(pTileLayer); }
void LevelParser::parseTileLayer (TiXmlElement *pTileElement, vector<ILayer *> *pLayers, vector<TileLayer*>* pCollisionLayers,vector<Tileset> *pTilesets){ TileLayer* pTileLayer = new TileLayer(m_tileSize, m_width, m_height, *pTilesets); //Check for layer properties bool collidable(false); for (TiXmlElement* e = pTileElement->FirstChildElement(); e != NULL; e = e->NextSiblingElement()){ //cout << "Checking " << e->Value() << "\n"; if (e->Value() == string("properties")){ for (TiXmlElement* p = e->FirstChildElement(); p != NULL; p = p->NextSiblingElement()){ if (p->Value() == string("property")){ cout << "Now checking " << p->Value() << "\n"; string currentProperty = p->Attribute("name"); if (currentProperty == string("collidable")){ if (p->Attribute("value") == string("true")){ collidable = true; } else { collidable = false; } if (collidable){ cout << "Found collidable layer\n"; } } } } } } //Find data node then store it //pDataNode = findElement("data", pTileElement->FirstChildElement()); bool isBase64 = false ; bool isZlibCompressed = false; TiXmlElement* pDataNode= 0; for (TiXmlElement* e = pTileElement->FirstChildElement(); e != NULL; e = e->NextSiblingElement()){ if (e->Value() == string("data")){ pDataNode = e; //Check if encoded/compressed if (e->Attribute("encoding")){ if (e->Attribute("encoding") == string("base64")){ isBase64 = true; } } if (e->Attribute("compression")){ if (e->Attribute("compression") == string("zlib")){ isZlibCompressed = true; } } } } //Decode data and store string decodedIDs; if (pDataNode && isBase64){ for (TiXmlNode* e = pDataNode->FirstChild(); e != NULL; e = e->NextSibling()){ TiXmlText* text = e ->ToText(); string t = text->Value(); decodedIDs = base64_decode(t); } } //Placeholder for data vector<vector<int>> data; //Calculate number of GIDS present uLongf numGids = m_width * m_height * sizeof(int); vector<unsigned> gids(numGids); //Horizontal register for vector vector<int> layerRow(m_width); //Build empty data vector to fill for(int j = 0 ; j < m_height; j++){ data.push_back(layerRow); } //Compressed data assignment if (isZlibCompressed){ uncompress ((Bytef*)&gids[0], &numGids, (const Bytef*)decodedIDs.c_str(), decodedIDs.size()); for (int rows = 0 ; rows <m_height; rows++){ for (int cols = 0; cols < m_width; cols++){ data[rows][cols] = gids[rows * m_width + cols]; } } } else { //Uncompressed data assignment int index = 0; int tileID = 0; //Find all tiles, assign GID to proper data vector place for (TiXmlElement* e = pDataNode->FirstChildElement(); e != NULL; e = e->NextSiblingElement()){ e->Attribute("gid",&tileID); data[index / m_width][index % m_width] = tileID; index++; } } //Set Tile Layer properties pTileLayer->setTileIDs(data); pTileLayer->setNumColumns(m_width); pTileLayer->setNumRows(m_height); //Save new tile layer to Level cout << "Added new layer\n"; pLayers->push_back(pTileLayer); //Add collision tiles to collision layer if (collidable){ pCollisionLayers->push_back(pTileLayer); cout << "Added new collision layer\n"; } }
void LevelParser::parseTileLayer(XMLElement* pTileElement, Level *pLevel) { // New TileLayer instance TileLayer* pTileLayer = new TileLayer(m_tileSize, m_width, m_height, TheGame::Instance().getTilesets()); // local temporary variable bool collidable = false; // A multidimensional array of int values to hold our final decoded and uncompressed tile data std::vector<std::vector<int>> data; // xml data node XMLElement* pDataNode = nullptr; // to store base64 decoded information std::string decodedIDs; // We search for the node we need for (XMLElement* e = pTileElement->FirstChildElement(); e != NULL; e = e->NextSiblingElement()) { // check if layer has properties if (e->Value() == std::string("properties")) { for (XMLElement* property = e->FirstChildElement(); property != NULL; property = property->NextSiblingElement()) { if (property->Value() == std::string("property")) { // Check if it is a collision layer if (property->Attribute("name") == std::string("collidable")) { collidable = true; } } } } if (e->Value() == std::string("data")) { pDataNode = e; } } // Tile information not encoded nor compressed if (pDataNode->Attribute("encoding") == nullptr) { std::vector<int> layerRow(m_width); for (int rows = 0; rows < m_height; rows++) { data.push_back(layerRow); } XMLElement* tile = pDataNode->FirstChildElement(); int id; for (int rows = 0; rows < m_height; rows++) { for (int cols = 0; cols < m_width ; cols++) { tile->QueryAttribute("gid", &data[rows][cols]); tile = tile->NextSiblingElement(); } } } else { // We get the text (our encoded/compressed data) from the data node and use the base64 decoder to decode it for (XMLNode* e = pDataNode->FirstChild(); e != NULL; e = e->NextSibling()) { XMLText* text = e->ToText(); std::string t = text->Value(); decodedIDs = base64_decode(t); } // We use the zlib library to decompress our data once again uLongf sizeofids = m_width * m_height * sizeof(int); std::vector<unsigned> gids(sizeofids); uncompress((Bytef*)&gids[0], &sizeofids, (const Bytef*)decodedIDs.c_str(), decodedIDs.size()); // gids now contains all of our tile IDs, so we fill our data array with the correct values std::vector<int> layerRow(m_width); for (int j = 0; j < m_height; j++) { data.push_back(layerRow); } for (int rows = 0; rows < m_height; rows++) { for (int cols = 0; cols < m_width; cols++) { data[rows][cols] = gids[rows * m_width + cols]; } } } pTileLayer->setTileIDs(data); pTileLayer->setMapWidth(m_width); // push into collision array and mark the layer as collidable if necessary if (collidable) { pTileLayer->setCollidable(true); pLevel->getCollisionLayers()->push_back(pTileLayer); } pLevel->getLayers()->push_back(pTileLayer); }