How to iterate tiles like layer.objects():

So I want to check how many tiles named “coin” I have in my map.

This is my attempt:

[lua]

local i = 0

for tile in map.layer[“tileobjects”].tilesInRect(map.width*0.5,map.height*0.5,map.width,map.height) do

    if tile.name and tile.name == “coin” then

         i = i+1

    end

end

print("coins in map: ",i)

[/lua]

Loop took ~1 minute and I got 0 in result when there were supposed to be 9 coins… :smiley:

So is there other method to do this?

Coordinates for tilesInRect are specified in tiles. I think that’s where you’re going wrong. You’re iterating along something like 500,000 tiles. Now that you bring this up, though, it does make more sense for tilesInRect to be pixels.

  • Caleb

Thanks Caleb that helped with the too long loop problem, but now I noticed that this loop only iterates built tiles, not culled tiles included. Is there a way to iterate all tiles in layer? :slight_smile:

Hm. There isn’t really a way to iterate tiles that aren’t built, because… they’re not built. I’m open to suggestions on how this would work, though. What are you thinking of? Would something like this help (function names definitely not defined yet!):

local tileGIDs = map.getTileGIDsWithProperty("name", "coin") -- Find all the tile GIDs which have the property "name" set to "coin" for gid, x, y in layer.tileGIDs() do -- Iterate through all data GIDs if gid is in tileGIDs then print("The tile at " .. x .. "," .. y .. " is one of the tiles with coin property") end end
  • Caleb

Just wanted to share how I solved a simular problem:

I needed to move the camera so it had a certain object in the middle. So before the scene is visible:

  1. Find all objects of a given type.

  2. Loop through the objects and check if it was the certain one.

if not:

  1. Get the cameras viewpoint and move the camera from the current viewpoint + the width of the screen (My map has a height of  the screen, so only in the x direction.)

  2. Then find all objects again

  3. Check the objects again, if not move the camera etc etc

In your case you move the camera to the end of the map counting all coins, and then back to start again before showing the scene.

I guess when moving the camera, it should move by the culling width, but in my case that type of accuracy is not needed.

Objects are a different matter. There is an iterator to iterate all object datas regardless of build status:

for data in map.layer["object layer"].objDatas() do -- 'data' will refer to each object's data stored in Dusk's core object data structure. -- Some things you might need to know about the structure: -- `data.type` = the type of object (viz. "rect", "ellipse", etc.) -- `data.transfer` = properties which will be set on the object when it's created. For example, this has `transfer.x` set to the object's final X position, `transfer.rotation` set to the rotation, etc. Anything you set in here will show up on the object when it's built. end
  • Caleb

Well, that solves my issue a bit more elegant :slight_smile:
But wouldnt my method work with tiles?

The map.getTileGIDsWithProperty function sounds good. Could the function work also without property value parameter? The loop also seems nice. Could the layer.tileGIDs function also work iterating only the specific tilelayer like layer[“layername”].tileGIDs?

Coordinates for tilesInRect are specified in tiles. I think that’s where you’re going wrong. You’re iterating along something like 500,000 tiles. Now that you bring this up, though, it does make more sense for tilesInRect to be pixels.

  • Caleb

Thanks Caleb that helped with the too long loop problem, but now I noticed that this loop only iterates built tiles, not culled tiles included. Is there a way to iterate all tiles in layer? :slight_smile:

Hm. There isn’t really a way to iterate tiles that aren’t built, because… they’re not built. I’m open to suggestions on how this would work, though. What are you thinking of? Would something like this help (function names definitely not defined yet!):

local tileGIDs = map.getTileGIDsWithProperty("name", "coin") -- Find all the tile GIDs which have the property "name" set to "coin" for gid, x, y in layer.tileGIDs() do -- Iterate through all data GIDs if gid is in tileGIDs then print("The tile at " .. x .. "," .. y .. " is one of the tiles with coin property") end end
  • Caleb

Just wanted to share how I solved a simular problem:

I needed to move the camera so it had a certain object in the middle. So before the scene is visible:

  1. Find all objects of a given type.

  2. Loop through the objects and check if it was the certain one.

if not:

  1. Get the cameras viewpoint and move the camera from the current viewpoint + the width of the screen (My map has a height of  the screen, so only in the x direction.)

  2. Then find all objects again

  3. Check the objects again, if not move the camera etc etc

In your case you move the camera to the end of the map counting all coins, and then back to start again before showing the scene.

I guess when moving the camera, it should move by the culling width, but in my case that type of accuracy is not needed.

Objects are a different matter. There is an iterator to iterate all object datas regardless of build status:

for data in map.layer["object layer"].objDatas() do -- 'data' will refer to each object's data stored in Dusk's core object data structure. -- Some things you might need to know about the structure: -- `data.type` = the type of object (viz. "rect", "ellipse", etc.) -- `data.transfer` = properties which will be set on the object when it's created. For example, this has `transfer.x` set to the object's final X position, `transfer.rotation` set to the rotation, etc. Anything you set in here will show up on the object when it's built. end
  • Caleb

Well, that solves my issue a bit more elegant :slight_smile:
But wouldnt my method work with tiles?

The map.getTileGIDsWithProperty function sounds good. Could the function work also without property value parameter? The loop also seems nice. Could the layer.tileGIDs function also work iterating only the specific tilelayer like layer[“layername”].tileGIDs?