Giter Site home page Giter Site logo

marshallward / tiledsharp Goto Github PK

View Code? Open in Web Editor NEW
329.0 32.0 86.0 749 KB

C# library for parsing and importing TMX and TSX files generated by Tiled, a tile map generation tool

Home Page: http://marshallward.github.io/TiledSharp

License: Apache License 2.0

C# 100.00%
tiled-map-editor tmx

tiledsharp's Introduction

TiledSharp

A .NET C# library for importing Tiled TMX tile maps

NOTE: This project is no longer being maintained. Please consider using the TiledCS project, which has a similar API and supports a greater number of features.

About TiledSharp

TiledSharp is a .NET C# library for importing TMX tilemaps and TSX tilesets generated by Tiled, a tile map generation tool. The data is saved as a TmxMap object, whose structure closely resembles the original TMX file.

As a generic TMX and TSX parser, TiledSharp does not render the maps or depend on any external framework beyond .NET, such as Windows, XNA/MonoGame, Unity, or PSM. However, it can be used as an interface between TMX data and external games.

Usage

To import a TMX file into your C# application:

  • Include a reference to TiledSharp. You can either incorporare it directory into your own project, or you can pre-compile it and include the DLL.

  • Import the TiledSharp namespace (optional):

    using TiledSharp;
  • Create a Map object using the constructor:

    var map = new TmxMap("someMap.tmx");

    TiledSharp supports both resource names and file paths, and should work as expected in most situations. For more details, please consult the wiki.

  • Access the TMX data using the Map fields. Principal classes can be accessed by either name or index:

    var map = new TmxMap("someMap.tmx");
    var version = map.Version;
    var myTileset = map.Tilesets["myTileset"];
    var myLayer = map.Layers[2];
    var hiddenChest = map.ObjectGroups["Chests"].Objects["hiddenChest"];

Map data fields correspond closely to the TMX file structure. For a complete listing, see the documentation.

Although TiledSharp can manage elements with the same name, it is not recommended. For more information, see the TmxList specification.

Examples

Notes

TiledSharp parses XML files produced by Tiled, an open-source (GPL) tile map editor developed and maintained by Thorbjørn Lindeijer.

Licensing

TiledSharp is distributed under the Apache 2.0 License. The code can be used freely in any project, including commercial software, and does not place any restrictions on your own code. But any changes to TiledSharp must be documented explicitly.

Attribution is not necessary, but always appreciated.

Contact

Marshall Ward <[email protected]>

tiledsharp's People

Contributors

bjorn avatar codemyst avatar eropple avatar execomrt avatar f1tz81 avatar firedragonweb avatar hu9o avatar josh1billion avatar kevinbalz avatar kubagdynia avatar marshallward avatar miaodadao avatar paramecium13 avatar rlalance avatar sharparam avatar shawncowles avatar temeez avatar travisgesslein avatar zarickan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tiledsharp's Issues

PCL Support

Would it be possible to convert TiledSharp to a Portable Class Libray ?

It would be really useful for my Monogame project, because i can't put all map related code into my Game PCL.

I've started porting, so far i've replaced the current zlib with Zlib.Portable. The main issues i encountered is the current Constructor, loading files with paths is not possible in PCL's, so you have to pass a Stream or pass a class which implements some kind of 'IMapLoader' interface, see http://timheuer.com/blog/archive/2014/05/23/porting-taglib-sharp-to-portable-class-library.aspx , which are obviously breaking changes to the current API.

So i wanted to aks if it would be ok to do this, or if there any other plans or suggestions before i continue.

Chunk info for infinite maps?

Looking at the code, I'm not seeing chunk information for infinite maps (x, y, width, height) being stored within the layer structure. Is there any reason for this?
It's not a big deal as it can always be calculated but would've been nice to read it directly from the loaded structure

TMX export?

I was looking for a library for adding TMX export capabilities to an application.

Is TiledSharp capable of that? It doesn't seem to be, but I could be wrong.

Monodevelop Add NuGet packages

When I try to install this package I get the following error:

