Retrieve grid position of touched object

Hi,

I’m trying to develop a game based on a 2D grid layout and got inspired from this demo project but I’m having issues retrieving the grid position (e.g. 3, 4) of the click object to move it.

I’ve tried event.x and event.y but that returns the coordinates in pixel instead (e.g. 135.120093, 96.700010).

Any help would be appreciated. My code is (see at the end) :

local GRID\_WIDTH = 8&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -- Number of cells in width (background image needs to cover right space) local GRID\_HEIGHT = 8&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-- Number of cells in height (background image needs to cover right space) local CELL\_WIDTH = 40&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-- Pixels per cell local CELL\_HEIGHT = 40&nbsp; &nbsp; &nbsp; &nbsp; -- Pixels per cell -- -- Create a 2D array to hold our objects. local grid = {} for i = 1, GRID\_HEIGHT do grid[i] = {} end -- -- load the background image: local backgroundImage = display.newImageRect("table.png", 320, 320)&nbsp; -- Number of pixes occupied by image (needs to be GRID\_WIDTH \* CELL\_WIDTH) backgroundImage.x = display.contentCenterX&nbsp; &nbsp;-- Center image on x axis backgroundImage.y = display.contentCenterY&nbsp; &nbsp;-- Center image on y axis -- -- Calculate some values -- local gbOffsetX = backgroundImage.x - ( backgroundImage.width \* backgroundImage.anchorX )&nbsp; local gbOffsetY = backgroundImage.y - ( backgroundImage.height \* backgroundImage.anchorY ) -- Create a group containing background image and objects local backgroundObjectsGroup = display.newGroup() -- Insert background into backgroundObjectsGroup backgroundObjectsGroup:insert( backgroundImage )&nbsp;&nbsp; -- make the whole background and object group dragable with ponywolf plugin (backgroundObjectsGroup) local dragable = require "com.ponywolf.plugins.dragable"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -- Create a dragable object --backgroundObjectsGroup = dragable.new(backgroundObjectsGroup)&nbsp; &nbsp; &nbsp;-- Associate the dragable object to backgroundObjectsGroup -- Using positions 1, 8 for X and Y, draw the object at the right place in the grid -- local function spawnPiece( xPos, yPos, pieceType ) if pieceType ~= "red" and pieceType ~= "white" then print( "Invalid piece type", pieceType ) return nil end if xPos \< 1 or xPos \> GRID\_WIDTH or yPos \< 1 or yPos \> GRID\_HEIGHT then print( "Position out of range:", xPos, yPos ) return nil end local piece = display.newImageRect( "token\_" .. pieceType .. ".png", CELL\_WIDTH, CELL\_HEIGHT ) &nbsp; backgroundObjectsGroup:insert( piece )&nbsp; &nbsp; &nbsp; -- Insert the object into backgroundObjectsGroup (to be dragable) -- -- record the pieces logical position on the board -- piece.xPos = xPos piece.yPos = yPos -- -- Position the piece -- piece.x = (xPos - 1) \* CELL\_WIDTH + (CELL\_WIDTH \* 0.5) + gbOffsetX piece.y = (yPos - 1) \* CELL\_HEIGHT + (CELL\_HEIGHT \* 0.5) + gbOffsetY return piece end local function movePiece(piece, xPos, yPos ) -- check to see if the position is occupied.&nbsp; You can do either: -- 1. "Capture the piece".&nbsp; This would involve removeing the piece&nbsp; --&nbsp; &nbsp; that is there before moving to the spot or -- 2. "Reject the move" because the spot is occupied.&nbsp; For the purpose --&nbsp; &nbsp; of this tutorial we will reject the move. -- if xPos \< 1 or xPos \> GRID\_WIDTH or yPos \< 1 or yPos \> GRID\_HEIGHT then return false end if grid[yPos][xPos] == nil then -- got an empty spot -- -- get the screen x, y for where we are moving to -- local x = (xPos - 1) \* CELL\_WIDTH + (CELL\_WIDTH \* 0.5) + gbOffsetX local y = (yPos - 1) \* CELL\_HEIGHT + (CELL\_HEIGHT \* 0.5) + gbOffsetY -- -- save the old grid x, y -- local oldXPos = piece.xPos local oldYPos = piece.yPos -- -- Move the object in the table -- grid[yPos][xPos] = piece grid[yPos][xPos].xPos = xPos grid[yPos][xPos].yPos = yPos grid[oldYPos][oldXPos] = nil -- -- Now move the physical graphic -- transition.to(grid[yPos][xPos], { time = 500, x = x, y = y}) return true end end -- -- Generate a few objects -- -- -- a holding piece for moving the object -- local lastObject&nbsp; for i = 1, 10 do local xPos = math.random( 1, GRID\_WIDTH ) local yPos = math.random( 1, GRID\_HEIGHT ) local color = "red" if math.random(2) == 2 then color = "white" end grid[yPos][xPos] = spawnPiece(xPos, yPos, color, backgroundImage) lastObject = grid[yPos][xPos] end -- -- -- -- I'm trying to get the touch position here and call the MovePiece function -- So far I have 1,1 but that should be replaced by the position where the user ended the touch -- local function onObjectTouch( event ) &nbsp; &nbsp; print(event.x) &nbsp; &nbsp; print(event.y) &nbsp; &nbsp; if ( event.phase == "began" ) then &nbsp; &nbsp; &nbsp; &nbsp; display.getCurrentStage():setFocus( event.target ) &nbsp; &nbsp; &nbsp; &nbsp; event.target.isFocus = true &nbsp; &nbsp; elseif ( event.target.isFocus ) then &nbsp; &nbsp; &nbsp; &nbsp; if ( event.phase == "moved" ) then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print( "moved phase" ) &nbsp; &nbsp; &nbsp; elseif ( event.phase == "ended" or event.phase == "cancelled" ) then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; movePiece( lastObject, 1, 1) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; display.getCurrentStage():setFocus( nil ) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; event.target.isFocus = false &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print (event.y) &nbsp; &nbsp; &nbsp; &nbsp; end &nbsp; &nbsp; end &nbsp; &nbsp; return true end backgroundImage:addEventListener( "touch", onObjectTouch ) --timer.performWithDelay(200, function() movePiece( lastObject, 1, 1); end, 1)

