scene:hide() Not Being Called

Having an issue with moving between scenes and having one removed properly. Basically I have a game.lua file which runs all of the levels, levelSelect.lua, pause.lua, and refresh.lua as my main scenes. refresh.lua contains the following:

local composer = require "composer"; local prev = composer.getSceneName "previous"; local scene = composer.newScene(); function scene:show(event)  local phase = event.phase;  if phase == "will" then   composer.removeScene(prev);  elseif phase == "did" then   composer.gotoScene(prev, {params = event.params});  end end scene:addEventListener("show", scene); return scene

When I hide my pause.lua overlay (which also is run when the player dies and wins, kind of like the Angry Brids menu) I call composer.hideOverlay(true, “fade”, fadeTime); where fadeTime = 100 or 400 and when the pause menu will hide I call parent:resume(buttonName);. My problem is that when going to the next level through refresh.lua my game.lua scene is not actually ever being hidden. I go to the refresh.lua scene via composer.gotoScene(“scene.refresh”, {params = {worldNum = world, levelNum = level + 1}}); in scene:resume(buttonName) however the refresh.lua scene doesn’t actually hide the previous scene and when I go to the next level I also have the previous running behind it since none of the event listeners are removed via scene:hide(event) (since it isn’t ever called in game.lua).

Any ideas why?

Thanks

Where is your hide code?

That is the show events handler, of which there are two phases:

  • will show
  • did show

Neither of these is the equivalent of hide.

See the examples that come with Simulator or mine here:

https://github.com/roaminggamer/CoronaGeek/raw/master/Hangouts/composer_scene_manager.zip

Index to examples:

https://github.com/roaminggamer/CoronaGeek/blob/master/Hangouts/composer_scene_manager/README.md

PS - Try a few line breaks and paragraphs too please.  That last wall of text…well I didn’t read it because I have have an aversion to super-long run-on paragraphs.  However, your code is missing the hide section.

To hide your game scene, you need another scene. There is nothing in refresh.lua to create a scene to show so unless you transitioned the game scene off screen, it’s just going to sit there and try to show your refresh scene on top of it. I’d create a proper “Try again” or “Next level” cut scene.  If you don’t want this and just want to restart the game, when your overlay hides, have it call a function that sets all of your variables back to their default, positions objects back to their original position.

Rob

Note: IIR correctly, showing an overlay does NOT call the current scene’s hide code because you’re NOT hiding it.  You’re overlaying it.

[quote name=“roaminggamer” post=“359090” timestamp=“1496854324”]Note: IIR correctly, showing an overlay does NOT call the current scene’s hide code because you’re NOT hiding it.  You’re overlaying it.[/quote] In that big paragraph that you ignored I indicated that I know this and that my problem is with the game.lua scene, not the pause overlay or the refresh scene, both of which are working fine. My goal as I mentioned above is an overlay menu similar to that of Angry Birds that is shown over the frozen game scene. When the player selects an option in the menu the overlay is hidden and then composer.gotoScene() is called with arguments depending on the button pressed (go to the level select, next level, or restart the same level). My problem is that refresh.lua isn’t actually hiding the previous game.lua scene despite the code I have to destroy the previous scene

I don’t see the purpose of the refresh scene (in particular since you’re not displaying anything in it.) Composer is a scene manager. When you goto a scene, there should be a scene there. Your menu seems to want to go to other scenes.  

If you want to restart a scene without a visual cut scene, then simply have a function that gets called instead of composer.gotoScene() that repositions things and resets the level.  You can even us that function when you create the scene for the first time.

Rob

Didn’t know you could actually get away with just doing that. With regards to the refresh.lua usage I was following some of the stuff Sticker Knight did (one of the examples)

I decided to mark this unsolved again.

After reading this here again I realized something I’m doing is very wrong: https://docs.coronalabs.com/guide/system/composer/index.html.

I’m feeling a little frustrated since the tutorial reads the following…

“Once the scene is fully off screen, another hide event is dispatched to the scene:hide() function with a phase parameter equal to “did”. At this point, the scene’s view remains initialized since, by default, Composer keeps hidden/inactive scenes in memory on the assumption that they may be re-shown periodically.”

…however a scene:hide() event is still not being dispatched despite composer.gotoScene(); is being called. I am however getting the scene:destroy() event running since I do remove the scene in the next scene (hence scene:create() is called again the next time that scene is entered) but I feel like I am still doing something wrong.

I am still wondering why the scene:hide() event would not be called as well as if it is okay to remove event listeners, etc. in scene:destroy().

Also btw despite scene:destroy() being called and my display objects within the scene group being removed I am still having for example two game.lua scenes running at a time and feel like that will hurt runtime if eventually I have 100s of scenes running at once when levels are being played consecutively because even if I remove the event listeners will the scene not still be there?

Can you zip up your project and share it with us via drop box or other trusted DL provider?

If you can, post the link, tell me what scene file is the problem, and I’ll take a peek.

-Ed

Thanks a lot.

Here is the link: https://www.dropbox.com/s/ypk5003fzy6u6a4/Rustic%20Maze.zip?dl=0

It is not very optimized yet or anything but I did document the game.lua scene extensively

  1. Download this: https://github.com/roaminggamer/RG_FreeStuff/raw/master/ForumsImages/Rustic%20Maze.zip

  2. Look in the folder Rustic Maze/Rustic Maze

  3. Open game.lua and find changes marked with ’ RG

  4. See new scene file: refresh.lua

Note: I wouldn’t do it this way myself, but it will work.

Thank you very much.

I’m not sure I can tell what exactly causes scene:hide() but it is definitely being called now. Could you explain please? I want to make sure I know what I was doing wrong for future projects.

Also, what is the purpose of showing a screen shade in refresh.lua so briefly? Would it be better just to use another way that ditches refresh.lua completely.

Also now that the scenes aren’t actually being destroyed, I’m supposed to reset all of my variables manually in scene:show(), correct?

Generally there are two ways to reset a level. Go to a cut scene and remove the game scene in the process. BTW we have discovered it’s actually safe to call composer.removeScene(“sceneImin”) in its scene:hide() “did” phase. At that point the scene is off screen and can be safely disposed. This should make self-removing scenes easier. However you still have to go to a functioning scene.

The other way is to not leave the game scene at all and simply resposition/reset variables. In your question above, if you’re not going to change scenes, you won’t get scene:show() called. Just have a function that has all your positioning in it and call that function. If you add it to the scene object:

function scene:resetLevel( whateverParamsYouNeed )     --  end

Then in your overlay scene, your scene events should have an event.parent member which is the parent scene object. If you save that event.parent to local variable in the overlay scene, say parent:

local parent ... function scene:show( event ) parent = event.parent ... end

Then when you are hitting the scene restart button:

parent:resetLevel(parameters) composer.hideOverlay()

No need to change scenes. Depending on how much you’re doing in scene:create(), you could move that to your resetLevel function and have scene:create() call the resetLevel() function for the initial setup.

Rob

  1. I didn’t change anything with respect to scene:hide()  You simply didn’t have a refresh.lua scene to go to so the game crashed on your composer call to go to scene reresh.

  2. You have code ‘going’ to this scene, but you didn’t have the scene.  I assumed you were trying a hack where,

a. You go to scene refresh.  This triggers the hide in game

b. You immediately return to game.

  1.  I didn’t bother to fully grok your code, but I can see that it is wrong.  That is, the way you build up, destroy, and re-create a ‘refreshed’ scene are wrong.

You should really:

a. Put all of the game code in a module.

b. Give that module create, destroy, and refresh methods.

c. Test the module till you’re happy all those methods work.

d. require the module in game and call the module methods, thus having a nice slim composer scene file.

This is difficult, because you’re mixing learning composer with designing your game.

That’s very odd. There should have been a refresh.lua file in the scene folder with the same code as I posted at the top of this page

Sir, but how to create a proper “Next level” cut scene?? In my app,the next screen is coming on top of my base game screen i m saying it because my base screen isn’t moving anywhere and the problem is the buttons on my base screen are still active i don’t want them to be active once the next scene has appeared what is the solution to it?? Can i destroy my base game screen once the next screen has appeared?? If yes then how?? or is there any other way to do the same??

@swanandthakur1105,

Please start a new thread.  Adding your own questions to an old or ongoing thread is considered ‘hijacking’.

Where is your hide code?

That is the show events handler, of which there are two phases:

  • will show
  • did show

Neither of these is the equivalent of hide.

See the examples that come with Simulator or mine here:

https://github.com/roaminggamer/CoronaGeek/raw/master/Hangouts/composer_scene_manager.zip

Index to examples:

https://github.com/roaminggamer/CoronaGeek/blob/master/Hangouts/composer_scene_manager/README.md

PS - Try a few line breaks and paragraphs too please.  That last wall of text…well I didn’t read it because I have have an aversion to super-long run-on paragraphs.  However, your code is missing the hide section.

To hide your game scene, you need another scene. There is nothing in refresh.lua to create a scene to show so unless you transitioned the game scene off screen, it’s just going to sit there and try to show your refresh scene on top of it. I’d create a proper “Try again” or “Next level” cut scene.  If you don’t want this and just want to restart the game, when your overlay hides, have it call a function that sets all of your variables back to their default, positions objects back to their original position.

Rob

Note: IIR correctly, showing an overlay does NOT call the current scene’s hide code because you’re NOT hiding it.  You’re overlaying it.