Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

Director class - check this out!
Started by ricardorauber Oct 06 2010 03:20 AM

- - - - -
79 replies to this topic
[TOPIC CONTROLS]
Page 1 of 4 1 2 3 »
This topic has been archived. This means that you cannot reply to this topic.
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

ricardorauber

[GLOBAL: userInfoPane.html]
ricardorauber
  • Contributor

  • 219 posts
  • Corona SDK

Hey everybody!!!

I'm so pleased to show you something that I'm working on, the Director class (module)!!

With this class, everyone can easily create transitions between scenes (lua files) and make the work easier then ever!

Ex: You have a main.lua and need 50 other lua files each one for a totally different thing. With director class, all you need to do is this command:

director.loadScene("settings","moveFromLeft")

It will animate the transition and allocate/free memory and graphics!

Check this out: http://bit.ly/ayCHAb

When I finish it, I will send to Ansca to put on "Code" page!
uid: 8556 topic_id: 2447 reply_id: 302447


[TOPIC: post.html]
#2

Magenda

[GLOBAL: userInfoPane.html]
Magenda
  • Contributor

  • 427 posts
  • Corona SDK

Excellent news for a much wanted feature!

I am looking forward to your Director class. Is it going to handle (remove from memory) tables, listeners and other data-related memory consumers created inside the lua files?

Many thanks!
uid: 7356 topic_id: 2447 reply_id: 7211


[TOPIC: post.html]
#3

ricardorauber

[GLOBAL: userInfoPane.html]
ricardorauber
  • Contributor

  • 219 posts
  • Corona SDK

Thanks Magenda!

For now, I'm using the "tab bar" example for controlling that. Each lua file must have a display group and the functions new() and cleanUp() that are called from director.
uid: 8556 topic_id: 2447 reply_id: 7212


[TOPIC: post.html]
#4

LiveToCollect

[GLOBAL: userInfoPane.html]
LiveToCollect
  • Enthusiast

  • 53 posts
  • Guests

Nice - seems cool - looking forward to the finished project.

Thanks for sharing!
uid: 4621 topic_id: 2447 reply_id: 7213


[TOPIC: post.html]
#5

carlos m. icaza

[GLOBAL: userInfoPane.html]
carlos m. icaza
  • Corona Geek

  • 2,992 posts
  • Alumni

Very nice. Looking forward when you share it. let us know too so we can post it and blog about it.

c
uid: 24 topic_id: 2447 reply_id: 7214


[TOPIC: post.html]
#6

ricardorauber

[GLOBAL: userInfoPane.html]
ricardorauber
  • Contributor

  • 219 posts
  • Corona SDK

Finished!

http://developer.anscamobile.com/code/director-class-10

Please do some feedback!
uid: 8556 topic_id: 2447 reply_id: 7229


[TOPIC: post.html]
#7

Magenda

[GLOBAL: userInfoPane.html]
Magenda
  • Contributor

  • 427 posts
  • Corona SDK

Ricardo, thanks for sharing! Excellent set of transitions...

Some notes:
Why don't you replace the multiple fxEnded local functions with a single one out of the "if then elseif" statement.

Also, inside that fxEnded function you only remove the previous display group.
Consider adding a child=nil assignment in order to also delete other data the user has attached to the display group's table. Same applies for the group's object, so I would firstly cycle through the child's children and remove + nulify them.
Thanks again
uid: 7356 topic_id: 2447 reply_id: 7253


[TOPIC: post.html]
#8

ricardorauber

[GLOBAL: userInfoPane.html]
ricardorauber
  • Contributor

  • 219 posts
  • Corona SDK

Magenda,

Each effect has it's own logic, so I decided to create that fxEnded to personalize them. The fade effect, for example, is not like moveFromLeft.

For the child display groups is a good idea to make a recursive function, I will work on it!

Thanks a lot!
uid: 8556 topic_id: 2447 reply_id: 7257


[TOPIC: post.html]
#9

Magenda

[GLOBAL: userInfoPane.html]
Magenda
  • Contributor

  • 427 posts
  • Corona SDK

Ricardo, from what I see you use fxEnded for two things:
a) reset vars
b) removals

So, b) could be isolated and delivered from a function outside your "if" statement. This would make the code cleaner and your future work on improving the function simpler, as you would only change it in one point instead of 10.

Having said that, I like your project very much. What I think is missing for consider it perfect is a better memory cleaner that would automate the whole process of "deleting" the previous screen and all of its memory consumers. I am a newbie in lua, but I am going to try helping on that...

Thanks for sharing your work with us!

uid: 7356 topic_id: 2447 reply_id: 7258


[TOPIC: post.html]
#10

dknell

[GLOBAL: userInfoPane.html]
dknell
  • Contributor

  • 143 posts
  • Corona SDK

Ricardo,
Thanks for sharing this utility!!! It looks very nice.
uid: 8194 topic_id: 2447 reply_id: 7272


[TOPIC: post.html]
#11

ricardorauber

[GLOBAL: userInfoPane.html]
ricardorauber
  • Contributor

  • 219 posts
  • Corona SDK

Ok, let's improve that! I putted the fxEnded out of the changeScene function, it's now like this:

local function fxEnded ( event )

	currentView.x = 0
	currentView.y = 0
	currentView.xScale = 1
	currentView.yScale = 1
	--
	while (currentView.numChildren > 0) do
		currentView[currentView.numChildren] = nil
		currentView:remove(currentView.numChildren)
	end
	--
	currentScreen = nextScreen
	currentView:insert(currentScreen)
	nextView.x = display.contentWidth
	nextView.y = 0
	nextView.xScale = 1
	nextView.yScale = 1
	
end

The problem is that because of that
currentView[currentView.numChildren] = nil
assignment, I'm getting the message
WARNING: Attempting to set property(1) with nil
at the Terminal. Is that right? Carlos?
uid: 8556 topic_id: 2447 reply_id: 7273


[TOPIC: post.html]
#12

Magenda

[GLOBAL: userInfoPane.html]
Magenda
  • Contributor

  • 427 posts
  • Corona SDK

I suppose it doesn't compile properly (not at home right now), but I would make it this way:
for child=currentView.numChildren,1,-1 dofor childofchild=currentView[child].numChildren,1,-1 docurrentView[child]:remove(childofchild)currentView[child][childofchild] = nilendcurrentView:remove(child)currentView[child] = nil                end
uid: 7356 topic_id: 2447 reply_id: 7275


[TOPIC: post.html]
#13

ricardorauber

[GLOBAL: userInfoPane.html]
ricardorauber
  • Contributor

  • 219 posts
  • Corona SDK

In this case you can only clean 2 levels. I'm thinking in something to go into the entire tree.

Imagine this:

local g1 = display.newGroup()
local g2 = display.newGroup()
local g3 = display.newGroup()
local g4 = display.newGroup()

g1:insert(g2)
g2:insert(g3)
g3:insert(g4)

local q1 = display.newImage("logo.png",100,100)
local q2 = display.newImage("logo.png",300,100)
local q3 = display.newImage("logo.png",100,300)
local q4 = display.newImage("logo.png",300,300)

g1:insert(q1)
g2:insert(q2)
g3:insert(q3)
g4:insert(q4)

How can I go though all four groups and clean them?
uid: 8556 topic_id: 2447 reply_id: 7276


[TOPIC: post.html]
#14

Magenda

[GLOBAL: userInfoPane.html]
Magenda
  • Contributor

  • 427 posts
  • Corona SDK

You have right!

Ok, I would first go deep inside the levels checking for the existance of .numChildren with an assert and increasing a "levelsnum" var by +1.

Then I would construct a while loop using .parent to climb up the levels removing+nulifying whatever exists.

Tricky! (but not impossible)
The biggest problem, however, is how to find where listeners and timers are stored to delete them too, climbing all the way up.

I am going to work on it tomorrow...
uid: 7356 topic_id: 2447 reply_id: 7278


[TOPIC: post.html]
#15

ricardorauber

[GLOBAL: userInfoPane.html]
ricardorauber
  • Contributor

  • 219 posts
  • Corona SDK

Got it!

Check this out:

local g1 = display.newGroup()
local g2 = display.newGroup()
local g3 = display.newGroup()
local g4 = display.newGroup()

g1:insert(g2)
g2:insert(g3)
g3:insert(g4)

local q1 = display.newImage("logo.png",100,100)
local q2 = display.newImage("logo.png",300,100)
local q3 = display.newImage("logo.png",100,300)
local q4 = display.newImage("logo.png",300,300)

g1:insert(q1)
g2:insert(q2)
g3:insert(q3)
g4:insert(q4)

print ("g1.numChildren: " .. g1.numChildren)
print ("g2.numChildren: " .. g2.numChildren)
print ("g3.numChildren: " .. g3.numChildren)
print ("g4.numChildren: " .. g4.numChildren)
print ("-----------------------")

g1.name = "g1"
g2.name = "g2"
g3.name = "g3"
g4.name = "g4"
q1.name = "q1"
q2.name = "q2"
q3.name = "q3"
q4.name = "q4"

print ("g1.name: "..g1.name)
print ("g2.name: "..g2.name)
print ("g3.name: "..g3.name)
print ("g4.name: "..g4.name)
print ("q1.name: "..q1.name)
print ("q2.name: "..q2.name)
print ("q3.name: "..q3.name)
print ("q4.name: "..q4.name)
print ("-----------------------")

local function cleanGroups ( curGroup )
	print ("curGroup = " .. tostring(curGroup.name) .. " - children = " .. tostring(curGroup.numChildren))
	if curGroup.numChildren then
		while curGroup.numChildren > 0 do
			cleanGroups ( curGroup[curGroup.numChildren] )
		end
		curGroup:removeSelf()
	else
		curGroup:removeSelf()
		curGroup = nil
		return
	end
end

cleanGroups(g1)

print ("-----------------------")
print ("g1.numChildren: " .. tostring(g1.numChildren))
print ("g2.numChildren: " .. tostring(g2.numChildren))
print ("g3.numChildren: " .. tostring(g3.numChildren))
print ("g4.numChildren: " .. tostring(g4.numChildren))
uid: 8556 topic_id: 2447 reply_id: 7280


[TOPIC: post.html]
#16

ricardorauber

[GLOBAL: userInfoPane.html]
ricardorauber
  • Contributor

  • 219 posts
  • Corona SDK

Version 1.1 deployed!

I made some changes to make it better!

- Best memory clean up
- Best organization
- Only one group is needed to insert in main.lua

http://developer.anscamobile.com/code/director-class-10
uid: 8556 topic_id: 2447 reply_id: 7319


[TOPIC: post.html]
#17

Magenda

[GLOBAL: userInfoPane.html]
Magenda
  • Contributor

  • 427 posts
  • Corona SDK

Cleaning up doesn't seem to work properly.
Try this, for two screens ("p1","p2") that return a "lg" group

director:changeScene("p1","moveFromRight")print(p1.lg==nil)     -- lg is the returning (global) group of p1 screenlocal function onTap(event)	if "began" == event.phase then		director:changeScene("p2","moveFromRight")		print(p1.lg==nil)     --should be nil, but it isn't 	endendRuntime:addEventListener("touch", onTap)  -- LISTENER --


uid: 7356 topic_id: 2447 reply_id: 7328


[TOPIC: post.html]
#18

ricardorauber

[GLOBAL: userInfoPane.html]
ricardorauber
  • Contributor

  • 219 posts
  • Corona SDK

I don't know exactly what you are trying to do but I'm always getting true using version 1.1 of director class.

display.setStatusBar( display.HiddenStatusBar )

-- Import director class
local director = require("director")

-- Create a main group
local mainGroup = display.newGroup()

-- Main function
local function main()

	-- Add the group from director class
	mainGroup:insert(director.directorView)

	-- Change scene without effects
	director:changeScene("screen1")
	print(screen1.lg==nil)
	local function onTap(event)
		if "began" == event.phase then
			director:changeScene("screen2","moveFromRight")
			print(screen1.lg==nil)     --should be nil, but it isn't 
		end
	end
	Runtime:addEventListener("touch", onTap)  -- LISTENER --
	
	return true
end

-- Begin
main()

-- It's that easy! :-)
uid: 8556 topic_id: 2447 reply_id: 7330


[TOPIC: post.html]
#19

Magenda

[GLOBAL: userInfoPane.html]
Magenda
  • Contributor

  • 427 posts
  • Corona SDK

Ricardo, you get always true (object==nil) because you have (properly) set your objects as *locals*, so you can not see them from main.lua. You would also get true if you checked for a non-existent variable (because it doesn't exist, it is "nil").

Try to set your returning group as a *global* one for it to be accessible from main. You will get false (group table exists after screen change!)

For some reason, function cleanGroups removes the display objects from screen but *do not* nullify the objects as tables. To understand why the latter is essential, imagine a module in which you download 5mb of data from the web and attach this data as a property to the group (group.data), so it can be deleted on screen change. If the group is removed graphically but not deleted as a table, there is no memory management at all. Display objects removal is just the first step. The hard part is tables, timers, listeners etc...
PS: How can I access the current screen's name from main.lua? Thanks!
uid: 7356 topic_id: 2447 reply_id: 7335


[TOPIC: post.html]
#20

ricardorauber

[GLOBAL: userInfoPane.html]
ricardorauber
  • Contributor

  • 219 posts
  • Corona SDK

Some variables aren't accessible programmatically, like timers. I tried to clean all but for some you have to do it manually. If there's a way to clean up this kind of variables, I will put it into the cleanGroups function! I'm not an expert, I'm still learning how to use Corona.

For now, use can this:

myVar = nil
changeScene("scene","effect")
uid: 8556 topic_id: 2447 reply_id: 7341


[TOPIC: post.html]
#21

mtchapman

[GLOBAL: userInfoPane.html]
mtchapman
  • Observer

  • 8 posts
  • Guests

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:

------------------------------------------------------------------------	-- 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!


Change loadScene as follows:

------------------------------------------------------------------------	-- 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()	endend


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

function cleanup() 	-- Add any scene specific deletions not handled in this function	timer.cancel(mytimer)	end


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

Mike Chapman
uid: 9827 topic_id: 2447 reply_id: 7486


[TOPIC: post.html]
#22

oz-machine

[GLOBAL: userInfoPane.html]
oz-machine
  • Enthusiast

  • 42 posts
  • Guests

This is cool. :)

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. :)

Thanks for your great solution!
Mike
uid: 4454 topic_id: 2447 reply_id: 7495


[TOPIC: post.html]
#23

oz-machine

[GLOBAL: userInfoPane.html]
oz-machine
  • Enthusiast

  • 42 posts
  • Guests

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" :)

Mike
uid: 4454 topic_id: 2447 reply_id: 7500


[TOPIC: post.html]
#24

ricardorauber

[GLOBAL: userInfoPane.html]
ricardorauber
  • Contributor

  • 219 posts
  • Corona SDK

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.
uid: 8556 topic_id: 2447 reply_id: 7580


[TOPIC: post.html]
#25

awesomeware14

[GLOBAL: userInfoPane.html]
awesomeware14
  • Observer

  • 10 posts
  • Guests

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);
uid: 3325 topic_id: 2447 reply_id: 7697



[topic_controls]
Page 1 of 4 1 2 3 »
 
[/topic_controls]