Пример #1
0
        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);
        }
Пример #2
0
        public static ReducedLayerInfo ReadFrom(BinaryReader reader, int version)
        {
            ReducedLayerInfo toReturn = new ReducedLayerInfo();

            toReturn.Z = reader.ReadSingle();

            toReturn.Texture = reader.ReadString();

            toReturn.Name = reader.ReadString();

            toReturn.NumberOfQuads = reader.ReadUInt32();

            for (int i = 0; i < toReturn.NumberOfQuads; i++)
            {
                toReturn.Quads.Add(ReducedQuadInfo.ReadFrom(reader));
            }

            if (version >= 2)
            {
                toReturn.TextureId = reader.ReadInt32();
            }

            if (version >= 3)
            {
                toReturn.ParallaxMultiplierX = reader.ReadSingle();
                toReturn.ParallaxMultiplierY = reader.ReadSingle();

                toReturn.CameraOffsetX = reader.ReadSingle();
                toReturn.CameraOffsetY = reader.ReadSingle();
            }

            return(toReturn);
        }
        public static ReducedLayerInfo ReadFrom(BinaryReader reader)
        {
            ReducedLayerInfo toReturn = new ReducedLayerInfo();

            toReturn.Texture = reader.ReadString();
            toReturn.NumberOfQuads = reader.ReadUInt32();

            for(int i = 0; i < toReturn.NumberOfQuads; i++)
            {
                toReturn.Quads.Add( ReducedQuadInfo.ReadFrom(reader));
            }

            return toReturn;
        }
Пример #4
0
        private static void AddObjectLayerTiles(ReducedLayerInfo reducedLayerInfo, AbstractMapLayer tiledLayer, Tileset tileSet, uint?gid, int tileWidth, int tileHeight)
        {
            var asMapLayer = tiledLayer as mapObjectgroup;

            // early out
            if (asMapLayer.@object == null)
            {
                return;
            }

            foreach (var objectInstance in asMapLayer.@object)
            {
                if (objectInstance.gid > 0)
                {
                    ReducedQuadInfo quad = new DataTypes.ReducedQuadInfo();

                    quad.LeftQuadCoordinate   = (float)objectInstance.x;
                    quad.BottomQuadCoordinate = (float)-objectInstance.y;

                    quad.OverridingWidth  = objectInstance.width;
                    quad.OverridingHeight = objectInstance.height;

                    quad.RotationDegrees = (float)objectInstance.Rotation;

                    quad.FlipFlags = (byte)(gid.Value & 0xf0000000 >> 7);

                    var valueWithoutFlip = gid.Value & 0x0fffffff;

                    int leftPixelCoord;
                    int topPixelCoord;
                    int rightPixelCoord;
                    int bottomPixelCoord;
                    TiledMapSave.GetPixelCoordinatesFromGid(gid.Value, tileSet,
                                                            out leftPixelCoord, out topPixelCoord, out rightPixelCoord, out bottomPixelCoord);

                    quad.LeftTexturePixel = (ushort)Math.Min(leftPixelCoord, rightPixelCoord);
                    quad.TopTexturePixel  = (ushort)Math.Min(topPixelCoord, bottomPixelCoord);

                    quad.Name = objectInstance.Name;
                    if (string.IsNullOrEmpty(quad.Name))
                    {
                        var prop = quad.QuadSpecificProperties.FirstOrDefault(quadProp => quadProp.Name.ToLowerInvariant() == "name");
                        quad.Name = (string)prop.Value;
                    }

                    reducedLayerInfo?.Quads.Add(quad);
                }
            }
        }
        public static ReducedLayerInfo ReadFrom(BinaryReader reader)
        {
            ReducedLayerInfo toReturn = new ReducedLayerInfo();


            toReturn.Texture       = reader.ReadString();
            toReturn.NumberOfQuads = reader.ReadUInt32();

            for (int i = 0; i < toReturn.NumberOfQuads; i++)
            {
                toReturn.Quads.Add(ReducedQuadInfo.ReadFrom(reader));
            }

            return(toReturn);
        }
        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;
        }
