2
votes

I am relatively new to coding in lua so bear with me. I'm ultimately trying to setup a drag & drop function for multiple 'tiles' on one scene. But to begin with (and to make sure I understand all of this correctly) I am just trying to get one tile moving around the screen.

So I browsed the interwebs for a while and found the solution below (among other similar solutions) and implemented this myself with my own object names etc.

It works great....but...unfortunatelt when i drag the object into the top right quadrant of the screen (on the simulator and a phone) the object gets stuck. It stops dragging as it hits any part of the top right quadrant of the screen, and I cannot re-select it to drag it back to the rest of the screen.

Any ideas as to why this is happening?? (my code is below)

local _H = display.contentHeight
local _W = display.contentWidth

local notesGroup = display.newGroup()

local tile1 = display.newImage ("graphics/image.PNG")
tile1.x = _W/2
tile1.y =  _H/2 

function tile1:touch( event )
    if event.phase == "began" then

    self.markX = self.x    -- store x location of object
    self.markY = self.y    -- store y location of object

elseif event.phase == "moved" then

    local x = (event.x - event.xStart) + self.markX
    local y = (event.y - event.yStart) + self.markY

    self.x, self.y = x, y   
end

return true

end

notesGroup:insert(tile1)

tile1:addEventListener("touch", tile1)
3
There's a small typo in your question: the end that closes tile1:touch() is outside the code block. I thought you'd forgotten it. - GoojajiGreg
Not to split hairs, but your unfamiliarity with Lua isn't really the problem. It's unfamiliarity with the Corona API. We've all been there, of course. That's what StackOverflow is for. - GoojajiGreg

3 Answers

1
votes

You need to set focus on touched object to prevent from loosing it while you drop it outside screen. Your touch event should look like this:

function tile1:touch( event )
if event.phase == "began" then

    display.getCurrentStage():setFocus( event.target )
    self.markX = self.x    -- store x location of object
    self.markY = self.y    -- store y location of object

elseif event.phase == "moved" then

    local x = (event.x - event.xStart) + self.markX
    local y = (event.y - event.yStart) + self.markY

    self.x, self.y = x, y

elseif event.phase == "ended"  or event.phase == "cancelled" then

    display.getCurrentStage():setFocus(nil)

end

return true

end
0
votes

Try

-- create a circle and put it in the center of the screen
local circle = display.newCircle( display.contentWidth*0.5,display.contentHeight*0.5, 75)
circle:setFillColor( 255 )

-- touch listener function
function circle:touch( event )
  if event.phase == "began" then
    -- first we set the focus on the object
    display.getCurrentStage():setFocus( self, event.id )
    self.isFocus = true

    -- then we store the original x and y position
    self.markX = self.x
    self.markY = self.y

  elseif self.isFocus then

    if event.phase == "moved" then
      -- then drag our object
      self.x = event.x - event.xStart + self.markX
      self.y = event.y - event.yStart + self.markY
    elseif event.phase == "ended" or event.phase == "cancelled" then
      -- we end the movement by removing the focus from the object
      display.getCurrentStage():setFocus( self, nil )
      self.isFocus = false
    end

  end

-- return true so Corona knows that the touch event was handled propertly
 return true
end

-- finally, add an event listener to our circle to allow it to be dragged
circle:addEventListener( "touch", circle )
0
votes

A problem with your way of handling movement of the touch is that if the touch moves off the DisplayObject (in this case, tile1) between frames, the object's listener method won't be called before rendering the next frame and its position won't be updated. This may explain the weird "stuck in upper right quadrant" behaviour you're getting.

lduriat and Lukis show that setting the focus for this touch event (note the use of event.id by lduriat to handle the multitouch case) on the object avoids this problem. The use of setFocus() in handling touch events is explained in this section of the Corona Events/Listeners dev guide.