HKTMXTiledMap Ported to Cocos2d-x

I would really like to use the standard CCTMXTiledMap in cocos2d-x but I find that for larger maps it is just too slow. The main problem being that it makes no attempt to limit drawing only visible tiles.

HKTMXTiledMap is suppose to address that but is only available for cocos2d-iphone (http://www.hkasoftware.com/fileserve/HKTMXTiledMap/cocos2d2.1/).

I have attached four files (zipped) that I have converted to work in cocos2d-x. Use it the way you would CCTMXTiledMap.

I no longer have time to work on this right now so I am hoping that someone else can take over. There are two problems:

  1. “OpenGL error 0x0500” errors. They don’t stop it from working, but should be addressed.
  2. It does not seem to return the correct gid based on screen coords. I only tested this quickly.

Keep in mind that I have done absolutely nothing to optimize it, just got it to compile/run so there are a number of ways it can be improved.

Please share your changes as you make them for everyone’s benefit.

Thanks


HKTMXTiledMap.zip (10.9 KB)

Thanks for posting this!

The project I am currently working on wouldn’t be able to use this, but I’m sure this will come in handy in future projects. Please let me know if you were able to fix any of the problems. I think not being able to return the correct gid could be pretty problematic.

I had some time to work on this again and I’ve attached the updated files. The GID is correct and now the OpenGL error only happens when the app starts, before it was constant. Again, the error doesn’t seem to have any negative effect. It has to do with ccGLBlendFunc in HKTMXLayer::draw. I really don’t know anything about this so if anyone can fix it that would be great.

Things to note:

  1. I had no use for the animation feature of the class so I doubt it works but I kept the code in there for the sake of being complete.
  2. I have only tested this in the win32 project, at this point I have no idea how/if it works on other platforms.

If anyone wants to optimize/improve the code please do so and be sure to post the changes here.

Thanks

Why not enhance the basic version of TileMap?

Ideally there would be an option in CCTMXTiledMap to render only visible tiles, although I assume there is a reason for this option not existing.

Personally I don’t like to alter the core cocos2d classes because it means potential issues when upgrading, and it seems like cocos2d-x is constantly changing, especially with the transition from version 2 to 3.

The reality is even if I decided to make the changes to CCTMXTiledMap it wouldn’t get finished for a very long time. As you can see in this thread, there was months between my initial attempt and follow up in porting this, I just don’t have the time. My hope in posting the files was that someone would help in polishing the code but it doesn’t seem like anyone else is interested.

Thanks a lot Daniel for the code! In case I manage to improve on it, I’ll post it here!

It’s GREATE!! Thank Daniel !

Thanks Daniel.

I read that HKTMXTiledMap is faster that the current code.
I haven’t read the HKTMXTiledMap code yet, but could you briefly describe how it works ?

I would happily replace the current TMX implementation with HK if it is faster, supports all the current features (and bonus point for having a code that it is easier to maintain).

Do you have your code hosted in github ?

Thanks!

I read the KHTMXTiledMap source code and I like the way it works.

It has some limitations like:

  1. only works for orthogonal maps, but adding isometric support seems to be trivial
  2. you cannot convert a Tile into a Sprite
  3. I haven’t tested it yet, but I do not know if it will OK if you rotate/scale the whole tilemap
  4. It says that it only supports dimensions that are Power Of Two (eg: 256 x 512)

but it has great features:
5) super fast for big maps
6) supports maps of any size

My take:
cocos2d needs something like KHTMXTileMap. 5) and 6) are great feature and we need something like that.

How to solve the limitations:

  1. it seems to be somewhat easy to fix that
  2. this is not trivial to fix, although this use case is not very popular, so I’m OK in removing this feature, or, if you want to support this feature you have to use the old (current) version of TMX
  3. This could be a big issue if it is not currently solved. But it shouldn’t be difficult to fix it.
  4. not sure why, but it should be easy to fix this limitation.

