9

My question is pretty simple, according to the apple docs you have the ability to preload textures into RAM prior to presenting a scene like so:

SKTextureAtlas * atlas = [SKTextureAtlas atlasNamed:@"effect_circle_explode"];
SKTextureAtlas * atlas2 = [SKTextureAtlas atlasNamed:@"box_explodes"];
SKTextureAtlas * atlas3 = [SKTextureAtlas atlasNamed:@"fence_new"];
SKTextureAtlas * atlas4 = [SKTextureAtlas atlasNamed:@"swipe"];
SKTextureAtlas * atlas5 = [SKTextureAtlas atlasNamed:@"coin"];
SKTextureAtlas * atlas6 = [SKTextureAtlas atlasNamed:@"two_times"];
SKTextureAtlas * atlas7 = [SKTextureAtlas atlasNamed:@"three_times"];
SKTextureAtlas * atlas8 = [SKTextureAtlas atlasNamed:@"gus"];

[SKTextureAtlas preloadTextureAtlases:@[atlas, atlas2, atlas3, atlas4, atlas5, atlas6, atlas7, atlas8] withCompletionHandler:^{

    [moron_logo removeFromSuperview];
    moron_logo = NULL;

    stuff.hidden = NO;
    store.hidden = NO;

    scroll_view.userInteractionEnabled = YES;

    [self present_game_view];


}];

Now would there be any negative effect if later on through out gameplay you also call a preload to the same atlas like so:

-(void)load
{

SKTextureAtlas * atlas = [SKTextureAtlas atlasNamed:@"effect_circle_explode"];
SKTextureAtlas * atlas2 = [SKTextureAtlas atlasNamed:@"coin"];

[SKTextureAtlas preloadTextureAtlases:@[atlas, atlas2] withCompletionHandler:^{

explode_textures = [[NSMutableArray alloc] init];
int numImages = (int)atlas.textureNames.count;
for (int i=0; i <= numImages/2-1; i++)
{
    NSString *textureName = [NSString stringWithFormat:@"effect_circle_explode_%d.png", i];
    SKTexture *temp = [atlas textureNamed:textureName];
    [explode_textures addObject:temp];
}

explodeAnimation = [SKAction animateWithTextures:explode_textures timePerFrame:.05];

idle_textures = [[NSMutableArray alloc] init];
int numImages2 = (int)atlas.textureNames.count;
for (int i=0; i <= numImages2/2-1; i++)
{
    NSString *textureName = [NSString stringWithFormat:@"coin_%d.png", i];
    SKTexture *temp = [atlas2 textureNamed:textureName];
    [idle_textures addObject:temp];
}


idleAnimation = [SKAction animateWithTextures:idle_textures timePerFrame:.05];

[self animate:0];

}];


}

Now if I do not preload the texture again the game will actually crash once in awhile not all the time if I just directly inserted the textures into the SKAction. The crash is an exec_bad_access on the Sprite::update(double) call, so my assumption is that somehow the textures from the first preload were removed from RAM and thats why I preload every single time I create a new node now. It seems to have fixed that error. This leads to another problem though when it comes to performance and hence the reason why I am asking this.

The game runs fine on the 5S and the 5 but as soon you touch an iPod touch 5th gen it barely can go over 15 FPS. I ran instruments and this is what is eating up all the CPU time: enter image description here Could this be related to my constant call of the preloadatlas call? Does anyone know why this would be eating my processor time up so badly on older devices? Thanks so much and hopefully someone else might be having a similar problem and this will help them out once I make my way to bottom of it.

Thanks in advance.

Krzemienski
  • 1,185
  • 13
  • 28

1 Answers1

10

Preloading atlases every time you create a new sprite is generally a bad idea.

Your actual problem seems to be that you preload the atlases but you don't keep them around. Unless the atlas variables are global.

As soon as the method that does the preloading returns, the atlas objects are now longer referenced and will be removed from memory automatically. Sprite Kit internally implements a caching system so you won't notice it right away but eventually one or more of the atlases will be gone.

Keep a strong reference to each atlas in your scene so that the atlases remain in memory, and stop preloading at runtime. Whether this helps with fps I don't know.

CodeSmile
  • 64,284
  • 20
  • 132
  • 217
  • @ LearnCocos2D Ahh that makes sense, for some reason I thought it would automatically know to keep the textures in memory. Now when I load the textures I should not have any issues. Will try and follow back with you, thanks so much. – Krzemienski Jan 13 '14 at 20:23
  • it fixed all my errors with the exec bad access and now I am not leaking any memory, still having issues with the FPS, any idea what that process on the CPU is exactly? I think my next step is going to be to use pools of nodes that are loaded in the preload method and see if that helps. – Krzemienski Jan 14 '14 at 02:20
  • So I am having this problem too I think and I want to be clear: Right now to load SKTextures in an atlas I am just adding them all to an array of SKTextures and then I am using [SKTexture preload...], and I'm getting the exc_bad_acs stuff... so should I just switch to [SKTextureAtlas preload and also remove the SKTexture preloading? As long as I make the SKTextureAtlas a property so it's hanging around?? – Cocorico Feb 06 '14 at 18:33
  • @Cocorico that is what did it for me. Make sure you have a strong reference to those atlases and you won't crash anymore. – Krzemienski Apr 21 '14 at 19:05