SKTextureAtlas加载和内存pipe理
我在SpriteKit上开发一个游戏,并有多个场景每个场景都有3个TextureAtlas在每个TextureAtlas的图像的最小和最大尺寸是60K我的游戏崩溃从内存问题
我在每个场景中所做的是在头文件中定义动作,例如:
initialise them in -(id)initWithSize:(CGSize)size Function @interface FirstLevel : SKScene { SKAction *RedBirdAnimation; }
并在实施文件:
-(id)initWithSize:(CGSize)size{ if(self=[super initWithSize:size]) {[self setupRedBirdActions];} return self; } -(void)setupRedBirdActions{ SKTextureAtlas *RedBirdAtlas = [SKTextureAtlas atlasNamed:@"RedBird"]; SKTexture *RedBird1 = [RedBirdAtlas textureNamed:@"Redbird_01_iphone.png"]; SKTexture *RedBird2 = [RedBirdAtlas textureNamed:@"Redbird_02_iphone.png"]; SKTexture *RedBird3 = [RedBirdAtlas textureNamed:@"Redbird_03_iphone.png"]; NSArray *atlasTexture = @[RedBird1, RedBird2, RedBird3]; SKAction* atlasAnimation = [SKAction animateWithTextures:atlasTexture timePerFrame:0.2]; RedBirdAnimation = atlasAnimation;}
有没有像最佳实践加载我的游戏中的纹理图集,以防止由于内存崩溃。
我在每个Skscene的最后使用Nil创build所有SkAction,并从所有SkSpriteNode移除所有的动作
有没有解决办法
每个TextureAtlas是60K
作为一个文件也许。 但这不是内存使用。 要计算图像文件的内存使用量,请取该文件的尺寸并将其与颜色位深度(通常为32位= 4个字节)相乘。
例如,4096×4096纹理使用16 MB的纹理内存(但可能比1 MB小得多,如PNG文件)。
4096 x 4096 x (32/8) = 16 Megabytes
长话短说:使用仪器来validation您的应用程序的实际内存消耗。
基于SpriteKit的游戏内存不足的问题几乎总是由开发人员使用如此多的纹理造成的,所有活动的RAM都被纹理消耗掉了。 我将假设你使用标准的基于SKAction的animation方法,并且你没有任何怪异的强引用引起的内存泄漏。 确定纹理消耗RAM数量的正确方法是(WIDTH * HEIGHT * 4/1000),这表示存储纹理所需的内存数量。 对于4096×4096纹理,即67108 kB或大约68 Megs。 这是否存储在一个图册或作为一个单一的纹理并不重要。 实际减lessSpriteKit游戏使用的内存总量的关键是减less每个纹理消耗的内存量。 请看这个SpriteKitFireAnimation示例的源代码,该示例演示了如何减less每帧的内存使用量,从而可以使得在64位iOS系统上以60FPS执行的非常复杂的alpha通道animation,从286 Megs减less到130 Megs 。 这种方法仅适用于A7和更新的64位系统。 如果您正在寻找质量较低但完全免费的方法,请参阅比较非常有损耗的纹理压缩方法与SpriteKit。 作为最后的努力,可以将每个纹理的宽度和高度减less1/2,然后在渲染到节点时将纹理备份,但看起来并不好,但在运行时使用的内存减less了4倍。
textureAtlas太大,系统无法加载。 您需要将图像分成两个或多个单独的textureAtlases,以便系统pipe理内存。 将初始设置所需的图像放置在自己的地图集中,以便在游戏开始时预加载这些图像。 参考图像就好像它们是单个文件一样,系统将根据需要加载和卸载地图集。 系统可以做更好的pipe理内存,那么你可以放过它。