How to change a sprite's animation in tick ( )?

Okay, my code is kind of spread out, and my problem is simple, so I’ll just explain the basic issue:

  1. A game object G has a CCSprite S. Note that my game object class does not inherit from any Cocos class.
  2. G also an array of CCRepeatForever actions created with CCAnimation actions.
  3. My goal is to have G be able to run different CCAnimation actions depending on where it’s facing, what it’s doing, etc.
  4. To change actions, a method of G calls S~~>runAction .
  5. 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.
  6. 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()”…