1

I am loading a selection scene for a player, however, when I tap the button which moves to that scene, it takes 4-5 seconds until it reveals the new scene.

In main menu I use:

SKTransition *transition = [SKTransition fadeWithDuration:0.1];

SKScene * scene = [[SelectionScene alloc] initWithSize:self.size];

[self.view presentScene:scene transition:transition];

And inside the SelectionScene I use:

- (id) initWithSize:(CGSize)size
{
    if (self = [super initWithSize:size]) {                

        [self setupScene];
        [self setupSelection];

    }

    return self;
}

As explained, it takes 4-5 seconds between the tap on the button until it moves to the next scene. Is there a way to setup the scene later so it first shows the next scene (I will display a loading screen) and load in background?

I have tried using :

dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){

    //Background Thread
    dispatch_async(dispatch_get_main_queue(), ^(void){


    });
});

But it won't work.

Yuvals
  • 3,094
  • 5
  • 32
  • 60

2 Answers2

2

To avoid the delay, the best practice is to load all the screen assets first by using loadSceneAssetsWithCompletionHandler function before the game begins or after level selection.

Reference: Adventure Loads Assets Asynchronously

Jesse Onolemen
  • 1,277
  • 1
  • 15
  • 32
user1872384
  • 6,886
  • 11
  • 61
  • 103
  • Since I do not have shared assets, I wish to load *after* level selection (present loader screen and load in background). How can I do so? – Yuvals Jun 02 '14 at 07:45
  • Have you tried adding a SKSpriteNode *loadingScreenNode and [self addChild:self.loadingScreenNode] and a loading icon before loading the scene? – user1872384 Jun 02 '14 at 07:54
  • Yes. However, it won't reveal the scene until all assets are loaded and it takes a very long time (the scene and loading screenNode won't show up until all assets are fully loaded) – Yuvals Jun 02 '14 at 08:50
  • Just to clarify, is this the flow you are implementing? user tap button--->Add SKSpriteNode *loadingScreenNode to current screen (which displays the loading screen)---> load the asset --> on completion move to the next scene. – user1872384 Jun 02 '14 at 09:08
  • NO. It is : Move to next screen, then use the loader. – Yuvals Jun 02 '14 at 09:26
  • I recommend presenting the loading icon in the current scene. That way, you can asynchronously load the texture data after which you can seamlessly transition to the new scene. See this [related question](http://stackoverflow.com/questions/22130857/not-working-transitions-in-spritekit/24016057#24016057) (including my answer). – CloakedEddy Jun 03 '14 at 14:31
  • the link attached is a Broken Link – Jesse Onolemen Aug 22 '16 at 21:19
0

For the simplest option, I would recommend loading an activity indicator on the current SKScene (send startAnimating message to the property), load the scene in the dispatch, then within that dispatch at the very end, send the activity indicator a message to stopAnimating.

Include this property in the interface of the current SKScene object:

@property(strong, nonatomic) UIActivityIndicatorView *activityIndicator;

Then wherever you are loading the scene (i.e. touchesEnded event), use something like this:

[self.activityIndicator startAnimating];

dispatch_async(dispatch_get_main_queue(), ^{

    PVZLevelScene *levelScene =
    [[PVZLevelScene alloc] initWithSize:self.size level:theSelectedLevel];

    [self.view presentScene:levelScene
             transition:[SKTransition flipHorizontalWithDuration:0.5]];

    [self.activityIndicator stopAnimating];

});
therealbriansc
  • 75
  • 2
  • 10