Example #1
0
        public static TmxObject FromXml(XElement xml, TmxObjectGroup tmxObjectGroup, TmxMap tmxMap)
        {
            Logger.WriteVerbose("Parsing object ...");
            uint attributeAsUInt = TmxHelper.GetAttributeAsUInt(xml, "tid", 0u);

            if (attributeAsUInt != 0 && tmxMap.Templates.TryGetValue(attributeAsUInt, out TgxTemplate value))
            {
                xml    = value.Templatize(xml);
                tmxMap = value.TemplateGroupMap;
            }
            TmxObject tmxObject = null;

            if (xml.Element("ellipse") != null)
            {
                tmxObject = new TmxObjectEllipse();
            }
            else if (xml.Element("polygon") != null)
            {
                tmxObject = new TmxObjectPolygon();
            }
            else if (xml.Element("polyline") != null)
            {
                tmxObject = new TmxObjectPolyline();
            }
            else if (xml.Attribute("gid") != null)
            {
                uint attributeAsUInt2 = TmxHelper.GetAttributeAsUInt(xml, "gid");
                attributeAsUInt2 = TmxMath.GetTileIdWithoutFlags(attributeAsUInt2);
                if (tmxMap.Tiles.ContainsKey(attributeAsUInt2))
                {
                    tmxObject = new TmxObjectTile();
                }
                else
                {
                    Logger.WriteWarning("Tile Id {0} not found in tilesets. Using a rectangle instead.\n{1}", attributeAsUInt2, xml.ToString());
                    tmxObject = new TmxObjectRectangle();
                }
            }
            else
            {
                tmxObject = new TmxObjectRectangle();
            }
            tmxObject.Id                = TmxHelper.GetAttributeAsInt(xml, "id", 0);
            tmxObject.Name              = TmxHelper.GetAttributeAsString(xml, "name", "");
            tmxObject.Type              = TmxHelper.GetAttributeAsString(xml, "type", "");
            tmxObject.Visible           = (TmxHelper.GetAttributeAsInt(xml, "visible", 1) == 1);
            tmxObject.ParentObjectGroup = tmxObjectGroup;
            float attributeAsFloat  = TmxHelper.GetAttributeAsFloat(xml, "x");
            float attributeAsFloat2 = TmxHelper.GetAttributeAsFloat(xml, "y");
            float attributeAsFloat3 = TmxHelper.GetAttributeAsFloat(xml, "width", 0f);
            float attributeAsFloat4 = TmxHelper.GetAttributeAsFloat(xml, "height", 0f);
            float attributeAsFloat5 = TmxHelper.GetAttributeAsFloat(xml, "rotation", 0f);

            tmxObject.Position   = new PointF(attributeAsFloat, attributeAsFloat2);
            tmxObject.Size       = new SizeF(attributeAsFloat3, attributeAsFloat4);
            tmxObject.Rotation   = attributeAsFloat5;
            tmxObject.Properties = TmxProperties.FromXml(xml);
            tmxObject.InternalFromXml(xml, tmxMap);
            return(tmxObject);
        }
Example #2
0
 public void VisitObject(TmxObject obj)
 {
     // Objects only increase draw order if they are tiles
     if (obj is TmxObjectTile)
     {
         TmxObjectTile tile = obj as TmxObjectTile;
         tile.DrawOrderIndex = this.drawOrderIndex++;
     }
 }
        private void DrawObjectCollider(Graphics g, TmxObject tmxObject, Color color)
        {
            Color brushColor = Color.FromArgb(128, color);

            using (Brush brush = new HatchBrush(HatchStyle.BackwardDiagonal, color, brushColor))
                using (Pen pen = new Pen(color))
                {
                    pen.Alignment = PenAlignment.Inset;

                    GraphicsState state = g.Save();
                    g.TranslateTransform(tmxObject.Position.X, tmxObject.Position.Y);
                    g.RotateTransform(tmxObject.Rotation);

                    if (tmxObject.GetType() == typeof(TmxObjectPolygon))
                    {
                        DrawPolygon(g, pen, brush, tmxObject as TmxObjectPolygon);
                    }
                    else if (tmxObject.GetType() == typeof(TmxObjectRectangle))
                    {
                        // Rectangles are polygons
                        DrawPolygon(g, pen, brush, tmxObject as TmxObjectPolygon);
                    }
                    else if (tmxObject.GetType() == typeof(TmxObjectEllipse))
                    {
                        DrawEllipse(g, pen, brush, tmxObject as TmxObjectEllipse);
                    }
                    else if (tmxObject.GetType() == typeof(TmxObjectPolyline))
                    {
                        DrawPolyline(g, pen, tmxObject as TmxObjectPolyline);
                    }
                    else if (tmxObject.GetType() == typeof(TmxObjectTile))
                    {
                        TmxObjectTile tmxObjectTile = tmxObject as TmxObjectTile;

                        RectangleF rcTile = new RectangleF();
                        rcTile.X    = 0;
                        rcTile.Y    = -tmxObjectTile.Tile.TileSize.Height;
                        rcTile.Size = tmxObjectTile.Tile.TileSize;

                        g.FillRectangle(brush, rcTile);
                        g.DrawRectangle(pen, rcTile.X, rcTile.Y, rcTile.Width - 1, rcTile.Height - 1);
                    }
                    else
                    {
                        g.Restore(state);
                        RectangleF bounds = tmxObject.GetWorldBounds();
                        g.FillRectangle(Brushes.Red, bounds.X, bounds.Y, bounds.Width, bounds.Height);
                        g.DrawRectangle(Pens.White, bounds.X, bounds.Y, bounds.Width, bounds.Height);
                        string message = String.Format("Unhandled object: {0}", tmxObject.GetNonEmptyName());
                        DrawString(g, message, bounds.X, bounds.Y);
                    }

                    // Restore our state
                    g.Restore(state);
                }
        }
