Unable to remove tap event listener properly even after setting it to nil

I have set a tap eventlistener on a button with a function to handle it but i am unable to remove it completely, this is the code

 

local function dlevel(event) titlegroup:removeSelf() titlegroup=nil playbutt:removeEventListener("tap", dlevel) require("th\_b") dispscb() return true end

this the button with tap event added 

 

function disptitle() titlegroup=display.newGroup() tscreen=display.newImage("images/gtitle.jpg",x,y) titlegroup:insert(tscreen) playbutt=display.newImage("images/start.png",x,y) titlegroup:insert(playbutt) playbutt:addEventListener("tap",dlevel) end

while i am playing my game on real device(android) i am getting the runtime error " attempt to index upvalue “titlegroup” a nil value" , so i am suspecting that though i had set eventlistener to nil but still it’s being called for no reason, am i doing anything wrong ?  :mellow:

Here is my suggestion (involves slight re-write):

local function dlevel( self, event) if( event.phase == "began" ) then self:removeEventListener( "tap" ) display.remove( self.parent ) -- removes 'titlegroup' require("th\_b") -- NOT clear why you are doing this dispscb() -- not sure what this is either end return true end local function disptitle() local titlegroup = display.newGroup() local tscreen = display.newImage( titlegroup, "images/gtitle.jpg",x,y) local playbutt = display.newImage( titlegroup, "images/start.png",x,y) playbutt.tap = dlevel -- Notice, the name of the field I assign 'dlevel' to is playbutt:addEventListener( "tap" ) -- the same as the event. end

Note: The reason you were getting that error was probably a scoping issue, and/or because you didn’t refine the event by phase, so you were calling it more than once and the second time through the variable was removed.

In any case, my code is much cleaner and negates the need for ‘nil’-ing as well as gets rid of all those possibly floating globals.

PS - Thanks for the well formed and formatted question.

@roaminggamer thanx for the response but your solution isn’t firing the tap event even :mellow: , as you pointed that i didn’t refine the event but i read in corona docs that " tap" event doesn’t have began & ended phases unlike in touch 

Well, when you’re right you’re right. I forgot about tap not having phases.  I’m afraid there are a few features of Corona I don’t use, including:

  • tap Events
  • newRect

Note: I don’t use them because they don’t give me the control or precision I want.

  • tap Events - Can’t do anything on a specific part of the tap.
  • newRect - No control over size of object and no auto scaling [@2x, @3x, …] (unless that has changed?).

Anyways, here are two (tested and working) examples of a tap and a touch handler:

local function onTap( self, event) self:removeEventListener( "tap" ) display.remove( self.parent ) print("Got Tap") return true end local function taptest( x, y ) local titlegroup = display.newGroup() local tscreen = display.newRect( titlegroup, x, y, 100, 100 ) local playbutt = display.newRect( titlegroup, x, y, 50, 50 ) playbutt:setFillColor(1,0,0) playbutt.tap = onTap playbutt:addEventListener( "tap" ) end local function onTouch( self, event) if( event.phase == "began" ) then self:removeEventListener( "touch" ) display.remove( self.parent ) print("Got Touch ", event.phase) end return true end local function touchtest( x, y ) local titlegroup = display.newGroup() local tscreen = display.newRect( titlegroup, x, y, 100, 100 ) local playbutt = display.newRect( titlegroup, x, y, 50, 50 ) playbutt:setFillColor(0,1,0) playbutt.touch = onTouch playbutt:addEventListener( "touch" ) end taptest(75,150) touchtest(200,150)

@Roaming gamer i thought for a while & came up with a simple solution i.e to assign names to each object & when touch event is fired i wrote a if statement to check whether the target object is the one specified or other & do the stuff, after implementing this everything is going fine & clean what do u say  :slight_smile:

this is the code i re-wrote, pretty simple changes  :smiley:

