Cocos2D-X Tile Map Tutorial: Part 2
Part 2 of a Cocos2D-X tile map tutorial series about his ninja and his quest for watermelon. By Jorge Jordán.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Cocos2D-X Tile Map Tutorial: Part 2
15 mins
Welcome back to our 2-part Cocos2D-X tile map tutorial series!
Here you’ll learn how to make a tile-based game with Cocos2D-X, the cross-platform C++ port of Cocos2D-iPhone.
Note: This tutorial is a port of a similar tutorial for Cocos2D-iPhone. If you are looking for the Cocos2D-iPhone version, you can check it out here.
Note: This tutorial is a port of a similar tutorial for Cocos2D-iPhone. If you are looking for the Cocos2D-iPhone version, you can check it out here.
In the first part of the tutorial, you learned how to create a map with Tiled, how to add the map to the game, how to scroll the map to follow the player and how to use object layers.
This part of the tutorial covers how to make collidable areas in the map, how to use tile properties, how to make collectable items and modify the map dynamically, and how to make sure your ninja doesn’t overeat.
So let’s pick up where you left off last time and make the map a bit more game-like!
Tiled Maps and Collisions
You may have noticed that currently the ninja can move right through walls and obstacles with no problem at all. He is a ninja, but even ninjas aren’t that good!
So you need to figure out a way to mark some tiles as “collidable” so you can prevent the player from moving into those positions. There are many possible solutions to this (including using object layers), but I’m going to show you a new technique that I think is effective and also a good learning exercise – using a meta layer and layer properties.
Let’s dive right in! Load up Tiled again, click Layer\Add Tile Layer and name the Layer Meta. This is the layer you will be putting a few fake tiles in to indicate “special tiles”.
So now you need to add the special tiles. Click Map\New Tileset…, browse to meta_tiles.png in your TileGame\Resources\TileGameResources folder, and click Open. Set the Margin and Spacing to 1 and click OK.
With the Layers window selected, click on meta_tiles in the Tilesets window. You will see two tiles: red and green.

There is nothing at all special about these tiles – I just made a simple image with two red and green tiles with partial transparency. Henceforth, red means “collidable” and it will be used to paint the scene appropriately.
So make sure the Meta layer is selected, choose the Stamp Brush tool, choose the red tile, and paint over any object that you want the ninja to collide with. When you’re done it might look like the following:
Next, you need to set a property on the tile to flag it so you can recognize in code that this is the tile that is “collidable.” Right click on the red tile in the Tilesets section, and click Tile Properties…. Add a new property for Collidable set to True like the following:

Click OK, save the map and return to Xcode. Add a new private property to HelloWorldScene.h:
CCTMXLayer *_meta;
This will be a reference to your new meta layer. Add add a new public method declaration:
CCPoint tileCoordForPosition(CCPoint position);
This will be a helper routine you’ll write to convert a position to a tile coordinate.
Next open HelloWorldScene.cpp and add these lines to the the init method, right after loading background:
_meta = _tileMap->layerNamed("Meta");
_meta->setVisible(false);
This gets a reference to the meta layer, and turns it to be invisible. You don’t want the player to see red cactii!
Next, add this new method:
CCPoint HelloWorld::tileCoordForPosition(CCPoint position)
{
int x = position.x / _tileMap->getTileSize().width;
int y = ((_tileMap->getMapSize().height * _tileMap->getTileSize().height) - position.y) / _tileMap->getTileSize().height;
return ccp(x, y);
}
Ok let’s stop here a second. Here you declare a member/variable for the meta layer as usual, and load a reference from the tile map. Note that you mark the layer as invisible since you don’t want to see these objects, they are for annotating what is collidable only.
Next you add a new helper method that helps you convert x,y coordinates to “tile coordinates”. Each of the tiles has a coordinate, starting with (0,0) for the upper left and (49,49) for the bottom right (in your case).
The above screenshot is from an older (Java) version of Tiled, by the way. Showing the coordinates for tiles is a feature they’ve ported to newer (Qt) version yet.
Anyway, some of the functions you’re about to use require tile coordinates rather than x,y coordintes, so you need a way to convert the x,y coordinates into tile coordinates. This is exactly what the function tileCoordForPosition does!
Getting the x coordinate is easy – you just divide it by the width of a tile. To get the y coordinate, you have to flip things around because in Cocos2D-X (0,0) is at the bottom left, not the top left.
Next replace the contents of setPlayerPosition with the following:
void HelloWorld::setPlayerPosition(CCPoint position)
{
CCPoint tileCoord = this->tileCoordForPosition(position);
int tileGid = _meta->tileGIDAt(tileCoord);
if (tileGid) {
CCDictionary *properties = _tileMap->propertiesForGID(tileGid);
if (properties) {
CCString *collision = new CCString();
*collision = *properties->valueForKey("Collidable");
if (collision && (collision->compare("True") == 0)) {
return;
}
}
}
_player->setPosition(position);
}
Here you convert the x,y coordinates for the player to tile coordinates. Then you use the tileGIDAt function in the meta layer to get the GID at the specified tile coordinate.
Huh, what’s a GID? GID stands for “globally unique identifier” (I think). But in this case I like to think of it as the id for the tile is used, which would be the red square if that’s where you’re trying to move.
You then use the GID to look up properties for that tile. It returns a dictionary of properties, so you look through to see if Collidable is set to true, and if it is you return immediately, hence not setting the player position and making the move invalid.
And that’s it! Build and run the project, and you should now no longer be able to walk through any tiles you painted red: