/// <summary> /// Converts a TiledMapSave to a ReducedTileMapInfo object /// </summary> /// <param name="tiledMapSave">The TiledMapSave to convert</param> /// <param name="scale">The amount to scale by - default of 1</param> /// <param name="zOffset">The zOffset</param> /// <param name="directory">The directory of the file associated with the tiledMapSave, used to find file references.</param> /// <param name="referenceType">How the files in the .tmx are referenced.</param> /// <returns></returns> public static ReducedTileMapInfo FromTiledMapSave(TiledMapSave tiledMapSave, float scale, float zOffset, string directory, FileReferenceType referenceType) { var toReturn = new ReducedTileMapInfo { NumberCellsTall = tiledMapSave.Height, NumberCellsWide = tiledMapSave.Width }; toReturn.CellHeightInPixels = (ushort)tiledMapSave.tileheight; toReturn.CellWidthInPixels = (ushort)tiledMapSave.tilewidth; toReturn.QuadHeight = tiledMapSave.tileheight; toReturn.QuadWidth = tiledMapSave.tilewidth; if (FastCreateFromTmx) { CreateFromTiledMapSave(tiledMapSave, directory, referenceType, toReturn); } else { // slow: CreateFromSpriteEditorScene(tiledMapSave, scale, zOffset, referenceType, toReturn); } return(toReturn); }
public static ReducedTileMapInfo ReadFrom(BinaryReader reader) { ReducedTileMapInfo toReturn = new ReducedTileMapInfo(); toReturn.VersionNumber = reader.ReadInt32(); toReturn.CellWidthInPixels = reader.ReadUInt16(); toReturn.CellHeightInPixels = reader.ReadUInt16(); toReturn.QuadHeight = reader.ReadSingle(); toReturn.QuadWidth = reader.ReadSingle(); toReturn.NumberOfLayers = reader.ReadUInt32(); for (int i = 0; i < toReturn.NumberOfLayers; i++) { toReturn.Layers.Add(ReducedLayerInfo.ReadFrom(reader, toReturn.VersionNumber)); } // Version 1: if (toReturn.VersionNumber > 0) { toReturn.NumberCellsWide = reader.ReadInt32(); toReturn.NumberCellsTall = reader.ReadInt32(); } return(toReturn); }
public static LayeredTileMap FromReducedTileMapInfo(TMXGlueLib.DataTypes.ReducedTileMapInfo rtmi, string contentManagerName, string tilbToLoad) { var toReturn = new LayeredTileMap(); string oldRelativeDirectory = FileManager.RelativeDirectory; FileManager.RelativeDirectory = FileManager.GetDirectory(tilbToLoad); MapDrawableBatch mdb; for (int i = 0; i < rtmi.Layers.Count; i++) { var reducedLayer = rtmi.Layers[i]; mdb = MapDrawableBatch.FromReducedLayer(reducedLayer, contentManagerName, rtmi.CellWidthInPixels, rtmi.CellHeightInPixels, rtmi.QuadWidth, rtmi.QuadHeight); mdb.AttachTo(toReturn, false); mdb.RelativeZ = reducedLayer.Z; toReturn.mMapLists.Add(mdb); } FileManager.RelativeDirectory = oldRelativeDirectory; return(toReturn); }
private static void SetQuadWidthAndHeight(ReducedTileMapInfo toReturn, SceneSave ses) { if (ses.SpriteList.Count != 0) { SpriteSave spriteSave = ses.SpriteList[0]; toReturn.QuadWidth = spriteSave.ScaleX * 2; toReturn.QuadHeight = spriteSave.ScaleY * 2; } }
public static ReducedTileMapInfo FromFile(string fileName) { ReducedTileMapInfo rtmi = null; using (Stream inputStream = FileManager.GetStreamForFile(fileName)) using (BinaryReader binaryReader = new BinaryReader(inputStream)) { rtmi = ReducedTileMapInfo.ReadFrom(binaryReader); } return(rtmi); }
public static ReducedTileMapInfo FromTiledMapSave(TiledMapSave tiledMapSave, float scale, string directory) { var toReturn = new ReducedTileMapInfo(); var ses = tiledMapSave.ToSceneSave(1); ses.SpriteList.Sort((first, second) => first.Z.CompareTo(second.Z)); float z = float.NaN; ReducedLayerInfo reducedLayerInfo = null; Dictionary<string, Point> loadedTextures = new Dictionary<string, Point>(); if (ses.SpriteList.Count != 0) { SpriteSave spriteSave = ses.SpriteList[0]; Point point = GetTextureDimensions(directory, loadedTextures, spriteSave); toReturn.CellHeightInPixels = (ushort)FlatRedBall.Math.MathFunctions.RoundToInt((spriteSave.BottomTextureCoordinate - spriteSave.TopTextureCoordinate) * point.Y); toReturn.CellWidthInPixels = (ushort)FlatRedBall.Math.MathFunctions.RoundToInt((spriteSave.RightTextureCoordinate - spriteSave.LeftTextureCoordinate) * point.X); toReturn.QuadWidth = spriteSave.ScaleX * 2; toReturn.QuadHeight = spriteSave.ScaleY * 2; } foreach (SpriteSave spriteSave in ses.SpriteList) { if (spriteSave.Z != z) { z = spriteSave.Z; reducedLayerInfo = new ReducedLayerInfo(); reducedLayerInfo.Texture = spriteSave.Texture; toReturn.Layers.Add(reducedLayerInfo); } Point point = GetTextureDimensions(directory, loadedTextures, spriteSave); ReducedQuadInfo quad = ReducedQuadInfo.FromSpriteSave(spriteSave, point.X, point.Y); reducedLayerInfo.Quads.Add(quad); } return toReturn; }
public static LayeredTileMap FromReducedTileMapInfo(TMXGlueLib.DataTypes.ReducedTileMapInfo rtmi, string contentManagerName, string tilbToLoad) { var toReturn = new LayeredTileMap(); string oldRelativeDirectory = FileManager.RelativeDirectory; FileManager.RelativeDirectory = FileManager.GetDirectory(tilbToLoad); MapDrawableBatch mdb; if (rtmi.NumberCellsWide != 0) { toReturn.mNumberTilesWide = rtmi.NumberCellsWide; } if (rtmi.NumberCellsTall != 0) { toReturn.mNumberTilesTall = rtmi.NumberCellsTall; } toReturn.mWidthPerTile = rtmi.QuadWidth; toReturn.mHeightPerTile = rtmi.QuadHeight; for (int i = 0; i < rtmi.Layers.Count; i++) { var reducedLayer = rtmi.Layers[i]; mdb = MapDrawableBatch.FromReducedLayer(reducedLayer, rtmi, contentManagerName); mdb.AttachTo(toReturn, false); mdb.RelativeZ = reducedLayer.Z; toReturn.mMapLists.Add(mdb); } FileManager.RelativeDirectory = oldRelativeDirectory; return(toReturn); }
public static ReducedTileMapInfo ReadFrom(BinaryReader reader) { ReducedTileMapInfo toReturn = new ReducedTileMapInfo(); toReturn.CellWidthInPixels = reader.ReadUInt16(); toReturn.CellHeightInPixels = reader.ReadUInt16(); toReturn.QuadHeight = reader.ReadSingle(); toReturn.QuadWidth = reader.ReadSingle(); toReturn.NumberOfLayers = reader.ReadUInt32(); for (int i = 0; i < toReturn.NumberOfLayers; i++) { toReturn.Layers.Add(ReducedLayerInfo.ReadFrom(reader)); } return toReturn; }
internal static MapDrawableBatch FromReducedLayer(TMXGlueLib.DataTypes.ReducedLayerInfo reducedLayerInfo, LayeredTileMap owner, TMXGlueLib.DataTypes.ReducedTileMapInfo rtmi, string contentManagerName) { int tileDimensionWidth = reducedLayerInfo.TileWidth; int tileDimensionHeight = reducedLayerInfo.TileHeight; float quadWidth = reducedLayerInfo.TileWidth; float quadHeight = reducedLayerInfo.TileHeight; string textureName = reducedLayerInfo.Texture; #if IOS || ANDROID textureName = textureName.ToLowerInvariant(); #endif Texture2D texture = FlatRedBallServices.Load <Texture2D>(textureName, contentManagerName); MapDrawableBatch toReturn = new MapDrawableBatch(reducedLayerInfo.Quads.Count, tileDimensionWidth, tileDimensionHeight, texture); toReturn.Name = reducedLayerInfo.Name; Vector3 position = new Vector3(); Vector2 tileDimensions = new Vector2(quadWidth, quadHeight); IEnumerable <TMXGlueLib.DataTypes.ReducedQuadInfo> quads = null; if (rtmi.NumberCellsWide > rtmi.NumberCellsTall) { quads = reducedLayerInfo.Quads.OrderBy(item => item.LeftQuadCoordinate).ToList(); toReturn.mSortAxis = SortAxis.X; } else { quads = reducedLayerInfo.Quads.OrderBy(item => item.BottomQuadCoordinate).ToList(); toReturn.mSortAxis = SortAxis.Y; } foreach (var quad in quads) { position.X = quad.LeftQuadCoordinate; position.Y = quad.BottomQuadCoordinate; // The Z of the quad should be relative to this layer, not absolute Z values. // A multi-layer map will offset the individual layer Z values, the quads should have a Z of 0. // position.Z = reducedLayerInfo.Z; var textureValues = new Vector4(); // The purpose of CoordinateAdjustment is to bring the texture values "in", to reduce the chance of adjacent // tiles drawing on a given tile quad. If we don't do this, we can get slivers of adjacent colors appearing, causing // lines or grid patterns. // To bring the values "in" we have to consider rotated quads. textureValues.X = CoordinateAdjustment + (float)quad.LeftTexturePixel / (float)texture.Width; // Left textureValues.Y = -CoordinateAdjustment + (float)(quad.LeftTexturePixel + tileDimensionWidth) / (float)texture.Width; // Right textureValues.Z = CoordinateAdjustment + (float)quad.TopTexturePixel / (float)texture.Height; // Top textureValues.W = -CoordinateAdjustment + (float)(quad.TopTexturePixel + tileDimensionHeight) / (float)texture.Height; // Bottom // pad before doing any rotations/flipping const bool pad = true; if (pad) { const float amountToAdd = .0000001f; textureValues.X += amountToAdd; // Left textureValues.Y -= amountToAdd; // Right textureValues.Z += amountToAdd; // Top textureValues.W -= amountToAdd; // Bottom } if ((quad.FlipFlags & TMXGlueLib.DataTypes.ReducedQuadInfo.FlippedHorizontallyFlag) == TMXGlueLib.DataTypes.ReducedQuadInfo.FlippedHorizontallyFlag) { var temp = textureValues.Y; textureValues.Y = textureValues.X; textureValues.X = temp; } if ((quad.FlipFlags & TMXGlueLib.DataTypes.ReducedQuadInfo.FlippedVerticallyFlag) == TMXGlueLib.DataTypes.ReducedQuadInfo.FlippedVerticallyFlag) { var temp = textureValues.Z; textureValues.Z = textureValues.W; textureValues.W = temp; } int tileIndex = toReturn.AddTile(position, tileDimensions, //quad.LeftTexturePixel, quad.TopTexturePixel, quad.LeftTexturePixel + tileDimensionWidth, quad.TopTexturePixel + tileDimensionHeight); textureValues); if ((quad.FlipFlags & TMXGlueLib.DataTypes.ReducedQuadInfo.FlippedDiagonallyFlag) == TMXGlueLib.DataTypes.ReducedQuadInfo.FlippedDiagonallyFlag) { toReturn.ApplyDiagonalFlip(tileIndex); } // This was moved to outside of this conversion, to support shaps //if (quad.QuadSpecificProperties != null) //{ // var listToAdd = quad.QuadSpecificProperties.ToList(); // listToAdd.Add(new NamedValue { Name = "Name", Value = quad.Name }); // owner.Properties.Add(quad.Name, listToAdd); //} if (quad.RotationDegrees != 0) { // Tiled rotates clockwise :( var rotationRadians = -MathHelper.ToRadians(quad.RotationDegrees); Vector3 bottomLeftPos = toReturn.Vertices[tileIndex * 4].Position; Vector3 vertPos = toReturn.Vertices[tileIndex * 4 + 1].Position; MathFunctions.RotatePointAroundPoint(bottomLeftPos, ref vertPos, rotationRadians); toReturn.Vertices[tileIndex * 4 + 1].Position = vertPos; vertPos = toReturn.Vertices[tileIndex * 4 + 2].Position; MathFunctions.RotatePointAroundPoint(bottomLeftPos, ref vertPos, rotationRadians); toReturn.Vertices[tileIndex * 4 + 2].Position = vertPos; vertPos = toReturn.Vertices[tileIndex * 4 + 3].Position; MathFunctions.RotatePointAroundPoint(bottomLeftPos, ref vertPos, rotationRadians); toReturn.Vertices[tileIndex * 4 + 3].Position = vertPos; } toReturn.RegisterName(quad.Name, tileIndex); } return(toReturn); }
private static void CreateFromTiledMapSave(TiledMapSave tiledMapSave, string directory, FileReferenceType referenceType, ReducedTileMapInfo reducedTileMapInfo) { ReducedLayerInfo reducedLayerInfo = null; for (int i = 0; i < tiledMapSave.MapLayers.Count; i++) { var tiledLayer = tiledMapSave.MapLayers[i]; string texture = null; uint tileIdOfTexture = 0; Tileset tileSet = null; uint? firstGid = null; if (tiledLayer is MapLayer) { var mapLayer = tiledLayer as MapLayer; if (mapLayer.data.Length != 0) { firstGid = mapLayer.data[0].tiles.FirstOrDefault(item => item != 0); } } else { var objectLayer = tiledLayer as mapObjectgroup; var firstObjectWithTexture = objectLayer.@object?.FirstOrDefault(item => item.gid != 0); firstGid = firstObjectWithTexture?.gid; } if (firstGid > 0) { tileSet = tiledMapSave.GetTilesetForGid(firstGid.Value); if (tileSet != null) { if (referenceType == FileReferenceType.NoDirectory) { texture = tileSet.Images[0].sourceFileName; } else if (referenceType == FileReferenceType.Absolute) { if (!string.IsNullOrEmpty(tileSet.SourceDirectory) && tileSet.SourceDirectory != ".") { directory += tileSet.SourceDirectory; directory = FlatRedBall.IO.FileManager.RemoveDotDotSlash(directory); } texture = FlatRedBall.IO.FileManager.RemoveDotDotSlash(directory + tileSet.Images[0].Source); } else { throw new NotImplementedException(); } } int tileWidth = FlatRedBall.Math.MathFunctions.RoundToInt(tiledMapSave.tilewidth); int tileHeight = FlatRedBall.Math.MathFunctions.RoundToInt(tiledMapSave.tileheight); reducedLayerInfo = new ReducedLayerInfo { Z = i, Texture = texture, Name = tiledLayer.Name, TileWidth = tileWidth, TileHeight = tileHeight, }; reducedTileMapInfo.Layers.Add(reducedLayerInfo); var tilesetIndex = tiledMapSave.Tilesets.IndexOf(tileSet); reducedLayerInfo.TextureId = tilesetIndex; // create the quad here: if (tiledLayer is MapLayer) { AddTileLayerTiles(tiledMapSave, reducedLayerInfo, i, tiledLayer, tileSet, tileWidth, tileHeight); } else if (tiledLayer is mapObjectgroup) { AddObjectLayerTiles(reducedLayerInfo, tiledLayer, tileSet, firstGid, tileWidth, tileHeight); } } } }
private static void CreateFromSpriteEditorScene(TiledMapSave tiledMapSave, float scale, float zOffset, FileReferenceType referenceType, ReducedTileMapInfo toReturn) { var ses = tiledMapSave.ToSceneSave(scale, referenceType); // This is not a stable sort! //ses.SpriteList.Sort((first, second) => first.Z.CompareTo(second.Z)); ses.SpriteList = ses.SpriteList.OrderBy(item => item.Z).ToList(); ReducedLayerInfo reducedLayerInfo = null; float z = float.NaN; int textureWidth = 0; int textureHeight = 0; AbstractMapLayer currentLayer = null; int indexInLayer = 0; foreach (var spriteSave in ses.SpriteList) { if (spriteSave.Z != z) { indexInLayer = 0; z = spriteSave.Z; int layerIndex = FlatRedBall.Math.MathFunctions.RoundToInt(z - zOffset); var abstractMapLayer = tiledMapSave.MapLayers[layerIndex]; currentLayer = abstractMapLayer; reducedLayerInfo = new ReducedLayerInfo { Z = spriteSave.Z, Texture = spriteSave.Texture, Name = abstractMapLayer.Name, TileWidth = FlatRedBall.Math.MathFunctions.RoundToInt(spriteSave.ScaleX * 2), TileHeight = FlatRedBall.Math.MathFunctions.RoundToInt(spriteSave.ScaleY * 2) }; var mapLayer = abstractMapLayer as MapLayer; // This should have data: if (mapLayer != null) { var idOfTexture = mapLayer.data[0].tiles.FirstOrDefault(item => item != 0); Tileset tileSet = tiledMapSave.GetTilesetForGid(idOfTexture); var tilesetIndex = tiledMapSave.Tilesets.IndexOf(tileSet); textureWidth = tileSet.Images[0].width; textureHeight = tileSet.Images[0].height; reducedLayerInfo.TextureId = tilesetIndex; toReturn.Layers.Add(reducedLayerInfo); } var objectGroup = tiledMapSave.MapLayers[layerIndex] as mapObjectgroup; // This code only works based on the assumption that only one tileset will be used in any given object layer's image objects var mapObjectgroupObject = [email protected](o => o.gid != null); if (mapObjectgroupObject?.gid != null) { var idOfTexture = mapObjectgroupObject.gid.Value; Tileset tileSet = tiledMapSave.GetTilesetForGid(idOfTexture); var tilesetIndex = tiledMapSave.Tilesets.IndexOf(tileSet); textureWidth = tileSet.Images[0].width; textureHeight = tileSet.Images[0].height; reducedLayerInfo.TextureId = tilesetIndex; toReturn.Layers.Add(reducedLayerInfo); } } ReducedQuadInfo quad = ReducedQuadInfo.FromSpriteSave(spriteSave, textureWidth, textureHeight); if (currentLayer is mapObjectgroup) { var asMapObjectGroup = currentLayer as mapObjectgroup; var objectInstance = asMapObjectGroup.@object[indexInLayer]; // skip over any non-sprite objects: while (objectInstance.gid == null) { indexInLayer++; if (indexInLayer >= [email protected]) { objectInstance = null; break; } else { objectInstance = asMapObjectGroup.@object[indexInLayer]; } } if (objectInstance != null && objectInstance.properties.Count != 0) { var nameProperty = objectInstance.properties.FirstOrDefault(item => item.StrippedNameLower == "name"); if (nameProperty != null) { quad.Name = nameProperty.value; } else { quad.Name = spriteSave.Name; bool needsName = string.IsNullOrEmpty(spriteSave.Name); if (needsName) { quad.Name = $"_{currentLayer.Name}runtime{indexInLayer}"; } } List <NamedValue> list = new List <NamedValue>(); foreach (var property in objectInstance.properties) { list.Add( new NamedValue { Name = property.StrippedName, Value = property.value, Type = property.Type } ); } quad.QuadSpecificProperties = list; } } reducedLayerInfo?.Quads.Add(quad); indexInLayer++; } }
private void Verify(ReducedTileMapInfo rtmi, string fileName) { using(FileStream stream = File.OpenRead(fileName)) using(BinaryReader reader = new BinaryReader(stream)) { ReducedTileMapInfo compareAgainst = ReducedTileMapInfo.ReadFrom(reader); string original; string fromFile; FileManager.XmlSerialize(rtmi, out original); FileManager.XmlSerialize(compareAgainst, out fromFile); if (original != fromFile) { throw new Exception("NONONO"); } } }
/// <summary> /// Converts a TiledMapSave to a ReducedTileMapInfo object /// </summary> /// <param name="tiledMapSave">The TiledMapSave to convert</param> /// <param name="scale">The amount to scale by - default of 1</param> /// <param name="zOffset">The zOffset</param> /// <param name="directory">The directory of the file associated with the tiledMapSave, used to find file references.</param> /// <param name="referenceType">How the files in the .tmx are referenced.</param> /// <returns></returns> public static ReducedTileMapInfo FromTiledMapSave(TiledMapSave tiledMapSave, float scale, float zOffset, string directory, FileReferenceType referenceType) { var toReturn = new ReducedTileMapInfo { NumberCellsTall = tiledMapSave.Height, NumberCellsWide = tiledMapSave.Width }; var ses = tiledMapSave.ToSceneSave(scale, referenceType); // This is not a stable sort! //ses.SpriteList.Sort((first, second) => first.Z.CompareTo(second.Z)); ses.SpriteList = ses.SpriteList.OrderBy(item => item.Z).ToList(); ReducedLayerInfo reducedLayerInfo = null; // If we rely on the image, it's both slow (have to open the images), and // doesn't work at runtime in games: //Dictionary<string, Point> loadedTextures = new Dictionary<string, Point>(); //SetCellWidthAndHeight(tiledMapSave, directory, toReturn, ses, loadedTextures); toReturn.CellHeightInPixels = (ushort)tiledMapSave.tileheight; toReturn.CellWidthInPixels = (ushort)tiledMapSave.tilewidth; SetQuadWidthAndHeight(toReturn, ses); float z = float.NaN; int textureWidth = 0; int textureHeight = 0; AbstractMapLayer currentLayer = null; int indexInLayer = 0; foreach (var spriteSave in ses.SpriteList) { if (spriteSave.Z != z) { indexInLayer = 0; z = spriteSave.Z; int layerIndex = FlatRedBall.Math.MathFunctions.RoundToInt(z - zOffset); var abstractMapLayer = tiledMapSave.MapLayers[layerIndex]; currentLayer = abstractMapLayer; reducedLayerInfo = new ReducedLayerInfo { Z = spriteSave.Z, Texture = spriteSave.Texture, Name = abstractMapLayer.Name, TileWidth = FlatRedBall.Math.MathFunctions.RoundToInt(spriteSave.ScaleX * 2), TileHeight = FlatRedBall.Math.MathFunctions.RoundToInt(spriteSave.ScaleY * 2) }; var mapLayer = abstractMapLayer as MapLayer; // This should have data: if (mapLayer != null) { var idOfTexture = mapLayer.data[0].tiles.FirstOrDefault(item => item != 0); Tileset tileSet = tiledMapSave.GetTilesetForGid(idOfTexture); var tilesetIndex = tiledMapSave.Tilesets.IndexOf(tileSet); textureWidth = tileSet.Images[0].width; textureHeight = tileSet.Images[0].height; reducedLayerInfo.TextureId = tilesetIndex; toReturn.Layers.Add(reducedLayerInfo); } var objectGroup = tiledMapSave.MapLayers[layerIndex] as mapObjectgroup; // This code only works based on the assumption that only one tileset will be used in any given object layer's image objects var mapObjectgroupObject = [email protected](o => o.gid != null); if (mapObjectgroupObject?.gid != null) { var idOfTexture = mapObjectgroupObject.gid.Value; Tileset tileSet = tiledMapSave.GetTilesetForGid(idOfTexture); var tilesetIndex = tiledMapSave.Tilesets.IndexOf(tileSet); textureWidth = tileSet.Images[0].width; textureHeight = tileSet.Images[0].height; reducedLayerInfo.TextureId = tilesetIndex; toReturn.Layers.Add(reducedLayerInfo); } } ReducedQuadInfo quad = ReducedQuadInfo.FromSpriteSave(spriteSave, textureWidth, textureHeight); if (currentLayer is mapObjectgroup) { var objectInstance = (currentLayer as mapObjectgroup).@object[indexInLayer]; if (objectInstance.properties.Count != 0) { var nameProperty = objectInstance.properties.FirstOrDefault(item => item.StrippedNameLower == "name"); if (nameProperty != null) { quad.Name = nameProperty.value; } else { quad.Name = spriteSave.Name; bool needsName = string.IsNullOrEmpty(spriteSave.Name); if (needsName) { quad.Name = $"_{currentLayer.Name}runtime{indexInLayer}"; } } List<NamedValue> list = new List<NamedValue>(); foreach (var property in objectInstance.properties) { list.Add( new NamedValue { Name = property.StrippedName, Value = property.value, Type = property.Type } ); } quad.QuadSpecificProperties = list; } } reducedLayerInfo?.Quads.Add(quad); indexInLayer++; } return toReturn; }
private static void SetQuadWidthAndHeight(ReducedTileMapInfo toReturn, SceneSave ses) { if (ses.SpriteList.Count != 0) { SpriteSave spriteSave = ses.SpriteList[0]; toReturn.QuadWidth = spriteSave.ScaleX * 2; toReturn.QuadHeight = spriteSave.ScaleY * 2; } }
private static void CreateFromTiledMapSave(TiledMapSave tiledMapSave, string tmxDirectory, FileReferenceType referenceType, ReducedTileMapInfo reducedTileMapInfo) { ReducedLayerInfo reducedLayerInfo = null; var allLayers = GetAllMapLayers(tiledMapSave); for (int i = 0; i < allLayers.Count; i++) { string directory = tmxDirectory; var tiledLayer = allLayers[i]; string texture = null; uint tileIdOfTexture = 0; Tileset tileSet = null; uint? firstGid = null; if (tiledLayer is MapLayer) { var mapLayer = tiledLayer as MapLayer; if (mapLayer.data.Length != 0) { firstGid = mapLayer.data[0].tiles.FirstOrDefault(item => item != 0); } } else if (tiledLayer is mapObjectgroup) { var objectLayer = tiledLayer as mapObjectgroup; //The first element on the list might have null as a gid (it could be a shape) //so we should use ">" instead of "!=" to avoid ignoring the rest of the list var firstObjectWithTexture = objectLayer.@object?.FirstOrDefault(item => item.gid > 0); firstGid = firstObjectWithTexture?.gid; } else { //Image layers and any other future layer types in Tiled are not supported at //this time. Just move onto the next layer and ignore this one. continue; } if (firstGid > 0) { tileSet = tiledMapSave.GetTilesetForGid(firstGid.Value); if (tileSet != null) { if (referenceType == FileReferenceType.NoDirectory) { texture = tileSet.Images[0].sourceFileName; } else if (referenceType == FileReferenceType.Absolute) { if (!string.IsNullOrEmpty(tileSet.SourceDirectory) && tileSet.SourceDirectory != ".") { directory += tileSet.SourceDirectory; directory = FlatRedBall.IO.FileManager.RemoveDotDotSlash(directory); } texture = FlatRedBall.IO.FileManager.RemoveDotDotSlash(directory + tileSet.Images[0].Source); } else { throw new NotImplementedException(); } } } int tileWidth = FlatRedBall.Math.MathFunctions.RoundToInt(tiledMapSave.tilewidth); int tileHeight = FlatRedBall.Math.MathFunctions.RoundToInt(tiledMapSave.tileheight); reducedLayerInfo = new ReducedLayerInfo { Z = i, Texture = texture, Name = tiledLayer.Name, TileWidth = tileWidth, TileHeight = tileHeight, ParallaxMultiplierX = tiledLayer.ParallaxX, ParallaxMultiplierY = tiledLayer.ParallaxY, }; reducedTileMapInfo.Layers.Add(reducedLayerInfo); var tilesetIndex = tiledMapSave.Tilesets.IndexOf(tileSet); reducedLayerInfo.TextureId = tilesetIndex; // create the quad here: if (tiledLayer is MapLayer) { AddTileLayerTiles(tiledMapSave, reducedLayerInfo, i, tiledLayer, tileSet, tileWidth, tileHeight); } else if (tiledLayer is mapObjectgroup) { AddObjectLayerTiles(reducedLayerInfo, tiledLayer, tileSet, firstGid, tileWidth, tileHeight); } } }
/// <summary> /// Converts a TiledMapSave to a ReducedTileMapInfo object /// </summary> /// <param name="tiledMapSave">The TiledMapSave to convert</param> /// <param name="scale">The amount to scale by - default of 1</param> /// <param name="zOffset">The zOffset</param> /// <param name="directory">The directory of the file associated with the tiledMapSave, used to find file references.</param> /// <param name="referenceType">How the files in the .tmx are referenced.</param> /// <returns></returns> public static ReducedTileMapInfo FromTiledMapSave(TiledMapSave tiledMapSave, float scale, float zOffset, string directory, FileReferenceType referenceType) { var toReturn = new ReducedTileMapInfo(); toReturn.NumberCellsTall = tiledMapSave.Height; toReturn.NumberCellsWide = tiledMapSave.Width; var ses = tiledMapSave.ToSceneSave(scale, referenceType); ses.SpriteList.Sort((first, second) => first.Z.CompareTo(second.Z)); ReducedLayerInfo reducedLayerInfo = null; // If we rely on the image, it's both slow (have to open the images), and // doesn't work at runtime in games: //Dictionary<string, Point> loadedTextures = new Dictionary<string, Point>(); //SetCellWidthAndHeight(tiledMapSave, directory, toReturn, ses, loadedTextures); toReturn.CellHeightInPixels = (ushort)tiledMapSave.tileheight; toReturn.CellWidthInPixels = (ushort)tiledMapSave.tilewidth; SetQuadWidthAndHeight(toReturn, ses); float z = float.NaN; int textureWidth = 0; int textureHeight = 0; for (int i = 0; i < ses.SpriteList.Count; i++) { SpriteSave spriteSave = ses.SpriteList[i]; if (spriteSave.Z != z) { z = spriteSave.Z; reducedLayerInfo = new ReducedLayerInfo(); reducedLayerInfo.Z = spriteSave.Z; reducedLayerInfo.Texture = spriteSave.Texture; int layerIndex = FlatRedBall.Math.MathFunctions.RoundToInt(z - zOffset); var mapLayer = tiledMapSave.Layers[layerIndex]; // This should have data: var idOfTexture = mapLayer.data[0].tiles.FirstOrDefault(item => item != 0); Tileset tileSet = tiledMapSave.GetTilesetForGid(idOfTexture); var tilesetIndex = tiledMapSave.Tilesets.IndexOf(tileSet); textureWidth = tileSet.Images[0].width; textureHeight = tileSet.Images[0].height; reducedLayerInfo.Name = mapLayer.Name; reducedLayerInfo.TextureId = tilesetIndex; toReturn.Layers.Add(reducedLayerInfo); } ReducedQuadInfo quad = ReducedQuadInfo.FromSpriteSave(spriteSave, textureWidth, textureHeight); reducedLayerInfo.Quads.Add(quad); } return(toReturn); }