如何在cocos2d-x中设置多个动画

3
我目前正在使用cocos2d-x构建黑莓/安卓/iOS游戏。我有一个角色动画的png和plist文件,使用texturepacker创建。我使用CCSpriteBatchNodeCCSpriteFrameCache加载它们,然后使用一个由我创建的函数将所有帧加载到帧数组中,然后创建一个CCAnimation对象并存储用动画创建的CCAnimate对象(代码更加清晰)。问题在于,我有一个检测触摸的函数,它应该循环播放所有动画,但总是崩溃。
以下是一些代码(这些代码放在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);

加载动画的函数(_charanimation []只是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);
}

我成功让动画(使用runAction()设置的那个)运行起来了,但是如果我尝试更改动画,比如当我触摸屏幕时:

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);

}

我的应用程序崩溃了……我不知道是我操作有误还是其他原因,如果有人可以帮忙,我将不胜感激。

如果我在 runAction() 中更改动画,则可以正确显示动画,但我无法通过触摸在游戏中更改该动画。

顺便说一下,这是我在控制台中收到的错误信息:

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

3
因为您创建的CCAnimate对象是一个自动释放对象,您没有对该对象进行保留。如果自动释放对象没有被保留(无论是显式地还是通过其他对象),它们将被自动删除。
在添加到数组时,您可以这样做:
CCAnimate *animate = CCAnimate::create(CCAnimation::createWithSpriteFrames(animframes, delay));
animate->retain();
_charanimation[a] = animate;

不要忘记在一切结束时释放数组中的所有对象。
_charanimation[index]->release();
  • 注意:

    与使用简单的 C 或 C++ 数组不同,您可以使用 Cocos2d 的 CCArray,它在将对象添加到数组后会保留该对象。

例如:(内存处理类似于 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);

您可以参考此链接了解有关CCArray的更多信息


非常好,非常感谢。我不知道有些cocos2d对象会自动释放。您能否举个例子说明如何使用CCArray使其正常工作?我不知道如何在将对象添加到CCArray后获取它们。我还在学习如何使用它。 - nosmirck
我还有一个问题...如何将所有这些东西整合到一个类中(比如一个Player类),然后将其集成到init中呢?我尝试过但它会崩溃,我想我没有很好地管理batchnodes和cache,也许不能作为一个独立的类的一部分,我不知道,我需要例子......你能帮我吗?我需要一个类,可以传递.png和.plist(以及任何其他所需的信息),并且有一个我可以调用的方法,例如PlayAnimation(index)。这样我就可以创建像Player p1、p2这样的东西,在代码的某个部分中可以运行p1.PlayAnimation(2);p2.PlayAnimation(0); - nosmirck
1
我已经在答案中添加了一个示例。您可以参考链接以获取有关CCArray的更多信息。 - Souandios
在代码的最后一段中提到的情况下,将对象添加到一个未保留的数组中是否会保留该对象?还是我必须保留该数组以自动保留这些对象? - Omar HossamEldin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接