When a scene changes from one to another it takes time to get ready, what I need to do is till the next scene gets completely ready, it should be hidden by a background and the progress bar should tell how much the next scene is ready. Once the next scene is completely ready that scene should be shown removing progress bar and the background. But I am not finding a way to do it, I checked for another topic related to the same functioning but it didn’t give me expected results.
There are solutions using timer.performWithDelay(), like look for the time in which the scene gets ready, have a background for that much time and then remove the background once the scene is ready, but I am looking for some different solution
I am grateful to everyone who will be taking part in the above discussions.
Unfortunately scene loading isn’t asynchronous. In order to have a progress bar, you’d need to do something like:
Load Scene, but don’t create any images or do any heavy calculations.
Show progress bar and background. Don’t insert into scene group so it stays above everything else.
Using an enterFrame listener, break your image loading and heavy calculations into smaller chunks.
After each chunk has been processed, update the progress bar.
Once all loading is done, remove the progress bar and background.
It depends on what your scene is like as to whether this is manageable and whether it makes sense to put all the image filenames, default positions, physics data etc into a table to iterate through one image at a time.
You would need to write your code in such a way that the scene builder runs, then stops, then runs, then stops, otherwise as @nick_sherman points out, the loading scene will block any other code, including your ‘progress bar’.
Three ways come to mind:
enterFrame driven loader where only a small amount of work is done per frame.
timer based (same as above)
co-routines - same as above.
I prefer the enterFrame concept and have used it before.
Or you could just use a loading spinner that you fade in at the starting point, and out again when loading is done and just before displaying the newly loaded scene.
Its pretty standard behaviour out there so I doubt users will dismiss that in favour of an old-fashioned loading progress bar.
Hey, I didnt know that one existed so made my own but yes, thats the concept
EDIT - And after testing it and reading the tutorials, useless stuff!
On Android it has a solid white background without any options to change it or make it transparent, being a native object.
Make your own with a full screen see through square that catches tap and touch events, and you get the same functionality, yet customizable to your own needs.
Tip: Creating your own activity indicator with display objects will NOT work unless you break up the scene loading like I did.
Corona is single-threaded, so once the scene starts to load, any timer or enterframe code used to update your activity indicator will be blocked.
UPDATE: This is not a composer.* limitation. It is true in every case. For example if you do this:
create spinner object
2.
add enteFrame listener or timer to ‘spin it’
3.
run a function that takes 5 seconds to complete
(also true if the spinner is a animated sprite; it will not animate in step #3)
The spinner will not spin during the time step #3 is executing. Why? Corona is single-threaded and the enterFrame handler will not be called while step #3 is running.
FYI - This is where game lag come from. If Corona has too much work to do in any frame, all future frames are blocked till that work is done.
For example, in my games I load data in chunks, each chunk represents <5% of total data. I can then animate a progress bar to provide visual feedback to the user.
You must do this out of scope to the scene being loaded and it is a chunk of work so I wouldn’t bother unless your screen is +10s to load.
I should have mentioned i dont use composer, so if that is a limitation as RG says then he know better.
I remember reading that composer has a kind of parent layer that might be able to handle cross scene code, might want to look into that, or maybe RG know more about what I refer to
Oh i see. Yeah my spinner isnt always silk smooth but it depends on how much work is being done in the background, and sometimes cose can be altered slightly to make it look better.
However, it is smooth enough to be functional and after all, cant get past the single threaded limitation of corona, so no point wanting something that cannot be had.
It is of course being updated on enterFrame events.
Thanks to all for their inputs. Looking at the above discussions many of the experts are suggesting enterFrame, but I am not understanding how exactly I should work regarding to it, for exactly what and where I should use enterFrame ??
Can I get the same functioning using functions?? like after loading some assets the value of progress bar will get update as the function to update it will be called??
Sir @roaminggamer, I am founding it hard to understand your code would it be possible for you to simplify it?
Three examples showing how to display work load (one showing issue; second showing native activity indicator, third showing enterFrame solution).
If this is too hard to understand at this point, you’re better off just living with the delay. This isn’t a simple thing.
PS - As @sgs pointed out: “Doing this is a significant chunk of work.” This technique requires both knowledge and discipline to deal with. If you’e new, this may be beyond your current skills.
Using the enterFrame event is pretty straight forward.
Is just like a timer except instead of setting the timer to call function to run after set time has expired, enterFrame will run the function each time a new frame is drawn. If your app runs at 30fps that means it will call the function 30 times per second. Now if you have a display object you can for example rotate it X degrees each time the function is run, meaning it will rotate a little 30 times per second.
Sorry for the lack of formatting, writing on a mobile phone.
let’s say you have a bit of code somewhere name “Preloader” (for example) that knows how to process() a single step in the loading sequence, for example:
if “sequence”==1 then you do the first of many time-intensive things, then return
if “sequence”==2 then you do the second of many time-intensive things, then return
up to as many discrete steps as you wish
then in a “loading” scene you’d set up an enterFrame listener and call Preloader:process() on each frame with an increasing sequence number, pseudocode:
-- LoadingScene.lua -- partial, psuedocode local Preloader = require("Preloader") functions scene:create(event) self.preloadSequence = 1 Runtime:addEventListener("enterFrame", self) end function scene:enterFrame(event) -- animate a progress bar (or whatever) as a percentage of current sequence versus total Preloader:process(self.preloadSequence) self.preloadSequence = self.preloadSequence + 1 -- \* see note below, re "who" maintains this if (Preloader:isComplete()) then Runtime:removeEventListener("enterFrame", self) composer.gotoScene("NextScene", whatever) end end
that’s the general pattern for a “typical” preloader. if you don’t already know what coroutines are and how to use them, then it’d be hard to recommend that approach.
* if you want to get “fancy” and make it reusable, then build your preloader to accept an array of loader functions, then it’s easy to vary the total number, keep track of the sequence, calculate a percentage complete for you, and basically track the whole process for itself.