Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I properly use CCSpriteFrameCache and CCSpriteBatchNode?

I do not understand what I do exactly when I add a CCSpriteFrameCache or CCSpriteBatchNode to my cocos2d application. Can somebody please explain the following points (it would be helpful if you could explain a few; please write the corresponding letter in front of your answer according to which question you are answering):

[all questions imply the achievement of best performance and lowest memory-use]

a) Is it crucial to create spritesheets for every single layer ? (For example: Menu - own spritesheet, GameLayer - own spritesheet...)

b) Can somebody explain why I have to add sprites to the batch node, and what a batch node generally is ?

b1)So, why can't I just do something like:

      [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"menusprites.plist"];
       CCSpriteBatchNode *spriteSheet = [CCSpriteBatchNode batchNodeWithFile:@"menusprites.png"];
      [self addChild:spriteSheet];

And then just add sprites to my layer by calling

CCSprite *mySprite = [CCSprite  spriteWithSpriteFrameName:@""]; 
[self addChild:mySprite];

without adding them to the batch node ? Because from what I understand it works like this :

I add my spritesheet with all the sprites on it to the screen. My app then goes into the plist and looks for the coordinates of the sprite I want to display and then places it on the screen. So why should I call

[spriteSheet addChild:mySprite];

?

c) How do I then get rid of the spritesheet for memory purposes when I do not need it anymore ?

like image 375
the_critic Avatar asked Jun 02 '12 10:06

the_critic


2 Answers

a) It is best to create as few spritesheets (CCSpriteBatchNodes) as is possible. Sprite batching reduces draw calls. Draw calls are expensive. Still, every batch node creates one draw call. So you want to use as few as possible because the ultimate goal is to keep draw calls as low as possible.

b) The CCSpriteBatchNode renders all of its children in one go, in one batched draw call. That's why you need to add sprites to the batch node so it can render them all together. Only sprites using the same texture as the batch node can be added to a batch node, because you can only batch draw from the same texture. Whenever the engine has to switch from one texture to another, it issues a new draw call.

b1) You can't do this because the batch node renders its children. If you add the sprites to any other node, each sprite draws itself, which means one additional draw call per sprite. And the sprite batch node has nothing to do.

c) The CCSpriteBatchNode is just a regular node. You can remove it from the scene like any other node. The texture and sprite frames are cached in the CCTextureCache and CCSpriteFrameCache singleton classes. If you want to remove the textures and sprite frames from memory, you have to do it through the cache classes.

like image 136
LearnCocos2D Avatar answered Sep 25 '22 11:09

LearnCocos2D


  • a) no

  • b) batchNode increases your performance when you need to draw many sprites at the same time, in case of small number of sprites (10, 20. etc.) i dont think that you will notice any performance increasing. batchNode is much faster because opengl should draw only it to see all content. in other case opengl will draw all your objects separately. that is - if you will have 500, 600, 700 sprites, the draw() and visit() methods will be called for each one. if they all will be placed to the batchNode, it will be only one draw() call and one visit() call

  • c) you can purge cached data manually to force memory freeing by calling these methods:


[CCTextureCache purgeSharedTextureCache];
[CCSpriteFrameCache purgeSharedSpriteFrameCache];
[CCAnimationCache purgeSharedAnimationCache];
like image 35
Morion Avatar answered Sep 24 '22 11:09

Morion