Example #4
0
        public static TmxObject FromXml(XElement xml, TmxObjectGroup tmxObjectGroup, TmxMap tmxMap)
        {
            Program.WriteLine("Parsing object ...");
            Program.WriteVerbose(xml.ToString());

            // What kind of TmxObject are we creating?
            TmxObject tmxObject = null;

            if (xml.Element("ellipse") != null)
            {
                tmxObject = new TmxObjectEllipse();
            }
            else if (xml.Element("polygon") != null)
            {
                tmxObject = new TmxObjectPolygon();
            }
            else if (xml.Element("polyline") != null)
            {
                tmxObject = new TmxObjectPolyline();
            }
            else if (xml.Attribute("gid") != null)
            {
                tmxObject = new TmxObjectTile();
            }
            else
            {
                // Just a rectangle
                tmxObject = new TmxObjectRectangle();
            }

            // Data found on every object type
            tmxObject.Name              = TmxHelper.GetAttributeAsString(xml, "name", "");
            tmxObject.Type              = TmxHelper.GetAttributeAsString(xml, "type", "");
            tmxObject.Visible           = TmxHelper.GetAttributeAsInt(xml, "visible", 1) == 1;
            tmxObject.ParentObjectGroup = tmxObjectGroup;

            float x = TmxHelper.GetAttributeAsFloat(xml, "x");
            float y = TmxHelper.GetAttributeAsFloat(xml, "y");
            float w = TmxHelper.GetAttributeAsFloat(xml, "width", 0);
            float h = TmxHelper.GetAttributeAsFloat(xml, "height", 0);
            float r = TmxHelper.GetAttributeAsFloat(xml, "rotation", 0);

            tmxObject.Position = new System.Drawing.PointF(x, y);
            tmxObject.Size     = new System.Drawing.SizeF(w, h);
            tmxObject.Rotation = r;

            tmxObject.Properties = TmxProperties.FromXml(xml);

            tmxObject.InternalFromXml(xml, tmxMap);

            return(tmxObject);
        }
Example #5
0
        public static TmxObject FromXml(XElement xml, TmxObjectGroup tmxObjectGroup, TmxMap tmxMap)
        {
            Program.WriteLine("Parsing object ...");
            Program.WriteVerbose(xml.ToString());

            // What kind of TmxObject are we creating?
            TmxObject tmxObject = null;

            if (xml.Element("ellipse") != null)
            {
                tmxObject = new TmxObjectEllipse();
            }
            else if (xml.Element("polygon") != null)
            {
                tmxObject = new TmxObjectPolygon();
            }
            else if (xml.Element("polyline") != null)
            {
                tmxObject = new TmxObjectPolyline();
            }
            else if (xml.Attribute("gid") != null)
            {
                tmxObject = new TmxObjectTile();
            }
            else
            {
                // Just a rectangle
                tmxObject = new TmxObjectRectangle();
            }

            // Data found on every object type
            tmxObject.Name = TmxHelper.GetAttributeAsString(xml, "name", "");
            tmxObject.Type = TmxHelper.GetAttributeAsString(xml, "type", "");
            tmxObject.Visible = TmxHelper.GetAttributeAsInt(xml, "visible", 1) == 1;
            tmxObject.ParentObjectGroup = tmxObjectGroup;

            float x = TmxHelper.GetAttributeAsFloat(xml, "x");
            float y = TmxHelper.GetAttributeAsFloat(xml, "y");
            float w = TmxHelper.GetAttributeAsFloat(xml, "width", 0);
            float h = TmxHelper.GetAttributeAsFloat(xml, "height", 0);
            float r = TmxHelper.GetAttributeAsFloat(xml, "rotation", 0);
            tmxObject.Position = new System.Drawing.PointF(x, y);
            tmxObject.Size = new System.Drawing.SizeF(w, h);
            tmxObject.Rotation = r;

            tmxObject.Properties = TmxProperties.FromXml(xml);

            tmxObject.InternalFromXml(xml, tmxMap);

            return tmxObject;
        }
