private void ParseImageLayerXml(XElement xml) { if (xml.Element("image") == null) { Logger.WriteWarning("Image Layer '{0}' is being ignored since it has no image.", base.Name); base.Ignore = IgnoreSettings.True; } else { Width = 1; Height = 1; string imagePath = TmxHelper.GetAttributeAsFullPath(xml.Element("image"), "source"); TmxTile value = base.ParentMap.Tiles.First((KeyValuePair <uint, TmxTile> t) => t.Value.TmxImage.AbsolutePath.ToLower() == imagePath.ToLower()).Value; Data = new TmxData(this); TmxChunk tmxChunk = new TmxChunk(Data); tmxChunk.X = 0; tmxChunk.Y = 0; tmxChunk.Width = 1; tmxChunk.Height = 1; tmxChunk.TileIds.Add(value.GlobalId); Data.Chunks.Add(tmxChunk); PointF offset = base.Offset; offset.Y -= (float)base.ParentMap.TileHeight; offset.Y += (float)value.TmxImage.Size.Height; PointF pointF = TmxMath.TileCornerInScreenCoordinates(base.ParentMap, 0, 0); offset.X -= pointF.X; offset.Y -= pointF.Y; offset.X += TmxHelper.GetAttributeAsFloat(xml, "x", 0f); offset.Y += TmxHelper.GetAttributeAsFloat(xml, "y", 0f); base.Offset = offset; } }
private void BuildCollisionLayers_ByObjectType() { for (int i = 0; i < Data.Chunks.Count; i++) { TmxChunk tmxChunk = Data.Chunks[i]; for (int j = 0; j < tmxChunk.TileIds.Count; j++) { uint num = tmxChunk.TileIds[j]; if (num != 0) { uint tileIdWithoutFlags = TmxMath.GetTileIdWithoutFlags(num); foreach (TmxObject @object in base.ParentMap.Tiles[tileIdWithoutFlags].ObjectGroup.Objects) { if (@object is TmxHasPoints) { TmxLayer tmxLayer = CollisionLayers.Find((TmxLayer l) => string.Compare(l.Name, @object.Type, true) == 0); if (tmxLayer == null) { tmxLayer = new TmxLayer(null, base.ParentMap); CollisionLayers.Add(tmxLayer); tmxLayer.Name = @object.Type; tmxLayer.Offset = base.Offset; tmxLayer.Width = Width; tmxLayer.Height = Height; tmxLayer.Ignore = base.Ignore; tmxLayer.Properties = base.Properties; tmxLayer.Data = Data.MakeEmptyCopy(tmxLayer); } tmxLayer.Data.Chunks[i].TileIds[j] = num; } } } } } }
public static TmxData FromDataXml(XElement xml, TmxLayer parentLayer) { TmxData tmxData = new TmxData(parentLayer); tmxData.Encoding = TmxHelper.GetAttributeAsEnum(xml, "encoding", DataEncoding.Xml); tmxData.Compression = TmxHelper.GetAttributeAsEnum(xml, "compression", DataCompression.None); tmxData.Chunks = TmxChunk.ListFromDataXml(xml, tmxData); return(tmxData); }
private static List <TmxChunk> ListFromDataXml_Finite(XElement xml, TmxData parentData) { TmxChunk tmxChunk = new TmxChunk(parentData); tmxChunk.X = 0; tmxChunk.Y = 0; tmxChunk.Width = parentData.ParentLayer.Width; tmxChunk.Height = parentData.ParentLayer.Height; tmxChunk.ReadTileIds(xml); return(tmxChunk.ToEnumerable().ToList()); }
private static List <TmxChunk> ListFromDataXml_Infinite(XElement xml, TmxData parentData) { List <TmxChunk> list = new List <TmxChunk>(); foreach (XElement item in xml.Elements("chunk")) { TmxChunk tmxChunk = new TmxChunk(parentData); tmxChunk.X = TmxHelper.GetAttributeAsInt(item, "x", 0); tmxChunk.Y = TmxHelper.GetAttributeAsInt(item, "y", 0); tmxChunk.Width = TmxHelper.GetAttributeAsInt(item, "width", 0); tmxChunk.Height = TmxHelper.GetAttributeAsInt(item, "height", 0); tmxChunk.ReadTileIds(item); list.Add(tmxChunk); } return(list); }
public static List <TmxMesh> ListFromTmxChunk(TmxChunk chunk) { List <TmxMesh> list = new List <TmxMesh>(); for (int i = 0; i < chunk.TileIds.Count; i++) { uint num = chunk.TileIds[i]; TmxTile tile = chunk.ParentData.ParentLayer.ParentMap.GetTileFromTileId(num); if (tile != null) { int timeMs = 0; foreach (TmxFrame frame in tile.Animation.Frames) { uint globalTileId = frame.GlobalTileId; globalTileId |= (num & TmxMath.FLIPPED_HORIZONTALLY_FLAG); globalTileId |= (num & TmxMath.FLIPPED_VERTICALLY_FLAG); globalTileId |= (num & TmxMath.FLIPPED_DIAGONALLY_FLAG); TmxMesh tmxMesh = list.Find((TmxMesh m) => m.CanAddFrame(tile, timeMs, frame.DurationMs, tile.Animation.TotalTimeMs)); if (tmxMesh == null) { TmxTile tileFromTileId = chunk.ParentData.ParentLayer.ParentMap.GetTileFromTileId(globalTileId); tmxMesh = new TmxMesh(); tmxMesh.X = chunk.X; tmxMesh.Y = chunk.Y; tmxMesh.Width = chunk.Width; tmxMesh.Height = chunk.Height; tmxMesh.TileIds = new uint[chunk.TileIds.Count]; tmxMesh.UniqueMeshName = string.Format("{0}_mesh_{1}", chunk.ParentData.ParentLayer.ParentMap.Name, chunk.ParentData.ParentLayer.ParentMap.GetUniqueId().ToString("D4")); tmxMesh.TmxImage = tileFromTileId.TmxImage; tmxMesh.StartTimeMs = timeMs; tmxMesh.DurationMs = frame.DurationMs; tmxMesh.FullAnimationDurationMs = tile.Animation.TotalTimeMs; tmxMesh.ObjectName = Path.GetFileNameWithoutExtension(tileFromTileId.TmxImage.AbsolutePath); if (tmxMesh.DurationMs != 0) { TmxMesh tmxMesh2 = tmxMesh; tmxMesh2.ObjectName += $"[{timeMs}-{timeMs + tmxMesh.DurationMs}][{tmxMesh.FullAnimationDurationMs}]"; } list.Add(tmxMesh); } tmxMesh.AddTile(i, globalTileId); timeMs += frame.DurationMs; } } } return(list); }
public static PolyTree ExecuteClipper(TmxMap map, TmxChunk chunk, TransformPointFunc xfFunc) { ////for(int i=0;i<chunk.Height;i++) //// { //// for(int j=0; j<chunk.Width;j++) //// { //// var raw = chunk.GetRawTileIdAt(j, i); //// if(raw!=0) //// { //// var tid = TmxMath.GetTileIdWithoutFlags(raw); //// var tile = map.Tiles[tid]; //// foreach(var p in tile.ObjectGroup.Objects) //// { //// if(p is TmxHasPoints) //// { //// p.ToEnumerable().Where((x) => //// { //// if (!usingUnityLayerOverride) //// { //// return string.Compare(tuple.Item1.Type, chunk.ParentData.ParentLayer.Name, true) == 0; //// } //// return true; //// }); //// } //// } //// } //// } //// } // Clipper clipper = new Clipper(0); // Tuple<TmxObject, TmxTile, uint> tuple = new Tuple<TmxObject, TmxTile, uint>(null, null, 0); // bool usingUnityLayerOverride = !string.IsNullOrEmpty(chunk.ParentData.ParentLayer.UnityLayerOverrideName); // foreach (var item2 in from h__TransparentIdentifier4 in (from y in Enumerable.Range(0, chunk.Height) // from x in Enumerable.Range(0, chunk.Width) // let rawTileId = chunk.GetRawTileIdAt(x, y) // where rawTileId != 0 // let tileId = TmxMath.GetTileIdWithoutFlags(rawTileId) // let tile = map.Tiles[tileId] // from polygon in tile.ObjectGroup.Objects // where polygon is TmxHasPoints // select polygon.ToEnumerable().ToList().TrueForAll // (h__TransparentIdentifier4 => // { // UnityEngine.Debug.Log("liudaodelh"); // tuple = new Tuple<TmxObject, TmxTile, uint>(polygon, tile, rawTileId); // if (!usingUnityLayerOverride) // { // return string.Compare(tuple.Item1.Type, chunk.ParentData.ParentLayer.Name, true) == 0; // } // return true; // })) // select new // { // PositionOnMap = map.GetMapPositionAt((int)tuple.Item1.Position.X + chunk.X, (int)tuple.Item1.Position.Y + chunk.Y, tuple.Item2), // HasPointsInterface = (tuple.Item1 as TmxHasPoints), // TmxObjectInterface = tuple.Item1, // IsFlippedDiagnoally = TmxMath.IsTileFlippedDiagonally(tuple.Item3), // IsFlippedHorizontally = TmxMath.IsTileFlippedHorizontally(tuple.Item3), // IsFlippedVertically = TmxMath.IsTileFlippedVertically(tuple.Item3), // TileCenter = new PointF((float)tuple.Item2.TileSize.Width * 0.5f, (float)tuple.Item2.TileSize.Height * 0.5f) // }) // { // List<IntPoint> list = new List<IntPoint>(); // SizeF offset = new SizeF(item2.TmxObjectInterface.Position); // PointF[] array = item2.HasPointsInterface.Points.Select((PointF pt) => PointF.Add(pt, offset)).ToArray(); // TmxMath.TransformPoints(array, item2.TileCenter, item2.IsFlippedDiagnoally, item2.IsFlippedHorizontally, item2.IsFlippedVertically); // PointF[] array2 = array; // for (int i = 0; i < array2.Length; i++) // { // PointF pointF = array2[i]; // float x2 = (float)item2.PositionOnMap.X + pointF.X; // float y2 = (float)item2.PositionOnMap.Y + pointF.Y; // IntPoint item = xfFunc(x2, y2); // list.Add(item); // } // list.Reverse(); // clipper.AddPath(list, PolyType.ptSubject, item2.HasPointsInterface.ArePointsClosed()); // } // PolyTree polyTree = new PolyTree(); // clipper.Execute(ClipType.ctUnion, polyTree, SubjectFillRule, ClipFillRule); // return polyTree; ClipperLib.Clipper clipper = new ClipperLib.Clipper(); // Limit to polygon "type" that matches the collision layer name (unless we are overriding the whole layer to a specific Unity Layer Name) bool usingUnityLayerOverride = !String.IsNullOrEmpty(chunk.ParentData.ParentLayer.UnityLayerOverrideName); var polygons = from y in Enumerable.Range(0, chunk.Height) from x in Enumerable.Range(0, chunk.Width) let rawTileId = chunk.GetRawTileIdAt(x, y) where rawTileId != 0 let tileId = TmxMath.GetTileIdWithoutFlags(rawTileId) let tile = map.Tiles[tileId] from polygon in tile.ObjectGroup.Objects where (polygon as TmxHasPoints) != null where usingUnityLayerOverride || String.Compare(polygon.Type, chunk.ParentData.ParentLayer.Name, true) == 0 select new { PositionOnMap = map.GetMapPositionAt(x + chunk.X, y + chunk.Y, tile), HasPointsInterface = polygon as TmxHasPoints, TmxObjectInterface = polygon, IsFlippedDiagnoally = TmxMath.IsTileFlippedDiagonally(rawTileId), IsFlippedHorizontally = TmxMath.IsTileFlippedHorizontally(rawTileId), IsFlippedVertically = TmxMath.IsTileFlippedVertically(rawTileId), TileCenter = new PointF(tile.TileSize.Width * 0.5f, tile.TileSize.Height * 0.5f), }; // Add all our polygons to the Clipper library so it can reduce all the polygons to a (hopefully small) number of paths foreach (var poly in polygons) { // Create a clipper library polygon out of each and add it to our collection ClipperPolygon clipperPolygon = new ClipperPolygon(); // Our points may be transformed due to tile flipping/rotation // Before we transform them we put all the points into local space relative to the tile SizeF offset = new SizeF(poly.TmxObjectInterface.Position); PointF[] transformedPoints = poly.HasPointsInterface.Points.Select(pt => PointF.Add(pt, offset)).ToArray(); // Now transform the points relative to the tile TmxMath.TransformPoints(transformedPoints, poly.TileCenter, poly.IsFlippedDiagnoally, poly.IsFlippedHorizontally, poly.IsFlippedVertically); foreach (var pt in transformedPoints) { float x = poly.PositionOnMap.X + pt.X; float y = poly.PositionOnMap.Y + pt.Y; ClipperLib.IntPoint point = xfFunc(x, y); clipperPolygon.Add(point); } // Because of Unity's cooridnate system, the winding order of the polygons must be reversed clipperPolygon.Reverse(); // Add the "subject" clipper.AddPath(clipperPolygon, ClipperLib.PolyType.ptSubject, poly.HasPointsInterface.ArePointsClosed()); } ClipperLib.PolyTree solution = new ClipperLib.PolyTree(); clipper.Execute(ClipperLib.ClipType.ctUnion, solution, LayerClipper.SubjectFillRule, LayerClipper.ClipFillRule); return(solution); }