Graceful loading levels

as suggested by user Anon in this thread I publish here a snippet to see how to load/unload your game levels using Sequence hiding behind a curtain and a loading image message your 2d/3d resources while destroying or showing out. You may download the zipped snippet here.

Excelent!!! I was asking myself how to do that and was going to spam the forum.
Thanks astelix, exactly what I needed :slight_smile:

A MUST thing to add would be : loading all models while the loadingimage is reparented to render. Only thing I know about it is that I should load models asynchronously using threading… And don’t know how go further!

P.S: Global variable “terrain” is not used :wink:

why do you need that? this functionality purpose is to wait while all the stuff of an upcoming level is loaded so the async feature ain’t no use - also, with sync resource loading you may i.e. add a loading bar to show the level loading progress. Unless you got in mind something fancy I have actually no idea…

I don’t get it, is this a pre-loader or is it? If yes, why are other posted preloaders, from ynjh_jo for example, way longer and more complex? And what’s with the globals x,y thing?

no by far - it’s true ynjh_jo routines are complicated but that stuff do magic mine is just a little procedure to hide back a black curtain what’s going on while models and stuff is loading, to not have showing out to the user eyes. BTW can you show me the piece of code of that x,y stuff you’re referring to?

In x.py, line 48:

  global loadingimage, terrain

ah that’s nothing to care about - that is junk I hadn’t clean up but now it’s gone - I updated the package.

You forgot to include the loading.png model with the new one. So it will crash.
Also, is this required?:

from direct.showbase.Transitions import Transitions

?
And could you make it so that the program doesn’t start with the black png but rather the grey background colour?
PS. Your 200000 poly model didn’t slow down my PC, lol

well looks like I was too sufficient with this snippet - now is quite satisfying. You may now choose whatever background color you want.

yeah - looks like the panda is more power-demanding. BTW I put up a fps meter to check what model stress your card limit the most if you want.

Thats not what I ment (but still nice).
I just think you should add the line

curtain.setColorScale(1,1,1,0)

after you load the curtain image. Right now it isn’t transparent untill it reaches the color interval in the sequence.

Months have passed but i still fail to get the results I want, and I have tried on several PCs.

Basically, when I go from menu to game and backwards ,in my game, I want to fade to black, remove menu assets, and load game assets, then fade back.

I make a “curtain” with cardmaker.

Basically with any PC, if you use intervals to fade in/ out, then Panda doesnt wait for the interval to finish to continue executing the next line of code. This is normal. But then how should I go in doing this? If I have the fade in/out intervals and clean up function (in the middle) inside a sequence, even then Panda wont wait for the cleanup function to finish before fading back. By my knowledge this is how it should be, as ‘function intervals’ just call the function and finish. But in this case that function freezes panda for few seconds while performing the loading/unloading and when it finally finishes and draws a new frame, then the fade out interval which had to hide the “curtain” (black card) has already been run (though not rendered).

This is something any game has and it works perfectly. So what is the technique?
Should I actually have a task which tests if all the nodes have been removed and new ones loaded??

PS. I could start a new topic, but it is relevant as this snippet works the same way.

A task is a fine solution to this problem. Probably better than trying to use an interval, though you can do the fading in and out with an interval.

Your task will need to load the models one at a time, and then return (or at least yield) between models, to allow the frames to continue to be drawn so you can see the fade-to-black happen.

Or, you can spawn a different task to load each model, and then throw an event when the last model is loaded. You can also use the callback option to loader.loadModel() to do this asynchronously, which means you don’t have to spawn your own task; though having your own task does give you more control.

David

I dont think if i really understand how to use the task here and how it woud be different from a sequence. Example?

More control in what? Anyway, isnt asynchronous mean that even if the loading screen will finish, somemodels will still ‘pop-up’ in the world?

With asynchonous loading you can specifiy a callback-method and so you will be able to know when loading finished.

OKay, so drwr, what did you mean with using a task?

I mean you write a task something like this:

def loadTask(self, task):
    if not self.modelsToLoad:
        # All models loaded
        messenger.send('allModelsLoaded')
        return task.done
    filename = self.modelsToLoad[0]
    del self.modelsToLoad[0]
    model = loader.loadModel(filename)
    self.modelsLoaded.append(model)
    return task.cont

That’s just a skeleton. You’ll have to flesh it out yourself.

David

I dont think i understand it very well.

What about the asynchronous approach? What do you mean by ‘more control’?

From the manual i understood that ‘callback’ argument which is anything but None will make the model load in ‘background’, which i understand as not slowing down everything else but lasting longer.

What does it mean to cancel the request? why manually? I dont understand anything that comes after it:
panda3d.org/manual/index.php/Threading

Basically, when you call loader.loadModel with a non-None callback object, you’ll tell it to run the load operation in the background. If you change your mind and want to cancel the load operation (e.g. if the user pressed a close button while the model hasn’t loaded yet) you can call cancelRequest.

Oh, makes sense now.
For the rest… still not getting it

Try experimenting with these interfaces a bit until you can see what they are doing.

David