Example #6
0
        private void AddTileObjectElements(TmxObjectTile tmxTile, XElement xmlTileObject)
        {
            // We combine the properties of the tile that is referenced and add it to our own properties
            AssignTiledProperties(tmxTile.Tile, xmlTileObject);

            // Add any colliders that might be on the tile
            foreach (TmxObject tmxObject in tmxTile.Tile.ObjectGroup.Objects)
            {
                // All the objects/colliders in our object group need to be separate game objects because they can have unique tags/layers
                XElement xmlObject = new XElement("GameObject", new XAttribute("name", tmxObject.GetNonEmptyName()));

                // Transform object locaction into map space (needed for isometric and hex modes)
                PointF   xfPosition = TmxMath.ObjectPointFToMapSpace(this.tmxMap, tmxObject.Position);
                Vector3D pos        = PointFToUnityVector(xfPosition);
                xmlObject.SetAttributeValue("x", pos.X);
                xmlObject.SetAttributeValue("y", pos.Y);
                xmlObject.SetAttributeValue("rotation", tmxObject.Rotation);

                XElement objElement = null;

                if (tmxObject.GetType() == typeof(TmxObjectRectangle))
                {
                    // Note: Tile objects have orthographic rectangles even in isometric orientations so no need to transform rectangle points
                    objElement = CreateBoxColliderElement(tmxObject as TmxObjectRectangle);
                }
                else if (tmxObject.GetType() == typeof(TmxObjectEllipse))
                {
                    objElement = CreateCircleColliderElement(tmxObject as TmxObjectEllipse, tmxTile.Tile.ObjectGroup.Name);
                }
                else if (tmxObject.GetType() == typeof(TmxObjectPolygon))
                {
                    objElement = CreatePolygonColliderElement(tmxObject as TmxObjectPolygon);
                }
                else if (tmxObject.GetType() == typeof(TmxObjectPolyline))
                {
                    objElement = CreateEdgeColliderElement(tmxObject as TmxObjectPolyline);
                }

                if (objElement != null)
                {
                    xmlTileObject.Add(objElement);
                }
            }
        }
        private void AddTileObjectElements(TmxObjectTile tmxTile, XElement xmlTileObject)
        {
            // We combine the properties of the tile that is referenced and add it to our own properties
            AssignTiledProperties(tmxTile.Tile, xmlTileObject);

            // Add any colliders that might be on the tile
            foreach (TmxObject tmxObject in tmxTile.Tile.ObjectGroup.Objects)
            {
                // All the objects/colliders in our object group need to be separate game objects because they can have unique tags/layers
                XElement xmlObject = new XElement("GameObject", new XAttribute("name", tmxObject.GetNonEmptyName()));

                Vector3D pos = PointFToUnityVector(tmxObject.Position);
                xmlObject.SetAttributeValue("x", pos.X);
                xmlObject.SetAttributeValue("y", pos.Y);
                xmlObject.SetAttributeValue("rotation", tmxObject.Rotation);

                XElement objElement = null;

                if (tmxObject.GetType() == typeof(TmxObjectRectangle))
                {
                    objElement = CreateBoxColliderElement(tmxObject as TmxObjectRectangle);
                }
                else if (tmxObject.GetType() == typeof(TmxObjectEllipse))
                {
                    objElement = CreateCircleColliderElement(tmxObject as TmxObjectEllipse, tmxTile.Tile.ObjectGroup.Name);
                }
                else if (tmxObject.GetType() == typeof(TmxObjectPolygon))
                {
                    objElement = CreatePolygonColliderElement(tmxObject as TmxObjectPolygon);
                }
                else if (tmxObject.GetType() == typeof(TmxObjectPolyline))
                {
                    objElement = CreateEdgeColliderElement(tmxObject as TmxObjectPolyline);
                }

                if (objElement != null)
                {
                    xmlTileObject.Add(objElement);
                }
            }
        }
        private void AddTileObjectElements(TmxObjectTile tmxObjectTile, XElement xmlTileObjectRoot)
        {
            // TileObjects can be scaled (this is separate from vertex scaling)
            SizeF scale = tmxObjectTile.GetTileObjectScale();

            // Flipping is done through negative-scaling on the child object
            float flip_w = tmxObjectTile.FlippedHorizontal ? -1.0f : 1.0f;
            float flip_h = tmxObjectTile.FlippedVertical ? -1.0f : 1.0f;

            // Helper values for moving tile about local origin
            float full_w = tmxObjectTile.Tile.TileSize.Width;
            float full_h = tmxObjectTile.Tile.TileSize.Height;
            float half_w = full_w * 0.5f;
            float half_h = full_h * 0.5f;

            // Scale goes onto root node
            xmlTileObjectRoot.SetAttributeValue("scaleX", scale.Width);
            xmlTileObjectRoot.SetAttributeValue("scaleY", scale.Height);

            // We combine the properties of the tile that is referenced and add it to our own properties
            AssignTiledProperties(tmxObjectTile.Tile, xmlTileObjectRoot);

            // Add a TileObject component for scripting purposes
            {
                XElement xmlTileObjectComponent = new XElement("TileObjectComponent");
                xmlTileObjectComponent.SetAttributeValue("width", tmxObjectTile.Tile.TileSize.Width * scale.Width * Tiled2Unity.Settings.Scale);
                xmlTileObjectComponent.SetAttributeValue("height", tmxObjectTile.Tile.TileSize.Height * scale.Height * Tiled2Unity.Settings.Scale);
                xmlTileObjectRoot.Add(xmlTileObjectComponent);
            }

            // Child node positions game object to match center of tile so can flip along x and y axes
            XElement xmlTileObject = new XElement("GameObject");

            xmlTileObject.SetAttributeValue("name", "TileObject");
            if (tmxMap.Orientation == TmxMap.MapOrientation.Isometric)
            {
                // In isometric mode the local origin of the tile is at the bottom middle
                xmlTileObject.SetAttributeValue("x", 0);
                xmlTileObject.SetAttributeValue("y", half_h);
            }
            else
            {
                // For non-isometric maps the local origin of the tile is the bottom left
                xmlTileObject.SetAttributeValue("x", half_w);
                xmlTileObject.SetAttributeValue("y", half_h);
            }
            xmlTileObject.SetAttributeValue("scaleX", flip_w);
            xmlTileObject.SetAttributeValue("scaleY", flip_h);

            // Add any colliders that might be on the tile
            // Note: Colliders on a tile object are always treated as if they are in Orthogonal space
            TmxMap.MapOrientation restoreOrientation = tmxMap.Orientation;
            this.tmxMap.Orientation = TmxMap.MapOrientation.Orthogonal;
            {
                foreach (TmxObject tmxObject in tmxObjectTile.Tile.ObjectGroup.Objects)
                {
                    XElement objElement = null;

                    if (tmxObject.GetType() == typeof(TmxObjectRectangle))
                    {
                        // Note: Tile objects have orthographic rectangles even in isometric orientations so no need to transform rectangle points
                        objElement = CreateBoxColliderElement(tmxObject as TmxObjectRectangle);
                    }
                    else if (tmxObject.GetType() == typeof(TmxObjectEllipse))
                    {
                        objElement = CreateCircleColliderElement(tmxObject as TmxObjectEllipse, tmxObjectTile.Tile.ObjectGroup.Name);
                    }
                    else if (tmxObject.GetType() == typeof(TmxObjectPolygon))
                    {
                        objElement = CreatePolygonColliderElement(tmxObject as TmxObjectPolygon);
                    }
                    else if (tmxObject.GetType() == typeof(TmxObjectPolyline))
                    {
                        objElement = CreateEdgeColliderElement(tmxObject as TmxObjectPolyline);
                    }

                    if (objElement != null)
                    {
                        // This object is currently in the center of the Tile Object we are constructing
                        // The collision geometry is wrt the top-left corner
                        // The "Offset" of the collider translation to get to lop-left corner and the collider's position into account
                        float offset_x = (-half_w + tmxObject.Position.X) * Tiled2Unity.Settings.Scale;
                        float offset_y = (half_h - tmxObject.Position.Y) * Tiled2Unity.Settings.Scale;
                        objElement.SetAttributeValue("offsetX", offset_x);
                        objElement.SetAttributeValue("offsetY", offset_y);

                        xmlTileObject.Add(objElement);
                    }
                }
            }
            this.tmxMap.Orientation = restoreOrientation;

            // Add a child for each mesh
            // (The child node is needed due to animation)
            foreach (var mesh in tmxObjectTile.Tile.Meshes)
            {
                XElement xmlMeshObject = new XElement("GameObject");

                xmlMeshObject.SetAttributeValue("name", mesh.ObjectName);
                xmlMeshObject.SetAttributeValue("copy", mesh.UniqueMeshName);

                xmlMeshObject.SetAttributeValue("sortingLayerName", tmxObjectTile.SortingLayerName ?? tmxObjectTile.ParentObjectGroup.SortingLayerName);
                xmlMeshObject.SetAttributeValue("sortingOrder", tmxObjectTile.SortingOrder ?? tmxObjectTile.ParentObjectGroup.SortingOrder);

                // Game object that contains mesh moves position to that local origin of Tile Object (from Tiled's point of view) matches the root position of the Tile game object
                // Put another way: This translation moves away from center to local origin
                xmlMeshObject.SetAttributeValue("x", -half_w);
                xmlMeshObject.SetAttributeValue("y", half_h);

                if (mesh.FullAnimationDurationMs > 0)
                {
                    XElement xmlAnimation = new XElement("TileAnimator",
                                                         new XAttribute("startTimeMs", mesh.StartTimeMs),
                                                         new XAttribute("durationMs", mesh.DurationMs),
                                                         new XAttribute("fullTimeMs", mesh.FullAnimationDurationMs));
                    xmlMeshObject.Add(xmlAnimation);
                }

                xmlTileObject.Add(xmlMeshObject);
            }

            xmlTileObjectRoot.Add(xmlTileObject);
        }
        private List <XElement> CreateObjectElementList(TmxObjectGroup objectGroup)
        {
            List <XElement> elements = new List <XElement>();

            foreach (TmxObject tmxObject in objectGroup.Objects)
            {
                // All the objects/colliders in our object group need to be separate game objects because they can have unique tags/layers
                XElement xmlObject = new XElement("GameObject", new XAttribute("name", tmxObject.GetNonEmptyName()));

                // Transform object locaction into map space (needed for isometric and hex modes)
                PointF xfPosition = TmxMath.ObjectPointFToMapSpace(this.tmxMap, tmxObject.Position);
                PointF pos        = PointFToUnityVector(xfPosition);
                xmlObject.SetAttributeValue("x", pos.X);
                xmlObject.SetAttributeValue("y", pos.Y);
                xmlObject.SetAttributeValue("rotation", tmxObject.Rotation);

                AssignUnityProperties(tmxObject, xmlObject, PrefabContext.Object);
                AssignTiledProperties(tmxObject, xmlObject);

                // If we're not using a unity:layer override and there is an Object Type to go with this object then use it
                if (String.IsNullOrEmpty(objectGroup.UnityLayerOverrideName))
                {
                    xmlObject.SetAttributeValue("layer", tmxObject.Type);
                }

                XElement objElement = null;

                if (tmxObject.GetType() == typeof(TmxObjectRectangle))
                {
                    if (this.tmxMap.Orientation == TmxMap.MapOrientation.Isometric)
                    {
                        TmxObjectPolygon tmxIsometricRectangle = TmxObjectPolygon.FromRectangle(this.tmxMap, tmxObject as TmxObjectRectangle);
                        objElement = CreatePolygonColliderElement(tmxIsometricRectangle);
                    }
                    else
                    {
                        objElement = CreateBoxColliderElement(tmxObject as TmxObjectRectangle);
                    }
                }
                else if (tmxObject.GetType() == typeof(TmxObjectEllipse))
                {
                    objElement = CreateCircleColliderElement(tmxObject as TmxObjectEllipse, objectGroup.Name);
                }
                else if (tmxObject.GetType() == typeof(TmxObjectPolygon))
                {
                    objElement = CreatePolygonColliderElement(tmxObject as TmxObjectPolygon);
                }
                else if (tmxObject.GetType() == typeof(TmxObjectPolyline))
                {
                    objElement = CreateEdgeColliderElement(tmxObject as TmxObjectPolyline);
                }
                else if (tmxObject.GetType() == typeof(TmxObjectTile))
                {
                    TmxObjectTile tmxObjectTile = tmxObject as TmxObjectTile;

                    // Apply z-cooridnate for use with the depth buffer
                    // (Again, this is complicated by the fact that object tiles position is WRT the bottom edge of a tile)
                    if (Tiled2Unity.Settings.DepthBufferEnabled)
                    {
                        float mapLogicalHeight  = this.tmxMap.MapSizeInPixels().Height;
                        float tileLogicalHeight = this.tmxMap.TileHeight;
                        float logicalPos_y      = (-pos.Y / Tiled2Unity.Settings.Scale) - tileLogicalHeight;

                        float depth_z = CalculateFaceDepth(logicalPos_y, mapLogicalHeight);
                        xmlObject.SetAttributeValue("z", depth_z);
                    }

                    AddTileObjectElements(tmxObject as TmxObjectTile, xmlObject);
                }
                else
                {
                    Logger.WriteLine("Object '{0}' has been added for use with custom importers", tmxObject);
                }

                if (objElement != null)
                {
                    xmlObject.Add(objElement);
                }

                elements.Add(xmlObject);
            }

            return(elements);
        }
Example #10
0
        private List <XElement> CreateObjectElementList(TmxObjectGroup objectGroup)
        {
            List <XElement> elements = new List <XElement>();

            foreach (TmxObject tmxObject in objectGroup.Objects)
            {
                // All the objects/colliders in our object group need to be separate game objects because they can have unique tags/layers
                XElement xmlObject = new XElement("GameObject", new XAttribute("name", tmxObject.GetNonEmptyName()));

                // Transform object locaction into map space (needed for isometric and hex modes)
                PointF xfPosition = TmxMath.ObjectPointFToMapSpace(this.tmxMap, tmxObject.Position);
                PointF pos        = PointFToUnityVector(xfPosition);
                xmlObject.SetAttributeValue("x", pos.X);
                xmlObject.SetAttributeValue("y", pos.Y);
                xmlObject.SetAttributeValue("rotation", tmxObject.Rotation);

                AssignUnityProperties(tmxObject, xmlObject, PrefabContext.Object);
                AssignTiledProperties(tmxObject, xmlObject);

                // If we're not using a unity:layer override and there is an Object Type to go with this object then use it
                if (String.IsNullOrEmpty(objectGroup.UnityLayerOverrideName))
                {
                    // why would we /ever/ do this, christ
                    //xmlObject.SetAttributeValue("layer", tmxObject.Type);
                }

                XElement objElement   = null;
                XElement objComponent = new XElement("TmxObjectComponent",
                                                     new XAttribute("tmx-object-id", tmxObject.Id),
                                                     new XAttribute("tmx-object-name", tmxObject.Name),
                                                     new XAttribute("tmx-object-type", tmxObject.Type),
                                                     new XAttribute("tmx-object-x", tmxObject.Position.X),
                                                     new XAttribute("tmx-object-y", tmxObject.Position.Y),
                                                     new XAttribute("tmx-object-width", tmxObject.Size.Width),
                                                     new XAttribute("tmx-object-height", tmxObject.Size.Height),
                                                     new XAttribute("tmx-object-rotation", tmxObject.Rotation));

                // Do not create colliders if the are being ignored. (Still want to creat the game object though)
                bool ignoringCollisions = (objectGroup.Ignore == TmxLayerNode.IgnoreSettings.Collision);

                if (!ignoringCollisions && tmxObject.GetType() == typeof(TmxObjectRectangle))
                {
                    if (this.tmxMap.Orientation == TmxMap.MapOrientation.Isometric)
                    {
                        TmxObjectPolygon tmxIsometricRectangle = TmxObjectPolygon.FromRectangle(this.tmxMap, tmxObject as TmxObjectRectangle);
                        objElement = CreatePolygonColliderElement(tmxIsometricRectangle);
                    }
                    else
                    {
                        objElement = CreateBoxColliderElement(tmxObject as TmxObjectRectangle);
                    }

                    // Set object component type
                    objComponent.Name = "RectangleObjectComponent";
                }
                else if (!ignoringCollisions && tmxObject.GetType() == typeof(TmxObjectEllipse))
                {
                    objElement = CreateCircleColliderElement(tmxObject as TmxObjectEllipse, objectGroup.Name);

                    // Set the component type
                    objComponent.Name = "CircleObjectComponent";
                }
                else if (!ignoringCollisions && tmxObject.GetType() == typeof(TmxObjectPolygon))
                {
                    objElement = CreatePolygonColliderElement(tmxObject as TmxObjectPolygon);

                    // Set the component type
                    objComponent.Name = "PolygonObjectComponent";
                }
                else if (!ignoringCollisions && tmxObject.GetType() == typeof(TmxObjectPolyline))
                {
                    objElement = CreateEdgeColliderElement(tmxObject as TmxObjectPolyline);

                    // Set the component type
                    objComponent.Name = "PolylineObjectComponent";
                }
                else if (tmxObject.GetType() == typeof(TmxObjectTile))
                {
                    TmxObjectTile tmxObjectTile = tmxObject as TmxObjectTile;

                    // Apply z-cooridnate for use with the depth buffer
                    if (Tiled2Unity.Settings.DepthBufferEnabled)
                    {
                        float depth_z = CalculateFaceDepth(tmxObjectTile.Position.Y, tmxMap.MapSizeInPixels.Height);
                        xmlObject.SetAttributeValue("z", depth_z);
                    }

                    AddTileObjectElements(tmxObjectTile, xmlObject, objComponent);
                }
                else
                {
                    Logger.WriteLine("Object '{0}' has been added for use with custom importers", tmxObject);
                }

                if (objElement != null)
                {
                    xmlObject.Add(objComponent);
                    xmlObject.Add(objElement);
                }

                elements.Add(xmlObject);
            }

            return(elements);
        }
Example #11
0
        private void AddTileObjectElements(TmxObjectTile tmxObjectTile, XElement xmlTileObjectRoot)
        {
            // We combine the properties of the tile that is referenced and add it to our own properties
            AssignTiledProperties(tmxObjectTile.Tile, xmlTileObjectRoot);

            // TileObjects can be scaled (this is separate from vertex scaling)
            SizeF scale = tmxObjectTile.GetTileObjectScale();

            xmlTileObjectRoot.SetAttributeValue("scaleX", scale.Width);
            xmlTileObjectRoot.SetAttributeValue("scaleY", scale.Height);

            // Need another transform to help us with flipping of the tile (and their collisions)
            XElement xmlTileObject = new XElement("GameObject");

            xmlTileObject.SetAttributeValue("name", "TileObject");

            if (tmxObjectTile.FlippedHorizontal)
            {
                xmlTileObject.SetAttributeValue("x", tmxObjectTile.Tile.TileSize.Width * Tiled2Unity.Settings.Scale);
                xmlTileObject.SetAttributeValue("flipX", true);
            }
            if (tmxObjectTile.FlippedVertical)
            {
                xmlTileObject.SetAttributeValue("y", tmxObjectTile.Tile.TileSize.Height * Tiled2Unity.Settings.Scale);
                xmlTileObject.SetAttributeValue("flipY", true);
            }

            // Add any colliders that might be on the tile
            // Note: Colliders on a tile object are always treated as if they are in Orthogonal space
            TmxMap.MapOrientation restoreOrientation = tmxMap.Orientation;
            this.tmxMap.Orientation = TmxMap.MapOrientation.Orthogonal;
            {
                foreach (TmxObject tmxObject in tmxObjectTile.Tile.ObjectGroup.Objects)
                {
                    XElement objElement = null;

                    if (tmxObject.GetType() == typeof(TmxObjectRectangle))
                    {
                        // Note: Tile objects have orthographic rectangles even in isometric orientations so no need to transform rectangle points
                        objElement = CreateBoxColliderElement(tmxObject as TmxObjectRectangle);
                    }
                    else if (tmxObject.GetType() == typeof(TmxObjectEllipse))
                    {
                        objElement = CreateCircleColliderElement(tmxObject as TmxObjectEllipse, tmxObjectTile.Tile.ObjectGroup.Name);
                    }
                    else if (tmxObject.GetType() == typeof(TmxObjectPolygon))
                    {
                        objElement = CreatePolygonColliderElement(tmxObject as TmxObjectPolygon);
                    }
                    else if (tmxObject.GetType() == typeof(TmxObjectPolyline))
                    {
                        objElement = CreateEdgeColliderElement(tmxObject as TmxObjectPolyline);
                    }

                    if (objElement != null)
                    {
                        // Objects can be offset (and we need to make up for the bottom-left corner being the origin in a TileObject)
                        objElement.SetAttributeValue("offsetX", tmxObject.Position.X * Tiled2Unity.Settings.Scale);
                        objElement.SetAttributeValue("offsetY", (tmxObjectTile.Size.Height - tmxObject.Position.Y) * Tiled2Unity.Settings.Scale);

                        xmlTileObject.Add(objElement);
                    }
                }
            }
            this.tmxMap.Orientation = restoreOrientation;

            // Add a child for each mesh (with animation if needed)
            foreach (var mesh in tmxObjectTile.Tile.Meshes)
            {
                XElement xmlMeshObject = new XElement("GameObject");

                xmlMeshObject.SetAttributeValue("name", mesh.ObjectName);
                xmlMeshObject.SetAttributeValue("copy", mesh.UniqueMeshName);

                xmlMeshObject.SetAttributeValue("sortingLayerName", tmxObjectTile.SortingLayerName ?? tmxObjectTile.ParentObjectGroup.SortingLayerName);
                xmlMeshObject.SetAttributeValue("sortingOrder", tmxObjectTile.SortingOrder ?? tmxObjectTile.ParentObjectGroup.SortingOrder);

                // This object, that actually displays the tile, has to be bumped up to account for the bottom-left corner problem with Tile Objects in Tiled
                xmlMeshObject.SetAttributeValue("x", 0);
                xmlMeshObject.SetAttributeValue("y", tmxObjectTile.Tile.TileSize.Height * Tiled2Unity.Settings.Scale);

                if (mesh.FullAnimationDurationMs > 0)
                {
                    XElement xmlAnimation = new XElement("TileAnimator",
                                                         new XAttribute("startTimeMs", mesh.StartTimeMs),
                                                         new XAttribute("durationMs", mesh.DurationMs),
                                                         new XAttribute("fullTimeMs", mesh.FullAnimationDurationMs));
                    xmlMeshObject.Add(xmlAnimation);
                }

                xmlTileObject.Add(xmlMeshObject);
            }

            xmlTileObjectRoot.Add(xmlTileObject);
        }