The  movePiece functions works fine, my problem is passing the x and y coordinate to it (I can’t retrieve them from the user touch action.

event.target.xPos and event.target.yPos should give you the grid reference of the touched piece within onObjectTouch.

I just tried but both return  nil.

I also tried event.target  and  event but it returns:

table: 060F3CA8

table: 10DC35F8

table: 060F3D98

Ah, you need to add the onObjectTouch listener to each grid piece, not to the background image. If it’s attached to the background, event.target will be the background. 

It’s fantastic when one is inspired by what others have done. Do, however, make sure that you also understand everything what it is that you are copying. That way you’ll speed up your learning process immensely. 

Well, I started from a simple example which I am cleaning up and following with different tutorials and pages of documentation (such as this one). I’ve also followed several Hangouts videos. Still, I’m in the early process of learning Lua and Corona SDK.

Regarding Nick’s suggestion, I have tried to add the listener to  piece  but the program complains about " addEventListener: listener cannot be nil: nil"

&nbsp; piece:addEventListener( "touch", onObjectTouch )

I have added a debugging row:

print(inspect(piece))

which prints:

21:31:07.693&nbsp; { 21:31:07.693&nbsp; &nbsp; \_class = \<1\>{ 21:31:07.693&nbsp; &nbsp; &nbsp; \_\_index = \<table 1\>, 21:31:07.693&nbsp; &nbsp; &nbsp; addEventListener = \<function 1\>, 21:31:07.693&nbsp; &nbsp; &nbsp; removeEventListener = \<function 2\>, 21:31:07.693&nbsp; &nbsp; &nbsp; \<metatable\> = \<2\>{ 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; \_\_index = \<table 2\>, 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; \_super = \<3\>{ 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \_\_index = \<table 3\>, 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \_indexForType = { 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; function = "\_functionListeners", 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; table = "\_tableListeners" 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }, 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \_super = \<4\>{ 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \_\_index = \<table 4\>, 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new = \<function 3\>, 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; newClass = \<function 4\> 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }, 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; addEventListener = \<function 5\>, 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; didRemoveListener = \<function 6\>, 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dispatchEvent = \<function 7\>, 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; getOrCreateTable = \<function 8\>, 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hasEventListener = \<function 9\>, 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; removeEventListener = \<function 10\>, 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; respondsToEvent = \<function 11\>, 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \<metatable\> = \<table 4\> 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; }, 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; addEventListener = \<function 12\>, 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; removeEventListener = \<function 13\>, 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; \<metatable\> = \<table 3\> 21:31:07.693&nbsp; &nbsp; &nbsp; } 21:31:07.693&nbsp; &nbsp; }, 21:31:07.693&nbsp; &nbsp; \_proxy = \<userdata 1\>, 21:31:07.693&nbsp; &nbsp; xPos = 1, 21:31:07.693&nbsp; &nbsp; yPos = 7, 21:31:07.693&nbsp; &nbsp; \<metatable\> = { 21:31:07.693&nbsp; &nbsp; &nbsp; \_\_index = \<function 14\>, 21:31:07.693&nbsp; &nbsp; &nbsp; \_\_newindex = \<function 15\> 21:31:07.693&nbsp; &nbsp; } 21:31:07.693&nbsp; }

On a side note, I can now retrieve the coordinates with print(inspect(piece.yPos)) but I now need to catch the object that was touch (add the listener).

You need to move the listener function above the place where it is added.

event.target.xPos and event.target.yPos should give you the grid reference of the touched piece within onObjectTouch.

I just tried but both return  nil.

I also tried event.target  and  event but it returns:

table: 060F3CA8

table: 10DC35F8

table: 060F3D98

Ah, you need to add the onObjectTouch listener to each grid piece, not to the background image. If it’s attached to the background, event.target will be the background. 

It’s fantastic when one is inspired by what others have done. Do, however, make sure that you also understand everything what it is that you are copying. That way you’ll speed up your learning process immensely. 

Well, I started from a simple example which I am cleaning up and following with different tutorials and pages of documentation (such as this one). I’ve also followed several Hangouts videos. Still, I’m in the early process of learning Lua and Corona SDK.

Regarding Nick’s suggestion, I have tried to add the listener to  piece  but the program complains about " addEventListener: listener cannot be nil: nil"

&nbsp; piece:addEventListener( "touch", onObjectTouch )

I have added a debugging row:

print(inspect(piece))

which prints:

21:31:07.693&nbsp; { 21:31:07.693&nbsp; &nbsp; \_class = \<1\>{ 21:31:07.693&nbsp; &nbsp; &nbsp; \_\_index = \<table 1\>, 21:31:07.693&nbsp; &nbsp; &nbsp; addEventListener = \<function 1\>, 21:31:07.693&nbsp; &nbsp; &nbsp; removeEventListener = \<function 2\>, 21:31:07.693&nbsp; &nbsp; &nbsp; \<metatable\> = \<2\>{ 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; \_\_index = \<table 2\>, 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; \_super = \<3\>{ 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \_\_index = \<table 3\>, 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \_indexForType = { 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; function = "\_functionListeners", 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; table = "\_tableListeners" 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }, 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \_super = \<4\>{ 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \_\_index = \<table 4\>, 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new = \<function 3\>, 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; newClass = \<function 4\> 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }, 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; addEventListener = \<function 5\>, 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; didRemoveListener = \<function 6\>, 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dispatchEvent = \<function 7\>, 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; getOrCreateTable = \<function 8\>, 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hasEventListener = \<function 9\>, 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; removeEventListener = \<function 10\>, 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; respondsToEvent = \<function 11\>, 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \<metatable\> = \<table 4\> 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; }, 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; addEventListener = \<function 12\>, 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; removeEventListener = \<function 13\>, 21:31:07.693&nbsp; &nbsp; &nbsp; &nbsp; \<metatable\> = \<table 3\> 21:31:07.693&nbsp; &nbsp; &nbsp; } 21:31:07.693&nbsp; &nbsp; }, 21:31:07.693&nbsp; &nbsp; \_proxy = \<userdata 1\>, 21:31:07.693&nbsp; &nbsp; xPos = 1, 21:31:07.693&nbsp; &nbsp; yPos = 7, 21:31:07.693&nbsp; &nbsp; \<metatable\> = { 21:31:07.693&nbsp; &nbsp; &nbsp; \_\_index = \<function 14\>, 21:31:07.693&nbsp; &nbsp; &nbsp; \_\_newindex = \<function 15\> 21:31:07.693&nbsp; &nbsp; } 21:31:07.693&nbsp; }

On a side note, I can now retrieve the coordinates with print(inspect(piece.yPos)) but I now need to catch the object that was touch (add the listener).

You need to move the listener function above the place where it is added.