object on top of all layers

my question was really simple: “is there an easy way to force an object to be on top of every other object, even if others objects are created after?”

i think my fault was giving some background info about what was i doing so everyone started from there and sugesting things i already knew :slight_smile:

for that, I apologize to everyone who I may missleaded. 

Regards,

Carlos

@carloscosta  - I’ll PM this to you in case you’re not continuing to read this thread, but I’m posting it here because I hope to be at least a little helpful to you and others.
 
In your post above I noticed you said something about hating Runtimes.
 
I’m guessing this may be because it is easy to get crashes with Runtimes like ‘enterFrame’ and/or custom Runtime event listeners.
 
For example, this code using a table listener would crash:

local obj = display.newCircle( 100, 100, 100 ) obj.enterFrame = function( self ) self.x = self.x + 10 end Runtime:addEventListener( "enterFrame", obj ) timer.performWithDelay( 1000, function() display.remove(obj) ) end)

To prevent a crash you can do this:

local obj = display.newCircle( 100, 100, 100 ) obj.enterFrame = function( self ) self.x = self.x + 10 end Runtime:addEventListener( "enterFrame", obj ) function obj.finalize( self ) Runtime:removeEventListener( "enterFrame", self ) end obj:addEventListener( "finalize" ) timer.performWithDelay( 1000, function() display.remove(obj) ) end)

PS - I’m always mentioning SSK2 (now free), but in this case it has a handy feature for safely cleaning up Runtime listeners.

The safe code above would look like this in SSK2:

local obj = display.newCircle( 100, 100, 100 ) obj.enterFrame = function( self ) self.x = self.x + 10 end listen( "enterFrame", obj ) function obj.finalize( self ) ignoreList( { "enterFrame" } , self ) -- add more event names to table to safely remove them. end obj:addEventListener( "finalize" ) timer.performWithDelay( 1000, function() display.remove(obj) ) end)

 

this works as well

local obj = display.newCircle( 100, 100, 100 ) obj.enterFrame = function( self ) if type( self.removeSelf ) == "function" then self.x = self.x + 10 else Runtime:removeEventListener( "enterFrame", obj ) end end Runtime:addEventListener( "enterFrame", obj ) timer.performWithDelay( 1000, function() display.remove(obj) end)

Hi sphere, i hate runtimes, because they are always working 30/60 times a second (depending on your  config) running, slowing down the app (even if we don’t notice…i do) and consuming battery…that the only reason :slight_smile: never had a problem with crashes, i always remove then before trying to remove anything inside it.

saying that, your last code is very cool way to remove the runtime. thank you, for sharing  your knowledge, i learned something from it. i would never by myself remember to  compare the self.removeSelf to check if it exists.

Hi,

Using display groups should solve that issue although I dont use composer myself so perhaps it works differently

Anaqim

hi anaqim,

I don’t use composer also and using display.groups won’t solve the problem. the code needs to be independent of any other code, so I can integrate it, like a plugin. For now, I resolved the problem with the runtime solution, but I really don’t like it (i hate runtime code)

@Carlos, why won’t display groups solve your issue?

If you had say 2 groups, lets call them sceneDG and overlayDG.  You create sceneDG first and then overlayDG second.  

Objects you want “above” your game insert into overlayDG and all other objects insert into sceneDG.  Anything inserted into overlayDG will always on top.

I give you one example that won’t work.

you have 3 groups,

sceneDG1

sceneDG2

overlayDG

I load sceneDG1 into memory

in that scene, I open the overlayDG),

if I press a button to go sceneDG2 overlayDG will be behind scenceDG2. (i will remove sceneDG1 from memory and create sceneDG2 only when it is called. I can’t create all groups in advance…that’s not the proper way to do scenes).

my only hope is having a hidden “top layer” that I could use it for cases like this. ofc I could put all my other groups on level 2 layer, but if I shared my code it would not work with anyone else because everybody else was creating groups from layer 1.

so my question still remains, is there a way to put an object on a “super group” that would be on top of everything, regarding of other groups are creating after.

toaster plugin does exactly that, so I guess its possible, my only concern is that is only possible with native code.

If you’re only loading (and showing) one scene at a time, why the need for sceneDG1 and sceneDG2?

Just remove everything from sceneDG and load in the new objects to the same group.

Or you could just call overlayDG:toFront() every time a new scene display group is created - no need to continually do it in the runtime listener.

It doesn’t matter what scene you are playing you only load that into sceneDG.  So…

sceneDG:insert(sceneDG1)

