Nil value on drag

Hi,

I currently have a bot object that can be dragged across the screen. When the object is touched and dragged, its drag position is relative to where the object is tapped. However, if the user touches the screen (not on object) and drags onto the object, an error causes the game to crash (regarding x0 and y0). Is there a way to make it so that I can drag an object relative to its touch position (so it does not snap to the center of the touch), while ensuring that if the user touches and drags onto the object nil value errors do not occur.

Here’s my code:

local function botTouch(self, event) local p = event.phase local t = event.target if p == "began" then -- print("bot:touch - began") local parent = t.parent parent:insert(t) display.getCurrentStage():setFocus(t) t.isFocus = true t.x0 = event.x - t.x t.y0 = event.y - t.y elseif p == "moved" then t.x = event.x - t.x0 t.y = event.y - t.y0 elseif p == "cancelled" or p == "ended" then -- print("bot:touch - ended") display.getCurrentStage():setFocus(nil) t.isFocus = false end return true end function botNew(x, y) print("botNew()") local o = display.newRect(x, y, 32, 32) o.type = "bot" o.touch = botTouch o:setFillColor(0) physics.addBody(o, { density=1, friction=0, bounce=0}) o.isSensor = true o:addEventListener("touch") return o end local b1 = botNew(100,100)

Thanks!

This is a common problem which seems to be part of the learning curve with touch listeners. The issue is basically that you’re listening for all phases of the touch event, rather than checking for whether the particular phase is relevant to the object you want to touch. I’ve resolved this by using the same listener code for any touch interaction in any of my programs…

local function touch(e) if (e.phase == "began") then -- the touch has started e.target.hasFocus = true display.currentStage:setFocus( e.target ) return true elseif (e.target.hasFocus) then if (e.phase == "moved") then -- the touch has moved else -- the touch has ended e.target.hasFocus = nil display.currentStage:setFocus( nil ) end return true end return false end

I also recommend that you use descriptive variable names and not names like ‘o’ because you will find this very misleading as your program gets bigger.

This works perfectly! Thank you for the method and I will update all my other touch events now.

This is a common problem which seems to be part of the learning curve with touch listeners. The issue is basically that you’re listening for all phases of the touch event, rather than checking for whether the particular phase is relevant to the object you want to touch. I’ve resolved this by using the same listener code for any touch interaction in any of my programs…

local function touch(e) if (e.phase == "began") then -- the touch has started e.target.hasFocus = true display.currentStage:setFocus( e.target ) return true elseif (e.target.hasFocus) then if (e.phase == "moved") then -- the touch has moved else -- the touch has ended e.target.hasFocus = nil display.currentStage:setFocus( nil ) end return true end return false end

I also recommend that you use descriptive variable names and not names like ‘o’ because you will find this very misleading as your program gets bigger.

This works perfectly! Thank you for the method and I will update all my other touch events now.