HaxeFlixel Tutorial – Loading TMX Data

Edit 2015-04-24: This tutorial has been revised completely to cater for multiple tile/object layers.

So far we have covered how to load CSV data and then parsing the loaded data. However, we assumed there’s only one layer; so if there is a player tile at (10,5), then there cannot be any ground tile behind it. And what if there’s an enemy that spawns on a specific grass tile? We would usually need layers. This is where Tiled Editor and the TMX file come in.

In Tiled, you can create multiple “tile” and “object” layers. You could have a map with the following setup:

  • tile layer for background (ground, river, etc.)
  • tile layer for foreground (walls, trees, etc.)
  • object layer for actors (player, enemies, treasure, etc.)

Before we proceed, let me share some nuggets of knowledge I gained while researching on how to parse TMX data:

  1. What you need to load TMX data
    • In order to load TMX data, you only need the TiledMap addon,  flixel.addons.editors.tiled.TiledMap .
    • The addon is a haxelib which needs to be enabled in the Project.xml file, like this:  <haxelib name="flixel-addons" />
  2. TMX layer data format
    • Getting the layer data is quite flimsy: if the TMX format is in CSV, then you need to access the data via “csvData” property. If the TMX format is Base64, you need to access the data via “tileArray” property. I couldn’t get XML data from the TMX file, and since FlxTilemap isn’t able to parse XML data anyway, we’re only left with two choices.
  3. Parsing TMX data
    • TiledMap only loads the TMX file’s data. You will have to parse the data yourself. TMX data loads two main parts of the file — the tileset list, and the layer list.
    • The tileset list contains all the tilesheet images that you used in the TMX map. In Tiled Editor, you can import multiple different spritesheets and use them in one project.
    • The layer list (if you saved the layer format as CSV) will contain an array of CSV data for each layer. This is just a more convenient way of saying the TMX file keeps multiple CSV data in one place.
  4. TMX loading/parsing limitations
    • This is very important when proceeding with parsing TMX data. I struggled for a long time on figuring out an easy way to do this, until I realised the following limitations.
    • HaxeFlixel does not have any function (as far as I know) that supports loading a tile map which uses multiple tilesheets. As such, each layer can only have ONE tilesheet associated with it.
    • Layers in the TMX file also do NOT store info on which tilesheet is being used. As a result, you need to add a custom property on each layer to explicitly store the name of the tilesheet you used for that layer.
    • In short, TiledMap only extracts most of the important info you need from the TMX file. It’s entirely up to you regarding how you’ll use the data to generate and render the tile map.

With the wisdom above, let us proceed.

Setup

First, let’s create a template HaxeFlixel project with an arbitrary name:

Next, let’s setup the necessary resources — we need a placeholder tilesheet. Let’s use this excellent sample from Sharm, “tiny 16 basic“. We’ll be using 4 images from there:

  • basictiles_2.png
  • characters_1.png
  • dead_1.png
  • things_0.png

Put the images in your project’s  /assets/images  folder.

TMX Data Setup

Now to create the TMX file. Here’s the bare minimum steps you’d usually have to go through to create a layered TMX file:

1) Create a new project.

tmx-tutorial-ss0

2) Add the image tilesheets (basictiles_2.png, characters_1.png, dead_1.png and things_0.png) to your project.

tmx-tutorial-ss1 tmx-tutorial-ss2 tmx-tutorial-ss3

3) For the purpose of demonstrating multiple tile and object layers, let’s create two tile layers and two object layers. In my example below, I renamed the layers to match the tilesheet image’s name which I’ll use for each layer.

Screen Shot 2015-04-24 at 11.36.15 AM

4) Add a custom property to the tile layers so that when we parse the data in HaxeFlixel later, we can know what tilesheet this layer is using.

tmx-tutorial-ss9

5) Do the same for the object layers.

tmx-tutorial-ss8

6) Now place the tiles in the tile layer as you like. In my example below, I tried to use all possible tiles from each layer to test if all of them would appear correctly:

Screen Shot 2015-04-24 at 11.12.09 AM

Screen Shot 2015-04-24 at 11.12.23 AM

7) Do the same for the object layers:

Screen Shot 2015-04-24 at 11.44.58 AM

Screen Shot 2015-04-24 at 11.46.33 AM

8) When I enable all the layers, I should be able to see all of them, like this:

Screen Shot 2015-04-24 at 11.45.26 AM

9) This step is optional. When you have specific object types in the object layer, such as “player”, “enemy”, “door” and “key”, you would normally do this — Select an arbitrary “player” object and add a custom property “type” to it, with the value “player”. We will use this value to parse it in TiledMap later. Without doing this, we won’t know how to identify different unique objects in the layer when we want to parse the data later. Repeat this step for other objects, such as enemies (“type” = “enemy”).

tmx-tutorial-ss7

10) Save the file as something easy to remember, e.g. “my-map.tmx” Put the TMX file in the /assets/data  folder. You’re now ready to load and parse the map data in HaxeFlixel!

Code

Now let’s get straight to the code:

Now if you test the game with lime test neko  …

Screen Shot 2015-04-24 at 11.56.20 AM

Oops, I forgot to set the screen resolution, but let’s assume you fixed that (change the gameWidth  and gameHeight  values in Main.hx).

Anyway, the game renders the two tile layers correctly! Now you know how to load multiple layers in your tilemap. Now let’s load the game objects:

EDIT: Thanks to Keith for the info — If you’re familiar with some other languages (C++, C#, etc.), you probably have this habit of ending every switch case with a break , like I do.

However, in Haxe, switch cases do NOT fall through, as stated on the syntax page. In fact, if you add breaks in your switch case, it will end up exiting the while-loop or for-loop outside of the switch block.

… And now, we can see the objects on the map as well:

Screen Shot 2015-04-24 at 12.03.46 PM

But wait, we’re not quite done yet — Notice that the placement of the objects in the layer is a little off (the y-position is lower by one tile than it should be). Thanks to Rafael J in the comment for fix:

And now the positions are all correct!

Screen Shot 2015-04-24 at 12.16.58 PM

The code above isn’t complete — we didn’t cover customising tile property, player/enemy logic, etc.. But anyway this concludes the tutorial. Thank you for reading. :)