Error when removing display object in touch "ended" phase

Hi,

I am trying to create a function that creates display text on touch and deletes it on release, but I am getting a runtime error “attempt to index field ‘?’ (a nil value)”. I am also using composer.

If I comment out this line the code runs, but of course doesn’t delete the text

[lua]

touches[touchID].coords:removeSelf()

[/lua]

full code here:

[lua]

local function storeTouches(event)

local touchID = tostring(event.id)

if event.phase == “began” then

 touches[touchID] = {}

touches[touchID].coords = {} 

touches[touchID].x = event.x

touches[touchID].y = event.y

touches[touchID].coords = display.newText(touchID…" = “…event.x…”,"…event.y,0,0,system.nativeFont,15)

touches[touchID].coords.x = event.x

touches[touchID].coords.y = event.y - 20

elseif event.phase == “moved” then

 

elseif event.phase == “ended” then

        touches[touchID].coords:removeSelf()

        touches[touchID] = nil

end

end

[/lua]

and further down

[lua]

Runtime:addEventListener( “touch”, storeTouches )

[/lua]

Putting the touchid variable outside of any event phase means that for every single touch event (including end phases) a new touchid variable is created. Try putting the touchid variable inside of the began phase. Print statements would also help identifying potential issues.

Hi,

Moving the touchID variable doesn’t seem to make a difference. I’ve even tried removing the variable completely and just referring to event.id.

The runtime error fires as soon as the page loads, not on touch. I don’t understand why I would get a runtime about a nil variable in a function that hasn’t been called because there haven’t been any touches.

After further investigation the issue seems to be that a “ended” touch event is being fired when I take my finger off the screen after transitioning from the previous screen.

What is the best way to get it to ignore touches from a previous screen?

Assuming the previous scene had Runtime listeners in it, you need to remove them. I’d suggest creating your Runtime listeners outside of the scene function, then adding and removing them upon scene creation/disposal (I’d be more specific there but I don’t know if you’re using Storyboard or Composer).

I’m using composer

I’m adding the runtime listener when the scene is created and Im removing them on scene exit. The problem is that when the scene is created and the new listener is added, you may still have your finger on the screen from when you tapped to go to the new screen

If that’s the case, you might want to throw a variable in the began phase for which the end phase listens, so that the new listener knows this is a “new” touch.

Something like this: (didn’t test, YMMV…)

EDIT: updated after testing.

 local touchPhase = "nothing" local touchNum = 1 local function touchTest1a(event) if event.phase == "began" and touchPhase == "nothing" then touchPhase = "first" touchNum = 1 print("the current touchPhase value is "..tostring(touchPhase)) print("the current touchNum amount is "..touchNum) elseif event.phase == "ended" and touchPhase == "first" then touchPhase = "nothing" touchNum = touchNum+1 print("the current touchPhase value is "..tostring(touchPhase)) print("the current touchNum amount is "..touchNum) end end Runtime:addEventListener("touch", touchTest1a)

Thanks. I was hoping there was a better way, but a variable test is working for now. If it works, don’t fix it, as they say.

Putting the touchid variable outside of any event phase means that for every single touch event (including end phases) a new touchid variable is created. Try putting the touchid variable inside of the began phase. Print statements would also help identifying potential issues.

Hi,

Moving the touchID variable doesn’t seem to make a difference. I’ve even tried removing the variable completely and just referring to event.id.

The runtime error fires as soon as the page loads, not on touch. I don’t understand why I would get a runtime about a nil variable in a function that hasn’t been called because there haven’t been any touches.

After further investigation the issue seems to be that a “ended” touch event is being fired when I take my finger off the screen after transitioning from the previous screen.

What is the best way to get it to ignore touches from a previous screen?

Assuming the previous scene had Runtime listeners in it, you need to remove them. I’d suggest creating your Runtime listeners outside of the scene function, then adding and removing them upon scene creation/disposal (I’d be more specific there but I don’t know if you’re using Storyboard or Composer).

I’m using composer

I’m adding the runtime listener when the scene is created and Im removing them on scene exit. The problem is that when the scene is created and the new listener is added, you may still have your finger on the screen from when you tapped to go to the new screen

If that’s the case, you might want to throw a variable in the began phase for which the end phase listens, so that the new listener knows this is a “new” touch.

Something like this: (didn’t test, YMMV…)

EDIT: updated after testing.

 local touchPhase = "nothing" local touchNum = 1 local function touchTest1a(event) if event.phase == "began" and touchPhase == "nothing" then touchPhase = "first" touchNum = 1 print("the current touchPhase value is "..tostring(touchPhase)) print("the current touchNum amount is "..touchNum) elseif event.phase == "ended" and touchPhase == "first" then touchPhase = "nothing" touchNum = touchNum+1 print("the current touchPhase value is "..tostring(touchPhase)) print("the current touchNum amount is "..touchNum) end end Runtime:addEventListener("touch", touchTest1a)

Thanks. I was hoping there was a better way, but a variable test is working for now. If it works, don’t fix it, as they say.