Example #12
0
        public static TmxObject FromXml(XElement xml, TmxObjectGroup tmxObjectGroup, TmxMap tmxMap)
        {
            Logger.WriteLine("Parsing object ...");

            // What kind of TmxObject are we creating?
            TmxObject tmxObject = null;

            if (xml.Element("ellipse") != null)
            {
                tmxObject = new TmxObjectEllipse();
            }
            else if (xml.Element("polygon") != null)
            {
                tmxObject = new TmxObjectPolygon();
            }
            else if (xml.Element("polyline") != null)
            {
                tmxObject = new TmxObjectPolyline();
            }
            else if (xml.Attribute("gid") != null)
            {
                uint gid = TmxHelper.GetAttributeAsUInt(xml, "gid");
                gid = TmxMath.GetTileIdWithoutFlags(gid);
                if (tmxMap.Tiles.ContainsKey(gid))
                {
                    tmxObject = new TmxObjectTile();
                }
                else
                {
                    // For some reason, the tile is not in any of our tilesets
                    // Warn the user and use a rectangle
                    Logger.WriteWarning("Tile Id {0} not found in tilesets. Using a rectangle instead.\n{1}", gid, xml.ToString());
                    tmxObject = new TmxObjectRectangle();
                }
            }
            else
            {
                // Just a rectangle
                tmxObject = new TmxObjectRectangle();
            }

            // Data found on every object type
            tmxObject.Name              = TmxHelper.GetAttributeAsString(xml, "name", "");
            tmxObject.Type              = TmxHelper.GetAttributeAsString(xml, "type", "");
            tmxObject.Visible           = TmxHelper.GetAttributeAsInt(xml, "visible", 1) == 1;
            tmxObject.ParentObjectGroup = tmxObjectGroup;

            float x = TmxHelper.GetAttributeAsFloat(xml, "x");
            float y = TmxHelper.GetAttributeAsFloat(xml, "y");
            float w = TmxHelper.GetAttributeAsFloat(xml, "width", 0);
            float h = TmxHelper.GetAttributeAsFloat(xml, "height", 0);
            float r = TmxHelper.GetAttributeAsFloat(xml, "rotation", 0);

            tmxObject.Position = new System.Drawing.PointF(x, y);
            tmxObject.Size     = new System.Drawing.SizeF(w, h);
            tmxObject.Rotation = r;

            tmxObject.Properties = TmxProperties.FromXml(xml);

            tmxObject.InternalFromXml(xml, tmxMap);

            return(tmxObject);
        }
Example #13
0
        public static TmxObject FromXml(XElement xml, TmxObjectGroup tmxObjectGroup, TmxMap tmxMap)
        {
            Program.WriteLine("Parsing object ...");
            Program.WriteVerbose(xml.ToString());

            // What kind of TmxObject are we creating?
            TmxObject tmxObject = null;

            if (xml.Element("ellipse") != null)
            {
                tmxObject = new TmxObjectEllipse();
            }
            else if (xml.Element("polygon") != null)
            {
                tmxObject = new TmxObjectPolygon();
            }
            else if (xml.Element("polyline") != null)
            {
                tmxObject = new TmxObjectPolyline();
            }
            else if (xml.Attribute("gid") != null)
            {
                uint gid = TmxHelper.GetAttributeAsUInt(xml, "gid");
                gid = TmxMath.GetTileIdWithoutFlags(gid);
                if (tmxMap.Tiles.ContainsKey(gid))
                {
                    tmxObject = new TmxObjectTile();
                }
                else
                {
                    // For some reason, the tile is not in any of our tilesets
                    // Warn the user and use a rectangle
                    Program.WriteWarning("Tile Id {0} not found in tilesets. Using a rectangle instead.\n{1}", gid, xml.ToString());
                    tmxObject = new TmxObjectRectangle();
                }
            }
            else
            {
                // Just a rectangle
                tmxObject = new TmxObjectRectangle();
            }

            // Data found on every object type
            tmxObject.Name = TmxHelper.GetAttributeAsString(xml, "name", "");
            tmxObject.Type = TmxHelper.GetAttributeAsString(xml, "type", "");
            tmxObject.Visible = TmxHelper.GetAttributeAsInt(xml, "visible", 1) == 1;
            tmxObject.ParentObjectGroup = tmxObjectGroup;

            float x = TmxHelper.GetAttributeAsFloat(xml, "x");
            float y = TmxHelper.GetAttributeAsFloat(xml, "y");
            float w = TmxHelper.GetAttributeAsFloat(xml, "width", 0);
            float h = TmxHelper.GetAttributeAsFloat(xml, "height", 0);
            float r = TmxHelper.GetAttributeAsFloat(xml, "rotation", 0);
            tmxObject.Position = new System.Drawing.PointF(x, y);
            tmxObject.Size = new System.Drawing.SizeF(w, h);
            tmxObject.Rotation = r;

            tmxObject.Properties = TmxProperties.FromXml(xml);

            tmxObject.InternalFromXml(xml, tmxMap);

            return tmxObject;
        }
Example #14
0
        private void DrawObjectCollider(Graphics g, TmxObject tmxObject, Color color)
        {
            Color brushColor = Color.FromArgb(128, color);

            using (Brush brush = new HatchBrush(HatchStyle.BackwardDiagonal, color, brushColor))
                using (Pen pen = new Pen(color))
                {
                    pen.Alignment = PenAlignment.Inset;

                    GraphicsState state = g.Save();

                    PointF xfPosition = TmxMath.ObjectPointFToMapSpace(this.tmxMap, tmxObject.Position);
                    g.TranslateTransform(xfPosition.X, xfPosition.Y);
                    g.RotateTransform(tmxObject.Rotation);

                    if (tmxObject.GetType() == typeof(TmxObjectPolygon))
                    {
                        DrawPolygon(g, pen, brush, tmxObject as TmxObjectPolygon);
                    }
                    else if (tmxObject.GetType() == typeof(TmxObjectRectangle))
                    {
                        if (this.tmxMap.Orientation == TmxMap.MapOrientation.Isometric)
                        {
                            TmxObjectPolygon tmxIsometricRectangle = TmxObjectPolygon.FromRectangle(this.tmxMap, tmxObject as TmxObjectRectangle);
                            DrawPolygon(g, pen, brush, tmxIsometricRectangle);
                        }
                        else
                        {
                            // Rectangles are polygons
                            DrawPolygon(g, pen, brush, tmxObject as TmxObjectPolygon);
                        }
                    }
                    else if (tmxObject.GetType() == typeof(TmxObjectEllipse))
                    {
                        DrawEllipse(g, pen, brush, tmxObject as TmxObjectEllipse);
                    }
                    else if (tmxObject.GetType() == typeof(TmxObjectPolyline))
                    {
                        DrawPolyline(g, pen, tmxObject as TmxObjectPolyline);
                    }
                    else if (tmxObject.GetType() == typeof(TmxObjectTile))
                    {
                        GraphicsState tileState     = g.Save();
                        TmxObjectTile tmxObjectTile = tmxObject as TmxObjectTile;

                        // Apply scale
                        SizeF scale = tmxObjectTile.GetTileObjectScale();
                        g.ScaleTransform(scale.Width, scale.Height);

                        // Apply horizontal flip
                        if (tmxObjectTile.FlippedHorizontal)
                        {
                            g.TranslateTransform(tmxObjectTile.Tile.TileSize.Width, 0);
                            g.ScaleTransform(-1, 1);
                        }

                        // Apply vertical flip
                        if (tmxObjectTile.FlippedVertical)
                        {
                            g.TranslateTransform(0, -tmxObjectTile.Tile.TileSize.Height);
                            g.ScaleTransform(1, -1);
                        }

                        // (Note: Now we can draw the tile and collisions as normal as the transforms have been set up.)

                        // Draw the tile
                        Rectangle destination = new Rectangle(0, -tmxObjectTile.Tile.TileSize.Height, tmxObjectTile.Tile.TileSize.Width, tmxObjectTile.Tile.TileSize.Height);
                        Rectangle source      = new Rectangle(tmxObjectTile.Tile.LocationOnSource, tmxObjectTile.Tile.TileSize);
                        g.DrawImage(tmxObjectTile.Tile.TmxImage.ImageBitmap, destination, source, GraphicsUnit.Pixel);

                        // Put a black border around the tile so it sticks out a bit as an object
                        g.DrawRectangle(Pens.Black, destination);

                        // Draw the collisions
                        // Make up for the fact that the bottom-left corner is the origin
                        g.TranslateTransform(0, -tmxObjectTile.Tile.TileSize.Height);
                        foreach (var obj in tmxObjectTile.Tile.ObjectGroup.Objects)
                        {
                            DrawObjectCollider(g, obj, Color.Gray);
                        }

                        g.Restore(tileState);
                    }
                    else
                    {
                        g.Restore(state);
                        RectangleF bounds = tmxObject.GetWorldBounds();
                        g.FillRectangle(Brushes.Red, bounds.X, bounds.Y, bounds.Width, bounds.Height);
                        g.DrawRectangle(Pens.White, bounds.X, bounds.Y, bounds.Width, bounds.Height);
                        string message = String.Format("Unhandled object: {0}", tmxObject.GetNonEmptyName());
                        DrawString(g, message, bounds.X, bounds.Y);
                    }

                    // Restore our state
                    g.Restore(state);
                }
        }
        private void AddTileObjectElements(TmxObjectTile tmxObjectTile, XElement xmlTileObjectRoot)
        {
            // We combine the properties of the tile that is referenced and add it to our own properties
            AssignTiledProperties(tmxObjectTile.Tile, xmlTileObjectRoot);

            // TileObjects can be scaled (this is separate from vertex scaling)
            SizeF scale = tmxObjectTile.GetTileObjectScale();
            xmlTileObjectRoot.SetAttributeValue("scaleX", scale.Width);
            xmlTileObjectRoot.SetAttributeValue("scaleY", scale.Height);

            // Need another transform to help us with flipping of the tile (and their collisions)
            XElement xmlTileObject = new XElement("GameObject");
            xmlTileObject.SetAttributeValue("name", "TileObject");

            if (tmxObjectTile.FlippedHorizontal)
            {
                xmlTileObject.SetAttributeValue("x", tmxObjectTile.Tile.TileSize.Width * Tiled2Unity.Settings.Scale);
                xmlTileObject.SetAttributeValue("flipX", true);
            }
            if (tmxObjectTile.FlippedVertical)
            {
                xmlTileObject.SetAttributeValue("y", tmxObjectTile.Tile.TileSize.Height * Tiled2Unity.Settings.Scale);
                xmlTileObject.SetAttributeValue("flipY", true);
            }

            // Add any colliders that might be on the tile
            // Note: Colliders on a tile object are always treated as if they are in Orthogonal space
            TmxMap.MapOrientation restoreOrientation = tmxMap.Orientation;
            this.tmxMap.Orientation = TmxMap.MapOrientation.Orthogonal;
            {
                foreach (TmxObject tmxObject in tmxObjectTile.Tile.ObjectGroup.Objects)
                {
                    XElement objElement = null;

                    if (tmxObject.GetType() == typeof(TmxObjectRectangle))
                    {
                        // Note: Tile objects have orthographic rectangles even in isometric orientations so no need to transform rectangle points
                        objElement = CreateBoxColliderElement(tmxObject as TmxObjectRectangle);
                    }
                    else if (tmxObject.GetType() == typeof(TmxObjectEllipse))
                    {
                        objElement = CreateCircleColliderElement(tmxObject as TmxObjectEllipse, tmxObjectTile.Tile.ObjectGroup.Name);
                    }
                    else if (tmxObject.GetType() == typeof(TmxObjectPolygon))
                    {
                        objElement = CreatePolygonColliderElement(tmxObject as TmxObjectPolygon);
                    }
                    else if (tmxObject.GetType() == typeof(TmxObjectPolyline))
                    {
                        objElement = CreateEdgeColliderElement(tmxObject as TmxObjectPolyline);
                    }

                    if (objElement != null)
                    {
                        // Objects can be offset (and we need to make up for the bottom-left corner being the origin in a TileObject)
                        objElement.SetAttributeValue("offsetX", tmxObject.Position.X * Tiled2Unity.Settings.Scale);
                        objElement.SetAttributeValue("offsetY", (tmxObjectTile.Size.Height - tmxObject.Position.Y) * Tiled2Unity.Settings.Scale);

                        xmlTileObject.Add(objElement);
                    }
                }
            }
            this.tmxMap.Orientation = restoreOrientation;

            // Add a child for each mesh (with animation if needed)
            foreach (var mesh in tmxObjectTile.Tile.Meshes)
            {
                XElement xmlMeshObject = new XElement("GameObject");

                xmlMeshObject.SetAttributeValue("name", mesh.ObjectName);
                xmlMeshObject.SetAttributeValue("copy", mesh.UniqueMeshName);

                xmlMeshObject.SetAttributeValue("sortingLayerName", tmxObjectTile.SortingLayerName ?? tmxObjectTile.ParentObjectGroup.SortingLayerName);
                xmlMeshObject.SetAttributeValue("sortingOrder", tmxObjectTile.SortingOrder ?? tmxObjectTile.ParentObjectGroup.SortingOrder);

                // This object, that actually displays the tile, has to be bumped up to account for the bottom-left corner problem with Tile Objects in Tiled
                xmlMeshObject.SetAttributeValue("x", 0);
                xmlMeshObject.SetAttributeValue("y", tmxObjectTile.Tile.TileSize.Height * Tiled2Unity.Settings.Scale);

                if (mesh.FullAnimationDurationMs > 0)
                {
                    XElement xmlAnimation = new XElement("TileAnimator",
                        new XAttribute("startTimeMs", mesh.StartTimeMs),
                        new XAttribute("durationMs", mesh.DurationMs),
                        new XAttribute("fullTimeMs", mesh.FullAnimationDurationMs));
                    xmlMeshObject.Add(xmlAnimation);
                }

                xmlTileObject.Add(xmlMeshObject);
            }

            xmlTileObjectRoot.Add(xmlTileObject);
        }