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. :)

HaxeFlixel Tutorial – Parsing CSV Map Data

In the previous post we loaded CSV data to display a tiled map in HaxeFlixel. But I forgot to talk about what to do after loading the data, so let’s run through a quick tutorial on how to parse the loaded map data.

Let’s assume you’ve created a template HaxeFlixel project, and this is how your MenuState.hx looks like:

If you test the game with lime test neko  now, you should get this:

2015-03-12-tiled-ss1

A lot of other tutorials would have mentioned this, but in case you didn’t know yet — To change the resolution of the screen, you just need to modify these variables in Main.hx:

… and now it should look like this:

2015-03-12-tiled-ss2

Even though the map is loaded, it’s just a static image. There’s no player code, or wall data, or anything else. So how do we code from here? Assuming that we’re using the layout above, here’s the CSV data (generated from Tiled, and using Derek Yu’s tilesheet):

If you examine the tilesheet image, the numbers above correspond with the tile index, as noted below:

2015-03-12-tiled-ss3

Let’s start with the player object first. We know that tile 20 is the red player tile, so how do we convert it into a game object?

You can check the FlxTilemap API for more information on the functions used above. If you test the game, it should still look the same. We replaced the player tile with an actual player object, but we can’t control the player yet. So let’s add the code into the update()  function, like this:

Great! Now if you test the game, you’ll be able to move the player and collide with the walls… but wait, you’re also colliding with the key, trap, and door. Why? Because all non-empty tiles (values other than -1) are automatically considered solid walls.

Since we already know how to replace the player tile with the player object, you can repeat the code for other objects. Let’s try to apply DRY (don’t repeat yourself) principle and modify our existing code, resulting in below:

Oops, I forgot about the door object, but you should get the rough idea by now. The code above isn’t complete, but it shows how we can parse the map objects manually, if you’re loading a single .CSV file.

There’s of course a better way to load map data, assuming you have multiple layers. Perhaps I’ll cover that in a separate tutorial next time.

In the meantime, you can check out HaxeFlixel’s official tutorial (Part 5), for a rundown on how to load OgmoEditor’s data file (which includes layers). StrandedSoft’s SHMUP tutorial (Part 2) also talks about loading TiledEditor’s TMX map data.

HaxeFlixel Tutorial – Loading Tile Map Data

If you’ve checked out the Tiled Editor sample or the Tilemap sample, you’d know that HaxeFlixel has convenient libraries to parse Tiled map data.

Unfortunately, I couldn’t find any guide that explain how to do that in HaxeFlixel unless you study it, so here’s a post dedicated to that.

Before we proceed, here are some links to other tutorials that mentions about loading Tiled data in HaxeFlixel:

Map Editors

Here is a quick list of possible editors you can use to create tile maps:

And here is a list of of sprite editors you can use to create tilesheet images:

I personally recommend Tiled Map Editor because it’s the most cross-platform, has lots of features, and it’s free.

My second choice is PyxelEdit; It works with Windows and OSX, it is a map editor that can also handle tiled creation and sprite animation. Unfortunately it’s not free, but you can try out its free Alpha version.

DAME Editor also looks like an interesting alternative but I have yet to experiment on it.

Load Map In HaxeFlixel

The easiest way to load tiled map data is from a text file, separated by commas or anything else — or otherwise known as CSV (character-separated values) files.

You can quickly create any simple CSV data file from Tiled Editor and proceed reading below. If you’re unsure of how, refer to the tutorial links above, like this one by StrandedSoft.

Let’s assume you’ve created a new HaxeFlixel template project. I’m going to use the template code from the cheat sheet for the MenuState.hx:

Now let’s add the following code:

In order to load the map data, we only need two things:  flixel.tile.FlxTilemap to handle the map creation logic, and openfl.Assets to load the .CSV data as string data.

Note: Make sure to put the .CSV file in the /data  folder, and the tilesheet image in the /images  folder, and the code above should work. You can check the API on how to use loadMap  function.

Note 2: If the map data couldn’t be loaded, make sure the end of the data in the .CSV file is NOT an empty line. It happened to me and I spent an hour troubleshooting. :(

You can also load more complex data in HaxeFlixel, such as the original TMX file (the Tiled Editor’s project data format), with the help of flixel.addons.editors.tiled  library. Unfortunately, the API page does not have much info on how to do that. I’ll try to cover that in a new post next time.