Hi Ricardo, it’d be great if the HKTMXTiledMap was included in the Cocos2D-X repository. It’d be a killer if isometric maps too could be supported.

I had been trying to use it for one of my Android games but it kept giving me “Called unimplemented OpenGL ES API” error at line 103 (line shown below), even though I’m using GLES v2 in the game.

screenGrid = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);

I couldn’t find anything helpful on Google. Can you tell me what can I do to get this fixed?

@Abhimannyu:

Yes, I’m working on it.

It is based on HKTMX but it won’t be a literal port.

Progress:

  • Orthogonal: supported
  • Isometric: supported with some bugs
  • HKAnimations: not supported (and won’t be supported for the moment)
  • Flipped tiles: Not supported yet. Working on this
  • Possibility to convert a tile into sprite: Not supported yet. Working on this.
  • Scaled / Rotated tile maps: Not supported. It is in the roadmap, but low priority.
  • Integration with CCTMXTiledMap: Not yet, but will add this this week.

Basically I’m using a similar logic to HK… with some changes. The performance is similar to HK, perhaps this implementation is just a tiny bit faster.
It fixes some of the limitations of HK like Isometric, and fixes a other HK bugs like overlapped tiles.

This is still “work in progress”.

Hey Ric,

Im working in an pathfinding A* extension for cocos2d-x and one way of using it is going to be with tilemaps.

The idea is to leverage on the grid structure of the tilemap and the ability to declare properties on individual tiles on the map. The properties would be something like “pathfinder_isWalkable: false”, “pathfinder_cost: 10” etc…

If the tile doesn’t have any properties is going to use some default values.

So what im doing is looping through all the cells on the grid of the tilemap get the GID of the tile for that position and than get the Properties of the tile.

The problem is that if a tile has no properties the getPropertiesForGID creates a new object.

The current function:

Value TMXTiledMap::getPropertiesForGID(int GID) const
{
    if (_tileProperties.find(GID) != _tileProperties.end())
        return _tileProperties.at(GID);
    
    return Value();
}

Creating this new object can be expensive (Testing on windows) in a 100x100 where i mostly have tiles with no properties it takes 1100 ms to loop through all of them.

So i had to add a alternative function that is not going to create a new object if the tile has no properties, to make my test usable.

Alternative function:

bool TMXTiledMap::getPropertiesForGID(int GID, Value** value)
{
	if (_tileProperties.find(GID) != _tileProperties.end()) {
        *value = &_tileProperties.at(GID);
		return true;
	} else {
		return false;
	}        
}

Example use:

Value* tilePropertiesValue = NULL;
if (tileMap->getPropertiesForGID(gid, &tilePropertiesValue )) {
    ValueMap tileProperties = tilePropertiesValue->asValueMap();
    //do what you need with the tile properties
} else {
    //handle no properties on tile
}

This made a big difference from the previos 1100 ms to 12 ms.

I already made a pull request for this:
https://github.com/cocos2d/cocos2d-x/pull/5279

So now that you are working on the tilemaps i was wondering if we could add this or something similar.

What do you think about this?

@Ric and @Edba, both of you are awesome. thanks a lot guys.

@Ric, please do let us know when you are done with the fast_tmx.
Also, I feel HKAnimation is an extremely useful way of implementing simple repetitive background animations (without involving a developer). I’d request you to keep that feature if possible

@edba:
Thanks, your code looks good.
An alternative is to return nullptr if the GID is not found. Although that will require some changes in the logic… like, who owns the Value now.

UPDATE : Pull request merged. thanks.

@abhimanyu:
thanks. Once it is ready, I’ll announce it here. It won’t include the HK animations, but feel free to send us the patch for that :-).

Sure… will try my best. :slight_smile:

Hi @Ricardo, can you confirm if I can start using the fast_tmx. Sorry to be bothering you so much… :smiley: