TMX Tile Namer

Finally I managed to built a small AIR app to solve the naming problem for TiledMapEditor TMX file. Seems that I’m underestimating myself, or probably I'm just too lazy. XD

tileNamer
TMX Tile Namer… Yeah, it doesn't sound right… I’m not even sure that the term “Namer” is exist on English dictionary… XD

This is just one button app. To use, click on the button, and a browse window will appear. Then you can search for the tile atlas XML file. Open the file, wait for couple of second, then a new XML file will be created on your desktop.
Additionally, you can simply drag and drop the XML file to the button, and it will automatically generate an output XML file on your desktop.

There are some limitations in this app:
The app only work if the tiles have uniform size and make sure there are no empty tiles in the tileset. See below:

sprites

Something like tileset below won’t work as you can see, there are three empty tiles. Because TiledMapEditor will treat empty space/tile/region as a single tile, while on the atlas XML file, there are no information for that empty tiles.

sprites - Copy

To solve the problem, you can add new tiles or duplicate some of the existing tiles, so there are no empty tiles. Not a resource wise for sure. But that’s the only solution for now.

Another limitation is that the app won’t write the tile name directly to the TMX file. So, to complete the process, open this app’s output XML file, and copy all the <tile> node inside the root node <tiles>.

tileNamer2

Open the TMX file with your code editor, then paste them inside the <tileset> node

tileNamer3

Still a little bit complicated, but surely less headache than giving name to each tiles one by one via TiledMapEditor. XD

Probably in the future, I’ll improve the app. But for now, it’s enough for me.
If you want to improve the app, then here it is the app source code.
The code is messy & not commented. I’ve warn you… XD
It is a Flash CS6 project, but you can simply copy-paste or move the Main.as class to your new pure AS3 project. Flash CS6 is just used to build the interface, well, in this case it’s just a background and a button

The AIR app is inside the bin folder, named TMXTileNamer.air. Since it built with AIR 3.9, then you’ll need latest AIR runtime on your machine to install & run this app.

Well, here it is the new sample project on my previous article, but now with few more tiles added.

3 comments:

Citrus Engine + Tiled Map Editor: Starling Mode

Alright, just want to share my experience when using Tiled Map Editor on Citrus Engine with Starling. Nothing too fancy here. Almost all of the process is pretty much same with my previous article.

citrus-tiled

Hell yeah, there are some additional workaround if you working with CE Starling mode. The very first different task is the tileset creation. Unlike the display list version which you only need a .PNG file for the tileset, on Starling version, you’ll need an texture atlas (PNG + XML file). There are some tools to generate texture atlas: Flash Pro CS6 or above, Texture Packer and ShoeBox. Well, there are probably another tools, but maybe I’m too lazy to do a google search. Smile with tongue out

Flash Pro is very expensive of course, but if you have the license, you can use it to create the tiles and export it to an atlas. Texture Packer is also the paid one, although they also have the lite version which will leave a watermark on your tileset. So better use the third tool: ShoeBox. A free AIR application that have several functions for processing game arts: creating spritesheet, tileset, generating PNG sequence from animation, etc. More than enough for me.

shoebox

As I said before, the tileset creation is different. You’ll need to export a separate bitmap file for each of the tiles from your graphic editor software to be processed on ShoeBox.

Using the same tileset from Kenney, and I pick a few tiles:

Tile starling citrus engine


6 tiles, and the other files are the atlas (PNG + XML) and TiledMapEditor TMX.

Now, we can create an atlas from these tiles. Simply select all of the 6 tiles, drag and drop it to Shoebox’s Sprite Sheet feature. And a new window will popped up:

Tile starling citrus engine

Alright, the tricky part starts from here. We need to make some adjustment, so we can use this tileset properly, because of this issue. As you can read on that forum thread, there will be some kind of transparent lines between the adjacent tiles when the camera moving. It’s look like the tiles aren’t attached to each other correctly.

Starling tiled map citrus engine

You can found someone else already asked about this issue on Starling or Citrus Engine forum. And also, on the Starling wiki already mentioned about this. Well, all of them already pointing out a proven solution: Add some extrude to the tilemap. Extrude is simply expanding the edges of the tiles by specified pixel size. How this option can solve the problem? Well, let’s just continue this article.

Now click the Settings button.  Another window will appear.

starling tiled citrus engine

First things first, make sure you select Starling, Sparrow on the Template dropdown menu.
“Tex Extrude Size”, well, that’s we’re looking for. Let’s change the value to 1. Problem solved? Not yet.
With Tex Extrude Size 1 and Tex Padding 1, we’ll get these tileset:

starling tiled citrus engine

Extrude working correctly, it expand the edges by one pixel. And the padding as well, it separate each tiles by one pixel. But as you can see, the adjacent tiles shared the same expanded pixel. The most noticeable are between grey tiles and brown tiles. Their expanded pixel is filled with grey color only. It’s definitely wrong.

The solution is just simply increase Tex Padding value. Ideally, it’s 2 times larger than the extrude value. So if the extrude size is 1 then the padding should be 2, and so on.
This is what we’ll get if using extrude 1 & padding 2:

Starling tiled citrus engine

With 2 pixel spacing between tiles, each tiles have one pixel extra on its edges. Now this is correct.

Tile’s spacing problem fixed. But before hit the shinny blue Save button, take a screenshoot/print screen your Sprite Sheet window. Make sure the tile’s label is readable. Paste it to paint, or other image editing tools, and save it.
Don’t ask why, I’ll explain it later.

starling tiled map

Alright you can hit the save button. Two new files will be created, a .png file and .xml. The xml file holds each tiles information, such as its name, coordinate, etc. While the png file is the tiles merged into one image file.

Now open the TiledMapEditor, create a new map with 70x70 px tile size since our tiles is also 70 px sized. Create new tileset, and use the png file that already generated before.

starling tiled citrus engine

But for the tile width and height, we set it to 71 px instead of the actual size (70 px), because we already add one extra pixel for each tiles using the extrude option.

Also for the spacing, set it to 1. Don’t know why it’s not using the same value as Tex Padding value on Shoebox, which we set it to 2. But I also don’t know why it’s work for me. So if the created tileset is separated correctly on TiledMapEditor’s tileset panel, then it’s mean that you’re set the spacing correctly. lol

On the tileset panel, right click one of the available tile, then select ‘Tile Properties’. A window will appear. We’ll give a name property to each tiles in the TiledMapEditor according to the already created tileset.

Now, open the previously taken screenshot. Using that screenshot as guide, then insert the corresponding name to all tiles.

starling tiled map citrus

Dafuq?

Yep, you’ll need to insert the name one by one. Clearly a tedious process, especially for a larger tileset with lot of tiles. Not to mention that you’ll need to re-adding the name property if you make some changes on the tileset. XD

I’ve no other solution for now. But if you have some free times, then you can create a tiny AIR tools to read the SubTexture’s name property on the tileset’s XML file and then write it to the TMX file. Both of the files are based on XML, so I’m definitely sure it’s doable with AS3. But still beyond my knowledge. XD 
You can take a look at my app here: TMX Tile Namer

Alright, because we only have 6 tiles, so it should be done just in a few minutes. Now you can start drawing your map and adding citrus objects just like on my previous article.

starling tiled citrus

The picture above shows how the extrude work. As you can see there are extra pixel on the edge of the tile. With these extra pixel, then surely there will be no more problem with transparent lines between tiles as I mentioned before. Because now it closed by that extra pixel.

Done?
If yes, then open your Flash Develop, or your own preferred IDE. Set up a Starling Citrus Engine project. Then create a state for the game screen.
I won’t explain that here. So if you’re new to Citrus Engine, then you’d better to find some basic tutorial.

The first things to do is embed the atlas files (XML & PNG), also the TMX file.

[Embed(source="../assets/bitmap/tiles/Tileset.tmx",mimeType="application/octet-stream")]   
private const tileMap:Class;    
         
[Embed(source="../assets/bitmap/tiles/sprites.xml",mimeType="application/octet-stream")]    
private const tileMapXML:Class;    
        
[Embed(source="../assets/bitmap/tiles/sprites.png")]    
private const tileMapImage:Class;


On the initialize method, under the box2d object initialization, put the code to parse the tileset.

var mapAtlas:TextureAtlas = new TextureAtlas(Texture.fromBitmap(new tileMapImage()), XML(new tileMapXML()));     
ObjectMakerStarling.FromTiledMap(XML(new tileMap()), mapAtlas);


As you can see, we create a TextureAtlas object for the map before inserting it to the parser. Using the embedded PNG and XML file.
And since we’re working using Starling, so we using ObjectMakerStarling utility class. And then call the FromTiledMap() method. It accept three parameters. The first one is the the TMX file. Since it need to be an XML object, so we cast it to an XML.
The second one is the atlas. Simply insert the mapAtlas object we’ve already created before. And the third one isn’t necessary.

Don’t compile the game yet, as I’m sure it will throw lot of  errors. It because the tiles name on the XML and TMX isn’t same.

To correct this, we need to make some edits on the XML file. It just simply remove the extension on the SubTexture name property. You can remove it manually one by one, or using search & replace function on your IDE.

starling tiled citrus

Now compile the game, it should be running perfectly, and you’ll see your created level.

Game Objects?
Starting from the hero, using the character PNG sequence form the same art package as the tileset. Make sure it’s facing right direction. And give it CitrusEngine’s default animation name (idle, walk, jump, duck, hurt).

Using the Shoebox’s Sprite Sheet function to generate a Texture Atlas. Pretty much same as we generate the tileset. But for this one, we set the Tex Extrude Size and Tex Padding to 0, as we don’t need these options.

starling tiled citrus engine

After that, you can create a Hero object on the TiledMapEditor. Give it “hero” name, and set some properties if necessary. But unlike on the previous article, the view property need to set via code, not inside TiledMapEditor.

So, go back to the code editor. Embed the hero’s PNG & XML files on your code.
[Embed(source="../assets/bitmap/hero/sprites.png")]   
private const heroImage:Class;    
         
[Embed(source="../assets/bitmap/hero/sprites.xml",mimeType="application/octet-stream")]    
private const heroXML:Class;


Then on intialize() method:
var heroAtlas:TextureAtlas = new TextureAtlas(Texture.fromBitmap(new heroImage()), XML(new heroXML()));   
var heroSequence:AnimationSequence = new AnimationSequence(heroAtlas, ["walk", "idle", "jump", "hurt"], "idle");    
            
var hero:Hero = getObjectByName("hero") as Hero;    
hero.view = heroSequence;


What we do is create a TextureAtlas object using the embedded PNG and XML file. Then create AnimationSequence object using that TextureAtlas.

We will using the AnimationSequence as the hero’s view. So grab the reference to the hero via getObjectByName() method. Then simply assign the AnimationSequence to its view property.

Do the same for other animated objects, i.e: the enemies.

For non animated objects like crate and coin, no need to create an atlas, as we can use just the PNG file. So embed the PNG file on your code, then to specify a view for the crate object is just something like this:
for (i = 0; i < getObjectsByType(Crate).length; i++)   
{    
      Crate(getObjectsByType(Crate)[i]).view = new Image(Texture.fromBitmap(new crateImage()));    
}


Draw Calls
The game should be running perfectly without any problem. But if you see on the Starling stats monitor at the top left of the screen, you’ll see that it used more than 50 draw calls.

StarlingTiled12

What is draw calls? While I’m not pretty sure about that, from what I know it’ll really give some effect to your game performance. The more draw calls the more chance that the game performance will be dropped, especially if you’re working for a mobile game.

So let’s reduce it by merge our asset into one big texture atlas. Collect the previously created atlases or art into one single folder. Then using the same Shoebox’s Sprite Sheet function, we create another texture atlas.

starling tiled map citrus engine

Open the created XML file on your code editor, the remove file extension on each SubTexture’s name property. We’ll use this name property to get specified texture from this merged atlas.

StarlingTiled14

Now, instead embedding different PNG files for different objects, we can just embed this previously created PNG file. So the embedding codes in the game state class should be look like this:
private var textureAtlas:TextureAtlas;   
        
[Embed(source="../assets/bitmap/atlas/sprites.png")]    
private var atlasImage:Class;    
        
[Embed(source="../assets/bitmap/atlas/sprites.xml",mimeType="application/octet-stream")]    
private var atlasXML:Class;    
        
[Embed(source="../assets/bitmap/tiles/Tileset.tmx",mimeType="application/octet-stream")]    
private const tileMap:Class;    
         
[Embed(source="../assets/bitmap/tiles/sprites.xml",mimeType="application/octet-stream")]    
private const tileMapXML:Class;    
        
[Embed(source="../assets/bitmap/hero/sprites.xml",mimeType="application/octet-stream")]    
private const heroXML:Class;    
        
[Embed(source="../assets/bitmap/enemy/slime/sprites.xml",mimeType="application/octet-stream")]    
private const slimeXML:Class;    
        
[Embed(source="../assets/bitmap/enemy/snail/sprites.xml",mimeType="application/octet-stream")]    
private const snailXML:Class;



We just embed one merged PNG file. No more embedding each different object’s PNG file.

So, to use it we need to create a TextureAtlas object.
textureAtlas = new TextureAtlas(Texture.fromBitmap(new atlasImage()), XML(new atlasXML()));

If this object already created, we can simply call the getTexture() function to gather the specified object’s atlas or image.
For the hero, now we do something like this to create the atlas:
var heroAtlas:TextureAtlas = new TextureAtlas(textureAtlas.getTexture("hero"), XML(new heroXML()));


And for non animated object as well:
Crate(getObjectsByType(Crate)[i]).view = new Image(textureAtlas.getTexture("box"));


Simply call getTexture() function from textureAtlas object, and insert specified name to its parameter.

Compile and run the game to see the difference…

StarlingTiled15

Yep, now it’s only have three draw calls. That’s a huge difference.

The End
Well, this is the end of the article
You can test the finished game, as well as the source code.

download

Shameless Promotions
Just in case you need some tilesets, game characters, and/or game interfacesNyah-Nyah

royalty free game tile set

royalty free game sprite sheet

royalty free game interface

Or go here to view the complete items.


Btw, why the heck the colors on some of the image on this article became washed out?

4 comments:

Citrus Engine: Creating Level using Tiled Map Editor

Been using Citrus Engine for my several projects, but I never used any level editors, even if it’s possible to use Flash Pro as level editor. So, I think I need to give a try for CE supported level editors: Gleed2D, Level Architect, Tiled Map Editor, and Flash Pro itself.

Level Architect is eliminated early since it’s obsolete and not supported by latest CE version. Flash Pro might be great, but not what I’m looking for. I prefer a tile-based editors.
Why? because it’s the most efficient way to make a various level with very minimal assets. Creating a whole different art scene for each level will be a pain on my ass. Not to mention if it will also increase a lot of your file size.

I also tried Gleed2D, although it’s not a tile-based editor, but unfortunately Gleed2D crashed without any clear reasons when I attempting to open this application.

In the end, I’m using Tiled Map Editor. And after for about a day tinkering with this tool, and definitely the level editor I’m looking for. 

citrus engine tiled map editor

So, how to set-up this tool with CE? As I told before, it’s the level editor supported by CE, so there is a built-in parser on CE to read Tiled Map Editor file format (.tmx) which work like a magic… Open-mouthed smile

First things first, before we’re going too far, I just wanna let you know that it’s a CE with Display List mode, not the Starling one. But it could be also used for Starling CE. You can check my latest blog post about that here.

=====================
If you want to read the other Citrus Engine tutorial part, here are all the links:
1. Game Structure
2. Adding Screen Transition
3. Head-Up Display
4. Working with Data
5. Creating Level using Tiled Map Editor
=====================