Пример #7
0
        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 static void AddTileLayerTiles(TiledMapSave tiledMapSave, ReducedLayerInfo reducedLayerInfo, int i, AbstractMapLayer tiledLayer, Tileset tileSet, int tileWidth, int tileHeight)
        {
            var asMapLayer = tiledLayer as MapLayer;
            var count      = asMapLayer.data[0].tiles.Count;

            for (int dataId = 0; dataId < count; dataId++)
            {
                var dataAtIndex = asMapLayer.data[0].tiles[dataId];

                if (dataAtIndex != 0)
                {
                    ReducedQuadInfo quad = new DataTypes.ReducedQuadInfo();

                    float tileCenterX;
                    float tileCenterY;
                    float tileZ;

                    tiledMapSave.CalculateWorldCoordinates(i, dataId, tileWidth, tileHeight, asMapLayer.width,
                                                           out tileCenterX, out tileCenterY, out tileZ);

                    quad.LeftQuadCoordinate   = tileCenterX - tileWidth / 2.0f;
                    quad.BottomQuadCoordinate = tileCenterY - tileHeight / 2.0f;

                    var gid = dataAtIndex;

                    //quad.FlipFlags = (byte)((gid & 0xf0000000) >> 28);

                    var valueWithoutFlip = gid & 0x0fffffff;

                    spriteSaveForConversion.RotationZ      = 0;
                    spriteSaveForConversion.FlipHorizontal = false;
                    TiledMapSave.SetSpriteTextureCoordinates(gid, spriteSaveForConversion, tileSet, tiledMapSave.orientation);


                    bool isRotated = spriteSaveForConversion.RotationZ != 0;
                    if (isRotated)
                    {
                        quad.FlipFlags = (byte)(quad.FlipFlags | ReducedQuadInfo.FlippedDiagonallyFlag);
                    }

                    var leftTextureCoordinate = System.Math.Min(spriteSaveForConversion.LeftTextureCoordinate, spriteSaveForConversion.RightTextureCoordinate);
                    var topTextureCoordinate  = System.Math.Min(spriteSaveForConversion.TopTextureCoordinate, spriteSaveForConversion.BottomTextureCoordinate);

                    if (spriteSaveForConversion.LeftTextureCoordinate > spriteSaveForConversion.RightTextureCoordinate)
                    {
                        quad.FlipFlags = (byte)(quad.FlipFlags | ReducedQuadInfo.FlippedHorizontallyFlag);
                    }

                    if (spriteSaveForConversion.TopTextureCoordinate > spriteSaveForConversion.BottomTextureCoordinate)
                    {
                        quad.FlipFlags = (byte)(quad.FlipFlags | ReducedQuadInfo.FlippedVerticallyFlag);
                    }

                    quad.LeftTexturePixel = (ushort)FlatRedBall.Math.MathFunctions.RoundToInt(leftTextureCoordinate * tileSet.Images[0].width);
                    quad.TopTexturePixel  = (ushort)FlatRedBall.Math.MathFunctions.RoundToInt(topTextureCoordinate * tileSet.Images[0].height);


                    if (tileSet.TileDictionary.ContainsKey(valueWithoutFlip - tileSet.Firstgid))
                    {
                        var dictionary = tileSet.TileDictionary[valueWithoutFlip - tileSet.Firstgid].PropertyDictionary;
                        if (dictionary.ContainsKey("name"))
                        {
                            quad.Name = tileSet.TileDictionary[valueWithoutFlip - tileSet.Firstgid].PropertyDictionary["name"];
                        }
                        else if (dictionary.ContainsKey("Name"))
                        {
                            quad.Name = tileSet.TileDictionary[valueWithoutFlip - tileSet.Firstgid].PropertyDictionary["Name"];
                        }
                    }

                    reducedLayerInfo?.Quads.Add(quad);
                }
            }
        }
        /// <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;



        }
Пример #12
0
        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);
        }