Could not install package 'TiledSharp 1.0.1'. You are trying to install this package into a project that targets '.NETFramework,Version=v4.5', but the package does not contain any assembly references or content files that are compatible with that framework. For more information, contact the package author.

How do I solve this? I'm relatively new to C# and Nuget.

I have Monodevelop installed on Ubuntu

Collision Editor Support

Hey guys,

Do you have any plans to implement an abstraction layer for Collision Editor, just like we have for AnimationFrames?

I'd like to develop that, but I got some issues trying to compile it on my Mac, and I'm not that confident to keep the project conventions.

And correct me if I'm wrong, but in the current state I can get them via Tileset.Tile.ObjectGroups, right?
Thanks!

Suggestion to change TmxTileset.Tiles to a Dictionary

While using this library, I can into the issue that looking up a tile by its local ID required looping over the Tiles collection to find it:

string tileImage = null;
if (obj.Tile != null) {
    int gid = obj.Tile.Gid;
    for (int tilesetIndex = map.Tilesets.Count - 1; tilesetIndex >= 0; --tilesetIndex) {
        var tileset = map.Tilesets[tilesetIndex];
        if (tileset.FirstGid <= gid) {
            int tileId = gid - tileset.FirstGid;
            TmxTilesetTile tile = null;
            // todo: tileset.Tiles could be a map from tileId -> Tile
            foreach (var t in tileset.Tiles) {
                if (t.Id == tileId) {
                    tile = t;
                    break;
                }
            }
            if (tile != null && tile.Image != null)
                tileImage = tile.Image.Source;
        }
    }
}

Maybe Tiles should be a Dictionary<int, TmxTilesetTile>? I have it like that in libtiled and wondered if there would be any concerns in changing this library in that way.

Support for the Tiled Collision Editor

The Tiled Collision Editor is a relatively new feature in Tiled that allows you to create ObjectGroups that are associated with a GID (aka a tile in a tileset). This way you can edit the collisions for one tile in your tileset, and it will be instantly applied to every one of that tile in the map. You can access it through View > Tile Collision Editor.

In the TMX, it is represented something like:

 <tileset>  
 
  <image/>  
  
  <tile>  
  
   <objectgroup>  
   
    <object>  
    
     <polygon/>  
     
    </object>  
    
   </objectgroup>  
   
  </tile>  
  
  <tile>  
  
   <objectgroup>  
   
    <object/>  
    
   </objectgroup>  
   
  </tile>  
  
 </tileset>  

Any thoughts on getting support for this? I may take a dive into the code to try and get it working tomorrow

Nuget package 1.0.0 .NETFramework and .NETCoreApp compatibility

Thank you for your very good package!
I work with VS 2017 15.8.6.
When building dotnet core applications using your nuget package I get this warning

warning NU1701: Package 'TiledSharp 1.0.0' was restored using '.NETFramework,Version=v4.6.1' instead of the project target framework '.NETCoreApp,Version=v2.1'. This package may not be fully compatible with your project.

, but your package seems to work.

When building dotnet Framework (tried 4.6. 4.6.1 and 4.7.1) applications using your nuget package I get this error

error CS1705: Assembly 'TiledSharp' with identity 'TiledSharp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' uses 'System.Runtime, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' which has a higher version than referenced assembly 'System.Runtime' with identity 'System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'

and compilation fails. I tried to install the nuget package for System.Runtime with the required Version, but still the error persists.

The old nuget package 0.15 works with dotnet Framework and works (with the warning) with dotnet core.

Layers or ObjectGroup In Group

Hi,
First of all thank you very much to you and all the people who contributed to this project.
I am a beginner developer and I have searched everywhere but I can't find a way to load objectsGroup or Layers that are in a group on Tiled.

I tried to look in your code and add this into the map.cs

foreach (var e in xMap.Elements("group").Elements("layer"))
Layers.Add(new TmxLayer(e, Width, Height));
foreach (var e in xMap.Elements("group").Elements("objectgroup"))
ObjectGroups.Add(new TmxObjectGroup(e));

And it's working \o/

I don't know if it's the right way to do it or if it's already possible and i missed the process.

Thanks again for your work
Br

NuGet package version is not up-to-date

Hello,

It seems like the NuGet package for TiledSharp is not entirely up-to-date. Things like the constructor for TmxMap that takes an XDocument is not present in the NuGet version, while it is included in the latest version on GitHub.

This makes it impossible for me to use the NuGet version in favor of compiling the DLL myself, since I need certain new features. I know the package hasn't been up-to-date for a while and it would be great if it was!

Unhandled exception when loading map that has Image layers

"An unhandled exception of type 'System.ArgumentNullException' occurred in System.Xml.Linq.dll
Additional information: Value cannot be null."

Occurs when i try to load a tiled map that has ImageLayers, if I remove the image layer from the map everything loads just fine.

Part of stacktrace (error occurs on TmxMap ctor):
at System.Xml.Linq.XAttribute.op_Explicit(XAttribute attribute)
at TiledSharp.TmxImageLayer..ctor(XElement xImageLayer, String tmxDir)
at TiledSharp.TmxMap..ctor(String filename)

System.FormatException: Input string was not in a correct format

When using both the NuGet Package Manager or referencing the project myself in VS2017, the above exception throws. It seems to occur as soon I construct a TmxMap class. I assume this is pointing to the way I pass the filename string, but I tried all possible alternative ways I knew to format my string. Nothing worked. This is why I think this is an issue.

When running the code from the project and the exception is thrown, it tells me there is an exception on line 54 of the Layer.cs file. After a quick search, it turns out it might have something to do with the way the string is being parsed to an unsigned int.

My Tiled map uses the CSV format, but other formats do not work for me either.

DrawOrderType mixup

The DrawOrderType enum values are mixed up when being read.

You can find the mixup on lines 40 and 41 of the file "ObjectGroup.cs":

{"topdown", DrawOrderType.IndexOrder},
{"index", DrawOrderType.TopDown}

That should probably be:

{"topdown", DrawOrderType.TopDown},
{"index", DrawOrderType.IndexOrder}

Also, it's probably slightly better (though maybe more of a personal preference) to place the creation of the dictionary inside the if-clause, so that the dictionary doesn't get made for no reason when there's no draworder specified, making the code sequence as follows:

if (drawOrderValue != null) {
	var drawOrderDict = new Dictionary<string, DrawOrderType> {
		{"unknown", DrawOrderType.UnknownOrder},
		{"topdown", DrawOrderType.TopDown},
		{"index", DrawOrderType.IndexOrder}
	};
	DrawOrder = drawOrderDict[drawOrderValue];
}

Tiled allows exponent format numbers in polygon coords, TiledSharp does not

Yeah, it's an edge case, but I hit it by generating coords outside of Tiled. Tiled was perfectly happy with them, but TiledSharp errored out. Turned out to be choking on the exponent notation. The fix is to add NumberStyles.AllowExponent to the double.Parse as below to TmxObjectPoint...

    public class TmxObjectPoint
    {
        public double X {get; private set;}
        public double Y {get; private set;}

        public TmxObjectPoint(double x, double y)
        {
            X = x;
            Y = y;
        }

        public TmxObjectPoint(string s)
        {
            var pt = s.Split(',');
            X = double.Parse(pt[0], NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign | NumberStyles.AllowExponent, CultureInfo.InvariantCulture); // NOTE: allow exponent
            Y = double.Parse(pt[1], NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign | NumberStyles.AllowExponent, CultureInfo.InvariantCulture); // NOTE: allow exponent
        }
    }

Exception thrown when loading maps containing objects with decimal values for x,y coordinates

Found a new case where a bug can arise.

In ObjectGroup.cs, on lines 68-69, these lines can sometimes throw unhandled exceptions, crashing the program:

            X = (int)xObject.Attribute("x");
            Y = (int)xObject.Attribute("y");

Specifically, this happens if the x and/or y values for an object are decimal values.

Steps to reproduce:

  1. Create a new map in Tiled.
  2. Create an object layer.
  3. Create an object, and set its X or Y value (under Position) to a decimal value, such as 100.5
  4. Try loading the map in TiledSharp.

This might seem like a rare case ("who would enter a decimal value for an x or y coordinate, anyway?"), but in my case, Tiled actually set it to a decimal value automatically as I was dragging-and-dropping an object around in the editor, so it's entirely possible that users will run into this at some point after messing around in Tiled long enough, like I did. :)

NuGet package

That would be a lot easier to have a Nuget package for referencing the project!

And ideally with .NET Standard support. :)

issues loading relative resources

nice class :) when trying it out, i had problems to load a map because of the layout, where the tmx file referred to a tsx tilemap file in a different directory, relative to the tmx map file, but the TiledSharp map loader assumes this is relative to the application working directory.

i fixed it like below, but managed to mangle your source so i got a ugly diff out of it

in Map.cs:

 using System.IO;
...
  public TmxMap (string filename)
  {
            string fullFilename = Path.GetFullPath (filename);
            string fullPath = Path.GetDirectoryName (fullFilename);

            XDocument xDoc = ReadXml (fullFilename);

  ...

            Tilesets = new TmxList ();
            foreach (var e in xMap.Elements("tileset")) {
                var source = (string)e.Attribute ("source");
                if (!source.StartsWith ("/"))
                    e.SetAttributeValue ("source", fullPath + "/" + source);

                Tilesets.Add (new TmxTileset (e));
            }
  ...
  }

UWP Compatibility.

To include it needs to be a .CORE library. Creating a new project and adding the source files it complains about the streams having no close() functions. Thread and Threadpool also throw errors. Please help I'd really love to get this working for Monogame.

Can't be used with Web or Android target in Unity

Because TmxMap takes a file path, it can't be used with a web or android target. Instead, there should be an option to provide a string of data.

In Unity, there's a variety of ways to load in streamed/external asset data. On Web and Android targets however, there's no way to directly open streamed data as a file. Here you would use in unity a WWW object, which on Web downloads the file and on Android loads it in from the zipped package.

https://docs.unity3d.com/ScriptReference/Application-streamingAssetsPath.html

However, WWW will only give you a text string, which can't be fed into TiledSharp.

Currently the only workaround I can figure out is to use temporary files (which on Web will make use of local storage). This is however a needlessly error-prone and badly performing solution.

API Notice: File object inputs, Layer integration

This is a notice and request for comment on upcoming API changes. This will resolve a number of outstanding issues (#15, #25, #28).

The next tagged release will adopt the following changes:

  • TMX files will no longer be specified by filepath. Instead, the Map object will be created using an already-opened file object. While this will require additional file and resource management from the user, it will eliminate any filesystem dependencies from TiledSharp. This will also allow compilation as a Portable Class Library, and run on a greater number of platforms.

  • The ObjectGroup and ImageLayer lists will be merged into Layers, which more closely resembles the TMX layout format. Elements can still be accessed by layer name, so this should not introduce any major problems.

    If two layers of different types were using the same name, then there may be some internal namechanges, but this is probably not a major issue.

The following change is also being considered:

  • Removing the DotNetZip code dump and replacing it with a .NET 3.5 compatible zlib library (possibly ZLib.Portable). This would address issues #15 and #16.

The following changes have been completed:

  • Tiles within Tileset are now stored as an id-index Dictionary, rather than a list (as suggested in #38)
  • DotNetZip has been removed, zlib support now provided by DeflateStream over data section

Any comments on these changes (including approval) can be posted here.

System.NullReferenceException in PropertyDict class

Hi. I get a bug where the map has properties.

Sample:

In Tiled:

In *.tmx file:

...
 <properties>
  <property name="term:00">vallavllalvalvla</property>
 </properties>
...

In visual studio:

Result:

'System.NullReferenceException' in TiledSharp.dll
in TiledSharp.PropertyDict..ctor(XContainer xmlProp) in \TiledSharp\src\TiledCore.cs:line 109

Problem solved following the replacement lines of next code:

var pval = p.Attribute("value").Value; to var pval = p.Value;

But, if property have type Attribute, so then pval = "".

I want to know - only i have a mistake? The error occurs when string property have line wrapping.

Tiled v 0.17.0 and TiledSharp v 0.15

Close MemoryStream if replacing with GZipStream or ZlibStream

Currently, when using encoded data, we will open the base64 data and convert to a MemoryStream which is saved to Data. However, if the data is compressed, then we create a new stream and set Data to it without closing the original MemoryStream.

This should be fixed up in some way, either explicit closing the MemoryStream or not reusing the Data variable.

Object layers throwing exception

When I try to load a map that contains at least one object layer, an exception gets thrown. The exception appears to be related to the drawing order in some way.

To reproduce:

  1. Create a new map. Add a tile layer and place some tiles (probably unnecessary, but just for good measure).
  2. Add an object layer.
  3. On that object layer, place an object (I created a circle, gave it a name and a type).
  4. Save the map, and attempt to load it with TiledSharp.
  5. An exception should get thrown in ObjectGroup.cs, in the TmxObjectGroup constructor.

For the time being, I was able to get the map to load by editing ObjectGroup.cs and removing the offending code, replacing it with just this simple line: DrawOrder = DrawOrderType.TopDown;.

DeflateStream and LayerTile

As of .NET 4.5, DeflateStream uses the Zlib, so, is it possible to remove the external dependancy on DotNetZip?
Also, wouldn't it be more memory efficient to represent the LayerTile as a struct and not an object? Since big maps can create tons of instances of that object?

Consolidate Layer attributes

It looks like libtiled now parses all common layer attributes in a single function (getLayerAttributes), which reads Opacity, Visible, OffsetX and OffsetY.

This may also be why Width and Height are now optional in ImageLayer, since these were legacy attributes in the old Tiled Java application that are no longer used.

Someday we may as well move the parsing of those attributes into something like an ILayer method, which would then be inherited by Layer, ObjectLayer and ImageLayer.

Problem with external Tilesets

I'm trying to get TiledSharp to parse a few maps that have external Tilesets. I'm encountering problems within TmxTilesetTile class when using external tilesets.

We are not using any "terrain" in our tilesets/maps so the following code throws a NullReferenceException on line 159 of Tileset.cs -

var strTerrain = ((string)xTile.Attribute("terrain")).Split(',');

since the xTile.Attribute("terrain") returns null.

I'm also getting a NullReferenceException in the TmxTilesetTile class, line 170 -

Image = new TmxImage(xTile.Element("image"), tmxDir);

since the tile xml does not have a "image" attribute. I'm not actually sure what this code is trying to do since the tilessets I've created reference a source image at the top, but not within the tile elements. Here's an example tileset I created and exported showing what I mean:

<tileset name="myTileset" tilewidth="192" tileheight="192">
 <image source="myTileset.png" width="2048" height="2048"/>
 <tile id="0">
  <properties>
   <property name="testProp1" value="0"/>
  </properties>
 </tile>
</tileset>

I'm no expert on Tiled so I might just be doing something with my tilesets that isn't common. We've been using these maps and tilesets with the Cocos2d obj-c CCTMX classes for a while now without problems but now need to parse them in a c-sharp environment.

Usability in Content Pipeline extension

TiledSharp cant be used in Content Pipeline Extension Project as it is don't have empty constructor.

My proposition: add Empty Constructor and make new method that accept filename and works like TmxMap(string filename) constructor.

Target .Net Core or .Net Standard

From what I've seen while using this project, it works perfectly fine with .Net Core (2.1). I think it would be great to make the project target .Net Standard (2.0) so that the package can be used in both .Net Framework and .Net Core projects.

I can try and give this a shot, shouldn't be too difficult to do.

Typo in TmxObject ctor: TmxLayerTile ctor gets passed X position twice

While browsing the code, I came across what seems to be a typo:

Tile = new TmxLayerTile((uint)xGid,
Convert.ToInt32(Math.Round(X)),
Convert.ToInt32(Math.Round(X)));

X (rounded) is passed as argument to both the x and y params.

I just started using Tiled and TiledSharp, so I'm not sure what I'm looking at and I haven't encountered any bug caused by that -- it just looks very suspect.

JSON parsing?

Will this support the JSON export of Tiled as well?

UAP Compatibility

I'm trying to install this package using Nuget and I'm being told that TiledSharp isn't compatible with Windows 10 UAP. Is this something that can be worked on?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.