Problem with CCAnimation


#1

hello friends…
I am having some problem with removing animation from the scene:

Following is my code:

@

CCSprite m_pSprite3 ; //Global Variable
void GamePlay::carrotBurstAnimation{
CCSpriteBatchNode
spritebatch=CCSpriteBatchNode::create(“CarrotAnimSheet_CarrotAnimSheet.png”);
CCSpriteFrameCache spriteCache = CCSpriteFrameCache::sharedSpriteFrameCache;
spriteCache~~>addSpriteFramesWithFile;
m_pSprite3 = CCSprite::createWithSpriteFrameName;
spritebatch~~>setPosition;
spritebatch~~>addChild;
this~~>addChild;
CCAnimationCache
cache = CCAnimationCache::sharedAnimationCache(); // “caches” are always singletons in cocos2d
cache~~>addAnimationsWithFile;
CCAnimation *animation = cache~~>animationByName(“carrotAnim”); // I apologize for this method name, it should be getAnimationByName(…) in future versions
CCAnimate animate = CCAnimate::create; // Don’t confused between CCAnimation and CCAnimate :slight_smile:
CCFiniteTimeAction
action = CCSequence::create(animate,CCCallFuncO::create(this, callfuncO_selector(GamePlay::carrotBurstAnimationCallback),NULL),NULL);
m_pSprite3~~>runAction;
}
void GamePlay::carrotBurstAnimationCallback{
m_pSprite3~~>setVisible(false);
}
@

I have generated animation using spritehelper.
The animation is happening when a user hits a carrot. Every thing is working fine till user is hitting it slowly. But when the user is hitting it fast the previous animation does not get removed from the scene.

I guess it is happening because, since the next animation is staring before the previous animation gets complete, the previous animation does not get to the callback function…

do we have any other alternative to do this….???


#2

First, setVisible(false) didn’t remove the sprite from parent. It’s invisible, but it’s still there. Try CCRemoveSelf action.
Second, you can set a tag to action, and before run it you can detect if it’s already there by getActionByTag().
Or you just add a status like: bool isHit. And if(isHit) { not run animation again }


#3

Actually my problem is that i have to call the same animation at different places. But when second animation starts before the completion of first animation, the first animation does not gets removed from the scene, and that’s because the callback function gets associated with the new animation. And my condition to remove the animation is written in the callback method as stated in my post above.

I have tried a lot about it and have’nt got any solution about it…


#4

It’s not because the callback function gets associated with first/second animation, but because you use “m_pSprite3” in your callback method rather than the passed “obj”.
What happens in your code is that, whenever an animation starts, you overwrite the value where “m_pSprite3” points to, so it will always point to the latest animation started. You did use “CCCallFuncO” which passes the sender to the function that gets called. If in your method you wrote

obj->setVisible(false);

everything should work, because than each instance of your animation would be passed to this function and made invisible. In fact the usage of a global variable (“m_pSprite3”) is not necessary in this case.

Also keep in mind what Changjun said : making something invisible does not remove it from scene, and in general you want to have as little elements as possible. The “CCRemoveSelf” action seems to be the best option for you.


#5

Thanx Pawel for the reply……

But in my case ‘obj’ does not have any ‘setVisible()’ or ‘RemoveFromParentandCleanup()’ function….

and plz let me know how to use ‘CCRemoveSelf’ as i cannot find it in my Test.cpp

I am using cocos2dx version 2.0…. i guess it does not have ‘CCRemoveSelf’


#6
sprite->runAction(CCSequence::create(animate, CCRemoveSelf::create(), NULL));

Your cocos2d-x version is low. If you have never modified the cocos2dx code in your project, you can update to latest cocos2d-x version.


#7

Thank you so much for your replies…
My cocos2dx version does not have ‘CCRemoveSelf’ class….

I found an alternative:
instead of using " CCCallFuncO::create(…)" for my callback function i am Using “CCCallFuncND::create(…)” selector, and my callback function receives ‘CCNode *node’ parameter. After that i can use “node->removeFromParentAndCleanup(true);” and it is workin as i expected (as for now).
Following is my code:
void GamePlay::carrotBurstAnimation(CCPoint position){ //Everything same as previous code Except// CCFiniteTimeAction* action = CCSequence::create(animate_carrot,CCCallFuncND::create(this, callfuncND_selector(GamePlay::carrotBurstAnimationCallback),NULL),NULL); }

and in my callback function…

void GamePlay::carrotBurstAnimationCallback(CCNode *obj,void* data){ obj->removeFromParentAndCleanup(true); }


#8

@Suveer : You should cast it to CCSprite*


#9

@Pawel: thanx for your replies, But casting ‘obj’ to CCSprite is also throwing me error…
But the above solution (i.e. using CallFuncND selector is working fine), coz it is receiving CCNode as parameter which can be removed easily from the layer.