I have 3 question.
How to keep fps rate constant(almost) in cocos2d.When lots of CCSprite created and removed within a small interval like (5-8) per second is it possible to keep frame rate lmost constant??
Is [self removeChild:sprite cleanup:YES] is enough or i should also use
CCTexture2D *texture = [sprite texture];
[[CCTextureCache sharedTextureCache] removeTexture: texture];
The following Part of code is responsible for my frame drop.How to accomplish same task in better way-
id fadeout = [CCFadeOut actionWithDuration:1.4f];
id call = [CCCallFunc
actionWithTarget:self
selector:#selector(RemoveSmashedSprite:)];
CCSequence* sequence= [CCSequence actions:fadeout, call, nil];
[smash runAction:sequence];
and
-(void)RemoveSmashedSprite:(id)sender
{
CCSprite *sp = (CCSprite *)sender;
[self removeChild:sp cleanup:YES];
}
This is called 5-8 times per second.So the frame rate goes down.Can any one help me.
I am guessing that the "smashed sprite" in question is probably one of a number of sprites visible on the screen, more than likely sharing the same texture (part of a sprite sheet perhaps, or all the same image, etc?).
If this is the case, I would recommend allocating the number of sprites your games requires to have on screen and rather than "destroy" (remove them, re-create them) you should "re-use them".
Store a reference to all the CCSprite's in an NSMutableArray, populate this array with the number of sprites you think is appropriate (how many sprites are removed per second? how many sprites are added per second? how many sprites are on the screen to start? - use the answers to these questions to determine the most appropriate size of your array).
Then, rather than removing the sprite as a child, simply [sprite setVisible: NO] to hide it, then ... when you need to display a new one on screen, use the next "available" (hidden) sprite in the array (keep track of the last "used" sprite with an index, and simply increment it by 1 to find the next "available". Once the index exceeds the bounds, reset it to 0 - at this point, that sprite should have been "smashed"). Once you have the next "available" sprite, change it's properties (position, scale, texture?, visibility) and apply any actions that are appropriate (don't forget to "stop all actions" on it when "smashing it" - this is what "cleanup: YES" does).
If your game does not allow you to go around in a "circle" like this, because the user decides what may or may not be visible by interacting with the sprites in a varied order then you can store a reference to the "smashed sprites" in a separate array (while keeping them in the original array as well - then you can just pick anyObject from the "unused" array, remove it from that array and then alter it as mentioned above).
This should reduce your frame rate drops dramatically, as you won't be creating and destroying sprites all the time.
Another thing that may be occurring is that you are using different images, and each image is stored separately (image1.png, image2.png, image3.png) and the creation/destruction of these is causing the textures to be removed and re-added ... to resolve this, create a sprite sheet and add the sprite sheet to the Texture Cache, then create your images with 'spriteFromSpriteCacheName:#"image1.png"'
Related
I exchange sprite content with this code:
mySprite->setTexture(Director::getInstance()->getTextureCache()->addImage("newImage.png"));
The problem is that newImage.png is much smaller than the old content image of the sprite. But cocos2d-x scales newImage.png to have the same size as oldImage.png. How I can prevent this scaling. I need newImage.png to be its natural size, but to appear in the coordinates of oldImage.png (I want to retain the same sprite object, as far as I have a pointer on it and also the same position and same anchor point. That's why I use setTexture just to change the image.)
Well, this may not be the cleanest way, but it seems the most straigthforward to me :
Sprite *newSprite = Sprite::create("newImage.png");
newSprite->setAnchorPoint(mySprite->getAnchorPoint());
newSprite->setPosition(mySprite->getPosition());
mySprite->removeFormParentAndCleanup(true);
mySprite = newSprite; // <-- magic happens here
So basically you create a new sprite, place it based in old sprites position/anchor and then after removing the old one, you assigne the mySprite variable to point to the same place as newSprite.
mySprite->setTexture("newImage.png");
This sets the content Rect too.
I'm using cocos2d 1.0.1.
I've created a CCSpriteBatchNode, it includes a CCSprite (let's name it parentLayer) which includes some X number of childs(CCSprites).
The problem is - when I rotate parentLayer all sprites (childs) correctly displayed, however bounding boxes are at the same place (where they've been before rotation), so world coordinates of those sprites won't be changed.
Off course, all of the above works great without CCSpriteBatchNode. But, I would like to use batch node due to amount of sprites involved.
The question is, is there any way to update bounding boxes & child positions correspondingly?
How many sprites are we talking about? I would just go with a fast enumeration call to rotate each one individually. I nave never noticed a performance hit when doing this, have you?
CCArray *listOfChildren = [parentLayer children];
for (CCSprite *sprite in listOfChildren) {
[sprite setRotation:someValue];
}
In my program, I have created an NSMutable Array which contains a series of sprites that move across the screen (to the left)
However, while implemented in my code, they do not seem to appear on the screen simulator when tested.
Any ideas?
-(void) addBlocks
{
NSMutableArray *_blocks; blocktest=[CCSprite spriteWithFile:#"blocksquare.png"];
blocktest.tag = 1;
// add the block to the array of blocks
[_blocks addObject:blocktest];
blocktest.position=ccp(500,100);
id repeat2 =[CCRepeatForever actionWithAction:[CCSequence actions:
[CCMoveTo actionWithDuration:7 position:ccp(-180,100)],nil]];
[blocktest runAction:repeat2];
}
That's because you haven't added blocktest to your scene ( [self addChild:blocktest] ).
Adding it to _blocks, will work as a reference to fetch your sprites later, but will not add the sprites on any layer or scene, so you won't see them anywhere
I'm developing an iPhone game using cocos2d.
As the player moves around and scores points by doing things, I cause little CCLabelBMFont instances to appear and then fade out (CCFadeOut). These CCLabelBMFont instances are sprites that are added to the layer.
Am I "leaking" memory or anything by not removing the faded-out sprites from the layer after they have completed the CCFadeOut action, or are they then gone, or don't need to be considered "valid"?
After CCFadeOut has finished, the layer will keep hold of the now transparent label. You'll have to remove it from the layer manually afterwards, unless you are planning to fade it back in later, in which case you could keep it around.
It is inefficient memory usage, not a memory leak.
You aren't causing a memory leak because when the layer is deallocated it will deallocate its child nodes, including the labels, assuming you are not instantiating the labels in a way that doesn't trigger a retain.
Update: how to remove the labels after they fade out
Replace your CCFadeOut with a CCSequence that looks like this:
[yourLabel runAction:[CCSequence actions:[CCFadeOut actionWithDuration:DURATION], [CCCallFuncN actionWithTarget:self selector:#selector(removeLabel:)], nil]];
Now implement your new handler removeLabel: and make it remove the label. It takes the label as its argument.
CCFadeOut does NOT remove nor releases your sprites and you should do it once their purpose is over.
Infact no action does release/remove other objects. They are only manipulating them.
I have created a game of two levels.Now when we are in level one i create sprite sheet for animation and a lot of sprites.On reaching a certain score i move to level 2 now here here is another sprite sheet and a lot of variables.
When i am moving from level 1 to level 2 using.
[[CCDirector sharedDirector] pushScene:[Level2 node]];
when i lose on level 2 i move back to level 1 using
[[CCDirector sharedDirector] pushScene:[Level1 node]];
What happens to the sprite sheet and other sprites i created before on level 1 ? If i retry level 1 will the sprite sheet and sprites i created before be removed automatically ?or they will exists in this new scene?
kindly clear me these issue i am having a lot of trouble because of no understanding of this..
thank you in advance.. :(
In cocos2d almost everything is marked as autorelease. So when you create a new scene it is not released because it becomes the main scene. Once it is no longer the main scene, if you do not specifically retain it then it will be released.
In the case you state above I believe that both scenes are retained as you are using the director like a stack, pushing the scenes on each other. If you never need to go back to level 1 you can use CCDirector's replaceScene: method instead to release level 1.
Having a custom pause scene or bonus round might be a good example of when to use the pushScene: call.