Director class - check this out!

Ricardo,

Thanks for the great code. I have modified it slightly so it will call a cleanup function when you change scenes, just like it calls new when you start scenes.

Change changeScene as follows:

[lua]------------------------------------------------------------------------
– CHANGE SCENE

function director:changeScene(nextScene,
currentScene,
effect,
arg1,
arg2,
arg3)

– If is the same, don’t change

if lastScene then
if string.lower(lastScene) == string.lower(nextScene) then
return true
end
end

local showFx


– EFFECT: Move From Right

if effect == “moveFromRight” then

nextView.x = display.contentWidth
nextView.y = 0

loadScene (nextScene,currentScene)
– (make sure you change each loadScene like this![/lua]

Change loadScene as follows:

[lua]------------------------------------------------------------------------
– LOAD SCENE

local function loadScene ( nextScene, currentScene )

nextScreen = require(nextScene).new()
nextView:insert(nextScreen)
–print (“Current Scene” … tostring(currentScreen))
if currentScene ~= nil then
require(currentScene).cleanup()
end
end[/lua]

Add the following to your specific file like new():

[lua]function cleanup()
– Add any scene specific deletions not handled in this function
timer.cancel(mytimer)

end[/lua]

Hope this makes sense. I needed a way to stop timers I had running. :slight_smile:

Mike Chapman
[import]uid: 9827 topic_id: 2447 reply_id: 7486[/import]

This is cool. :slight_smile:

It would also be cool to allow for layering of screens, so one could load in persistent “top or bottom” menus, or popups.

Imagine a new method where you’d pass in tables of screens:

director:changeScene( { { "homeScreen", "moveFromRight" }, { "topMenu", "overFromTop" } } )  

With this method, you could create persistency by only changing screens that differ:

director:changeScene( { { "gameBoard", "moveFromRight" }, { "topMenu", "overFromTop" } } ) -- topMenu stays in place  

That sounds like a bit of work, though. :slight_smile:

Thanks for your great solution!
Mike [import]uid: 4454 topic_id: 2447 reply_id: 7495[/import]

Oh, wait, I get it. You can already achieve layering by having multiple directors, right?

-- \* In main.lua file, you have to import the class like this:  
--  
-- director = require("director")  
-- local g = display.newGroup()   
-- g:insert(director.directorView)  

So, you could have a different director for each display group that would constitute as a “layer” :slight_smile:

Mike [import]uid: 4454 topic_id: 2447 reply_id: 7500[/import]

Thanks all!!

mtchapman

When I created the first version of Director, I had this cleanUp function, but as I couldn’t stop timers and clean other kind of variables, I cut it off leaving this for the owner of the lua file. It’s a great ideia indeed.

oz-machine

Sure, you can use director N times! I have a project that uses tab bar and title using director and other files using other director, one inside the other. [import]uid: 8556 topic_id: 2447 reply_id: 7580[/import]

I’m having trouble using the timer.performWithDelay function using this module. I have a function that begins a count down timer counting down from 3 but I don’t want it to start counting down until the scene change animation is done so I have timer.performWithDelay(300, countDown) but whenever I use it the screen just goes black. If I remove the timer and simply call the function there is no problem other than the fact that the timer starts before the animation is finished. Has any one else had a similar problem?

Edit: There is also no error in the terminal.

Edit 2: Okay I have the problem partially solved. If it is placed in a table and inserted in the localGroup table the screen no longer goes black but instead skips over the animation. The lesser of the two evils.

So the final code would be something along the lines of:

local countDown\_timer = timer.performWithDelay(300, countDown); localGroup:insert(countDown\_timer); [import]uid: 3325 topic_id: 2447 reply_id: 7697[/import]

Everything that is inserted into the group, director will call the remove function while changing scenes but I don’t thing that timers works with that. I can’t test it right now, but as soon as I can I’ll do it. [import]uid: 8556 topic_id: 2447 reply_id: 7751[/import]

Okay, I’m not sure whether or not it deletes either yet but that would definitely be nice to know. However, that’s not the actual problem. When I’m using the timer.performWithDelay function the screen goes black. It is definitely the use of the timer.performWithDelay because I had it call an empty function as a test and it still caused the screen to go black. I’ve tried it both with and without putting it in a display.newGroup()and with and without giving a variable name. I’ll keep trying to figure it out let me know if you need more of the source code once you have time to look at it.

Edit: Okay so I was able to get get the timer.performWithDelay to work twice but I have no idea why they are working. They both happen to be within a function inside another function (plus the default new()) function and within the else step of an if then else statement. I recreated that layout with no such luck.

I’ve also confirmed that the application doesn’t crash or pause but the display group disappears (or possibly is moved behind something else?).

Unrelated Question: Is it possible to pass a variable from one scene to the next?

Edit 2: I’ve narrowed the error down to the moveOn* animation types. It does not seem to occur on any of the other animation types. Hope this helps. [import]uid: 3325 topic_id: 2447 reply_id: 7758[/import]

awesomeware14

Check this out:

local timerid = timer.performWithDelay(  
 500, listener, 100 )  
local timerid2 = timer.performWithDelay(  
 1000, listener, 100 )   
   
-- Some point later in the app  
function stopAllTimers()  
 timer.cancel(timerid)  
 timer.cancel(timerid2)  
}  

I got that in the Timer API: http://developer.anscamobile.com/content/timer-library

So, you could make a function like this:

local function changeScene ( scene, effect ) timer.cancel(timerid) timer.cancel(timerid2) ... timer.cancel(timeridN) director.changeScene( scene, effect ) end [import]uid: 8556 topic_id: 2447 reply_id: 7863[/import]

That does help with deleting timers but it doesn’t help with the screen disappearing. Maybe I should explain the problem differently. I load the document ‘play.lua’ from ‘main.lua’ using the director class, then I draw my display objects and insert those objects into the group. I then load the functions (not call them) and then create a timer.performWithDelay to call the first function after a few seconds. Regardless of the delay time the display group disappears. However this is only true when using the moveFrom*. All of the other transition animations do not have this problem. [import]uid: 3325 topic_id: 2447 reply_id: 7873[/import]

Can you send me the code or some code with the same problem? [import]uid: 8556 topic_id: 2447 reply_id: 7874[/import]

Sure I’ll throw together an example for you as soon as I get a chance. Also I would like to say other than this minor bug you did a great job this makes coding a lot easier! [import]uid: 3325 topic_id: 2447 reply_id: 7888[/import]

I have the same timer.performWithDelay => Black Screen problem.
Any luck yet?

Best
Matthias [import]uid: 6509 topic_id: 2447 reply_id: 8868[/import]

That’s very strange… send me some code! I can’t reproduce it [import]uid: 8556 topic_id: 2447 reply_id: 8880[/import]

It’s just a plain call to timer.performWithDelay:
[lua]-- Inside scene.lua#new()#startGame()
timer.performWithDelay(700, function(event)
if arrow then
localGroup:remove(arrow)
arrow = nil
end
createBall(xPos, yPos, xVel, yVel)
isPlaying = true
end)[/lua]

when i load the scene from the game menu with “overFromRight”,
everything works as expected; with “moveFromRight” i get the
mentioned black screen.

Matthias

BTW: Awesome work! Thanks! [import]uid: 6509 topic_id: 2447 reply_id: 8883[/import]

Going to give this Director class a whirl and have a question.

I am placing all my game code into a file called screen2.lua

I can see that all display objects need to be inserted into localGroup - is that correct?

If so then what do I need to do with existing groups that contain images?

Foe example i have a group declared as follows:

local allBallsGroup = display.newGroup()

Do I need to do something like the following?

localGroup:insert( allBallsGroup )

Or am I getting a bit mixed up here?

[import]uid: 7863 topic_id: 2447 reply_id: 9078[/import]

Ignore my last post - sorted now! It was simply a case of inserting into the localGroup.

I am however experiencing an issue where sometimes when I load screen2.lua it displays a black screen when using move from right or move from left. Not a show stopper as works with the other transitions and as yet I have no preference as to which transition to use.

Great class! Thank you for sharing it. [import]uid: 7863 topic_id: 2447 reply_id: 9113[/import]

Do you have a list of all things that need to be “cleaned” when switching between scenes?

I have realised certain things like transitions continue when I change scenes. Fortunately I have discovered there is a transition.cancel function that I can use to cancel these.

Would be useful to have a reference to other stuff that needs to be taken care of. For example, what would happen if the game was in the middle of a “for” loop moving objects and a user clicked a button to change scene?. I ask as I am getting a load of runtime errors when doing this and trying to track down the culprit.

[import]uid: 7863 topic_id: 2447 reply_id: 9475[/import]

mediakitchen, so sorry for the delay, I’m working on a game entirely with corona!

Director class can’t remove timers, transitions and eventListeners. When you want to change scenes, put some function that remove all that things. As I said inthe director code page, I will work on that for the next versions!

Thanks for using director! [import]uid: 8556 topic_id: 2447 reply_id: 9513[/import]

Hey no apology necessary!

Thank you for the reply to my question - that is fine to remove these elements manually. I guess I just assumed it did this automatically as it was so smooth an operation using the class for my game.

Thank you so much for sharing this with everyone.

Paul [import]uid: 7863 topic_id: 2447 reply_id: 9658[/import]

Hey guys, this is important!

Talking to jmartinho by e-mail, he asked me about a custom clean() function that executes every time that scenes are changed. Director should execute this function, so he doesn’t need to put the call in every file. So, I made a research and if you want the same functionality, just go to the end of the changeScene function and add the commented part below:

 -----------------------------------  
 -- Clean up memory  
 -----------------------------------  
  
 if lastScene then  
  
 -- If you want to use a custom function to clean, use this  
-- if string.lower(lastScene) ~= "main" then  
-- package.loaded[lastScene].clean()  
-- end  
  
 package.loaded[lastScene] = nil  
 end  
 lastScene = nextScene  
 collectgarbage("collect")  

As you can see, just before Director release the loaded file, you can make a call to any function of it. You can also use this type of call to other things but remember, you must create the same function name in EVERY file that Director will use as a scene!

Any doubts just tell me! [import]uid: 8556 topic_id: 2447 reply_id: 10722[/import]