Getting Started
Alright, let’s create a CE project on your Flash Develop. No more explanation for this step.
So, let’s jump to the next step: Creating the tileset.
tiled map editor citrus engine

For this sample, I’m using this free and cute art from Kenney at OpenGameArt.com. I arranged it into a 64x64 px tileset without spacing. I include anything from the ground tiles, decorations, to sky background. Yep, I’ll use a tiles for background also. Going so retro with no fancy background, and you’ll also lose the parallax function, but it’ll reduce the game resource, a lot.

Working with Tiled Map Editor
Tileset image ready, next step is importing it to the Tiled Map Editor. Open the application, create a new project.
To import the tileset image, go to Map –> New Tileset
tiled map editor citrus engine

Browse to your saved tileset image file. And change the name to the exact same with your tileset image name. In this sample, both image and tileset are named as “Tileset.png”. It’s very important, as the name will be used to parse the map to CE.

When the tileset already imported, you can see your already-sliced tileset appear on the bottom right dock of the app.
tiled map editor citrus engine

Okay, fun time…. click the specified tile and start drawing your game…
tiled map editor citrus engine

All done? Not yet. You need to specify the Citrus Object placement. The platforms, hero, enemies, crates, coins, etc.
How to do that? No worry it’s a piece of cake. Create a new Object Layer:
tiled map editor citrus engine

Now draw the CE objects using this available tools…
tiled map editor citrus engine

tiled map editor citrus engine

See these transparent squares? Yep, it’s the Citrus Objects I’ve drawn.
You can enable the Snap to Grid option on the View toolbar. It will really help to draw a perfect square that will match to the tile size. Will be very usable to draw the platform objects.

Almost done. Now you need to specify each type of the Citrus objects. Right click on the object, select Object Properties. A window will be opened:
tiled9

Object’s name is optional, so you can leave it blank. The most important is its type. Fill it with a complete path of the citrus object. So if it’s a Platform, the type will be: citrus.object.platformer.box2d.Platform as shown on the image above.

Do the same for other platform objects. Wut? Yes, this is the bad things from this app. You can’t change a bunch of objects properties at once and at the same time. So, for non-platform objects like enemy, coin, crates, etc you’d better create one object first, modify the properties, and then duplicate it.
tiled8

For non-platform objects, not much difference. But you can also modify its property in this app. Also, you can specify the view property in here too.
tiled10

The above image shows the property of Hero object. You need to give him a name as we will use it to set up the camera later.
Can you see this properties: canDuck, maxVelocity, view, etc? Yep, that’s the CE Hero object properties. You can simply define them here.

Non-Platform Art Creation
For non-platform objects I use Flash Pro to create its view and animation. Give them their linkage name then compiled them to a SWC file.
For example, I can access the hero view via its linkage name: CharMC.
You can take a look on my  Flash Pro library:
tiled11

The view for moving platforms, crates, coins, & enemies also created via Flash Pro.

Coding Time…
Level creation is done. Open your FlashDevelop project and crate a new state:

package
{     
    import citrus.math.MathVector;     
    import citrus.objects.platformer.box2d.Coin;     
    import citrus.objects.platformer.box2d.Enemy;     
    import citrus.objects.platformer.box2d.Hero;     
    import citrus.objects.platformer.box2d.MovingPlatform;     
    import citrus.objects.platformer.box2d.Platform;
    import citrus.objects.platformer.box2d.Crate;
    import citrus.physics.box2d.Box2D;     
    import citrus.utils.objectmakers.ObjectMaker2D;     
    import flash.display.Bitmap;     
    import flash.geom.Rectangle;     
 
    public class GameState extends State     
    {     
        [Embed(source="../assets/tmx/platformer.tmx", mimeType="application/octet-stream")]     
        private var tileMap:Class;     
        
        [Embed(source="../assets/tmx/Tileset.png")]     
        private var tileView:Class;     
       
        public function GameState()     
        {     
            super();    
           
            var objects:Array = [Hero, Crate, Platform, MovingPlatform, Enemy, Coin];     
        }    
       
        override public function initialize():void     
        {     
            super.initialize();     
            
            var box2D:Box2D = new Box2D("box2D");     
            //box2D.visible = true;     
            add(box2D);     
            
            var bitmapView:Bitmap = new tileView();     
            bitmapView.name = "Tileset.png";     
           
            ObjectMaker2D.FromTiledMap(XML(new tileMap()), [bitmapView]);     
            
            var hero:Hero = getObjectByName("hero") as Hero;     
            
            view.camera.setUp(hero, new MathVector(300, 200), new Rectangle(0, 0, 1472, 576));     
        }     
    }     
}


