CCAnimate 引起的bug

I'm trying to animate a sprite while it's moving. As per the examples: I create an array of frames, create a CCAnimation with them (and a delay), and then create the CCAnimate from that. When I do the following (in the constructor where animate is made):

this->addChild(sprite);
sprite->runAction(animate);

It works fine.

When I try to run a certain animation while it moves in a different method (animate is a global pointer to the animation) I get the following error:

In function retain -- ..\..\cocoa\CCObject.cpp:92 m_uReference > 0 -- assertion failed

Or more specifically: CCAssert(m_uReference > 0, "reference count should greater than 0");

 

I looked to this post (http://www.cocos2d-x.org/boards/6/topics/7553) and added a CC_SAFE_RETAIN(animate) and CC_SAFE_RETAIN(display) in the init method.
Now I see the first p_w_picpath of the animation but it crashes right after saying:
In function addAction -- ..\..\actions\CCActionManager.cpp:191 ! ccArrayContainsObject(pElement->actions, pAction) -- assertion failed

 

I figured out the problem.

Essentially follow the example here: http://www.cocos2d-x.org/boards/6/topics/7553)

The second part was that the action was being run twice, which is why that error was thrown. 
It was a logic error on my part (I'm using a custom CCNode child class)
I overrode the 'numberOfRunningActions' to take into account both the custom class and the sprite

 

 

 

class GameObject
{
public:
    GameObject();
    virtual ~GameObject();
    bool initWithParent(cocos2d::CCNode* pParent);
    void changeAction(int index);
    cocos2d::CCSprite* m_pSprite;
    cocos2d::CCMutableArray<cocos2d::CCAction*>* 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<CCAction*>::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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章