SKTextureAtlas Loading and Memory Management

2019-01-02 22:06发布

问题:

I developing a Game on SpriteKit and have Multiple Scenes each Scene has From 3 TextureAtlas in Minimum and Maximum Size of an Image in Each TextureAtlas is 60K my game Crashes From Memory issue

what I do in Each Scene is Defining action in the Header File for Example:

initialise them in -(id)initWithSize:(CGSize)size  Function 


@interface FirstLevel : SKScene
{

    SKAction  *RedBirdAnimation;
}

and in Implementation File:

-(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;}

is there Something Like Best Practice to Load Texture Atlas in my game to prevent it from Crashes due to Memory.

i make all SkAction with Nil at the end of Each Skscene and remove All action from All SkSpriteNode

is there any solution

回答1:

Each TextureAtlas is 60K

As a file maybe. But that's not memory usage. To calculate memory usage of an image file, take the file's dimensions and multiply them with color bit depth (usually 32 bits = 4 bytes).

For example a 4096x4096 texture uses 16 MB of texture memory (but it may be much less than 1 MB as a PNG file).

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

Long story short: use Instruments to verify your app's actual memory consumption.



回答2:

The problem of a SpriteKit based game running out of memory is almost always caused by the developer using so many textures that all active RAM is consumed by the textures. I am going to assume that you use the standard SKAction based animation approach and that you don't have any weird memory leaks caused by strong refs or anything. The correct way to determine the amount of RAM consumed by a texture is (WIDTH * HEIGHT * 4 / 1000), this indicates the number of kB of memory required to store the texture. For a 4096x4096 texture, that is 67108 kB or about 68 Megs. It does not matter if this is stored in an atlas or as a single texture. The key to actually reducing the total amount of memory used with a SpriteKit game is the reduce the amount of memory consumed by each texture. Please have a look at the source code for this SpriteKitFireAnimation example which shows how reducing the memory usage of each frame can lead to a reduction from 286 Megs down to 130 Megs for a very complex alpha channel animation that executes at 60FPS on a 64bit iOS system. This approach is for A7 and newer 64 bit systems only. If you are looking for lower quality but totally free approaches, see this comparison of very lossy texture compression approaches with SpriteKit. As a last ditch effort, one can reduce the width and height of each texture by 1/2 and then scale the textures back up when rendering into a node, it does not look as good, but uses 4x less memory at runtime.



回答3:

The textureAtlas is too large for the system to load. You need to break the images up to two or more separate textureAtlases allowing the system to manage memory. Place the images that are needed for the initial setup in its own atlas so you can preload those at the start of your game. Reference the images as if they are individual files and the system will load and unload atlases as needed. The system can do a better job managing memory then you can so let it.



标签: