Tile is nil

Im new to Corona, Lime, Lua and even mobile applications :P, and dont understand very well how to make some things to work.

I would like some help, because Im trying to get a tile object out of screen x and y positions(event.x, event.y) in an isometric map, whenever someone clicks on a tile. The problem is the tile always returns nil(I have tried to get the positions right, but nothing I have done works, so I would like some help

I thank you before hand, for taking the time to read this and helping if you can.

Here’s the last code I tried to make this work:

--Converting screen position to world...  
local screenToWorld = lime.utils.screenToWorldPosition(map, event)  
--...then to isometric  
local isoPosition = lime.utils.worldToIsometricPosition(map, screenToWorld)  
  
--tile now is nil  
--returned isoPosition.x would be something like 2, then just a little to the right would be -5.5  
local tile = grassLayer:getTileAt(isoPosition,false)  

I have tried to get the tile with the positions returned by functions(like worldToIsometricPosition(), IsometricToWorldPosition(), screenToGridPosition(), regular event.x and event.y, sending event as the position), but nothing so far has worked. I really appreciate any help, and it would be great if somebody could explain to me the difference between map, grid and world(as I dont know whats the difference will be between the position returned by all of these) or point to a tutorial or something of the sort [import]uid: 109816 topic_id: 19147 reply_id: 319147[/import]

Hey, welcome to the world of mobile development!

Firstly I will explain the different coordinate systems.

Screen Position - This is, as you have most likely worked out, the exact position something is on the current screen relative the the screen origin.

World Position - This is the exact pixel position of something relative to the maps origin.

Grid Position - This is the row and column number of a tile/object relative to the maps origin.

Secondly, you will need to add a little bit of code into “lime-utils.lua”, find the function “worldToGridPosition” and you will see an empty block after a check for the “isometric” orientation, simply add this code to it:

  
local xScale, yScale = \_map:getScale()  
  
\_gridPosition.column = floor( \_position.y / ( \_map.tileheight \* yScale ) + \_position.x / ( \_map.tilewidth \* xScale ) )  
\_gridPosition.row = floor( \_position.y / ( \_map.tileheight \* yScale ) - \_position.x / ( \_map.tilewidth \* xScale ) )  
  

Now somewhere in your code, depending on how your game is structured, you will want code like this:

[code]

local onTap = function( event )

– First just get the screen position from the passed in table
local screenPosition = { x = event.x, y = event.y }

– Now convert that to a world position
local worldPosition = lime.utils.screenToWorldPosition( map, screenPosition )

– And finally convert the world position to a grid position
local gridPosition = lime.utils.worldToGridPosition( map, worldPosition )

– Now access the top most tile at that position, you may wish to use a specific TileLayer instead of the whole map but that is up to you.
local tile = map:getTileAt( gridPosition )

– Just to prove it works, slightly alpha out the tile
if tile then
tile:getVisual().alpha = 0.5
end

end

Runtime:addEventListener( “tap”, onTap )

[/code] [import]uid: 5833 topic_id: 19147 reply_id: 73947[/import]

Great man, seriously thank you! It works perfectly, I get the tile, just a detail, when I tap on a tile, it highlights not that tile, but the tile diagonal to it(not the tapped tile), is that normal?

Thank you, seriously :P, and for the quick response [import]uid: 109816 topic_id: 19147 reply_id: 73966[/import]

Whoops my bad, in the first block of code you also need to add these two lines of code:

\_gridPosition.row = \_gridPosition.row - 1  
\_gridPosition.column = \_gridPosition.column - 1  

I will update my earlier post to show how it should go.

  • Edit -

Ok I can’t update my previous post so it should look like this

[code]

local xScale, yScale = _map:getScale()

_gridPosition.column = floor( _position.y / ( _map.tileheight * yScale ) + _position.x / ( _map.tilewidth * xScale ) )
_gridPosition.row = floor( _position.y / ( _map.tileheight * yScale ) - _position.x / ( _map.tilewidth * xScale ) )

_gridPosition.row = _gridPosition.row - 1
_gridPosition.column = _gridPosition.column - 1

[/code] [import]uid: 5833 topic_id: 19147 reply_id: 73968[/import]

Yeah, thanks, It works perfectly right now. One quick question if I dont take much of your time, how do I know what’s the gid to put on setImage().
Im working with the IsometricAndPlayer example(with the map and the tileset), I tried this:

if tile then  
 tile:setImage(0)  
 --Also tried setting the gid to 1 and 2  
end  

I want to change the tile for another one(grass to grass with small lake) whenever a tile is tapped. Appreciate your help [import]uid: 109816 topic_id: 19147 reply_id: 73969[/import]

The GID is controlled by your Tilesets in Tiled.

Essentially each individual tile in a tileset has an ID, these start from 1 and then go sequentially up from left to right, top to bottom. With me so far?

Then the GID ( global id ) is the tiles’ ID but each tilesets first id is 1 more than the last id of the previous tileset.

http://dl.dropbox.com/u/571145/globalIDs.png [import]uid: 5833 topic_id: 19147 reply_id: 73971[/import]

Ok, I think I understand, but right now I only have 1 tileset(with 3 tiles), so the first tile should be GID == 1, right? But whenever I tap on the tile(with tile:setImage(1)) it only highlights(or alpha) the tile not changing the tile.

Thanks for taking your time helping me out [import]uid: 109816 topic_id: 19147 reply_id: 73972[/import]

Yup that is correct, ID 1.

If you go into “lime-tile.lua”, find the function Tile:setImage() and scroll to the bottom if it, just after these lines:

-- Build the tile physical  
self:build()  

Place these:

-- Bring the new tile into focus  
self:getVisual():toFront()  
self:getVisual().isVisible = true  

See if that works. [import]uid: 5833 topic_id: 19147 reply_id: 73976[/import]

Yes, now it works perfectly. Thank you! You’re great :P, thank you so much [import]uid: 109816 topic_id: 19147 reply_id: 73980[/import]

Awesome, glad it does! [import]uid: 5833 topic_id: 19147 reply_id: 73986[/import]

Hi, I used your code which shows the tile where the screen is touched.

But i can’t run that code, it gives me error like this

…\lime\lime-utils.lua:267 bad argument #1 to floor (number expected, got nill)

_ _

_ …\lime\lime-utils.lua:267 in function ‘screenToWorldPosition’ _

I’ve attached the snapshot of error too.

Kindly tell me why this error is happening. I’ll be very thankful to you.

Hi, I used your code which shows the tile where the screen is touched.

But i can’t run that code, it gives me error like this

…\lime\lime-utils.lua:267 bad argument #1 to floor (number expected, got nill)

_ _

_ …\lime\lime-utils.lua:267 in function ‘screenToWorldPosition’ _

I’ve attached the snapshot of error too.

Kindly tell me why this error is happening. I’ll be very thankful to you.