then when you move to scene 2, remove scene 1 and insert scene 2, etc

display.remove(sceneDG1) sceneDG:insert(sceneDG2)

this way overlayDG is always on top

Assign the display groups in drawing order bottom to top

Then add and remove children and manipulate the display groups to your liking, but never remove them!!

That is perhaps your issue.

nick_sherman, scenes are independent and they don’t know that overlayDG exist. only 1 scene happens 1 at a time, but if you know what a toaster is…it will prevail even if you close that scene.

i know to resolve the problem (and i did if you read my posts) i’m just curious to know if there is a hidden or better way to do what i asked. a “super group”.

sphere, with toaster plugin, i just call the plugin, it will prevail on top of any other group or object i will create after. i don’t need to insert it on any group after to still work. it works alone and independent. it’s that what I’m after.

still thx for trying to help (all are included)

ps. please don’t insist on display groups (workarounds or ways how I could create my groups I already know them). my question was really simple if you don’t know the answer don’t try to give me alternatives.i already know them.

To follow your logic of having 2 layers:

local sceneDG=display.newGroup()

local overlayDG=display.newGroup()

load your first scene into sceneDG

load your overlay into overlayDG

when it is time to change scene, iterate backwards through all the children of sceneDG and remove them like in this post

https://forums.coronalabs.com/topic/46257-find-all-children-in-a-display-group/

then add all objects for your second scene into sceneDG

your overlayDG will remain firmly on top.

to my knowledge there isnt a specific GUI layer that is always on top, like some other engines have.

then again, name one of the displaygroups GUI and you are good to go.

corona does this in a very powerful way.

anaqim

Assign the display groups in drawing order bottom to top

Then add and remove children and manipulate the display groups to your liking, but never remove them!!

 

That is perhaps your issue.

I know how groups work

I don’t have an issue with that. 

all my scenes, I create different files in each file they will be inside a closed group, that group can receive arguments so I can pass information from one scene to another. I’ ve an “ultimate delete function” that will remove any of my objects inside that group including that group. so I’m creating groups and deleting them as I need. I don’t have a group and put all inside. I could pass as an argument the

overlayDG from one scene to another. and put it on top on the second scene. my curiosity is that toaster already does what I want without this additional steeps and I already managed to do that without bothering of adding more code to make sure the code is independent and works alone (like it should). I’m just curious to know if there is another method of doing that without runtime. all your suggestions are worst because they are not independent and the other code needs to know the snackbar/toaster exist.

that description was easier to understand for me at least and i am not sure if this is will help, but its the only thing that springs to mind at this point.

https://docs.coronalabs.com/api/library/composer/showOverlay.html

anaqim

Sounds to me like you’re trying to use composer.* as some kind of layer manager.
 
If I’m wrong, ignore this, but I’ll post the same response I gave here below.

If you only need to separate content into layers, using composer.* is overkill.
 
In the separation of content case, you would be better off simply using display groups to separate your content.
 
https://docs.coronalabs.com/api/library/display/newGroup.html
 
Also, SSK2 provides a easy way to set up (named group) layer hierarchies.

If you are referring to the “toast” plugin (rather than toaster), the reason this is always on top is because it is a native Android object and not part of Corona’s OpenGL layout. You are not going to be able to create objects in Corona that perform in exactly the same way as this, because any objects created in Corona are always going to be part of the OpenGL layout.  

The only way to do something like this is with the method everyone else has suggested but that has been rejected, with layered groups (controlled via a module or something to keep them persistent and in the correct order).

Back again.  I’ve given this a quick re-read and I’m puzzled.  Why are you passing objects between scenes?  There isn’t any rule against it, but it seems weird to me.

Also, if you’re passing objects between scenes, you can just go on step further…

  1. Make a group hierarchy like I (and others) suggested above.

  2. Use the hierarchy to maintain layering order.

  3. Pass the hierarchy group parent between scenes.

  4. Insert the hierarchy group parent into the current scene.

  5. Done.  Unless I’m completely not getting this. 

Of course you won’t be able to use any sexy transitions at this point, but then I’m still confused about this use of composer.*

Maybe a small video would help clarify what’s being done here?

Alan QuizTix, respond to what I was looking and what iI already suspected (but with a little hope that someone had some hidden gem to share with everyone).

Thanks to all that tried to help. 

p.s. (roaminggamer, i’m not using composer like I already told, and I will not answer your post because I already have my answer. thanks anyway for trying to help)

p.s.2 (anaqim, same, but thanks again for trying to help :slight_smile: )