Пример #1
0
bool TileMap::load(const std::string& tmx_path) {

  Tmx::Map map;
  map.ParseFile(tmx_path);

  if (map.HasError()) {
    return false;
  }

  int width = map.GetWidth();
  int height = map.GetHeight();

  m_mapSize = sf::Vector2u(width, height);

  m_tileSize = sf::Vector2u(map.GetTileWidth(), map.GetTileHeight());

  std::string basepath = map.GetFilepath();
  for (int i = 0; i < map.GetNumTilesets(); i++) {
    const Tmx::Tileset *tileset = map.GetTileset(i);
    m_tilesets.emplace_back();
    if (!m_tilesets.back().load(*tileset, basepath))
      return false;
  }

  for (int j = 0; j < map.GetNumTileLayers(); j++) {
    const Tmx::TileLayer *tileLayer = map.GetTileLayer(j);
    m_tilelayers.emplace_back();
    if (!m_tilelayers.back().load(*tileLayer, m_tilesets, width, height))
      return false;
  }

  return true;
}
Пример #2
0
void TileMap::parseTmx(Tmx::Map &tmxMap) {

    this->width = tmxMap.GetWidth();
    this->height = tmxMap.GetHeight();
    this->tileWidth = tmxMap.GetTileWidth();
    this->tileHeight = tmxMap.GetTileHeight();
    LOG(INFO) << "Number of tilesets: " + std::to_string(tmxMap.GetNumTilesets());

    std::vector<Tileset> tilesets;

    for (int i = 0; i < tmxMap.GetNumTilesets(); ++i) {
        const Tmx::Tileset *tmxTileset = tmxMap.GetTileset(i);
        Tileset tileset;
        tileset.imageSource = tmxTileset->GetImage()->GetSource();
        tileset.imageWidth = tmxTileset->GetImage()->GetWidth();
        tileset.imageHeight = tmxTileset->GetImage()->GetHeight();
        tileset.tileWidth = tmxTileset->GetTileWidth();
        tileset.tileHeight = tmxTileset->GetTileHeight();
        tilesets.push_back(tileset);
    }

    for (int i = 0; i < tmxMap.GetNumTileLayers(); ++i) {
        const Tmx::TileLayer *tmxTileLayer = tmxMap.GetTileLayer(i);
        parseTileLayer(tilesets, tmxTileLayer);
    }
}
Пример #3
0
void ParserMap::LoadMap(ServerMap *drawmap, const std::string &name)
{
	// загрузка карты
	Tmx::Map *map = new Tmx::Map();
	map->ParseFile(Config::Get()["dir.maps"] + name);
	if ( map->HasError() )
	{
		Log::Error("error code: " + std::to_string(map->GetErrorCode()));
		Log::Error("error text: " + map->GetErrorText());
		throw (std::runtime_error("map->GetErrorCode()"));
	}

	for ( int i = 0; i < map->GetNumTileLayers(); ++i )
	{
		const Tmx::TileLayer *tileLayer = map->GetTileLayer(i);
		const std::string tileLayerName = tileLayer->GetName();
		
		for ( int y = 0; y < tileLayer->GetHeight(); ++y )
		{
			for ( int x = 0; x < tileLayer->GetWidth(); ++x )
			{
				if ( tileLayer->GetTileTilesetIndex(x, y) == -1 )
				{
				}
				else
				{
					if ( tileLayerName == "Collision" )
					{
						if ( tileLayer->GetTileGid(x, y) == 50 )
							drawmap->m_tile[0][x][y].SetCollision(1);
					}
					else if ( tileLayerName == "enemy" )
					{
						if ( tileLayer->GetTileGid(x, y) == 52 )
							drawmap->m_tile[0][x][y].SetEnemy(1);
					}
					else
					{
						drawmap->m_tile[i][x][y].SetTileId(tileLayer->GetTileGid(x, y) - 1);
					}
				}
			}
		}
	}

	delete map;
	map = nullptr;
}
Пример #4
0
int main(int argc, char * argv[])
{
    Tmx::Map *map = new Tmx::Map();
    std::string fileName = (argc > 1) ? argv[1] : "./example/example.tmx";
    map->ParseFile(fileName);

    if (map->HasError())
    {
        printf("error code: %d\n", map->GetErrorCode());
        printf("error text: %s\n", map->GetErrorText().c_str());

        return map->GetErrorCode();
    }

    printf("====================================\n");
    printf("Map\n");
    printf("====================================\n");

    printf("Version: %1.1f\n", map->GetVersion());
    printf("Orientation: %d\n", map->GetOrientation());
    if (!map->GetBackgroundColor().IsTransparent())
        printf("Background Color (hex): %s\n",
               map->GetBackgroundColor().ToString().c_str());
    printf("Render Order: %d\n", map->GetRenderOrder());
    if (map->GetStaggerAxis())
        printf("Stagger Axis: %d\n", map->GetStaggerAxis());
    if (map->GetStaggerIndex())
        printf("Stagger Index: %d\n", map->GetStaggerIndex());
    printf("Width: %d\n", map->GetWidth());
    printf("Height: %d\n", map->GetHeight());
    printf("Tile Width: %d\n", map->GetTileWidth());
    printf("Tile Height: %d\n", map->GetTileHeight());

    // Iterate through map properties and print the type, name and value of each property.
    const std::unordered_map<std::string, Tmx::Property> &mapProperties = map->GetProperties().GetPropertyMap();
    for (auto &pair : mapProperties)
    {
        const Tmx::Property &property = pair.second;

        std::string type;

        if (property.GetType() == Tmx::TMX_PROPERTY_STRING)
        {
            type = "String";
        }
        else if (property.GetType() == Tmx::TMX_PROPERTY_FLOAT)
        {
            type = "Float";
        }
        else if (property.GetType() == Tmx::TMX_PROPERTY_INT)
        {
            type = "Integer";
        }
        else if (property.GetType() == Tmx::TMX_PROPERTY_BOOL)
        {
            type = "Boolean";
        }
        else if (property.GetType() == Tmx::TMX_PROPERTY_COLOR)
        {
            type = "Color";
        }
        else if (property.GetType() == Tmx::TMX_PROPERTY_FILE)
        {
            type = "File";
        }
        else
        {
            type = "Unknown";
        }

        printf("Map property %s (%s) = %s\n", pair.first.c_str(), type.c_str(),  property.GetValue().c_str());
    }

    // Make sure property parsing works correctly across the library.
    assert(mapProperties.at("StringProperty").GetValue() == map->GetProperties().GetStringProperty("StringProperty"));
    assert(mapProperties.at("IntProperty").GetIntValue() == map->GetProperties().GetIntProperty("IntProperty"));
    assert(mapProperties.at("NegativeIntProperty").GetIntValue() == map->GetProperties().GetIntProperty("NegativeIntProperty"));
    assert(mapProperties.at("FloatProperty").GetFloatValue() == map->GetProperties().GetFloatProperty("FloatProperty"));
    assert(mapProperties.at("NegativeFloatProperty").GetFloatValue() == map->GetProperties().GetFloatProperty("NegativeFloatProperty"));
    assert(mapProperties.at("BigInteger").GetIntValue() == map->GetProperties().GetIntProperty("BigInteger"));
    assert(mapProperties.at("FalseProperty").GetBoolValue() == map->GetProperties().GetBoolProperty("FalseProperty"));
    assert(mapProperties.at("TrueProperty").GetBoolValue() == map->GetProperties().GetBoolProperty("TrueProperty"));
    assert(mapProperties.at("YellowProperty").GetColorValue() == map->GetProperties().GetColorProperty("YellowProperty"));
    assert(mapProperties.at("FileProperty").GetBoolValue() == map->GetProperties().GetBoolProperty("FileProperty"));

    // Make sure color can be converted from and to string
    assert(map->GetProperties().GetColorProperty("YellowProperty").ToString() == map->GetProperties().GetStringProperty("YellowProperty"));
    assert(Tmx::Color("#ffffff") == Tmx::Color("#ffffffff"));

    // Iterate through the tilesets.
    for (int i = 0; i < map->GetNumTilesets(); ++i)
    {
        printf("                                    \n");
        printf("====================================\n");
        printf("Tileset : %02d\n", i);
        printf("====================================\n");

        // Get a tileset.
        const Tmx::Tileset *tileset = map->GetTileset(i);

        // Print tileset information.
        printf("Name: %s\n", tileset->GetName().c_str());
        printf("Margin: %d\n", tileset->GetMargin());
        printf("Spacing: %d\n", tileset->GetSpacing());
        printf("First gid: %d\n", tileset->GetFirstGid());
        printf("Image Width: %d\n", tileset->GetImage()->GetWidth());
        printf("Image Height: %d\n", tileset->GetImage()->GetHeight());
        printf("Image Source: %s\n", tileset->GetImage()->GetSource().c_str());
        if (!tileset->GetImage()->GetTransparentColor().IsTransparent())
            printf("Transparent Color (hex): %s\n",
                   tileset->GetImage()->GetTransparentColor().ToString().c_str());

        if (tileset->GetTiles().size() > 0)
        {
            // Get a tile from the tileset.
            const Tmx::Tile *tile = *(tileset->GetTiles().begin());

            // Print the properties of a tile.
            std::map<std::string, std::string> list =
                    tile->GetProperties().GetList();
            std::map<std::string, std::string>::iterator iter;
            for (iter = list.begin(); iter != list.end(); ++iter)
            {
                printf("%s = %s\n", iter->first.c_str(), iter->second.c_str());
            }

            if (tile->IsAnimated())
            {
                printf(
                        "Tile is animated: %d frames with total duration of %dms.\n",
                        tile->GetFrameCount(), tile->GetTotalDuration());

                const std::vector<Tmx::AnimationFrame> &frames =
                        tile->GetFrames();

                int i = 0;
                for (std::vector<Tmx::AnimationFrame>::const_iterator it =
                        frames.begin(); it != frames.end(); it++, i++)
                {
                    printf("\tFrame %d: Tile ID = %d, Duration = %dms\n", i,
                            it->GetTileID(), it->GetDuration());
                }
            }

            if(tile->HasObjects())
            {
                printf(
                        "Tile has objects.\n");

                if(tile->GetType() != "")
                    printf("Tile has type: %s\n", tile->GetType().c_str());
                    
                // Iterate through all Collision objects in the tile.
                for (int j = 0; j < tile->GetNumObjects(); ++j)
                {
                    // Get an object.
                    const Tmx::Object *object = tile->GetObject(j);

                    // Print information about the object.
                    printf("Object Name: %s\n", object->GetName().c_str());
                    printf("Object Position: (%03d, %03d)\n", object->GetX(),
                           object->GetY());
                    printf("Object Size: (%03d, %03d)\n", object->GetWidth(),
                           object->GetHeight());

                    // Print Polygon points.
                    const Tmx::Polygon *polygon = object->GetPolygon();
                    if (polygon != 0)
                    {
                        for (int i = 0; i < polygon->GetNumPoints(); i++)
                        {
                            const Tmx::Point &point = polygon->GetPoint(i);
                            printf("Object Polygon: Point %d: (%f, %f)\n", i, point.x,
                                   point.y);
                        }
                    }

                    // Print Polyline points.
                    const Tmx::Polyline *polyline = object->GetPolyline();
                    if (polyline != 0)
                    {
                        for (int i = 0; i < polyline->GetNumPoints(); i++)
                        {
                            const Tmx::Point &point = polyline->GetPoint(i);
                            printf("Object Polyline: Point %d: (%f, %f)\n", i, point.x,
                                   point.y);
                        }
                    }
                }

            }
        }
    }

    // Iterate through the tile layers.
    for (int i = 0; i < map->GetNumTileLayers(); ++i)
    {
        printf("                                    \n");
        printf("====================================\n");
        printf("Layer : %02d/%s \n", i, map->GetTileLayer(i)->GetName().c_str());
        printf("====================================\n");

        // Get a layer.
        const Tmx::TileLayer *tileLayer = map->GetTileLayer(i);

        for (int y = 0; y < tileLayer->GetHeight(); ++y)
        {
            for (int x = 0; x < tileLayer->GetWidth(); ++x)
            {
                if (tileLayer->GetTileTilesetIndex(x, y) == -1)
                {
                    printf("........    ");
                }
                else
                {
                    // Get the tile's id and gid.
                    printf("%03d(%03d)", tileLayer->GetTileId(x, y), tileLayer->GetTileGid(x, y));

                    // Find a tileset for that id.
                    //const Tmx::Tileset *tileset = map->FindTileset(layer->GetTileId(x, y));
                    if (tileLayer->IsTileFlippedHorizontally(x, y))
                    {
                        printf("h");
                    }
                    else
                    {
                        printf(" ");
                    }
                    if (tileLayer->IsTileFlippedVertically(x, y))
                    {
                        printf("v");
                    }
                    else
                    {
                        printf(" ");
                    }
                    if (tileLayer->IsTileFlippedDiagonally(x, y))
                    {
                        printf("d ");
                    }
                    else
                    {
                        printf("  ");
                    }
                }
            }

            printf("\n");
        }
    }

    printf("\n\n");

    // Iterate through all of the object groups.
    for (int i = 0; i < map->GetNumObjectGroups(); ++i)
    {
        printf("                                    \n");
        printf("====================================\n");
        printf("Object group : %02d\n", i);
        printf("====================================\n");

        // Get an object group.
        const Tmx::ObjectGroup *objectGroup = map->GetObjectGroup(i);

        // Iterate through all objects in the object group.
        for (int j = 0; j < objectGroup->GetNumObjects(); ++j)
        {
            // Get an object.
            const Tmx::Object *object = objectGroup->GetObject(j);

            // Print information about the object.
            printf("Object Name: %s\n", object->GetName().c_str());
            printf("Object Position: (%03d, %03d)\n", object->GetX(),
                    object->GetY());
            printf("Object Size: (%03d, %03d)\n", object->GetWidth(),
                    object->GetHeight());

            if(object->GetGid() != 0) {
              printf("Object(tile) gid: %d\n", object->GetGid());
              printf("Object(tile) type: %s\n", object->GetType().c_str());
            }

            // Print Polygon points.
            const Tmx::Polygon *polygon = object->GetPolygon();
            if (polygon != 0)
            {
                for (int i = 0; i < polygon->GetNumPoints(); i++)
                {
                    const Tmx::Point &point = polygon->GetPoint(i);
                    printf("Object Polygon: Point %d: (%f, %f)\n", i, point.x,
                            point.y);
                }
            }

            // Print Polyline points.
            const Tmx::Polyline *polyline = object->GetPolyline();
            if (polyline != 0)
            {
                for (int i = 0; i < polyline->GetNumPoints(); i++)
                {
                    const Tmx::Point &point = polyline->GetPoint(i);
                    printf("Object Polyline: Point %d: (%f, %f)\n", i, point.x,
                            point.y);
                }
            }

            // Print Text information
            const Tmx::Text *text = object->GetText();
            if(text != 0)
            {
                printf("--Object Text--\n");
                printf("Font family: %s\n", text->GetFontFamily().c_str());
                printf("Pixel size: %d\n", text->GetPixelSize());
                printf("Wraps: %d\n", text->Wraps());
                printf("Bold: %d, Italic: %d, Underline: %d, Strikeout: %d\n", text->IsBold(), text->IsItalic(),
                                                                             text->IsUnderline(), text->IsStrikeout());
                printf("Kerning: %d\n", text->UseKerning());
                printf("Horizontal ALignment: %d\n", text->GetHorizontalAlignment());
                printf("Vertical Alignment: %d\n", text->GetVerticalAlignment());
                printf("Color: %d, %d, %d, %d", text->GetColor()->GetRed(), text->GetColor()->GetGreen(),
                                                text->GetColor()->GetBlue(), text->GetColor()->GetAlpha());
            }
        }
    }

    // Iterate through all of the group layers.
    for(int i = 0; i < map->GetNumGroupLayers(); ++i) {
        printf("                                    \n");
        printf("====================================\n");
        printf("Group Layer : %02d/%s \n", i, map->GetGroupLayer(i)->GetName().c_str());
        printf("====================================\n");
        // Get a group layer.
        const Tmx::GroupLayer *groupLayer = map->GetGroupLayer(i);

        printf("Offset X: %d", groupLayer->GetOffsetX());
        printf("Offset Y: %d", groupLayer->GetOffsetY());
        printf("Number of Children: %d", groupLayer->GetNumChildren());

        for(int j = 0; j < groupLayer->GetNumChildren(); j++) {
          const Tmx::Layer *childLayer = groupLayer->GetChild(j);
          printf("Child Layer Name: %s\n", childLayer->GetName().c_str());
          printf("Child Layer Type: %02d\n", childLayer->GetLayerType());

          if(childLayer->GetLayerType() == Tmx::TMX_LAYERTYPE_GROUP_LAYER) {
            const Tmx::GroupLayer *childGroupLayer = static_cast<const Tmx::GroupLayer*>(childLayer);
            printf("  Child group layer number of children: %d\n", childGroupLayer->GetNumChildren());
            printf("  Child group layer first child name: %s\n", childGroupLayer->GetChild(0)->GetName().c_str());
            printf("  Child group layer first child type: %d\n", childGroupLayer->GetChild(0)->GetLayerType());
          }
        }
    }

    delete map;

    return 0;
}
Пример #5
0
int main(int argc, char * argv[])
{
	Tmx::Map *map = new Tmx::Map();
	//std::string fileName = (argc > 1) ? argv[1] : "./example/example.tmx";
	std::string fileName = (argc > 1) ? argv[1] : "1.tmx";
	map->ParseFile(fileName);

	if (map->HasError())
	{
		printf("error code: %d\n", map->GetErrorCode());
		printf("error text: %s\n", map->GetErrorText().c_str());

		return map->GetErrorCode();
	}

	printf("====================================\n");
	printf("Map\n");
	printf("====================================\n");

	printf("Version: %1.1f\n", map->GetVersion());
	printf("Orientation: %d\n", map->GetOrientation());
	if (!map->GetBackgroundColor().empty())
		printf("Background Color (hex): %s\n",
			   map->GetBackgroundColor().c_str());
	printf("Render Order: %d\n", map->GetRenderOrder());
	if (map->GetStaggerAxis())
		printf("Stagger Axis: %d\n", map->GetStaggerAxis());
	if (map->GetStaggerIndex())
		printf("Stagger Index: %d\n", map->GetStaggerIndex());
	printf("Width: %d\n", map->GetWidth());
	printf("Height: %d\n", map->GetHeight());
	printf("Tile Width: %d\n", map->GetTileWidth());
	printf("Tile Height: %d\n", map->GetTileHeight());

	// Iterate through the tilesets.
	for (int i = 0; i < map->GetNumTilesets(); ++i)
	{
		printf("                                    \n");
		printf("====================================\n");
		printf("Tileset : %02d\n", i);
		printf("====================================\n");

		// Get a tileset.
		const Tmx::Tileset *tileset = map->GetTileset(i);

		// Print tileset information.
		printf("Name: %s\n", tileset->GetName().c_str());
		printf("Margin: %d\n", tileset->GetMargin());
		printf("Spacing: %d\n", tileset->GetSpacing());
		printf("First gid: %d\n", tileset->GetFirstGid());
		printf("Image Width: %d\n", tileset->GetImage()->GetWidth());
		printf("Image Height: %d\n", tileset->GetImage()->GetHeight());
		printf("Image Source: %s\n", tileset->GetImage()->GetSource().c_str());
		if (!tileset->GetImage()->GetTransparentColor().empty())
			printf("Transparent Color (hex): %s\n",
				   tileset->GetImage()->GetTransparentColor().c_str());

		if (tileset->GetTiles().size() > 0)
		{
			// Get a tile from the tileset.
			const Tmx::Tile *tile = *(tileset->GetTiles().begin());

			// Print the properties of a tile.
			std::map<std::string, std::string> list =
				tile->GetProperties().GetList();
			std::map<std::string, std::string>::iterator iter;
			for (iter = list.begin(); iter != list.end(); ++iter)
			{
				printf("%s = %s\n", iter->first.c_str(), iter->second.c_str());
			}

			if (tile->IsAnimated())
			{
				printf(
					"Tile is animated: %d frames with total duration of %dms.\n",
					tile->GetFrameCount(), tile->GetTotalDuration());

				const std::vector<Tmx::AnimationFrame> &frames =
					tile->GetFrames();

				int i = 0;
				for (std::vector<Tmx::AnimationFrame>::const_iterator it =
					 frames.begin(); it != frames.end(); it++, i++)
				{
					printf("\tFrame %d: Tile ID = %d, Duration = %dms\n", i,
						   it->GetTileID(), it->GetDuration());
				}
			}

			if (tile->HasObjects())
			{
				printf(
					"Tile has objects.\n");


				// Iterate through all Collision objects in the tile.
				for (int j = 0; j < tile->GetNumObjects(); ++j)
				{
					// Get an object.
					const Tmx::Object *object = tile->GetObject(j);

					// Print information about the object.
					printf("Object Name: %s\n", object->GetName().c_str());
					printf("Object Position: (%03d, %03d)\n", object->GetX(),
						   object->GetY());
					printf("Object Size: (%03d, %03d)\n", object->GetWidth(),
						   object->GetHeight());

					// Print Polygon points.
					const Tmx::Polygon *polygon = object->GetPolygon();
					if (polygon != 0)
					{
						for (int i = 0; i < polygon->GetNumPoints(); i++)
						{
							const Tmx::Point &point = polygon->GetPoint(i);
							printf("Object Polygon: Point %d: (%f, %f)\n", i, point.x,
								   point.y);
						}
					}

					// Print Polyline points.
					const Tmx::Polyline *polyline = object->GetPolyline();
					if (polyline != 0)
					{
						for (int i = 0; i < polyline->GetNumPoints(); i++)
						{
							const Tmx::Point &point = polyline->GetPoint(i);
							printf("Object Polyline: Point %d: (%f, %f)\n", i, point.x,
								   point.y);
						}
					}
				}

			}
		}
	}

	// Iterate through the tile layers.
	for (int i = 0; i < map->GetNumTileLayers(); ++i)
	{
		printf("                                    \n");
		printf("====================================\n");
		printf("Layer : %02d/%s \n", i, map->GetTileLayer(i)->GetName().c_str());
		printf("====================================\n");

		// Get a layer.
		const Tmx::TileLayer *tileLayer = map->GetTileLayer(i);

		for (int y = 0; y < tileLayer->GetHeight(); ++y)
		{
			for (int x = 0; x < tileLayer->GetWidth(); ++x)
			{
				if (tileLayer->GetTileTilesetIndex(x, y) == -1)
				{
					printf("........    ");
				}
				else
				{
					// Get the tile's id and gid.
					printf("%03d(%03d)", tileLayer->GetTileId(x, y), tileLayer->GetTileGid(x, y));

					// Find a tileset for that id.
					//const Tmx::Tileset *tileset = map->FindTileset(layer->GetTileId(x, y));
					if (tileLayer->IsTileFlippedHorizontally(x, y))
					{
						printf("h");
					}
					else
					{
						printf(" ");
					}
					if (tileLayer->IsTileFlippedVertically(x, y))
					{
						printf("v");
					}
					else
					{
						printf(" ");
					}
					if (tileLayer->IsTileFlippedDiagonally(x, y))
					{
						printf("d ");
					}
					else
					{
						printf("  ");
					}
				}
			}

			printf("\n");
		}
	}

	printf("\n\n");

	// Iterate through all of the object groups.
	for (int i = 0; i < map->GetNumObjectGroups(); ++i)
	{
		printf("                                    \n");
		printf("====================================\n");
		printf("Object group : %02d\n", i);
		printf("====================================\n");

		// Get an object group.
		const Tmx::ObjectGroup *objectGroup = map->GetObjectGroup(i);

		// Iterate through all objects in the object group.
		for (int j = 0; j < objectGroup->GetNumObjects(); ++j)
		{
			// Get an object.
			const Tmx::Object *object = objectGroup->GetObject(j);

			// Print information about the object.
			printf("Object Name: %s\n", object->GetName().c_str());
			printf("Object Position: (%03d, %03d)\n", object->GetX(),
				   object->GetY());
			printf("Object Size: (%03d, %03d)\n", object->GetWidth(),
				   object->GetHeight());

			// Print Polygon points.
			const Tmx::Polygon *polygon = object->GetPolygon();
			if (polygon != 0)
			{
				for (int i = 0; i < polygon->GetNumPoints(); i++)
				{
					const Tmx::Point &point = polygon->GetPoint(i);
					printf("Object Polygon: Point %d: (%f, %f)\n", i, point.x,
						   point.y);
				}
			}

			// Print Polyline points.
			const Tmx::Polyline *polyline = object->GetPolyline();
			if (polyline != 0)
			{
				for (int i = 0; i < polyline->GetNumPoints(); i++)
				{
					const Tmx::Point &point = polyline->GetPoint(i);
					printf("Object Polyline: Point %d: (%f, %f)\n", i, point.x,
						   point.y);
				}
			}
		}
	}

	delete map;

	return 0;
}
Пример #6
0
std::unique_ptr<Map> MapLoader::Load(const std::string& path)
{
	Tmx::Map* map = new Tmx::Map();
	map->ParseFile(RESOURCE_FOLDER + path);

	auto ThrowError = [&]() {
		Logger::Log("Unable to load map: \"" + path + "\"", licesium::Logger::Error);
		throw map->GetErrorCode();
	};

	if (map->HasError() || map->GetOrientation() != Tmx::TMX_MO_ISOMETRIC)
	{
		ThrowError();
	}

	auto resultMap = std::unique_ptr<Map>(new Map(map->GetFilename()));

	size_t tileWidth = static_cast<size_t>(map->GetTileWidth());
	size_t tileHeight = static_cast<size_t>(map->GetTileHeight());
	float tileRatio = static_cast<float>(tileWidth) / static_cast<float>(tileHeight);

	resultMap->m_mapSize = sf::Vector2u(map->GetWidth(), map->GetHeight());
	resultMap->m_tileSize = sf::Vector2u(tileWidth, tileHeight);
	resultMap->m_tileRatio = tileRatio;
	resultMap->m_renderOrder = map->GetRenderOrder();
	
	for (int i = 0; i < map->GetNumTilesets(); ++i)
	{
		const Tmx::Tileset* tileset = map->GetTileset(i);

		std::unique_ptr<sf::Texture> tilesetTexture(new sf::Texture);
		if (!tilesetTexture->loadFromFile(RESOURCE_FOLDER + tileset->GetImage()->GetSource()))
		{
			ThrowError();
		}

		int spacing = tileset->GetSpacing();
		int margin = tileset->GetMargin();

		int columns = (tilesetTexture->getSize().x - 2u * margin + spacing) / (tileWidth + spacing);
		int rows = (tilesetTexture->getSize().y - 2u * margin + spacing) / (tileHeight + spacing);

		for (int y = 0; y < rows; y++)
		{
			for (int x = 0; x < columns; x++)
			{
				sf::IntRect rect;
				rect.top = y * (tileHeight + spacing);
				rect.top += margin;
				rect.height = tileHeight;
				rect.left = x * (tileWidth + spacing);
				rect.left += margin;
				rect.width = tileWidth;

				int id = resultMap->m_tileInfo.size();

				resultMap->m_tileInfo.push_back(licesium::Map::TileInfo(rect,
					sf::Vector2f(static_cast<float>(rect.width), static_cast<float>(rect.height)),
					static_cast<sf::Uint16>(resultMap->m_tilesetTextures.size() - 1u)));

				const Tmx::Tile* tile = tileset->GetTile(id);
				if (tile->IsAnimated())
				{
					auto& resultTile = resultMap->m_tileInfo.back();
					resultTile.animated = true;
					resultTile.animationDuration = static_cast<float>(tile->GetTotalDuration());
					
					const auto& frames = tile->GetFrames();
					for (const auto& frame : frames)
					{
						resultTile.frames.push_back(std::make_pair(frame.GetTileID(), static_cast<float>(frame.GetDuration())));
					}
				}
			}
		}

		resultMap->m_tilesetTextures.push_back(std::move(tilesetTexture));
	}

	for (int i = 0; i < map->GetNumTileLayers(); ++i)
	{
		const Tmx::TileLayer* tileLayer = map->GetTileLayer(i);

		MapLayer mapLayer;

		mapLayer.m_name = tileLayer->GetName();
		mapLayer.m_opacity = tileLayer->GetOpacity();
		mapLayer.m_visible = tileLayer->IsVisible();

		for (int y = 0; y < tileLayer->GetHeight(); ++y)
		{
			for (int x = 0; x < tileLayer->GetWidth(); ++x)
			{
				if (tileLayer->GetTileTilesetIndex(x, y) != -1)
				{
					sf::Uint8 opacity = static_cast<sf::Uint8>(255.f * tileLayer->GetOpacity());
					sf::Color color = sf::Color(255u, 255u, 255u, opacity);

					sf::Vertex v0, v1, v2, v3;

					unsigned int gid = tileLayer->GetTileGid(x, y) - 1;
					Map::TileInfo tileInfo = resultMap->m_tileInfo[gid];

					v0.texCoords = tileInfo.coords[0] + sf::Vector2f( 0.5f, 0.5f);
					v1.texCoords = tileInfo.coords[1] + sf::Vector2f(-0.5f, 0.5f);
					v2.texCoords = tileInfo.coords[2] + sf::Vector2f(-0.5f,-0.5f);
					v3.texCoords = tileInfo.coords[3] + sf::Vector2f( 0.5f,-0.5f);

					v0.position = sf::Vector2f(static_cast<float>(tileWidth * x), static_cast<float>(tileHeight * y));
					v1.position = sf::Vector2f(static_cast<float>(tileWidth * x) + tileInfo.size.x, static_cast<float>(tileHeight * y));
					v2.position = sf::Vector2f(static_cast<float>(tileWidth * x) + tileInfo.size.x, static_cast<float>(tileHeight * y) + tileInfo.size.y);
					v3.position = sf::Vector2f(static_cast<float>(tileWidth * x), static_cast<float>(tileHeight * y) + tileInfo.size.y);

					sf::Uint16 thisTileHeight = static_cast<sf::Uint16>(tileInfo.size.y);
					if (thisTileHeight != tileHeight)
					{
						float diff = static_cast<float>(tileHeight - thisTileHeight);
						v0.position.y += diff;
						v1.position.y += diff;
						v2.position.y += diff;
						v3.position.y += diff;
					}

					sf::Vector2f isoOffset(-static_cast<float>(x * (tileWidth / 2u)), static_cast<float>(x * (tileHeight / 2u)));
					isoOffset.x -= static_cast<float>(y * (tileWidth / 2u));
					isoOffset.y -= static_cast<float>(y * (tileHeight / 2u));
					isoOffset.x -= static_cast<float>(tileWidth / 2u);
					isoOffset.y += static_cast<float>(tileHeight / 2u);

					v0.position += isoOffset;
					v1.position += isoOffset;
					v2.position += isoOffset;
					v3.position += isoOffset;

					v0.color = color;
					v1.color = color;
					v2.color = color;
					v3.color = color;

					size_t id = tileInfo.tilesetID;
					if (mapLayer.m_layerSets.find(id) == mapLayer.m_layerSets.end())
					{
						mapLayer.m_layerSets.insert(std::make_pair(id, 
							std::make_shared<LayerSet>(*resultMap->m_tilesetTextures[id], 
														sf::Vector2u(map->GetWidth(), map->GetHeight()), 
														sf::Vector2u(tileWidth, tileHeight))));
					}

					mapLayer.m_layerSets[id]->AddTile(v0, v1, v2, v3, x, y, tileInfo.animated, gid);
				}
			}
		}

		resultMap->m_layers.push_back(mapLayer);
	}

	for (int i = 0; i < map->GetNumObjectGroups(); ++i)
	{
		const Tmx::ObjectGroup* objectgroup = map->GetObjectGroup(i);

		MapLayer objectLayer;
		objectLayer.m_name = objectgroup->GetName();
		objectLayer.m_opacity = objectgroup->GetOpacity();
		objectLayer.m_visible = objectgroup->IsVisible();

		for (int j = 0; j < objectgroup->GetNumObjects(); ++j)
		{
			const Tmx::Object* object = objectgroup->GetObject(j);

			MapObject resultObject;

			sf::Vector2f offset(0.0f, tileHeight / 2.0f);

			resultObject.m_position = resultMap->IsoToOrtho(static_cast<float>(object->GetX()), static_cast<float>(object->GetY())) + offset;

			if (object->GetWidth() && object->GetHeight())
			{
				float width = static_cast<float>(object->GetWidth());
				float height = static_cast<float>(object->GetHeight());
				sf::Vector2f size = sf::Vector2f(width, height);
				resultObject.m_size = size;

				const Tmx::Ellipse* ellipse = object->GetEllipse();
				if (ellipse)
				{
					const float x = size.x / 2.0f;
					const float y = size.y / 2.0f;
					const float tau = 6.283185f;
					const float step = tau / 16.0f; //number of points to make up ellipse
					for (float angle = 0.0f; angle < tau; angle += step)
					{
						sf::Vector2f point(x + x * cos(angle), y + y * sin(angle));
						resultObject.m_polypoints.push_back(resultMap->IsoToOrtho(point));
					}

					resultObject.m_shapeType = MapObject::Ellipse;
				}
				else if (object->GetGid()) {
					sf::Color color = sf::Color(255u, 255u, 255u, 255u);

					sf::Vertex v0, v1, v2, v3;

					unsigned int gid = object->GetGid() - 1;
					Map::TileInfo tileInfo = resultMap->m_tileInfo[gid];

					v0.texCoords = tileInfo.coords[0] + sf::Vector2f(0.5f, 0.5f);
					v1.texCoords = tileInfo.coords[1] + sf::Vector2f(-0.5f, 0.5f);
					v2.texCoords = tileInfo.coords[2] + sf::Vector2f(-0.5f, -0.5f);
					v3.texCoords = tileInfo.coords[3] + sf::Vector2f(0.5f, -0.5f);

					v0.position = sf::Vector2f();
					v1.position = sf::Vector2f(size.x, 0.0f);
					v2.position = sf::Vector2f(size.x, size.y);
					v3.position = sf::Vector2f(0.0f, size.y);

					resultObject.m_position += sf::Vector2f((tileWidth - size.x) / 2, (tileHeight - size.y)) - resultMap->IsoToOrtho(tileWidth / 2.0f, 0.0f) - offset;
					sf::Vector2f position = resultObject.m_position;

					v0.position += position;
					v1.position += position;
					v2.position += position;
					v3.position += position;

					v0.color = color;
					v1.color = color;
					v2.color = color;
					v3.color = color;

					size_t id = tileInfo.tilesetID;
					if (objectLayer.m_layerSets.find(id) == objectLayer.m_layerSets.end())
					{
						objectLayer.m_layerSets.insert(std::make_pair(id,
							std::make_shared<LayerSet>(*resultMap->m_tilesetTextures[id],
								sf::Vector2u(map->GetWidth(), map->GetHeight()),
								sf::Vector2u(tileWidth, tileHeight))));
					}

					const int x = static_cast<int>(object->GetX() / tileWidth);
					const int y = static_cast<int>(object->GetY() / tileHeight);
					objectLayer.m_layerSets[id]->AddTile(v0, v1, v2, v3, x, y, tileInfo.animated, gid);

					resultObject.m_polypoints.push_back((sf::Vector2f(0.0f, size.y / 2.0f)));
					resultObject.m_polypoints.push_back((sf::Vector2f(size.x / 2.0f, 0.0f)));
					resultObject.m_polypoints.push_back((sf::Vector2f(size.x, size.y / 2.0f)));
					resultObject.m_polypoints.push_back((sf::Vector2f(size.x / 2.0f, size.y)));

					resultObject.m_shapeType = MapObject::Tile;
				}
				else {
					resultObject.m_polypoints.push_back(resultMap->IsoToOrtho(sf::Vector2f()));
					resultObject.m_polypoints.push_back(resultMap->IsoToOrtho(sf::Vector2f(size.x, 0.0f)));
					resultObject.m_polypoints.push_back(resultMap->IsoToOrtho(sf::Vector2f(size.x, size.y)));
					resultObject.m_polypoints.push_back(resultMap->IsoToOrtho(sf::Vector2f(0.0f, size.y)));

					resultObject.m_shapeType = MapObject::Rectangle;
				}
			}
			else if (object->GetPolygon()) {
				const Tmx::Polygon* polygon = object->GetPolygon();

				for (int k = 0; k < polygon->GetNumPoints(); k++)
				{
					const Tmx::Point &point = polygon->GetPoint(k);

					resultObject.m_polypoints.push_back(resultMap->IsoToOrtho(static_cast<float>(point.x), static_cast<float>(point.y)));
				}

				resultObject.m_shapeType = MapObject::Polygon;
			}
			else if (object->GetPolyline()) {
				//TODO: load polyline

				resultObject.m_shapeType = MapObject::Polyline;
			}

			resultObject.m_name = object->GetName();
			resultObject.m_type = object->GetType();
			resultObject.m_visible = object->IsVisible();
			resultObject.CreateDebugShape(sf::Color::Red);
			resultObject.m_tileRatio = tileRatio;

			resultObject.m_properties = object->GetProperties().GetList();

			objectLayer.m_objects.push_back(std::make_shared<MapObject>(resultObject));
		}

		resultMap->m_layers.push_back(objectLayer);
	}

	delete map;
	return resultMap;
}