Drag and drop objects

My game has a solve a jumbled word round, All the letters are displayed as tiles and you must drag them into answers spaces to solve the word. Here is my Event Handler for dragging and dropping the tiles on an answer space

local function onTouch( event )  
 local t = event.target  
  
 local phase = event.phase  
 if "began" == phase then  
 -- Make target the top-most object  
 local parent = t.parent  
 parent:insert( t )  
 display.getCurrentStage():setFocus( t )  
  
  
 -- Spurious events can be sent to the target, e.g. the user presses   
 -- elsewhere on the screen and then moves the finger over the target.  
 -- To prevent this, we add this flag. Only when it's true will "move"  
 -- events be sent to the target.  
 t.isFocus = true  
  
 -- Store initial position  
 t.x0 = event.x - t.x  
 t.y0 = event.y - t.y  
 elseif t.isFocus then  
 if "moved" == phase then  
 -- Make object move (we subtract t.x0,t.y0 so that moves are  
 -- relative to initial grab point, rather than object "snapping").  
 t.xScale = 1.7  
 t.yScale = 1.7  
 t.x = event.x - t.x0  
 t.y = event.y - t.y0  
 --t1 = t1..t.value  
 elseif "ended" == phase or "cancelled" == phase then  
 for i = 1, #posX do  
 if not containers2[i].isOccupied then  
 if (((t.x \>= ((sizeX/2) + posX[i] - ((2/3) \* sizeX))) and (t.y \>= ((sizeY/2) + posY - ((1/3) \* sizeY))) and (t.x \<= ((sizeX/2) + posX[i] + ((2/3) \* sizeX))) and (t.y \<= ((sizeY/2) + posY + ((1/3) \* sizeY)))) or ((t.x \>= ((sizeX/2) + posX[i] - ((1/3) \* sizeX))) and (t.y \>= ((sizeY/2) + posY - ((2/3) \* sizeY))) and (t.x \<= ((sizeX/2) + posX[i] + ((1/3) \* sizeX))) and (t.y \<= ((sizeY/2) + posY + ((2/3) \* sizeY)))) or ((t.x \>= ((sizeX/2) + posX[i] - ((1/2) \* sizeX))) and (t.y \>= ((sizeY/2) + posY - ((1/2) \* sizeY))) and (t.x \<= ((sizeX/2) + posX[i] + ((1/2) \* sizeX))) and (t.y \<= ((sizeY/2) + posY + ((1/2) \* sizeY))))) then  
 t.x, t.y = posX[i] + (sizeX/2), posY + (sizeY/2);  
 containers2[i].isOccupied = true  
  
 --check to see if answer is correct  
 if(string.len(s1) == 3) then  
 x = 165  
 elseif(string.len(s1) == 4) then  
 x = 145  
 elseif(string.len(s1) == 5) then  
 x = 125  
 elseif(string.len(s1) == 6) then  
 x = 105  
 elseif(string.len(s1) == 7) then  
 x = 85  
 elseif(string.len(s1) == 8) then  
 x = 65  
 elseif(string.len(s1) == 9) then  
 x = 45  
 elseif(string.len(s1) == 10) then  
 x = 25  
 else  
 x = 5  
 end  
 print(x)  
 print(posX[i])  
 if(posX[i] == x) then  
 answer[1] = t.value  
 elseif(posX[i] == x+40 or posX[i] == x+45 or posX[i] == x+50) then  
 answer[2] = t.value  
 elseif(posX[i] == x+80 or posX[i] == x+85 or posX[i] == x+90) then  
 answer[3] = t.value  
 elseif(posX[i] == x+120 or posX[i] == x+125 or posX[i] == x+130) then  
 answer[4] = t.value  
 elseif(posX[i] == x+160 or posX[i] == x+165 or posX[i] == x+170) then  
 answer[5] = t.value  
 elseif(posX[i] == x+200 or posX[i] == x+205 or posX[i] == x+210) then  
 answer[6] = t.value  
 elseif(posX[i] == x+240 or posX[i] == x+245 or posX[i] == x+250) then  
 answer[7] = t.value  
 elseif(posX[i] == x+280 or posX[i] == x+285 or posX[i] == x+290) then  
 answer[8] = t.value  
 elseif(posX[i] == x+320 or posX[i] == x+325 or posX[i] == x+330) then  
 answer[9] = t.value  
 elseif(posX[i] == x+360 or posX[i] == x+365 or posX[i] == x+370) then  
 answer[10] = t.value  
 elseif(posX[i] == x+400 or posX[i] == x+405 or posX[i] == x+410) then  
 answer[11] = t.value  
 elseif(posX[i] == x+440 or posX[i] == x+445 or posX[i] == x+450) then  
 answer[12] = t.value  
 end  
 --get string from answer array  
 --print ( 'table: '..table.concat( answer))  
 s4 = table.concat(answer)  
 print(s4)  
 elseif (((t.x \>= ((sizeX/2) + posX1[i] - ((2/3) \* sizeX))) and (t.y \>= ((sizeY/2) + posY1 - ((1/3) \* sizeY))) and (t.x \<= ((sizeX/2) + posX1[i] + ((2/3) \* sizeX))) and (t.y \<= ((sizeY/2) + posY1 + ((1/3) \* sizeY)))) or ((t.x \>= ((sizeX/2) + posX1[i] - ((1/3) \* sizeX))) and (t.y \>= ((sizeY/2) + posY1 - ((2/3) \* sizeY))) and (t.x \<= ((sizeX/2) + posX1[i] + ((1/3) \* sizeX))) and (t.y \<= ((sizeY/2) + posY1 + ((2/3) \* sizeY)))) or ((t.x \>= ((sizeX/2) + posX1[i] - ((1/2) \* sizeX))) and (t.y \>= ((sizeY/2) + posY1 - ((1/2) \* sizeY))) and (t.x \<= ((sizeX/2) + posX1[i] + ((1/2) \* sizeX))) and (t.y \<= ((sizeY/2) + posY1 + ((1/2) \* sizeY))))) then  
 t.x, t.y = posX1[i] + (sizeX/2), posY1 + (sizeY/2);  
 containers2[i].isOccupied = false  
  
 end  
 end  
 end  
 t1 = t1..t.value  
 --physics.addBody(t,"static",{})  
 t.xScale = 1  
 t.yScale = 1  
 display.getCurrentStage():setFocus( nil )  
 t.isFocus = false  
 --n = n + 1  
 --value = " "  
 end  
 end  
  
 -- Important to return true. This tells the system that the event  
 -- should not be propagated to listeners of any objects underneath.  
 return true  
 end  

When a tile is placed I am flagging the container I dropped it onto as occupied, this stops any other tiles from being allowed to drop onto it. My question is how to release this container if the tile is removed, at the moment, when I drag a tile back off, the container is still being read as occupied. I have a recall button in my app that recalls all the tiles to their original position and sets the isOccupied back to false, but I really want to know how to do it for just one tile when it is moved off the container
[import]uid: 208811 topic_id: 35202 reply_id: 335202[/import]

From the looks of it you could do this at the same time as you set isOccupied:

[lua]t.container = i[/lua]

and then when dragging off, do something like

[lua]if t.container then
containers2[t.container].isOccupied = false
t.container = nil
end[/lua] [import]uid: 27791 topic_id: 35202 reply_id: 139968[/import]

Thanks for the suggestion StarCrunch, I really appreciate it. I am struggling to get it to work though, I don’t really know where to put the “if t.container then” piece of code to get it to work. Could you help me out a bit more? [import]uid: 208811 topic_id: 35202 reply_id: 140049[/import]

Hi.

If this works like I think it does, it probably belongs at the beginning of the “ended” / “cancelled” block, before the loop.

That way, it will get overwritten with the new index (or the same one, if you barely moved) , and if you’re not on a space, will stay nil. [import]uid: 27791 topic_id: 35202 reply_id: 140096[/import]

Thanks StarCrunch, I was trying to do this after my “if not containers” loop, I didn’t really understand it, but I get it now. It is working exactly the way I want. [import]uid: 208811 topic_id: 35202 reply_id: 140196[/import]

From the looks of it you could do this at the same time as you set isOccupied:

[lua]t.container = i[/lua]

and then when dragging off, do something like

[lua]if t.container then
containers2[t.container].isOccupied = false
t.container = nil
end[/lua] [import]uid: 27791 topic_id: 35202 reply_id: 139968[/import]

Thanks for the suggestion StarCrunch, I really appreciate it. I am struggling to get it to work though, I don’t really know where to put the “if t.container then” piece of code to get it to work. Could you help me out a bit more? [import]uid: 208811 topic_id: 35202 reply_id: 140049[/import]

Hi.

If this works like I think it does, it probably belongs at the beginning of the “ended” / “cancelled” block, before the loop.

That way, it will get overwritten with the new index (or the same one, if you barely moved) , and if you’re not on a space, will stay nil. [import]uid: 27791 topic_id: 35202 reply_id: 140096[/import]

Thanks StarCrunch, I was trying to do this after my “if not containers” loop, I didn’t really understand it, but I get it now. It is working exactly the way I want. [import]uid: 208811 topic_id: 35202 reply_id: 140196[/import]