how to embeed multiple sprite sheet CCSpriteFrameCache animation in cocos2d - iphone

all
I want to embeed multiple spriteFrame cache using the following code.
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:#"abc.plist"];
// Create a sprite sheet with the Happy Bear images
CCSpriteBatchNode *spriteSheet = [CCSpriteBatchNode batchNodeWithFile:#"abc.png"];
[self addChild:spriteSheet];
the problem is that after 1st animation is cover I want to do another animation through another ccsprite fram cache, and add another sprite sheet, but when I add another sprite sheet it will give me sigerbat error.
how can I do multiple animation after one animation cover then the second animation will start, remember that there are 4 CCSpriteFrameCache file (ie,. 4 plist file)

All CCSprite added to a CCSpriteBatchNode must use the same texture. So what you're trying to accomplish is not possible because you're trying to add images from 4 different textures. If you check the Console (in Debug builds) you'll find a message stating something to that effect.
The solution: use one CCSpriteBatchNode for each texture (loaded via CCSpriteFrameCache plist). You'll have to write more code but that's the only way you can do it, apart from not using CCSpriteBatchNode at all.
You might want to do a performance test to check if you really, really need the CCSpriteBatchNode. For example, if you only display ONE sprite from the same texture on screen at any one time, you don't need a CCSpriteBatchNode. It's only improving performance if you have multiple (and many) sprites on screen and all are using the same texture.

Related

Can somebody please explain to me how CCSpriteBatchNodes and spritesheets work ?

I have built a little ipad game and spritesheets and batchnodes are all over the place. However I have no idea how they really work, when to add a sprite sheet, when to add sprites to the spritebatchnode etc. etc. .
This is what I do in the initial screen (main menu):
CCSpriteBatchNode *spriteSheet = [CCSpriteBatchNode batchNodeWithFile:#"sprites.png"];
screenSize = [CCDirector sharedDirector].winSize;
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:#"sprites.plist"];
[self addChild:spriteSheet];
In other classes - I always need to use the same batch node -> "sprites.png" - I call
CCSprite *someSprite = [CCSprite spriteWithSpriteFrameName:someSpriteFrameName.png];
and add it to self.
[self addChild:someSprite]; // I do not understand why I would add my sprite to the batch node instead of self
So the situation is the following:
I have 1 file called "sprites.png" where all my sprites are on.
Do I make a new batch node whenever I change the scene ? The spriteframecache should stay the same right ?
What would I have to do with the spriteframecache if i had two sprite sheet files ?
When do I add children to the batch node, and why ?
I really don't seem to grasp the concept entirely. I know approximately why I use it. But I would really appreciate it if somebody could explain everything to me again in layman terms, so I am 100% sure about what I do. Please try to explain it as basic as it gets.
Thank you very much -
Martin
CCSpriteBatchNode is CCNode successor so you have to create separate instance for every scene. You can use several batch nodes on the scene if you have more than one texture file.
CCSpriteFrameCache is a singleton so it stays the same during application lifetime.
Add both to CCSpriteFrameCache. CCSpriteFrameCache singleton has loadedFilenames_ field (instance of NSMutableSet) which caches all sprite frames for all scenes.
You have to use batch node when you expect large amount of sprites with similar textures. For example you want to generate 100 coins every 2 seconds. If you use usual CCNode and create sprites on it, your application will allocate these 100 CCSprite objects every 2 seconds. CCSpriteBatchNode is targeted for performance and better memory usage. It works like UITableView with reusable cells.
When you scroll table view with reusable cells, it does not create new cells. When new cell has to be presented on screen table view simply finds cell with same reuse identifier offscreen and replaces it's content with new content. CCSpriteBatchNode works in the same way. When you try to add new sprite to it, the node tries to find unused sprite offscreen and replaces it's content.
Remember that sprites which you add to CCSpriteBatchNode have to use the textures from texture file which was used to create this batch node.
Following example is based on code from your question:
CCSpriteBatchNode *batchNode = [CCSpriteBatchNode batchNodeWithFile:#"sprites.png"];
screenSize = [CCDirector sharedDirector].winSize;
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:#"sprites.plist"];
[self addChild:batchNode];
CCSprite *someSprite = [CCSprite spriteWithSpriteFrameName:#"someSpriteFrom_sprites.png_.png];
[batchNode addChild:someSprite]; // add sprite to batch node to get all advantages of it
Here is a good article about CCSpriteBatchNode performance: http://www.learn-cocos2d.com/2011/09/cocos2d-spritebatch-performance-test/
Modern renderer
We rewrote the renderer from scratch. The Render graph was decoupled from the Scene graph.
That means that auto-batching is supported, finally :-) And the new renderer is so fast, that we no longer encourage the use of SpriteBatchNode.
Sprites have auto-culling too.
And the good thing is that we didn't sacrifice any of the old features: custom OpenGL commands are still supported!
Refer this link
Hopes it helps

Cocos2D CCSprite question?

I am new to Cocos2D and I have question about texuture loading.
When I use code like follows to create two sprites ,does it load the texture "alien.png" two times into memory? Or does it save only one copy and create only one OpenGL texture ?
sp1=[CCSprite spriteWithFile:#"alien.png"];
sp2[CCSprite spriteWithFile:#"alien.png"];
If you have a look at the way Cocos2D is implemented (don't forget that it's open source and you can drill down into every method), you will see that [CCSprite spriteWithFile:#"alien.png"] uses [[CCTextureCache sharedTextureCache] addImage: filename];
to load/cache the texture. The addImage method on the CCTextureCache singleton checks to see if the texture is already cached, and only if it's not will start to load it from the specified path. Now, with the texture cached, it doesn't matter how many times you draw it on the screen, you will not load the texture in memory more than once.

Cocos2D should I use one image per sprite

If I have several identical sprites on the screen at once, do I need to load one image for each of the sprite, or can I simply re-use the images somehow?
i.e,
Do I need to do this?
CCSprite *mySprite1 = [CCSprite spriteWithFile:#"mySprite.png"];
CCSprite *mySprite2 = [CCSprite spriteWithFile:#"mySprite.png"];
Or is there a better way to deal with identical sprites?
Your solution is fine. The first call to spriteWithFile: will load the texture and add it to the shared CCTextureCache. The second one will check to see if the texture already exists, and this time will reuse it from the first one.
You should propably use
- (id)initWithCGImage:(CGImageRef)image
key:(NSString *)key
Reference
This method uses either image or a cached texture named by key. If no cached texture with this key is available, it'll create a texture and cache it for you.

How do I add background in cocos2d?

I'm a total noob. Starting my first app. I'm using cocos2d and there's isn't a .xib file so how do I add a background image behind the sprites I have in my scene?
In Cocos2d you don't use xibs you have to place all the objects by code. Check the samples that come with Cocos2d to get a sense of how it works.
If you already know how to add sprites, adding a background is done the same way, it would be just another sprite just add it with a lower z-order.
[self addChild:myBackground z:0];
"self" would be the actual CCLayer
"myBackground" the sprite you created with the bakcground iamge.
and "z" would have to be lower than the z used for the other elements.

The best way to remove a sprite from a batch in Cocos2D

I'm using Cocos2D in my project and I'm quite new to this library. And I don't understand one thing.
I have many sprites on the scene which are added and removed constantly. So at certain moment a sprite becomes useless and I have to remove it form a batch node.
In the comments of the removeChild method of CCSpriteBatchNode class is said:
#warning Removing a child from a CCSpriteBatchNode is very slow
Does anybody know what the best method of removing a sprite?
Thanks!
Instead of adding and removing sprites why not re use them, then you won't have any slow down caused by adding or removing sprites.
Setting a sprite not to be visible saves the render cost and when you need to add it again just move it to position and the texture frame if you need to and then turn the visibility back on.
I subclass a ccSprite and then add them to an array to keep track of active and inactive sprites.
Dave.