Search code examples
c++animationspritecocos2d-x

How to set multiple animations in cocos2d-x


I'm currently starting with cocos2d-x to build games for blackberry/android/iOS.

I have the png and plist for the animations of a character created with texturepacker. I load them with CCSpriteBatchNode and CCSpriteFrameCache then I use a function created by me that loads all frames into an array of frames, then create a CCAnimation object and store the CCAnimate object created with the animation (code is more clear) the thing is that I have a function that detect touches and it is supposed to cycle through all animations, but it always crashes.

here is some code (this goes in the init()):

_batchNode = CCSpriteBatchNode::create("Character/girl.png");
_cache = CCSpriteFrameCache::sharedSpriteFrameCache();

_cache->addSpriteFramesWithFile("Personajes/girl.plist");

_character = CCSprite::createWithSpriteFrameName("girlneutral1.png");
_character->setPosition(ccp(winSize.width * 0.1, winSize.height * 0.5));
_batchNode->addChild(_character, 1);
this->addChild(_batchNode);
createAnimation(0, "girlpush", 8, 0.15f);
createAnimation(1, "girlneutral", 4, 0.3f);
createAnimation(2, "girlcrash", 12, 0.3f);
createAnimation(3, "girljump", 12, 0.2f);
createAnimation(4, "girltrick", 12, 0.3f);

_character->runAction(CCRepeatForever::create( _charanimation[3]));

this->setTouchEnabled(true);

the function that loads the animations (_charanimation[] is just an array of CCAnimate):

void HelloWorld::createAnimation(int a, CCString animation_name, int frames, float delay)
{
    CCArray* animframes = CCArray::createWithCapacity(frames);
    char str[100] = {0};
    for(int i = 1; i <= frames; i++)
    {
        sprintf(str, "%s%d.png", animation_name.getCString(), i);
        CCSpriteFrame* frame = _cache->spriteFrameByName( str );
        animframes->addObject(frame);
    }
    _charanimation[a] = CCAnimate::create(CCAnimation::createWithSpriteFrames(animframes, delay));
    //_charanimation[a]->getAnimation()->setLoops(-1);
}

and I get the animation to work (the one I set with runAction()) but if I try to change the animation, for example, when I touch the screen:

void HelloWorld::ccTouchesBegan(cocos2d::CCSet* touches, cocos2d::CCEvent* event)
{
    action++;
    action%=5;
    _character->stopAllActions();
    _character->runAction( CCRepeatForever::create(_charanimation[action]));
    char str[100];
    sprintf(str, "Animation: %d", action);
    pLabel->setString(str);

}

it crashes... I don't know if I am doing it wrong, if anyone could help, I will appreciate.

If I change the animation in runAction() it shows the animation correctly, but I can't change ingame with touches.

by the way, this is the error I get in console:

cocos2d-x debug info Assert failed: reference count should greater than 0
In function retain -- ..\..\cocoa\CCObject.cpp:92 m_uReference > 0 -- assertion failed

Solution

  • Its because the CCAnimate object you have created is autorelease object and you are not retaining the object. Autorelease objects will be deleted automatically if they are not retained, either explicitly or by some other object.

    While adding to array You can do

    CCAnimate *animate = CCAnimate::create(CCAnimation::createWithSpriteFrames(animframes, delay));
    animate->retain();
    _charanimation[a] = animate;
    

    do not forget to release all the objects in the array when everything is over

    _charanimation[index]->release();
    
    • Note:

      Instead of using the simple C or C++ array you can use Cocos2d's CCArray which retains the object once it is added to the array.

    For Example: (The memory handling is similar to Objective-C)

    _charanimation = new CCArray();
    
    //To add object to array
    _charanimation->addObject(object);  //This will retain the object
    
    //To get an object
    _charanimation->objectAtIndex(index);
    _charanimation->lastObject();
    _charanimation->randomObject();
    
    //To remove object
    _charanimation->removeObjectAtIndex(index);  //This will release object
    _charanimation->removeObject(object);        //This will release object
    
    //Dont forget delete array later
    delete (_charanimation);
    

    You can refer this link for more on CCArray