4

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

khaled
  • 865
  • 9
  • 24

3 Answers3

3

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.

CodeSmile
  • 64,284
  • 20
  • 132
  • 217
  • i verify my app it consumes at the Game opening about 100 MB after playing the game it reaches 250 MB and crashes after a while Please help me how can i load SKTextureAtlas in Safe way to prevent Crashes Due to memory – khaled Mar 18 '14 at 15:18
  • @user3429971 have you created a folder named: texture.atlas ? (texture is only an example, the important thing is .atlas) in this way Xcode reduce memory usage of every sprite – Ilario Mar 18 '14 at 15:21
  • yup every Texture i made is created in Folder with RedBid.atlas CowEating.Atlas and so on – khaled Mar 18 '14 at 15:23
  • @LearnCocos2D can you help me how to Load TextureAtlas in my game in a safe way – khaled Mar 18 '14 at 15:54
  • @LLario can you help me how to Load TextureAtlas in my game in a safe way – khaled Mar 18 '14 at 15:54
  • 1
    This calculation is incorrect, a 4 byte 4096x4096 texture consumes about 68 Megs of memory, not 16. – MoDJ Jul 30 '16 at 22:13
3

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.

MoDJ
  • 4,309
  • 2
  • 30
  • 65
  • 1 MB = 1024 kB; 1 kB = 1024 B; 1 B = 8 Bit. So you have to divide by 1024, not 1000, what gives you exactly 64 MB for your example above. – salocinx Aug 22 '16 at 08:53
  • The kB form indicates use of 1000 as the multiple, one also sees this format when looking at files sizes in MacOSX Explorer: https://en.wikipedia.org/wiki/Kilobyte – MoDJ Aug 22 '16 at 19:02
  • Thanks - didn't know that. According to this, I am talking about kibibytes and your answer is totally correct :-) Therefore 67.108864 MB equals 64 MiB. – salocinx Aug 22 '16 at 22:13
0

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.

ejkujan
  • 271
  • 1
  • 3