local function dlevel(event) if(event.target.name=="playbutt") then titlegroup:removeSelf() titlegroup=nil playbutt:removeEventListener("tap", dlevel) require("th\_a") dispsca() end return true end function disptitle() titlegroup=display.newGroup() tscreen=display.newImage("images/gtitle.jpg",x,y) titlegroup:insert(tscreen) playbutt=display.newImage("images/start.png",x,y) playbutt.name="playbutt" titlegroup:insert(playbutt) playbutt:addEventListener("tap",dlevel) end

Here is my suggestion (involves slight re-write):

local function dlevel( self, event) if( event.phase == "began" ) then self:removeEventListener( "tap" ) display.remove( self.parent ) -- removes 'titlegroup' require("th\_b") -- NOT clear why you are doing this dispscb() -- not sure what this is either end return true end local function disptitle() local titlegroup = display.newGroup() local tscreen = display.newImage( titlegroup, "images/gtitle.jpg",x,y) local playbutt = display.newImage( titlegroup, "images/start.png",x,y) playbutt.tap = dlevel -- Notice, the name of the field I assign 'dlevel' to is playbutt:addEventListener( "tap" ) -- the same as the event. end

Note: The reason you were getting that error was probably a scoping issue, and/or because you didn’t refine the event by phase, so you were calling it more than once and the second time through the variable was removed.

In any case, my code is much cleaner and negates the need for ‘nil’-ing as well as gets rid of all those possibly floating globals.

PS - Thanks for the well formed and formatted question.

@roaminggamer thanx for the response but your solution isn’t firing the tap event even :mellow: , as you pointed that i didn’t refine the event but i read in corona docs that " tap" event doesn’t have began & ended phases unlike in touch 

Well, when you’re right you’re right. I forgot about tap not having phases.  I’m afraid there are a few features of Corona I don’t use, including:

  • tap Events
  • newRect

Note: I don’t use them because they don’t give me the control or precision I want.

  • tap Events - Can’t do anything on a specific part of the tap.
  • newRect - No control over size of object and no auto scaling [@2x, @3x, …] (unless that has changed?).

Anyways, here are two (tested and working) examples of a tap and a touch handler:

local function onTap( self, event) self:removeEventListener( "tap" ) display.remove( self.parent ) print("Got Tap") return true end local function taptest( x, y ) local titlegroup = display.newGroup() local tscreen = display.newRect( titlegroup, x, y, 100, 100 ) local playbutt = display.newRect( titlegroup, x, y, 50, 50 ) playbutt:setFillColor(1,0,0) playbutt.tap = onTap playbutt:addEventListener( "tap" ) end local function onTouch( self, event) if( event.phase == "began" ) then self:removeEventListener( "touch" ) display.remove( self.parent ) print("Got Touch ", event.phase) end return true end local function touchtest( x, y ) local titlegroup = display.newGroup() local tscreen = display.newRect( titlegroup, x, y, 100, 100 ) local playbutt = display.newRect( titlegroup, x, y, 50, 50 ) playbutt:setFillColor(0,1,0) playbutt.touch = onTouch playbutt:addEventListener( "touch" ) end taptest(75,150) touchtest(200,150)

@Roaming gamer i thought for a while & came up with a simple solution i.e to assign names to each object & when touch event is fired i wrote a if statement to check whether the target object is the one specified or other & do the stuff, after implementing this everything is going fine & clean what do u say  :slight_smile:

this is the code i re-wrote, pretty simple changes  :smiley:

local function dlevel(event) if(event.target.name=="playbutt") then titlegroup:removeSelf() titlegroup=nil playbutt:removeEventListener("tap", dlevel) require("th\_a") dispsca() end return true end function disptitle() titlegroup=display.newGroup() tscreen=display.newImage("images/gtitle.jpg",x,y) titlegroup:insert(tscreen) playbutt=display.newImage("images/start.png",x,y) playbutt.name="playbutt" titlegroup:insert(playbutt) playbutt:addEventListener("tap",dlevel) end