Access custom tile property in event

Hi 

Using the Tile properties in the Tile Editor, I setup a custom property on one of my tile and I’m trying to access that custom property via the event object and it doesn’t seem to work. I’m trying to access the property in the collision event of my player sprite.

for example, my player collision listener

function playerPreCollision(event)      if event.other.mycustomproperty == 'ground' then         print('player is touching ground')     elseif event.other.mycustomproperty == 'coin' then         print('player got a coin')     end end  

event.other.mycustomproperty  always return nil. I’m able to get bodyType and other MTE recognized properties… but not my own properties. 

I know I can get the properties of a tile from its location using getTileProperties, but it seems natural to access it from the event object. Is this something possible?

if not, what are the common/normal technique used to detect if the player is touching a coin, ground, or special object in a physical context?

thanks in advanced  :slight_smile:

I have something similar in my game but I went about it a different way.

In Tiled, I set a tile as “collectable = true” ( a property ).

In Lua, I then do:

-- Based on Dyson's code found on these forums local myCollectableBlocks = {} local onCollectableProperty = function(event) myCollectableBlocks[#myCollectableBlocks + 1] = event.target:makeSprite() myCollectableBlocks[#myCollectableBlocks].bodyType = "static" -- optional myCollectableBlocks[#myCollectableBlocks].name = "collectable" mte.updateTile({locX = event.target.locX, locY = event.target.locY, tile = 0, layer = event.target.layer}) end mte.addPropertyListener("collectable", onCollectableProperty)

This swaps anything in Tiled that has the collectable property with a new sprite in it’s place.

Later in my code, I can use:

event.other.name == "collectable"

At the moment the display object representing a tile does not actually contain all of the tile’s properties as set in Tiled, only those properties needed by MTE. This is easy enough to change, though. MTE adds its own required properties to a tile object starting at line 4133:

rects[layer][rectX][rectY].sX = posX rects[layer][rectX][rectY].sY = posY rects[layer][rectX][rectY].x = displayGroupData[layer].sX + rects[layer][rectX][rectY].sX + offsetX rects[layer][rectX][rectY].y = displayGroupData[layer].sY + rects[layer][rectX][rectY].sY - offsetY rects[layer][rectX][rectY].layer = layer rects[layer][rectX][rectY].level = map.layers[layer].properties.level --getLevel(layer) rects[layer][rectX][rectY].locX = locX rects[layer][rectX][rectY].locY = locY rects[layer][rectX][rectY].index = frameIndex rects[layer][rectX][rectY].tileSet = tileSetIndex rects[layer][rectX][rectY].tile = tileStr

You can add the following block after the above lines to add the tile’s property table as well:

if map.tilesets[tileSetIndex].tileproperties then if map.tilesets[tileSetIndex].tileproperties[tileStr] then rects[layer][rectX][rectY].properties = map.tilesets[tileSetIndex].tileproperties[tileStr] end end

Then you would retrieve the properties in your function with event.other.properties.mycustomproperty. I’ll look into adding this to the next update as well.

Thanks guys!!

jdsmith:

I thought about this and I was seriously evaluating the possibility to do that, I have the feeling it’s better to do the dirty job when I initialize the map, instead of adding process time everytime the precollision and collision event occur. I’ll see how work dyson workaround.

dyson:

can’t wait to try this tonight. Do you consider adding this to the code? Seems pretty useful to me and at least another guy! ;)  

Seriously, that would be great if it was added to your code. If it doesn’t slow down the rendering and usability, I think it would make the physics interaction way easier and efficient.

thanks again for your help!

cheers!

Yes, I’ve added it to my current development build! I’m hoping to have the next update ready by the end of next week.

@jerars

I think you misunderstood my solution. It is ran only once (not inside enterFrame) and I believe it would only execute when a new tile becomes visible so I only imagine it being a performance issue if you are quickly scrolling the map or you have a ton of collectable tiles.

@dyson122

I do like your solution better than mine though so thanks.

It sounds like I could remove that code and simply add ‘physics = true’ and ‘bodyType = static’ to Tiled for the collectable tiles and I could still use the property checking for the ‘collectable’ attribute in collision detection.

Cool dyson! 

jdsmith:

yeah I think I got ya… I was saying that I prefer your technique to initialize the tile the way you do it only once after the map is loaded, than using the getTileProperty in my precollision event handler like I was doing in my actual version. 

The next update will do just great for me, thanks for adding this dyson! 

@dyson

That works like a charm! I’ll let you know if I encounter any issue.

thanks a bunch!

I have something similar in my game but I went about it a different way.

In Tiled, I set a tile as “collectable = true” ( a property ).

In Lua, I then do:

-- Based on Dyson's code found on these forums local myCollectableBlocks = {} local onCollectableProperty = function(event) myCollectableBlocks[#myCollectableBlocks + 1] = event.target:makeSprite() myCollectableBlocks[#myCollectableBlocks].bodyType = "static" -- optional myCollectableBlocks[#myCollectableBlocks].name = "collectable" mte.updateTile({locX = event.target.locX, locY = event.target.locY, tile = 0, layer = event.target.layer}) end mte.addPropertyListener("collectable", onCollectableProperty)

This swaps anything in Tiled that has the collectable property with a new sprite in it’s place.

Later in my code, I can use:

event.other.name == "collectable"

At the moment the display object representing a tile does not actually contain all of the tile’s properties as set in Tiled, only those properties needed by MTE. This is easy enough to change, though. MTE adds its own required properties to a tile object starting at line 4133:

rects[layer][rectX][rectY].sX = posX rects[layer][rectX][rectY].sY = posY rects[layer][rectX][rectY].x = displayGroupData[layer].sX + rects[layer][rectX][rectY].sX + offsetX rects[layer][rectX][rectY].y = displayGroupData[layer].sY + rects[layer][rectX][rectY].sY - offsetY rects[layer][rectX][rectY].layer = layer rects[layer][rectX][rectY].level = map.layers[layer].properties.level --getLevel(layer) rects[layer][rectX][rectY].locX = locX rects[layer][rectX][rectY].locY = locY rects[layer][rectX][rectY].index = frameIndex rects[layer][rectX][rectY].tileSet = tileSetIndex rects[layer][rectX][rectY].tile = tileStr

You can add the following block after the above lines to add the tile’s property table as well:

if map.tilesets[tileSetIndex].tileproperties then if map.tilesets[tileSetIndex].tileproperties[tileStr] then rects[layer][rectX][rectY].properties = map.tilesets[tileSetIndex].tileproperties[tileStr] end end

Then you would retrieve the properties in your function with event.other.properties.mycustomproperty. I’ll look into adding this to the next update as well.

Thanks guys!!

jdsmith:

I thought about this and I was seriously evaluating the possibility to do that, I have the feeling it’s better to do the dirty job when I initialize the map, instead of adding process time everytime the precollision and collision event occur. I’ll see how work dyson workaround.

dyson:

can’t wait to try this tonight. Do you consider adding this to the code? Seems pretty useful to me and at least another guy! ;)  

Seriously, that would be great if it was added to your code. If it doesn’t slow down the rendering and usability, I think it would make the physics interaction way easier and efficient.

thanks again for your help!

cheers!

Yes, I’ve added it to my current development build! I’m hoping to have the next update ready by the end of next week.

@jerars

I think you misunderstood my solution. It is ran only once (not inside enterFrame) and I believe it would only execute when a new tile becomes visible so I only imagine it being a performance issue if you are quickly scrolling the map or you have a ton of collectable tiles.

@dyson122

I do like your solution better than mine though so thanks.

It sounds like I could remove that code and simply add ‘physics = true’ and ‘bodyType = static’ to Tiled for the collectable tiles and I could still use the property checking for the ‘collectable’ attribute in collision detection.

Cool dyson! 

jdsmith:

yeah I think I got ya… I was saying that I prefer your technique to initialize the tile the way you do it only once after the map is loaded, than using the getTileProperty in my precollision event handler like I was doing in my actual version. 

The next update will do just great for me, thanks for adding this dyson! 

@dyson

That works like a charm! I’ll let you know if I encounter any issue.

thanks a bunch!

this was just what i needed too and this was already included in an update sometime since this posting.  

super easy to get the tile property on collision with event.other.properties.mycustomtimeproperty  

Great work and support!

this was just what i needed too and this was already included in an update sometime since this posting.  

super easy to get the tile property on collision with event.other.properties.mycustomtimeproperty  

Great work and support!