If you take a look at http://doc.mapeditor.org/reference/tmx-map-format
and look at
- version: The TMX format version, generally 1.0.
- orientation: Map orientation. Tiled supports "orthogonal", "isometric", "staggered" (since 0.9) and "hexagonal" (since 0.11).
- renderorder:
The order in which tiles on tile layers are rendered. Valid values are
right-down
(the default),right-up
,left-down
andleft-up
. In all cases, the map is drawn row-by-row. (since 0.10, but only supported for orthogonal maps at the moment) - width: The map width in tiles.
- height: The map height in tiles.
- tilewidth: The width of a tile.
- tileheight: The height of a tile.
- hexsidelength: Only for hexagonal maps. Determines the width or height (depending on the staggered axis) of the tile's edge, in pixels.
- staggeraxis: For staggered and hexagonal maps, determines which axis ("x" or "y") is staggered. (since 0.11)
- staggerindex: For staggered and hexagonal maps, determines whether the "even" or "odd" indexes along the staggered axis are shifted. (since 0.11)
- backgroundcolor:
The background color of the map. (since 0.9, optional, may include alpha
value since 0.15 in the form
#AARRGGBB
) - nextobjectid: Stores the next available ID for new objects. This number is stored to prevent reuse of the same ID after objects have been removed. (since 0.11)
tilewidth
and tileheight
properties determine the general grid
size of the map. The individual tiles may have different sizes. Larger tiles
will extend at the top and right (anchored to the bottom left).A map contains three different kinds of layers. Tile layers were once the only type, and are simply called
layer
,
object layers have the objectgroup
tag and image layers use the imagelayer
tag. The order in which these layers appear is the order in which the layers
are rendered by Tiled.Can contain: properties, tileset, layer, objectgroup, imagelayer
Now if you create different types of maps with different
settings, layers, tilesets, and properties save them and then open them in a
text editor or xml editor you will see something similar to these.
In xml you have things called elements and things called
attributes. Every xml document will start with the next line is
called the root element. Every xml document will contain at least one root
element. Remember when we created the TMXMap class we added the [XmlRoot("map")] attribute/tag(from
here on out to remove confusion when talking about xml documents and C# code I
will be referring to these as tags). Notice that all of the things with built
points on the tile map format documentation are all listed before the “>”,
these are referred to as attributes in xml. And the things listed as a map can
contain are all in between these are called
child elements. Elements in an xml document will look like
Or
For example for the version attribute you would use
[XmlAttribute()]
public float version;
or
[XmlAttribute("version")]
public float versionNumber;
For child elements you need to use a public variable with
the same name or use the [XmlElement("ElementName")] tag. You can also
use [XmlElement("layer", typeof(LayerElement))] if you want to load several
different types into a list when using inheritance. I will show you an example
of this when we get to loading in the different layer’s that a map can contain.
For now, let’s take a look at the different xml attributes that
a map can contain and get them to load into our map. Every attribute is a
string so you can load these all as string’s if you want to, but we are going
to use types that are as close as possible to represent our attributes, this
will make it easier on us when we go to displaying our map in Unity.
version is a number and in code you have different number
data types, int, float, decimal, just to name a few. We will be using float in
this tutorial. As of Tiled 0.16.1 which is the current version of Tiled as of
this writing the version number will always be 1.0 unless you manually change
it after saving the map.
orientation is orthogonal, isometric, staggered, or hexagonal.
We will create our own enum for this.
renderorder is right-down, right-up, left-down, left-up. We
will be using a string type for this since you cannot use the – character in an
enum. We will not be using this to draw our map in Unity, this is used in Tiled
to control the order in which the tiles are drawn to the screen. We will be
looping thru our tiles on the tile layer right down, a tile with a position of
0,0 will be the first tile or the top left of your map and position n, -n will
be the last tile or the bottom right of your map. This is how Tiled saves out
the tiles when you set the Tile Layer Format to xml, regardless of the render
order.
width, height, tilewidth, tileHeight, and hexsidelength are
all whole numbers so we will use the int type for these.
staggeraxis is either x or y and staggerindex is either even
or odd so we will be making our own enum types for these.
backgroundcolor is a hex value in the form of #AARRGGBB
since we are using xml serialization this will be loaded in as a string. I may
show you how to convert this to a color and use this value to set the
background color of our scene when drawing the map in Unity.
nextobjectid is a whole number so we will use the int type
for this. Again this is really just for use in Tiled when creating new objects
in Tiled, we will more than likely not be using this within unity.
In Unity Create a new folder in TileMapXML->Scripts
called Map. Then create 3 new C# scripts in TileMapXML->Scripts->Map
called TMXMapOrientation, TMXStaggeraxis, and TMXStaggerIndex. Open these three
files and delete all of the generated code, we are going to use these to hold
our enums. You can skip this step and put all of your enums in TMXMap.cs
outside of the class if you want. I just like to keep my enums in their own
file so I can easily find them if I want to make a change to them.
TMXMapOrientation.cs
namespace TileMapXML.Map
{
///
/// Map orientation.
///
/// Tiled supports "orthogonal",
"isometric" and "staggered" (since 0.9) at the moment.
///
/// Tiled Map Editor Version 0.16.1
/// orthogonal
/// isometric
/// staggered-isometric staggered
/// hexagonal-hexagonal staggered
///
[System.Serializable]
public enum TMXMapOrientation
{
none,
orthogonal,
isometric,
staggered,
hexagonal,
}//enum
MapOrientation
}//namespace TileMapXML.Map
Nothing special here except we are using the
[Systm.Serializable] tag and this is a public enum instead of a class. Also
notice that the namespace is TileMapXML.Map. The Serializable tag is more for
the internal workings of Unity and this being displayed in the inspector
automatically when we use it in other classes derived from Monobehavior or
ScriptableObject. Notice that the first entry is none which is not listed in
the Tiled documentation. This is for us to use in error checking later on, we
will also be assigning none as the default when this variable is used. This
will be the same for TMXStaggerAxis and TMXStaggerIndex.
TMXStaggerAxis.cs
namespace TileMapXML.Map
{
///
/// Stagger Axis.
///
/// For staggered and hexagonal maps, determines which
axis("x" or "y") is staggered. (since 0.11)
///
[System.Serializable]
public enum TMXStaggerAxis
{
none,
x,
y
}//enum
TMXMapStaggerAxis
}//namespace TileMapXML.Map
TMXStaggerIndex.cs
namespace TileMapXML.Map
{
///
/// Stagger Index.
///
/// For staggered and hexagonal maps, determines whether the
"even" or "odd" indexes along the staggered axis are
shifted. (since 0.11)
///
[System.Serializable]
public enum TMXStaggerIndex
{
none,
odd,
even
}//enum
TMXStaggerIndex
}//namespace TileMapXML.Map
Now in TMXMap.cs
add using TileMapXML.Map; At the top with
the other using statements.
And then add the following code inside the Attributes
region.
#region Attributes
///
/// The TMX format version, generally 1.0
///
[XmlAttribute()]
public float version = 0;
///
/// Map orientation.
/// Tiled supports "orthogonal",
"isometric", "staggered" (since 0.9) and
"hexagonal" (since 0.11).
///
[XmlAttribute()]
public TMXMapOrientation orientation = TMXMapOrientation.none;
///
/// The order in which tiles on tile layers are rendered.
/// Valid values are right-down(the default), right-up,
left-down and left-up.
/// In all cases, the map is drawn row-by-row. (since 0.10,
but only supported for orthogonal maps at the moment)
///
[XmlAttribute()]
public string renderorder = "";
///
/// The map width in tiles
///
[XmlAttribute()]
public int width = 0;
///
/// The map height in tiles.
///
[XmlAttribute()]
public int height = 0;
///
/// The width of a tile.
///
[XmlAttribute()]
public int tilewidth = 0;
///
/// The height of a tile.
///
[XmlAttribute()]
public int tileheight = 0;
///
/// Only for hexagonal maps.
/// Determines the width or height (depending on the
staggered axis) of the tile's edge, in pixels.
///
[XmlAttribute()]
public int hexsidelength = -1;
///
/// For staggered and hexagonal maps, determines which
axis("x" or "y") is staggered. (since 0.11)
///
[XmlAttribute()]
public TMXStaggerAxis staggeraxis = TMXStaggerAxis.none;
///
/// For staggered and hexagonal maps, determines whether the
"even" or "odd" indexes along the staggered axis are
shifted. (since 0.11)
///
[XmlAttribute()]
public TMXStaggerIndex staggerindex = TMXStaggerIndex.none;
///
/// The background color of the map. (since 0.9, optional,
may include alpha value since 0.15 in the form #AARRGGBB)
///
[XmlAttribute()]
public string backgroundcolor = "";// = new Color32(128, 128, 128,
255);
///
/// Stores the next available ID for new objects. This number
is stored to prevent reuse of the same ID after objects have been removed.
(since 0.11)
///
[XmlAttribute()]
public int nextobjectid = 0;
#endregion
Notice how every attribute has the [XmlAttribute()] tag. Also notice
that I have initialized every variable when declaring them, this is to prevent
null reference errors and also for error/type checking latter on. Also notice
that I have included every attribute that can be included in a TMX file. If you
do not want to support loading in staggered, isometric, hexagonal or background
color you do not have to include the related variables in your code. Just be
aware that by using xml serialization to load in our TMX files that if one of
these attributes is included in the TMX file you may get an error when trying
to load the file if you do not have it included in your C# script. These errors
can be hard to track down latter if your maps are not loading correctly.
Now all that is left is for you to create your NUnit test,
add the following test code to TMXTest.cs
[Test]
public void TMXMapLoaded()
{
// Every
map has these
// The
version of the map should be 1.0
Assert.AreEqual(1.0f, tmx.map.version);
// The
orientation of the map should not be none
Assert.AreNotEqual(TileMapXML.Map.TMXMapOrientation.none, tmx.map.orientation);
// The
render-order should not be null or empty
Assert.IsNotNullOrEmpty(tmx.map.renderorder, "Failed to load in a render order");
// The
width should be > 0
Assert.Greater(tmx.map.width, 0);
// The
height should be > 0
Assert.Greater(tmx.map.height, 0);
// The
tilewidth should be > 0
Assert.Greater(tmx.map.tilewidth, 0);
// The
tileheight should be > 0
Assert.Greater(tmx.map.tileheight, 0);
// The
nextobjectid should be > 0
Assert.Greater(tmx.map.nextobjectid, 0);
// check
values based on the maps orientation
switch(tmx.map.orientation)
{
case TileMapXML.Map.TMXMapOrientation.orthogonal:
//
hexsidelength is only for hexagonal maps
Assert.AreEqual(-1, tmx.map.hexsidelength, "hexsidelength is only for hexagonal maps");
//
staggeraxis is only for hexagonal and staggered maps
Assert.AreEqual(0, (int)tmx.map.staggeraxis, "staggeraxis
is only for hexagonal and staggered maps");
//
staggerindex is only for hexagonal and staggered maps
Assert.AreEqual(0, (int)tmx.map.staggerindex, "staggerindex
is only for hexagonal and staggered maps");
break;
case TileMapXML.Map.TMXMapOrientation.isometric:
//
hexsidelength is only for hexagonal maps
Assert.AreEqual(-1, tmx.map.hexsidelength, "hexsidelength is only for hexagonal maps");
//
staggeraxis is only for hexagonal and staggered maps
Assert.AreEqual(0, (int)tmx.map.staggeraxis, "staggeraxis
is only for hexagonal and staggered maps");
//
staggerindex is only for hexagonal and staggered maps
Assert.AreEqual(0, (int)tmx.map.staggerindex, "staggerindex
is only for hexagonal and staggered maps");
break;
case TileMapXML.Map.TMXMapOrientation.staggered:
//
hexsidelength is only for hexagonal maps
Assert.AreEqual(-1, tmx.map.hexsidelength, "hexsidelength is only for hexagonal maps");
//
staggeraxis is only for hexagonal and staggered maps
Assert.Greater((int)tmx.map.staggeraxis, 0, "staggeraxis
is only for hexagonal and staggered maps");
//
staggerindex is only for hexagonal and staggered maps
Assert.Greater((int)tmx.map.staggerindex, 0, "staggerindex
is only for hexagonal and staggered maps");
break;
case TileMapXML.Map.TMXMapOrientation.hexagonal:
//
hexsidelength is only for hexagonal maps
Assert.Greater(tmx.map.hexsidelength, -1, "failed to load in a hexsidelength");
//
staggeraxis is only for hexagonal and staggered maps
Assert.Greater((int)tmx.map.staggeraxis, 0, "staggeraxis
is only for hexagonal and staggered maps");
//
staggerindex is only for hexagonal and staggered maps
Assert.Greater((int)tmx.map.staggerindex, 0, "staggerindex
is only for hexagonal and staggered maps");
break;
default:
break;
}
}//void MapLoaded
Here we check that every attribute was loaded in correctly.
Notice that the switch statement we check to make sure that for maps that are
not supposed to have a value do not.
Also notice that when checking the enums for the staggerindex and stageraxis
we cast them to an int value, this is one of the benefits of using enum types
and also why are first entry is none. You could have also done
Assert.AreEqual(TileMapXML.Map.TMXStaggerAxis.none, tmx.map.staggeraxis); and Assert.AreNotEqual(TileMapXML.Map.TMXStaggerAxis.none, tmx.map.staggeraxis);
Also notice that the test does not check the backgroundcolor
attribute, this is the one case where it is only set if you change it in Tiled
so it is possible that it will be an empty string, or it may have a value of
some sort. You could add a check to see if it is empty then check to see if it
is in the right format #AARRGGBB. I will leave that up to you to figure out how
to do on your own. At this point if you run the test in Unity all of your test
should pass no matter what map you are using and how it is configured.
No comments:
Post a Comment