Mysterious crash removing a listener when it says the obj is already nil

I have the following code that does a splash screen at startup. I added a tap listener to allow the user to skip the splash screen, and now it crashes when the tap occurs. 

local function SplashScreen()     print ("in SplashScreen")          local function ss\_end(event)        -- end of transition         ss:removeEventListener("tap", ss\_end) -- HERE IS WHERE IT SAYS THE CRASH IS         display.remove(ss)      -- remove splash screen         ss = nil         storyboard.gotoScene( "MM\_scene", "fade", 400 ) -- load first scene     end               local ss = display.newImage("L2T.png")     ss.x = display.contentCenterX     ss.y = display.contentCenterY     ss.alpha = 0     ss:addEventListener("tap", ss\_end)          -- fade in splash screen...     transition.to(ss,{time=1000, alpha=1 })     -- wait 5 seconds, and then over 2 seconds fade image away     transition.to( ss, { delay=5000, time=2000, alpha=0, onComplete=ss\_end } )      end  

here is what I see on the crash screen… 

Windows simulator build date: Apr &nbsp;3 2013 @ 13:54:22 Copyright (C) 2009-2013 &nbsp;C o r o n a &nbsp; L a b s &nbsp; I n c . &nbsp; &nbsp; &nbsp; &nbsp; Version: 2.0.0 &nbsp; &nbsp; &nbsp; &nbsp; Build: 2013.1076 waiting for connection... connected waiting for debugger initialization program started Copyright (C) 2009-2013 &nbsp;C o r o n a &nbsp; L a b s &nbsp; I n c . &nbsp; &nbsp; &nbsp; &nbsp; Version: 2.0.0 &nbsp; &nbsp; &nbsp; &nbsp; Build: 2013.1076 waiting for connection... connected waiting for debugger initialization program started Runtime error ...lds)\storyboard too(default)\storyboard too\main.lua:37: attempt to index global 'ss' (a nil value) stack traceback: &nbsp; &nbsp; &nbsp; &nbsp; [C]: ? &nbsp; &nbsp; &nbsp; &nbsp; ...lds)\storyboard too(default)\storyboard too\main.lua:37: in function \<...lds)\storyboard too(default)\storyboRuntime error: ...yboard too(default)\storyboard too\CiderDebugger.lua:1241: attempt to call field 'p' (a nil value) stack traceback: &nbsp; &nbsp; &nbsp; &nbsp; [C]: in function 'p' &nbsp; &nbsp; &nbsp; &nbsp; ...yboard too(default)\storyboard too\CiderDebugger.lua:1241: in functio n 'handleError' &nbsp; &nbsp; &nbsp; &nbsp; ...yboard too(default)\storyboard too\CiderDebugger.lua:34: in function \<...yboard too(default)\storyboard too\CiderDebugger.lua:33\> &nbsp; &nbsp; &nbsp; &nbsp; ?: in function \<?:218\> &nbsp; &nbsp; &nbsp; &nbsp; [C]: ? &nbsp; &nbsp; &nbsp; &nbsp; ...lds)\storyboard too(default)\storyboard too\main.lua:37: in function \<...lds)\storyboard too(default)\storyboard too\main.lua:36\> &nbsp; &nbsp; &nbsp; &nbsp; ?: in function \<?:218\> &nbsp;

Corona guys, please note that it is still launching twice at startup… 

Does anyone know what I am doing wrong? the ss object is only removed after the listener is removed so should not be NIL yet.

Thanks!
stu

Its hard to tell when you dont seee the whole code One thing to keep in mind is that lua is lexical scoping eventlisteners AFTER declaring and so on

I guess I don’t understand your comment about lexical scoping eventlisteners AFTER declaring??

This isn’t “all the code” but the section which is running at the time. 

the app puts up a splash screen, waits a few seconds and then fades out, then jumps to a scene where it puts up the menu.

I wanted to clean up the sandbox and remove the listeners, but when they are active, it crashes.

If I comment out the code with the ss:removeEventListener() it works fine.

All I wanted to do is to make it where the user could tap the screen in the splash screen and skip it. Otherwise, they are held hostage until the time is up and the splash screen goes away.

Thanks!
stu

You don’t need to remove the event listener.  When you remove the object the event listener goes with it.

The problem is that at the time the line “ss:removeEventListener(“tap”, ss_end)” is compiled by the Lua interpreter, ss_end is nil.  That’s because the line occurs within the code block where ss_end is first being defined.

To fix it, try pre-declaring ss_end, like this:

[lua]

local ss_end

ss_end = function(event)        – end of transition

        ss:removeEventListener(“tap”, ss_end)   – HERE IS WHERE IT SAYS THE CRASH IS

        display.remove(ss)      – remove splash screen

        ss = nil

        storyboard.gotoScene( “MM_scene”, “fade”, 400 ) – load first scene

    end 

[/lua]

So is it better to let the function remove wipe out everything or do it the latter way by pre-defining the ss_end function?

The strange thing is that it dies before the display.remove code is hit. Perhaps it is lost by that time and confused like me.

Stu

For objects that you remove that you’ve added touch/tap listeners too, removing the object prevents futher touches from working because the object isn’t there to touch.  You do not need to remove them.  Now if you put a touch listener on the Runtime, that you would need to remove.  Just kill the removeEventListener line and all will be good.

I was a bit sloppy there…I meant Runtime: eventListeners() of course

Thanks Rob.

So there is no need to clean up the mess after you switch to another slide, as long as you don’t install a runtime listener?

All the other tutorials say to clean up what you mess up, which I typically try to do.

The  storyboard appears to still have listeners active, and not acting like the storyboard event tutorials describe.

The following listing is the print statements that happen when I switch from the main menu (MM) to the JI page 1 scene.

It shows that it is created, 

starting Job Instruction&nbsp;&nbsp;&nbsp;&nbsp; 1:MM exitScene event&nbsp;&nbsp;&nbsp;&nbsp; 1: JI1 createScene event&nbsp;&nbsp;&nbsp;&nbsp;-- created from JI1\_scene.lua ending job instruction&nbsp;&nbsp;&nbsp;&nbsp; -- created by MM\_scene after gotoScene starting Job Instruction&nbsp;&nbsp;&nbsp;&nbsp;-- created by MM\_scene before gotoScene 1: JI1 exitScene event&nbsp;&nbsp;&nbsp;&nbsp; -- created by JI1 scene exit called ending job instruction&nbsp;&nbsp;&nbsp;&nbsp; -- created by MM\_scene after gotoScene 1: JI1 enterScene event&nbsp;&nbsp;&nbsp;&nbsp; -- created by JI1 enterScene event 1: JI1 enterScene event&nbsp;&nbsp;&nbsp;&nbsp; -- created by JI1 enterScene event &nbsp;

I have tried to move the functions to handle the event listeners to the inside of the create scene but that blows up.

I tried to remove the listeners at the exit scene and that blows up, if I set them to nil after the remove.

Someone should update the storyboard events so they show what happens when you leave a storyboard.

Thanks!
Stu

What you could do is:

When working with Storyboard API I do it this way (after some hours of tweaking)

1 declare your variables (forward reference your variables and functions) i.e. 

   local myBall

   local myFunction = {}

2 createScene

   making things like displayObjects, soundObjects and put them in the storyboard group i.e.

   myBall = display.newImage(“myBall.png”)  --yes, I know, but it looks cleaner and simpler with newImage() :wink:

   myBall.touch = myFunction

   group:insert( myBall )

  1. after createScreen you put all your forward declared functions like:

    myFunction = function()

    end

  1. enterScene: Here you start your timers, listeners, sounds etc. like

    Runtime:addEventListener( “touch”, myFunction )

  1. exitScene: remove RuntimeObjects that won’t be taken hand of by the garbage collector like:

    Runtime:removeEventListener( “touch”, myFunction )

I used a tableListener here but you can of course make it a functionListener if you like but in storyboard its worth mentioning that the two works very different and needs to be set up differently accordingly to the different listeners of storyboard

If I use functionListeners I put them together with the objects in createScene…think it´s because of the nature of lexical scoping and the storyboard api

well, it works for me :slight_smile:

Let me know if you get issues after this

Here are a few files of my project:

Main menu code, puts up an image and several buttons on top… first button would go to JI1 scene which follows

--------------------------------------------------------------------------------- -- -- scene1.lua - main menu&nbsp; -- --------------------------------------------------------------------------------- local storyboard = require( "storyboard" ) local scene = storyboard.newScene() -- storyboard.isDebug = true local widget = require( "widget" ) --------------------------------------------------------------------------------- -- BEGINNING OF YOUR IMPLEMENTATION --------------------------------------------------------------------------------- local BG local screenGroup local function JobInstruction\_ButtonEvent(self, event) &nbsp; &nbsp; print("starting Job Instruction") &nbsp; &nbsp; storyboard.gotoScene( "JI1\_scene", "slideUp", \_G.slideTrans &nbsp;) &nbsp; &nbsp; print("ending job instruction") end local function JobRelations\_ButtonEvent(self, event) &nbsp; &nbsp; print("starting Job Relations") &nbsp; &nbsp; storyboard.gotoScene( "JR1\_scene", "slideUp", \_G.slideTrans &nbsp;) &nbsp; &nbsp; &nbsp; print("ending job relations") end local function JobMethods\_ButtonEvent(self, event) &nbsp; &nbsp; print("starting job methods") &nbsp; &nbsp; storyboard.gotoScene( "JM1\_scene", "slideUp", \_G.slideTrans &nbsp;) &nbsp; &nbsp; print ("ending job methods") end local function JobSafety\_ButtonEvent(self, event) &nbsp; &nbsp; print("starting job safety") &nbsp; &nbsp; storyboard.gotoScene( "JS1\_scene", "slideUp", \_G.slideTrans &nbsp;) &nbsp; &nbsp; &nbsp; &nbsp; print("ending job safety") end local function AboutUs\_ButtonEvent(self, event) &nbsp; &nbsp; print("Starting About Us") &nbsp; &nbsp; storyboard.gotoScene( "AU1\_scene", "slideUp", \_G.slideTrans &nbsp;) &nbsp; &nbsp; &nbsp; &nbsp; print("ending About Us") end local function BGTouchEvent(event) &nbsp; &nbsp; &nbsp;-- if title is clicked, launch browser &nbsp; &nbsp; print("tapped at ",event.x, event.y) &nbsp; &nbsp; if (event.y \< 107) then &nbsp; &nbsp; &nbsp; &nbsp; system.openURL( "http://www.learning-2-think.org" ) &nbsp; &nbsp; elseif (event.y \> 470) then &nbsp; &nbsp; &nbsp; &nbsp; storyboard.gotoScene( "MM\_scene", "slideUp", \_G.slideTrans &nbsp;)&nbsp; &nbsp; &nbsp; end &nbsp; &nbsp; end -- Called when the scene's view does not exist: function scene:createScene( event ) &nbsp; &nbsp; screenGroup = self.view &nbsp; &nbsp; print( "\n1: MM createScene event") &nbsp; &nbsp; storyboard.printMemUsage() &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; -- title page acts as background for buttons as well as title. &nbsp; &nbsp; BG = display.newImageRect("Slide00.png",320,480) &nbsp; &nbsp; BG:setReferencePoint(display.TopLeftReferencePoint) &nbsp; &nbsp; BG.x = 0 &nbsp; &nbsp; BG.y = 0 &nbsp; &nbsp; screenGroup:insert( BG )&nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; local leftBias = (display.contentWidth - 184)/ 2 &nbsp; &nbsp; local Offset = 110 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-- offset from top &nbsp; &nbsp; local Spacing = ((display.viewableContentHeight - Offset) / 6) &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; JobInstruction\_Button = widget.newButton &nbsp; &nbsp; { &nbsp; &nbsp; &nbsp; &nbsp; left = leftBias, &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; top = Offset, &nbsp; &nbsp; &nbsp; &nbsp; defaultFile = "JobInstructionButton.png", &nbsp; &nbsp; &nbsp; &nbsp; overFile = "JobInstructionButton.png", &nbsp; &nbsp; &nbsp; &nbsp; onEvent = JobInstruction\_ButtonEvent &nbsp; &nbsp; } &nbsp; &nbsp; JobInstruction\_Button.baseLabel = "JobInstruction" &nbsp; &nbsp; screenGroup:insert( JobInstruction\_Button ) &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; local JobRelations\_Button = widget.newButton &nbsp; &nbsp; { &nbsp; &nbsp; &nbsp; &nbsp; left = leftBias, &nbsp; &nbsp; &nbsp; &nbsp; top = Offset + (Spacing \* 1), &nbsp; &nbsp; &nbsp; &nbsp; defaultFile = "JobRelationsButton.png", &nbsp; &nbsp; &nbsp; &nbsp; overFile = "JobRelationsButton.png", &nbsp; &nbsp; &nbsp; &nbsp; onEvent = JobRelations\_ButtonEvent &nbsp; &nbsp; } &nbsp; &nbsp; JobRelations\_Button.baseLabel = "JobRelations" &nbsp; &nbsp; screenGroup:insert( JobRelations\_Button )&nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; local JobMethods\_Button = widget.newButton &nbsp; &nbsp; { &nbsp; &nbsp; &nbsp; &nbsp; left = leftBias, &nbsp; &nbsp; &nbsp; &nbsp; top = Offset + (Spacing \* 2), &nbsp; &nbsp; &nbsp; &nbsp; defaultFile = "JobMethodsButton.png", &nbsp; &nbsp; &nbsp; &nbsp; overFile = "JobMethodsButton.png", &nbsp; &nbsp; &nbsp; &nbsp; onEvent = JobMethods\_ButtonEvent &nbsp; &nbsp; } &nbsp; &nbsp; JobMethods\_Button.baseLabel = "JobMethods" &nbsp; &nbsp; screenGroup:insert( JobMethods\_Button ) &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; local JobSafety\_Button = widget.newButton &nbsp; &nbsp; { &nbsp; &nbsp; &nbsp; &nbsp; left = leftBias, &nbsp; &nbsp; &nbsp; &nbsp; top = Offset + (Spacing \* 3), &nbsp; &nbsp; &nbsp; &nbsp; defaultFile = "JobSafetyButton.png", &nbsp; &nbsp; &nbsp; &nbsp; overFile = "JobSafetyButton.png", &nbsp; &nbsp; &nbsp; &nbsp; onEvent = JobSafety\_ButtonEvent &nbsp; &nbsp; } &nbsp; &nbsp; JobSafety\_Button.baseLabel = "JobSafety" &nbsp; &nbsp; screenGroup:insert( JobSafety\_Button ) &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; local AboutUs\_Button = widget.newButton &nbsp; &nbsp; { &nbsp; &nbsp; &nbsp; &nbsp; left = leftBias, &nbsp; &nbsp; &nbsp; &nbsp; top = Offset + (Spacing \* 4), &nbsp; &nbsp; &nbsp; &nbsp; defaultFile = "AboutUsButton.png", &nbsp; &nbsp; &nbsp; &nbsp; overFile = "AboutUsButton.png", &nbsp; &nbsp; &nbsp; &nbsp; onEvent = AboutUs\_ButtonEvent &nbsp; &nbsp; } &nbsp; &nbsp; AboutUs\_Button.baseLabel = "AboutUs" &nbsp; &nbsp; screenGroup:insert( AboutUs\_Button ) &nbsp; &nbsp;&nbsp; end -- Called immediately after scene has moved onscreen: function scene:enterScene( event ) &nbsp; &nbsp; storyboard.printMemUsage() &nbsp; &nbsp; print( "1: MM enterScene event" ) &nbsp; &nbsp; BG:addEventListener("tap",BGTouchEvent) &nbsp; &nbsp;&nbsp; end -- Called when scene is about to move offscreen: function scene:exitScene( event ) &nbsp; &nbsp; storyboard.printMemUsage() &nbsp; &nbsp; print( "1:MM exitScene event" ) &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; BG:removeEventListener("tap",BGTouchEvent) end -- Called prior to the removal of scene's "view" (display group) function scene:destroyScene( event ) &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; print( "((destroying MM\_scene view))" ) end --------------------------------------------------------------------------------- -- END OF YOUR IMPLEMENTATION --------------------------------------------------------------------------------- -- "createScene" event is dispatched if scene's view does not exist scene:addEventListener( "createScene", scene ) -- "enterScene" event is dispatched whenever scene transition has finished scene:addEventListener( "enterScene", scene ) -- "exitScene" event is dispatched before next scene's transition begins scene:addEventListener( "exitScene", scene ) -- "destroyScene" event is dispatched before view is unloaded, which can be -- automatically unloaded in low memory situations, or explicitly via a call to -- storyboard.purgeScene() or storyboard.removeScene(). scene:addEventListener( "destroyScene", scene ) --------------------------------------------------------------------------------- return scene &nbsp;

Second file is JI1 scene

It displays an image and two buttons. Installs three listeners, one for each button, and once to sense the user swipe left and right. two buttons are left and right. Left goes back to main menu, right goes to JI2 scene (almost identical to JI1)

--------------------------------------------------------------------------------- -- -- scene1.lua - main menu&nbsp; -- --------------------------------------------------------------------------------- local storyboard = require( "storyboard" ) local scene = storyboard.newScene() --storyboard.isDebug = true --------------------------------------------------------------------------------- -- BEGINNING OF YOUR IMPLEMENTATION --------------------------------------------------------------------------------- local BG local Next local Prev local Org\_x = 0 local Org\_y = 0 local function TouchNextEvent(self, event) &nbsp; &nbsp; storyboard.gotoScene( "JI2\_scene", "slideLeft", \_G.slideTrans &nbsp;) end local function TouchPrevEvent(self, event) &nbsp; &nbsp; storyboard.gotoScene( "MM\_scene", "slideRight", \_G.slideTrans &nbsp;) end local function BGTouchEvent(event) &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; if (event.phase == "began") then &nbsp; &nbsp; &nbsp; &nbsp; print ("BGTouchEvent Begin") &nbsp; &nbsp; &nbsp; &nbsp; Org\_x = event.x &nbsp; &nbsp; &nbsp; &nbsp; Org\_y = event.y &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; elseif (event.phase == "moved") then &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; elseif event.phase == "ended" or event.phase == "cancelled" then &nbsp; &nbsp; &nbsp; &nbsp; local distance\_y = event.y - Org\_y &nbsp; &nbsp; &nbsp; &nbsp; local distance\_x = event.x - Org\_x &nbsp; &nbsp; &nbsp; &nbsp; if (distance\_x \> 40 or distance\_x \< -40) then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print("distance met") &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (distance\_x \> 0 ) then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; storyboard.gotoScene( "MM\_scene", "slideRight", \_G.PageTrans ) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; storyboard.gotoScene( "JI2\_scene", "slideLeft", \_G.PageTrans ) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end &nbsp; &nbsp; &nbsp; &nbsp; end &nbsp; &nbsp; &nbsp; &nbsp; if (distance\_y \> 100 ) then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; storyboard.gotoScene( "MM\_scene", "slideDown", \_G.PageTrans ) &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; end &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; end -- Called when the scene's view does not exist: function scene:createScene( event ) &nbsp; &nbsp; local screenGroup = self.view &nbsp; &nbsp; print( "\n1: JI1 createScene event") &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; BG = display.newImageRect("Slide1.png",320,480) &nbsp; &nbsp; BG:setReferencePoint(display.TopLeftReferencePoint) &nbsp; &nbsp; BG.x = 0 &nbsp; &nbsp; BG.y = 0 &nbsp; &nbsp; screenGroup:insert( BG ) &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; Next = display.newImage("next\_black.png",25,25) &nbsp; &nbsp; Next.x = \_G.nextButtonX &nbsp; &nbsp; Next.y = \_G.nextButtonY &nbsp; &nbsp; Next.alpha = \_G.nextButtonAlpha &nbsp; &nbsp; screenGroup:insert(Next) &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; Prev = display.newImageRect("prev\_black.png",25,25) &nbsp; &nbsp; Prev.x = \_G.prevButtonX &nbsp; &nbsp; Prev.y = \_G.prevButtonY &nbsp; &nbsp; Prev.alpha = \_G.prevButtonAlpha &nbsp; &nbsp; screenGroup:insert(Prev) end -- Called immediately after scene has moved onscreen: function scene:enterScene( event ) &nbsp; &nbsp; print( "1: JI1 enterScene event" ) &nbsp; &nbsp; BG:addEventListener("touch",BGTouchEvent) &nbsp; &nbsp; Next:addEventListener("tap",TouchNextEvent) &nbsp; &nbsp; Prev:addEventListener("tap",TouchPrevEvent) end -- Called when scene is about to move offscreen: function scene:exitScene( event ) &nbsp; &nbsp; print( "1: JI1 exitScene event" ) &nbsp;&nbsp; &nbsp; &nbsp; BG:removeEventListener("touch",BGTouchEvent) &nbsp; &nbsp; Next:removeEventListener("tap",TouchNextEvent) &nbsp; &nbsp; Prev:removeEventListener("tap",TouchPrevEvent) &nbsp; &nbsp;&nbsp; end -- Called prior to the removal of scene's "view" (display group) function scene:destroyScene( event ) &nbsp; &nbsp; print( "((destroying scene JI1's view))" ) &nbsp; &nbsp;&nbsp; &nbsp; &nbsp;&nbsp; end --------------------------------------------------------------------------------- -- END OF YOUR IMPLEMENTATION --------------------------------------------------------------------------------- -- "createScene" event is dispatched if scene's view does not exist scene:addEventListener( "createScene", scene ) -- "enterScene" event is dispatched whenever scene transition has finished scene:addEventListener( "enterScene", scene ) -- "exitScene" event is dispatched before next scene's transition begins scene:addEventListener( "exitScene", scene ) -- "destroyScene" event is dispatched before view is unloaded, which can be -- automatically unloaded in low memory situations, or explicitly via a call to -- storyboard.purgeScene() or storyboard.removeScene(). scene:addEventListener( "destroyScene", scene ) --------------------------------------------------------------------------------- return scene &nbsp;

When this code runs, it shows multiple entries and exits of each scene. I can’t set the objects to NIL since the first pass would release and erase it, then leave nothing for the second pass.

I obviously am missing much of how this really works or how I should code to make it work properly.

Any help would be appreciated.

Thanks!
Stu

Send me the project file and let me have a look. Its better than to post it all in here :wink:

Send the folder zipped to :  henrruud@online.no

I will post a short answer here afterwards for others to learn from

Listeners:

   Touch, Tap:  Are attached to objects that Storyboard will push off screen and possibly purge.  You can’t interact with them once they are off screen, so you don’t need to remove them.  They are safe to create in createScene when you create the objects.

    Runtime events:  Add in enterScene, remove in exitScene

    Storyboard event’s (createScene, enterScene, etc.):  leave alone.  They are required for storyboard to function if you want to ever return to the scene.

Looking at work flow of print statements, I don’t see much weirdness, except I don’t know why you’re getting that last enterScene twice.

I thought I wrung out all the wierdness but apparently there are still a few gremlins floating around.

The longer it runs, the more print statements we see when I enter a scene. 2-3-4 enter statements, and 4-5-6 exit statements.

when I tap the screen and launch a browser, it starts 2-3 instances of the browser.

Stu

The problem is your handler functions for your widget buttons.  They fire off multiple events, and you are not trapping for that so your scene gets called multiple times:

local function JobInstruction\_ButtonEvent(event)&nbsp; -- note removed the self parameter. &nbsp;&nbsp; if event.phase == "ended" then &nbsp; &nbsp; &nbsp; print("starting Job Instruction") &nbsp; &nbsp; &nbsp; storyboard.gotoScene( "JI1\_scene", "slideUp", \_G.slideTrans &nbsp;) &nbsp; &nbsp;&nbsp;&nbsp; print("ending job instruction") &nbsp;&nbsp; end &nbsp;&nbsp; return true end &nbsp;

According to the docs and my testing in the simulator, the following code does not work on TAP listeners.

local function TouchNextEvent(event) &nbsp; &nbsp; if (event.phase == "ended") then &nbsp; &nbsp; &nbsp; &nbsp; print("Leaving JI1 to go to JI2") &nbsp; &nbsp; &nbsp; &nbsp; storyboard.gotoScene( "JI2\_scene", "slideLeft", \_G.slideTrans &nbsp;) &nbsp; &nbsp; end &nbsp; &nbsp; return(true) end &nbsp;

&nbsp; &nbsp; &nbsp; &nbsp; Next = display.newImageRect("next\_black.png",25,25) &nbsp; &nbsp; Next.x = \_G.nextButtonX &nbsp; &nbsp; Next.y = \_G.nextButtonY &nbsp; &nbsp; Next.alpha = \_G.nextButtonAlpha &nbsp; &nbsp; screenGroup:insert(Next) &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; Prev = display.newImageRect("prev\_black.png",25,25) &nbsp; &nbsp; Prev.x = \_G.prevButtonX &nbsp; &nbsp; Prev.y = \_G.prevButtonY &nbsp; &nbsp; Prev.alpha = \_G.prevButtonAlpha &nbsp; &nbsp; screenGroup:insert(Prev) &nbsp;

function scene:enterScene( event ) &nbsp; &nbsp; print( "1: JI1 enterScene event" ) &nbsp; &nbsp; BG:addEventListener("touch",BGTouchEvent) &nbsp; &nbsp; Next:addEventListener("tap",TouchNextEvent) &nbsp; &nbsp; Prev:addEventListener("tap",TouchPrevEvent) end &nbsp;

The problem is that it’s a widget.newButton, not a tap handler:

&nbsp; &nbsp; JobInstruction\_Button = widget.newButton &nbsp; &nbsp; { &nbsp; &nbsp; &nbsp; &nbsp; left = leftBias, &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; top = Offset, &nbsp; &nbsp; &nbsp; &nbsp; defaultFile = "JobInstructionButton.png", &nbsp; &nbsp; &nbsp; &nbsp; overFile = "JobInstructionButton.png", &nbsp; &nbsp; &nbsp; &nbsp; onEvent = JobInstruction\_ButtonEvent &nbsp; &nbsp; } &nbsp; &nbsp; JobInstruction\_Button.baseLabel = "JobInstruction" &nbsp; &nbsp; screenGroup:insert( JobInstruction\_Button )

See:  http://docs.coronalabs.com/api/library/widget/newButton.html

in particular the handleButtonEvent() function.

I found the errors so now it´s ok :slight_smile:

main.lua || line 40:  have to change “.png” to “.PNG”

same goes for MM:scene at line: 72

For whatever reason, it is now working. I ran a batch file to change all the PNG files that were in the folder to .png for standardization. Not sure how it got exported as uppercase rather than lower case.

I also removed the widget since it wasn’t needed in this app, since a tap of the button causes the page to flip, changing the button image was unnecessary. So replaced the widget buttons with simple images and hooked a tap listener to each one. 

Size went down and it works well, with no duplicates when it is tapped. 

Thanks for all those people who helped me get this rolling.

stu

Its hard to tell when you dont seee the whole code One thing to keep in mind is that lua is lexical scoping eventlisteners AFTER declaring and so on