我的问题很简单,根据 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 时间的原因: 这可能与我不断调用 preloadatlas 调用有关吗?有谁知道为什么这会在旧设备上严重占用我的处理器时间?非常感谢,希望其他人可能遇到类似的问题,一旦我深入了解它,这将帮助他们解决问题。
提前致谢。
最佳答案
每次创建新 Sprite 时都预加载图集通常不是一个好主意。
您的实际问题似乎是您预加载了 map 集,但没有保留它们。除非 atlas 变量是全局的。
一旦执行预加载的方法返回,现在不再引用图集对象并将自动从内存中删除。 Sprite Kit 内部实现了一个缓存系统,因此您不会立即注意到它,但最终一个或多个 map 集将会消失。
保持对场景中每个图集的强引用,以便图集保留在内存中,并在运行时停止预加载。我不知道这是否有助于 fps。
关于ios - SpriteKit 内存管理预加载缓存和 fps 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21098880/