-2
\$\begingroup\$

In my game I have a "rocket" type and I want to run a sequence of actions on it. At first it must run an explosion animation and then remove itself from the game. For this I used the following code, but it does not work and results in a runtime error.

Rocket class:

void Rocket::movingRocket(float dt)
{
    // ...
    if(rocketIsCollideWithEnemy()) // run only one time
    {
        this->stopAllActions();
        CCAnimation *animation = CCAnimation::create();

        for (int i = 0; i < EXPLOSION_FRAME_NUMBER; i++)
        {
            CCString *str = CCString::createWithFormat("/explosion-%d.png", i);
            animation->addSpriteFrameWithFileName(str->getCString());
        }

        animation->setDelayPerUnit(0.06f);
        CCAnimate *animate = CCAnimate::create(animation);
        CCCallFuncN* remove_rocket = CCCallFuncN::create(this, callfuncN_selector(Rocket::removeRocket));

        this->runAction(CCSequence::create(animate,remove_rocket, NULL));
        this->unschedule(schedule_selector(Rocket::movingRocket));
    }
}

And for removing a rocket I use:

void Rocket::removeRocket(CCObject *pSender)
{
    ((CCNode*)pSender)->removeFromParentAndCleanup(true);
}

And when I run the above, an error occurs in the following code, part Cocos2d, at line 4:

void CCAnimate::update(float t)
{
    // ...
    if( splitTime <= t ) 
    {
        CCAnimationFrame* frame = (CCAnimationFrame*)frames->objectAtIndex(i);
        frameToDisplay = frame->getSpriteFrame();
        ((CCSprite*)m_pTarget)->setDisplayFrame(frameToDisplay);

        CCDictionary* dict = frame->getUserInfo();
        if( dict )
        {
            //TODO: [[NSNotificationCenter defaultCenter] postNotificationName:CCAnimationFrameDisplayedNotification object:target_ userInfo:dict];
        }
        m_nNextFrame = i+1;
    }
    // ...
}

What could be causing my problem?

\$\endgroup\$
0
\$\begingroup\$

My answer won't be a clean solution but for a side note, and if you really need it to be fixed before attempting trying to find a clean working solution, I use the approach below.

I have a lot of action-chain used in my game. I found the exact same problem as you mention about that code section you posted.

I have spent so much time checking that whether every new action stops the previous one or unused ones. This is to minimize the chance of error in the case that actions might lost in the midst of nowhere. But I got no good result. So I applied the below code fix to CCActionInterval.cpp (I still use version 2.0.3)

if(m_pTarget == NULL)
{
     // make the animation finish
     t = 1.0f;

     return;
}

CCAnimationFrame* frame = (CCAnimationFrame*)frames->objectAtIndex(i);
frameToDisplay = frame->getSpriteFrame();
((CCSprite*)m_pTarget)->setDisplayFrame(frameToDisplay);

It might not be the best solution, but it works for me.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.