Obtain custom properties from tile layer in tmx file

Hi!

How can I get the custom properties of a tile so that when I iterate the whole tmx map I check every single tile and if it has a custom property named phys and the value for that is done then something more would happen to that specific tile?
Hope you understand my point.
Thanks!

Btw this should be the code for object but I want the thing for tiles and checking its custom properties:

 // loop over the object groups in this tmx file
  auto objectGroups = map->getObjectGroups();
  for (auto& objectGroup : objectGroups)
  {
    auto objects = objectGroup->getObjects();
    for (auto& object : objects)
    {
      auto properties = object.asValueMap();
      auto type = properties.at("type");
      if (!type.isNull())
      {
        this->addObject(type.asString().c_str(), properties);
        this->objectCount++;
      }
    }
  }

Update: The reason is I cannot really find any c++ info about how to retrieve it from a tile layer but only from an object layer

in javascript it’s this._tiledMap.getPropertiesForGID(this._layerItem.getTileGIDAt(nTile));
where nTile is a cc.p(x,y), note that if you wan’t to check for tiles on multiple layers you’ll have to check each layer.

it seems the methods are the same: http://www.cocos2d-x.org/docs/api-ref/cplusplus/v3x/d6/d48/classcocos2d_1_1_t_m_x_tiled_map.html

just iterate through the tilemap using a nested for loop (one for x one for y) and create a cc.p to get the GID from the layer, then get the properties of the gid from the tiledmap

hope this is what you were looking for, note that these properties will be the same for all tiles with the same texture

Thank you so much!!! I am gonna test this in a minute

But don’t you have to use the tile coordinates and not x,y when getting the GID?
Because then i have to make a functiont that can convert that which i don’t really know the calculations for…

Thanks Again

Like this:

	int tileGid = _meta->tileGIDAt(Point(x,y));
	if (tileGid) {
		CCDictionary *properties = _tileMap->propertiesForGID(tileGid);
		if (properties) {
			CCString *collision = new CCString();
			*collision = *properties->valueForKey("Collidable");
			if (collision && (collision->compare("True") == 0)) {
				return;
			}
		}
	}

where when using tileGIDAt, it should probably be tile coordinates correct? Because it does not really seem to work atm

you are correct, the cc.p is in tile coordinates, should have been more clear on that, just thought of the tile coordinates as x and y axes of a grid.

But what do you do to convert x, y coordinates to tile coordinates then? Because I need that to go on :))))

What you need to do if the screen only shows a part of your map ist to subtract the offset of the maps position, divide x by tilewidth and y by tileheight, then floor the result (this is simple for orthogonal maps).

here’s the method i used before switching to isometric (and inviting a world of trouble into my life XD)

_getTilePos: function(posInPixel) {

    var mapSize = this.node.getContentSize();
    var tileSize = this._tiledMap.getTileSize();

    var x = Math.floor(posInPixel.x / tileSize.width);
    var y = Math.floor((mapSize.height - posInPixel.y) / tileSize.height);

    return cc.p(x, y);

},

For isometric maps you’ll need to apply a little more math and figure out some magic numbers (in the case of my 60x60 isometric tilemap they were 89 and 29, as you can see it was a bit frustrating and written late at night so I just consider this part of my code ‘valid’ but I’ll need to keep an eye on it and figure out the formula for the magic numbers so that the solution is scalable):

_getTilePos: function(posInPixel) {

    var tileSize = this._tiledMap.getTileSize();
    var mapPos=this._tiledMap.node.getPosition();

    var y = 89-Math.floor(((posInPixel.x-mapPos.x)/(tileSize.width/2)+(posInPixel.y-mapPos.y)/(tileSize.height/2))/2);
    var x = 29-Math.floor(((posInPixel.y-mapPos.y)/(tileSize.height/2)-(posInPixel.x-mapPos.x)/(tileSize.width/2))/2);

    return cc.p(x, y);

},

If there is a more elegant way to do this, I’d like to know as well^^

cheers

Wow thank you so much!

But I have have one more and probably the final question(not really to @fliegenfuerst since he uses javascript) but why is this code not working and I get an error that says: "No suitable conversion from cocos2d::ValueMap to cocos2d::Dictionary when creating the properties?

Point tileCoord = this->tileCoordForPosition(Point(x,y));
	int tileGid = layer->tileGIDAt(tileCoord);
	if (tileGid) {
		Dictionary *properties = map->getPropertiesForGID(tileGid).asValueMap();
		if (properties) {
			String *collision = new String();
			*collision = *properties->valueForKey("Collidable");
			if (collision && (collision->compare("True") == 0)) {
				return;
			}
		}
	}

@slackmoehrle maybe?