SpriteKit内存管理预加载缓存和fps问题 [英] SpriteKit memory management preload cached and fps issue

查看:158
本文介绍了SpriteKit内存管理预加载缓存和fps问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题很简单,根据苹果文档,您可以在呈现这样的场景之前将纹理预加载到RAM中:

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];

}];


}

现在,如果我不再次预加载纹理,那么如果我直接将纹理插入SKAction中,游戏实际上就会偶尔崩溃一次.崩溃是Sprite :: update(double)调用上的exec_bad_access,所以我的假设是,从内存中删除了第一个预加载的纹理,这就是为什么现在每次我创建一个新节点时都要预加载.看来已经解决了该错误.但是,这会导致另一个问题,那就是性能,因此也是我问这个问题的原因.

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.

该游戏在5S和5S上运行良好,但是一旦您触摸iPod touch的第5代,它几乎不能超过15 FPS.我运行了仪器,这就是消耗所有CPU时间的原因: 这可能与我不断调用preloadatlas调用有关吗?有谁知道为什么这会在较旧的设备上严重消耗我的处理器时间?非常感谢,希望其他人也可能遇到类似的问题,一旦我走到最深处,这将对他们有所帮助.

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: 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.

谢谢.

推荐答案

每次创建新的精灵时都预加载地图集通常是个坏主意.

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

您的实际问题似乎是您预先加载了地图集,但没有将它们保留在身边.除非Atlas变量是全局变量.

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

一旦执行预加载的方法返回,现在将不再引用Atlas对象,并且将自动将其从内存中删除. Sprite Kit在内部实现了一个缓存系统,因此您不会立刻注意到它,但是最终一个或多个地图集将消失.

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.

强烈引用场景中的每个地图集,以便将地图集保留在内存中,并在运行时停止预加载.我不知道这是否对fps有帮助.

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.

这篇关于SpriteKit内存管理预加载缓存和fps问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