Animated Splash Screen while Loading Assets

I want to animate the loading bar while loading assets.

The basic idea:

  1. create the loading bar
  2. load asset 1
  3. interpolate loading bar to 25%
  4. load asset 2
  5. interpolate loading bar to 50%
    -repeat

By default each of these steps has to be in a seperate game cycle I think (because otherwise the loading bar will not visually progress).
Also normally these steps have to be in the create method?. - so there will be no rendering at all

How do I solve this?

Is this the right way to go?

void HelloWorld::loadTextures1(){
    Director::getInstance()->getTextureCache()->addImageAsync("sprites1.png", CC_CALLBACK_1(HelloWorld::loadTextures2, this));
}

void HelloWorld::loadTextures2(Texture2D* texture1){
    this->texture1 = texture1;
    CCLOG("Texture 1 loaded!");
    Director::getInstance()->getTextureCache()->addImageAsync("sprites2.png", CC_CALLBACK_1(HelloWorld::loadTextures3, this));
}


void HelloWorld::loadTextures3(Texture2D* texture2){
    this->texture2 = texture2;
    CCLOG("Texture 2 loaded!");
    Director::getInstance()->getTextureCache()->addImageAsync("sprites3.png", CC_CALLBACK_1(HelloWorld::allTexturesLoaded, this));
}

void HelloWorld::allTexturesLoaded(Texture2D* texture3){
    this->texture3 = texture3;
    CCLOG("Texture 3 loaded!");

    auto cache = SpriteFrameCache::getInstance();

    cache->addSpriteFramesWithFile("sprites1.plist", texture1);
    cache->addSpriteFramesWithFile("sprites2.plist", texture2);
    cache->addSpriteFramesWithFile("sprites3.plist", texture3);

    auto scene = GameScene::createScene();
    Director::getInstance()->replaceScene(TransitionShrinkGrow::create(.5, scene));
}

We have a loading bar widget.

http://cocos2d-x.org/docs/cocos2d-x/en/ui_components/loading_bar.html

Thank!

How would I go about animating something while assets are being created?

Just like you normally would if it were any other scene.

Edit: It looks like we could write more about animations, specifically how to do a flip book style animation.

Your scene will freezes, there is no way to do so.
You could do just a trick, after each object created update some % value of progress, but no animation can run at that moment.

std::thread

Thanks for your meaningful answer. As @cc_x stated the screen will freeze, thats why I am asking this question.

I know std::thread exists but I also read that cocos2dx is not thread safe.

Could you be a bit more specific on how to get this result:
A smooth animation while the 1.scene 2.assets is being loaded in the back.

I do this all the time. I load assets in another thread while a scene is loading.

And how you deal with OpenGL context?
@captainflyaway confirm that you asking about say creating 1k Sprites in another thread while animation running? There is no way in cocos2d-x to do so, because it’s not thread safe.

thats what I am asking for yes.

I believe that there has to be a way!

I use an std::vector that contains std::threads that are detached. One of them operates on Sprite Cache to load and unload assets I need to use or are done using. I tend to use whole spritesheets when possible but in some of my games I didn’t. You can’t do what you want in the main Cocos thread without locking the rest of your game.

Alright the only thing now is that my knowledge of c++ isnt that deep.

Can you maybe show some bits of your code necessary to understand it, because it seems brilliant.

It’s not brilliant by any means.

 // 4. We need to run an action every XX seconds that periodically saves the games data
    vTimers.push_back(std::thread([]() {
        TimerForSavingGameData _timerForSavingGameData;
        _timerForSavingGameData.detach();
    }));

    // 5. We need to run an action every XX seconds that provides notifications to the user
    vTimers.push_back(std::thread([]() {
        TimerForNotifications _timerForNotifications;
        _timerForNotifications.detach();
    }));

I have IntroScene and GameScene. In my GameScene in init I have some code like this:
for 1 to 10000
Sprite sprite = createSprite("name.png");

And creating this will freeze any animation. So @slackmoehrle howto load GameScene in another thread and got no problems with OpenGL context? Thats is actual question from me and captainflyaway.

Have you tried any threads? Preload your Sprites into the cache?

OpenGL context is not thread-safe, you can’t call retain(), release(), or create/ addChild() new Node type(which uses GLContext).

So, my question is how you do that? I want to see that full code sample to learn. Ideally a sample project, because I always wanted to to load a whole scene in another thread while animation running. Same for the creating Sprites in background thread.

I posted some code how I start the threads. If I can make a sample I will

I don;t understand that code at all, it doesn’t help at all.

So any code sample to learn?

What does loading resources have anything to do with scene creation related code like init() or addChild()? You shouldn’t be calling them in any thread besides the main thread. There’s a difference between loading resources and actually using those resources to create a scene.

Have you tried calling addSpriteFramesWithFile() in a separate thread in order to cache the graphic resources? Once that thread finishes loading the resources, you can start using them in the main thread (calling init()/addChild() etc to create your scene).

Here’s the order of how it should be done:

1 - Load initial animation (splash screen or anything else you want) in the main thread as you would normally.

2 - Play the spash screen animation.

3 - Spawn a new thread to load the rest of the game resources that you require for that scene (for instance, with addSpriteFramesWithFile(…)). Do not attempt to use the resources yet in creating sprites/nodes in this thread, because it does not belong in the resource loading code.

4 - Once the loading thread has finished, you can now call the scene creation code in the main thread as normal.

If you want to know how to use std::thread, then there’s plenty of info online about it. Here’s a great tutorial about using threads: https://thispointer.com/c-11-multithreading-part-1-three-different-ways-to-create-threads/