A pretty minimal code for a game with not-so-basic-level… I don't know smile

16-20: Embed the .TMX and .PNG file.
TMX is a Tiled Map Editor save files. While the PNG is a Tileset image we’ve created before. Give each of them a reference class: tileMap for the map and tileView for its view / tileset image.

26: I don’t know the exact cause, but if you don’t include all used CE objects in this array, you’ll get an error…
I almost gave up using Tiled Map Editor with CE before because of this issue. But after seeing the example here, which mentioned that line, everything work like a charm.

37-38: We need to convert the tileView into a bitmap first. And give it a name.
Exact same name with the tileset image file and also tileset that imported to Tiled Map Editor: Tileset.png

40: Execute the parser function.
The first parameter, we need to convert the tileMap as an XML. And on the second parameter, insert the bitmap into an array.

42-44: That’s why we need to define a name for the hero before… Smile

For the SWC file, don’t forget to add it to your library. Right click –> Add to Library:
tiled12

And change its options (Right click –> Options),  to be like this, or it won’t work at all:
tiled13

Everything done… YAY… Open-mouthed smile

Run Time…
Compile it and see the result…

Issues
Not everything work smoothly like as expected. I found some issues with this method. Well, it must be because of my noobness… Smile with tongue out

1. So far, what I know to define a view for non-platform objects that created on Tiled Map Editor is only can be done via their linkage name on FLA, SWC, or (probably) SWF. And via string of the image path, for example: “../assets/hero/hero.png”

For an assets that embedded via code seems to be not work. I’ve tried it, and don’t know why, the ObjectMaker can’t locate the reference class for the view although it’s already declared on the state class.

Define the view on the code like this also not work.
Hero(getObjectbyName(“hero”)).view = HeroMC;

You’ll get "…must be child of the caller”  error…

But if you create the objects not in the Tiled Map Editor, it will be work normally. But you’ll need to set its position manually on the game level.

2. I have no idea to use multiple tilesets image. It supported on Tiled Map Editor. The CE parser itself also accept array of tilesets, which means I can use multiple image for a map. But when I insert more that one tileset images on the array, I got this error: "ObjectMaker didn't find an image name corresponding to the tileset imagesource name, add its name to your bitmap."
The solution? Simply using all-in-one tileset image.

3. I think there is something weird with the parser. The tile that positioned on the very right side and not in the first row sometimes not drawn. Although it’s shown on Tiled Map Editor, but when the game compiled it’s magically gone…
That’s why I arranged my tileset oddly like this:
tiled14

I keep the last tile on the first row but will leave 5 blank tiles. Not the efficient way to create a tileset, but unfortunately, seems that this is the only way to sort the problem.

4. The position and size unit used on Tiled Map Editor isn’t pixel and I can’t find a way to change it to another format. So it will be quite a mess when you want to match the object size with their view / image size. Also when you want to define a position, like when defining the end position of a moving platform.

5. As mentioned before, you cannot do a ctrl-click to select multiple objects and change their properties at once…

Although there are few spotted issues, using this tool definitely better solution than built the level via hard-code, like what I’ve been done to my several CE games. LOL

Source Code:
download

Just Some Self-Ads…
I sell some game assets on my game asset store, if you’re looking a cheap tileset for your Citrus Engine game… Smile with tongue out
Samples:
platformer tile set for sale
platformer tile set for sale

Or simply take a look to the complete list of the items:

24 comments: