ios - SpriteKit 内存管理预加载缓存和 fps 问题

标签 ios sprite-kit

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

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


}];

现在,如果稍后在整个游戏过程中您也像这样对同一图集调用预加载,会有任何负面影响吗:

-(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,所以我的假设是,不知何故,第一次预加载的纹理已从 RAM 中删除,这就是为什么我现在每次创建新节点时都会预加载。它似乎已经修复了该错误。这会导致另一个问题,但在性能方面,这也是我提出这个问题的原因。

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

提前致谢。

最佳答案

每次创建新 Sprite 时都预加载图集通常不是一个好主意。

您的实际问题似乎是您预加载了 map 集,但没有保留它们。除非 atlas 变量是全局的。

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

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

关于ios - SpriteKit 内存管理预加载缓存和 fps 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21098880/

相关文章:

iOS - 使用 AVAudioSessionCategoryAmbient 和 duckOthers 和 mixWithOthers 开启静音

performance - childNodeWithName在SpriteKit中的表现如何?

ios - Swift 创建一个类来绘制瓦片 map 并将 map 添加到游戏场景

ios - Sprite Kit SKActions 未触发

swift - 使用 Image Name 属性的枚举值初始化 spritekit 对象

ios - Safari Web Inspector 上的 iPad 调试不显示所有 css 样式

带有返回字符串的iOS swift post方法

ios - 通过触摸按钮显示广告横幅

ios - WKProcessPool 可以使用 NSUserDefaults 或其他东西永久存储吗?

ios - 是否可以在 NSDateFormatter 的格式字符串中添加自定义文本?