Okay, my code is kind of spread out, and my problem is simple, so I’ll just explain the basic issue:
- A game object G has a CCSprite S. Note that my game object class does not inherit from any Cocos class.
- G also an array of CCRepeatForever actions created with CCAnimation actions.
- My goal is to have G be able to run different CCAnimation actions depending on where it’s facing, what it’s doing, etc.
- To change actions, a method of G calls S~~>runAction .
- There is no problem as long as the actions are changed in the init method of the parent node of S, in which G and S are created.
- However, whenever I call S~~>runAction ( ) from the tick ( ) method of the parent node of S (or any method called from tick ( )), the game crashes after showing the first frame.
So what am I doing wrong?
Hi, I have tested your method, but it works fine, no crash. Could you paste your code?
class GameObject
{
public:
GameObject();
virtual ~GameObject();
bool initWithParent(cocos2d::CCNode* pParent);
void changeAction(int index);
cocos2d::CCSprite* m_pSprite;
cocos2d::CCMutableArray* m_pActions;
cocos2d::CCNode* m_pParent;
};
GameObject::GameObject()
: m_pSprite(NULL)
, m_pActions(NULL)
, m_pParent(NULL)
{
}
GameObject::~GameObject()
{
CC_SAFE_RELEASE(m_pSprite);
CC_SAFE_RELEASE(m_pActions);
}
bool GameObject::initWithParent(CCNode* pParent)
{
bool bRet = false;
do
{
CCSize winSize = CCDirector::sharedDirector()->getWinSize();
CCAssert(pParent != NULL, "");
m_pParent = pParent;
m_pSprite = CCSprite::spriteWithFile("grossini.png");
m_pSprite->setPosition(ccp(winSize.width/2, winSize.height/2));
m_pParent->addChild(m_pSprite);
CC_SAFE_RETAIN(m_pSprite);
CCMoveBy* move = CCMoveBy::actionWithDuration(0.5f, ccp(100, 0));
CCActionInterval* moveReverse = move->reverse();
CCRepeatForever* moveForever = CCRepeatForever::actionWithAction((CCActionInterval*)CCSequence::actions(move, moveReverse, NULL));
CCFadeIn* fadeIn = CCFadeIn::actionWithDuration(0.5f);
CCActionInterval* fadeOut = fadeIn->reverse();
CCRepeatForever* fadeForever = CCRepeatForever::actionWithAction((CCActionInterval*)CCSequence::actions(fadeIn, fadeOut, NULL));
CCRotateBy* rotate = CCRotateBy::actionWithDuration(0.5f, 90.0f);
CCActionInterval* rotateReverse = rotate->reverse();
CCRepeatForever* rotateForever = CCRepeatForever::actionWithAction((CCActionInterval*)CCSequence::actions(rotate, rotateReverse, NULL));
m_pActions = CCMutableArray::arrayWithObjects(moveForever, fadeForever, rotateForever, NULL);
CC_SAFE_RETAIN(m_pActions);
changeAction(0);
bRet = true;
} while (false);
return bRet;
}
void GameObject::changeAction(int index)
{
int count = m_pActions->count();
CCAssert(index >= 0 && index < count, "");
if (m_pSprite->numberOfRunningActions() > 0)
{
m_pSprite->stopAllActions();
}
m_pSprite->setOpacity(255);
m_pSprite->runAction(m_pActions->getObjectAtIndex(index));
}
void HelloWorld::step(cocos2d::ccTime dt)
{
static int animationIndex = 0;
m_pGameObj->changeAction(animationIndex);
animationIndex = ++animationIndex > 2 ? 0 : animationIndex;
}
Hi Chen, thanks for posting this. It shows a quick reference for changing animations and also retaining sprites,
Muzzylogic
Thanks It reeeeally helped I was forgetting the “stopAllActions()”…