SKTextureAtlas加载和内存管理

时间:2014-03-18 05:14:25

标签: sprite-kit

我在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进行所有SkAction 并从所有SkSpriteNode中删除所有操作

有没有解决方案

3 个答案:

答案 0 :(得分:2)

  

每个TextureAtlas都是60K

作为文件可能。但这不是内存使用情况。要计算图像文件的内存使用量,请获取文件的尺寸并将其与颜色位深度相乘(通常为32位= 4个字节)。

例如,4096x4096纹理使用16 MB纹理内存(但作为PNG文件可能远小于1 MB)。

4096 x 4096 x (32/8) = 16 Megabytes

长话短说:使用Instruments来验证应用的实际内存消耗。

答案 1 :(得分:2)

基于SpriteKit的游戏耗尽内存的问题几乎总是由开发人员使用如此多的纹理导致纹理消耗掉所有活动的RAM。我将假设您使用标准的基于SKAction的动画方法,并且您不会因强大的参考或任何事情而导致任何奇怪的内存泄漏。确定纹理消耗的RAM量的正确方法是(WIDTH * HEIGHT * 4/1000),这表示存储纹理所需的内存的kB数。对于4096x4096纹理,即67108 kB或约68 Megs。如果它存储在地图册中或作为单个纹理并不重要。实际减少SpriteKit游戏使用的总内存量的关键是减少每个纹理消耗的内存量。请看一下这个SpriteKitFireAnimation example的源代码,它显示了如何减少每帧的内存使用量,从而导致从286 Megs减少到130 Megs,这是一个非常复杂的alpha通道动画,在60FPS上执行64位iOS系统。此方法仅适用于A7和更新的64位系统。如果您正在寻找质量较低但完全免费的方法,请参阅使用SpriteKit进行非常有损纹理压缩方法的this comparison。作为最后的努力,可以将每个纹理的宽度和高度减少1/2,然后在渲染到节点时将纹理缩放回来,它看起来不太好,但在运行时使用的内存减少了4倍。

答案 2 :(得分:0)

textureAtlas太大,无法加载系统。您需要将图像分解为两个或更多单独的textureAtlases,以允许系统管理内存。将初始设置所需的图像放在自己的图集中,这样您就可以在游戏开始时预加载这些图像。引用图像就好像它们是单个文件一样,系统将根据需要加载和卸载地图集。系统可以更好地管理内存,然后你可以这样做。