Ejemplo n.º 1
0
        public override TiledMap Process(TmxMap input, ContentProcessorContext context)
        {
            foreach (var tileSet in input.TileSets)
            {
                if (tileSet.Image == null)
                {
                    var images = new HashSet <string>();
                    foreach (var tile in tileSet.Tiles)
                    {
                        if (tile.Image != null)
                        {
                            images.Add(tile.Image.Source);
                        }
                    }

                    context.Logger.LogMessage("Packing {0} images\n", images.Count);

                    var bitmaps = new Dictionary <string, Bitmap>();
                    foreach (var image in images)
                    {
                        bitmaps.Add(image, new Bitmap(image));
                    }

                    var packedSprites = TextureAtlasPacker.PackSprites(bitmaps.Values.ToList());

                    var atlasPath = input.OriginalFileName + "-atlas.png";

                    packedSprites.OutputBitmap.Save(atlasPath, System.Drawing.Imaging.ImageFormat.Png);

                    var assetFileName = context.BuildAsset <string, Texture2DContent>(
                        new ExternalReference <string>(atlasPath),
                        nameof(TextureProcessor)).Filename;

                    tileSet.Image = new TmxImage
                    {
                        Source = ImportPathHelper.GetAssetName(context.OutputDirectory, assetFileName)
                    };

                    File.Delete(atlasPath);

                    foreach (var tile in tileSet.Tiles)
                    {
                        if (tile.Image == null)
                        {
                            continue;
                        }

                        var rect = packedSprites.SpritePositions[bitmaps[tile.Image.Source]];
                        tile.SourceRect = new Rectangle(rect.X, rect.Y, rect.Width, rect.Height);
                    }
                }
                else
                {
                    var assetFileName = context.BuildAsset <string, Texture2DContent>(
                        new ExternalReference <string>(tileSet.Image.Source),
                        nameof(TextureProcessor)).Filename;

                    tileSet.Image.Source = ImportPathHelper.GetAssetName(context.OutputDirectory, assetFileName);
                }
            }

            foreach (var layer in input.Layers.OfType <TmxImageLayer>())
            {
                if (layer.Image != null)
                {
                    var assetFileName = context.BuildAsset <string, Texture2DContent>(
                        new ExternalReference <string>(layer.Image.Source),
                        nameof(TextureProcessor)).Filename;
                    layer.Image.Source = ImportPathHelper.GetAssetName(context.OutputDirectory, assetFileName);
                }
            }

            var output = new TiledMap
            {
                FirstGid        = input.FirstGid,
                Width           = input.Width,
                Height          = input.Height,
                TileWidth       = input.TileWidth,
                TileHeight      = input.TileHeight,
                Orientation     = (TiledMapOrientation)input.Orientation,
                BackgroundColor = HexToColor(input.BackgroundColor),
                RenderOrder     = (TiledRenderOrder)input.RenderOrder,
                Properties      = input.Properties?.ToDictionary(a => a.Name, a => a.Value),
                ObjectGroups    = input.ObjectGroups?.Select(
                    a => new TiledObjectGroup
                {
                    Name       = a.Name,
                    Color      = HexToColor(a.Color),
                    Opacity    = a.Opacity,
                    Visible    = a.Visible,
                    Properties = a.Properties?.ToDictionary(b => b.Name, b => b.Value),
                    Objects    = a.Objects?.Select(
                        b =>
                    {
                        var tiledObject = new TiledObject
                        {
                            Id         = b.Id,
                            Name       = b.Name,
                            Type       = b.Type,
                            X          = (int)b.X,
                            Y          = (int)b.Y,
                            Width      = (int)b.Width,
                            Height     = (int)b.Height,
                            Rotation   = b.Rotation,
                            Gid        = b.Gid,
                            Visible    = b.Visible,
                            Properties = b.Properties?.ToDictionary(c => c.Name, c => c.Value),
                            ObjectType = b.Type,
                        };

                        if (b.Ellipse != null)
                        {
                            tiledObject.TiledObjectType = TiledObject.TiledObjectTypes.Ellipse;
                        }
                        else if (b.Image != null)
                        {
                            tiledObject.TiledObjectType = TiledObject.TiledObjectTypes.Image;
                        }
                        else if (b.Polygon != null)
                        {
                            tiledObject.TiledObjectType = TiledObject.TiledObjectTypes.Polygon;
                            tiledObject.PolyPoints      = GetPoints(b.Polygon.Points);
                        }
                        else if (b.PolyLine != null)
                        {
                            tiledObject.TiledObjectType = TiledObject.TiledObjectTypes.Polyline;
                            tiledObject.PolyPoints      = GetPoints(b.PolyLine.Points);
                        }
                        else
                        {
                            tiledObject.TiledObjectType = TiledObject.TiledObjectTypes.None;
                        }

                        return(tiledObject);
                    }).ToList()
                }).ToList(),

                TileSets = input.TileSets?.Select(
                    a =>
                {
                    var tileSet        = TiledTileSet.Build(a.Image.Width, a.Image.Height, a.TileWidth, a.TileHeight, a.Spacing, a.Margin, a.Columns);
                    tileSet.FirstGid   = a.FirstGid;
                    tileSet.Image      = a.Image.Source;
                    tileSet.Properties = a.Properties.ToDictionary(b => b.Name, b => b.Value);
                    foreach (var tile in a.Tiles)
                    {
                        var tiledTile = tileSet.Tiles.FirstOrDefault(b => b.Id == tile.Id);
                        if (tiledTile == null)
                        {
                            tiledTile = new TiledTileSetTile
                            {
                                Id = tile.Id
                            };
                            tileSet.Tiles.Add(tiledTile);
                        }

                        tiledTile.SourceRect      = tile.SourceRect != Rectangle.Empty ? tile.SourceRect : tiledTile.SourceRect;
                        tiledTile.AnimationFrames = tile.AnimationFrames == null || tile.AnimationFrames.Count == 0 ? null : tile.AnimationFrames.Select(b => new TiledTileSetAnimationFrame
                        {
                            TileId   = b.TileId,
                            Duration = b.Duration
                        }).ToList();
                        tile.Properties.ForEach(b => tiledTile.Properties[b.Name] = b.Value);
                    }
                    return(tileSet);
                }).ToList()
            };

            var existingIds = output.TileSets.SelectMany(a => a.Tiles.Select(b => (uint)(b.Id + a.FirstGid))).ToHashSet();

            output.Layers = input.Layers?.Select(
                a =>
            {
                var imageLayer = a as TmxImageLayer;
                var tiledLayer = a as TmxTileLayer;
                TiledLayer result;
                if (imageLayer != null)
                {
                    result = new TiledImageLayer {
                        AssetName = imageLayer.Image.Source
                    };
                }
                else if (tiledLayer != null)
                {
                    result = new TiledTileLayer
                    {
                        Width  = tiledLayer.Width,
                        Height = tiledLayer.Height,
                        X      = tiledLayer.X,
                        Y      = tiledLayer.Y,
                        Tiles  = tiledLayer.Data.Tiles.Select(
                            b =>
                        {
                            var flippedHorizontally = (b.Gid & FlippedHorizontallyFlag) != 0;
                            var flippedVertically   = (b.Gid & FlippedVerticallyFlag) != 0;
                            var flippedDiagonally   = (b.Gid & FlippedDiagonallyFlag) != 0;

                            if (flippedHorizontally || flippedVertically || flippedDiagonally)
                            {
                                b.Gid &= ~(FlippedHorizontallyFlag | FlippedVerticallyFlag
                                           | FlippedDiagonallyFlag);
                                b.FlippedHorizontally = flippedHorizontally;
                                b.FlippedVertically   = flippedVertically;
                                b.FlippedDiagonally   = flippedDiagonally;
                            }

                            if (!existingIds.Contains(b.Gid))
                            {
                                return(null);
                            }

                            return(new TiledTile
                            {
                                Id = (int)b.Gid,
                                FlippedDiagonally = b.FlippedDiagonally,
                                FlippedHorizonally = b.FlippedHorizontally,
                                FlippedVertically = b.FlippedVertically,
                            });
                        }).ToArray()
                    };
                }
                else
                {
                    throw new Exception($"Unknown layer type {a.GetType()}");
                }

                result.Name       = a.Name;
                result.Offset     = new Vector2(a.OffsetX, a.OffsetY);
                result.Opacity    = a.Opacity;
                result.Visible    = a.Visible;
                result.Properties = a.Properties.ToDictionary(b => b.Name, b => b.Value);
                return(result);
            }).ToList();
            return(output);
        }
Ejemplo n.º 2
0
        protected override TiledMap Read(ContentReader reader, TiledMap existingInstance)
        {
            var result = new TiledMap();

            result.FirstGid   = reader.ReadInt32();
            result.Width      = reader.ReadInt32();
            result.Height     = reader.ReadInt32();
            result.TileWidth  = reader.ReadInt32();
            result.TileHeight = reader.ReadInt32();
            if (reader.ReadBoolean())
            {
                result.BackgroundColor = reader.ReadColor();
            }
            result.RenderOrder = (TiledRenderOrder)reader.ReadInt32();
            result.Orientation = (TiledMapOrientation)reader.ReadInt32();
            this.ReadProperties(reader, result.Properties);
            var layerCount = reader.ReadInt32();

            for (var i = 0; i < layerCount; i++)
            {
                var        layerType = reader.ReadInt32();
                TiledLayer layer     = null;
                if (layerType == 1)
                {
                    var newLayer = new TiledImageLayer();
                    newLayer.AssetName = reader.ReadString();
                    layer = newLayer;
                }
                else if (layerType == 2)
                {
                    var newLayer = new TiledTileLayer();
                    newLayer.X      = reader.ReadInt32();
                    newLayer.Y      = reader.ReadInt32();
                    newLayer.Width  = reader.ReadInt32();
                    newLayer.Height = reader.ReadInt32();
                    newLayer.Tiles  = new TiledTile[reader.ReadInt32()];

                    for (var j = 0; j < newLayer.Tiles.Length; j++)
                    {
                        if (reader.ReadBoolean())
                        {
                            newLayer.Tiles[j]    = new TiledTile();
                            newLayer.Tiles[j].Id = reader.ReadInt32();
                            newLayer.Tiles[j].FlippedHorizonally = reader.ReadBoolean();
                            newLayer.Tiles[j].FlippedVertically  = reader.ReadBoolean();
                            newLayer.Tiles[j].FlippedDiagonally  = reader.ReadBoolean();
                        }
                    }

                    newLayer.Color = reader.ReadColor();
                    layer          = newLayer;
                }

                if (layer == null)
                {
                    throw new NotSupportedException();
                }

                result.Layers.Add(layer);
                layer.Offset = reader.ReadVector2();
                this.ReadProperties(reader, layer.Properties);
                layer.Name    = reader.ReadString();
                layer.Visible = reader.ReadBoolean();
                layer.Opacity = reader.ReadSingle();
            }
            var objectGroupsCount = reader.ReadInt32();

            for (var i = 0; i < objectGroupsCount; i++)
            {
                var objectGroup = new TiledObjectGroup();
                result.ObjectGroups.Add(objectGroup);

                objectGroup.Name    = reader.ReadString();
                objectGroup.Color   = reader.ReadColor();
                objectGroup.Opacity = reader.ReadSingle();
                objectGroup.Visible = reader.ReadBoolean();
                this.ReadProperties(reader, objectGroup.Properties);
                var objectsCount = reader.ReadInt32();
                for (var j = 0; j < objectsCount; j++)
                {
                    var obj = new TiledObject();
                    objectGroup.Objects.Add(obj);

                    obj.Id              = reader.ReadInt32();
                    obj.Name            = reader.ReadString();
                    obj.Type            = reader.ReadString();
                    obj.X               = reader.ReadInt32();
                    obj.Y               = reader.ReadInt32();
                    obj.Width           = reader.ReadInt32();
                    obj.Height          = reader.ReadInt32();
                    obj.Rotation        = reader.ReadInt32();
                    obj.Gid             = reader.ReadInt32();
                    obj.Visible         = reader.ReadBoolean();
                    obj.TiledObjectType = (TiledObject.TiledObjectTypes)reader.ReadInt32();
                    obj.ObjectType      = reader.ReadString();
                    var pointsCount = reader.ReadInt32();
                    for (var k = 0; k < pointsCount; k++)
                    {
                        obj.PolyPoints.Add(reader.ReadVector2());
                    }
                    this.ReadProperties(reader, obj.Properties);
                }
            }

            var tileSetCount = reader.ReadInt32();

            for (var i = 0; i < tileSetCount; i++)
            {
                var tileSet = new TiledTileSet();
                result.TileSets.Add(tileSet);
                tileSet.Spacing = reader.ReadInt32();
                tileSet.Margin  = reader.ReadInt32();
                this.ReadProperties(reader, tileSet.Properties);

                var tileCount = reader.ReadInt32();
                for (var j = 0; j < tileCount; j++)
                {
                    var tile = new TiledTileSetTile();
                    tileSet.Tiles.Add(tile);
                    tile.Id = reader.ReadInt32();
                    if (reader.ReadBoolean())
                    {
                        var animationFrameCount = reader.ReadInt32();
                        tile.AnimationFrames = new List <TiledTileSetAnimationFrame>(animationFrameCount);
                        for (var k = 0; k < animationFrameCount; k++)
                        {
                            var animationFrame = new TiledTileSetAnimationFrame();
                            tile.AnimationFrames.Add(animationFrame);

                            animationFrame.TileId   = reader.ReadInt32();
                            animationFrame.Duration = reader.ReadSingle();
                        }
                    }

                    this.ReadProperties(reader, tile.Properties);
                    var x      = reader.ReadInt32();
                    var y      = reader.ReadInt32();
                    var width  = reader.ReadInt32();
                    var height = reader.ReadInt32();
                    tile.SourceRect = new Rectangle(x, y, width, height);
                }

                tileSet.FirstGid     = reader.ReadInt32();
                tileSet.Image        = reader.ReadString();
                tileSet.ImageTexture = reader.ContentManager.Load <Texture2D>(tileSet.Image);
            }

            return(result);
        }