Cocos2d-x 与Cocosbuilder结合使用的一些技巧

转自:http://jetion.diandian.com/post/2012-12-04/40047798280,感谢作者分享

1. 使用Cocosbuilder制作帧动画,Publish的时候崩溃了。

解决方法如下:File -> projectsetting -> 取消选择 flatten paths when publishing

 

2. 使用Cocosbuilder制作完骨骼动画后,和Cocos2d-x中的Action结合,发现action只运行极短的时间就停止了。

解决方法:

其实这是因为在Cocosbuilder中设置了loop动画,在CCBAnimationManager中,当一次动画执行完毕后,它会执行stopAllAction(),而这个时候,我们的action还没有执行完毕,如果你的action的时间 > 运行一次Cocosbuilder动画的时间,就会出现这种情况。这时候我们只要稍微改一下原CCBAnimationManager中的runAniamtions()代码即可,如下:

void CCBAnimationManager::runAnimations(int nSeqId, float fTweenDuration)
{
    CCAssert(nSeqId != -1, "Sequence id couldn't be found");
                                                 
                                             
    mRootNode->stopActionByTag(100);
                                                 
    CCDictElement* pElement = NULL;
    CCDICT_FOREACH(mNodeSequences, pElement)
    {
        CCNode *node = (CCNode*)pElement->getIntKey();
        node->stopAllActions();
                                                     
        // Refer to CCBReader::readKeyframe() for the real type of value
        CCDictionary *seqs = (CCDictionary*)pElement->getObject();
        CCDictionary *seqNodeProps = (CCDictionary*)seqs->objectForKey(nSeqId);
                                                     
        set seqNodePropNames;
                                                     
        if (seqNodeProps)
        {
            // Reset nodes that have sequence node properties, and run actions on them
            CCDictElement* pElement1 = NULL;
            CCDICT_FOREACH(seqNodeProps, pElement1)
            {
                const char *propName = pElement1->getStrKey();
                CCBSequenceProperty *seqProp = (CCBSequenceProperty*)seqNodeProps->objectForKey(propName);
                seqNodePropNames.insert(propName);
                                                             
                setFirstFrame(node, seqProp, fTweenDuration);
                runAction(node, seqProp, fTweenDuration);
            }
        }
                                                     
        // Reset the nodes that may have been changed by other timelines
        CCDictionary *nodeBaseValues = (CCDictionary*)mBaseValues->objectForKey(pElement->getIntKey());
        if (nodeBaseValues)
        {
            CCDictElement* pElement2 = NULL;
            CCDICT_FOREACH(nodeBaseValues, pElement2)
            {
                if (seqNodePropNames.find(pElement2->getStrKey()) == seqNodePropNames.end())
                {
                    CCObject *value = pElement2->getObject();
                                                                 
                    if (value)
                    {
                       setAnimatedProperty(pElement2->getStrKey(), node, value, fTweenDuration);
                    }
                }
            }
        }
    }
                                                 
    // Make callback at end of sequence
    CCBSequence *seq = getSequence(nSeqId);
    CCAction *completeAction = CCSequence::createWithTwoActions(CCDelayTime::create(seq->getDuration() + fTweenDuration),
                                                                CCCallFunc::create(this, callfunc_selector(CCBAnimationManager::sequenceCompleted)));
    completeAction->setTag(100);
    mRootNode->runAction(completeAction);
                                                 
    // Set the running scene
    mRunningSequence = getSequence(nSeqId);
                                                 
}

第6行和第59行为添加的代码。

3. 给精灵添加发光的效果

在CCSprite右边的编辑窗口有一个Blend的设置项,我们只要选择下面的Additive即可实现发光效果; 手动设置Blend src为one- dst color,Blend dst为one, 可以去掉精灵的Alpha通道,这在去除某些黑色背景图片有不错的效果。

 

4.使用Cocosbuilder中的Visible动画时报错

这里要注意,是动画中的Visible,然后设置该动画为AutoRun,运行它就报错,报错内容如下:


但是如果你没设置AutoRun,而是手动的触发它,并不会报错。

暂时不知道为什么会出现这种情况,你可以灵活的使用opacity来代替显示隐藏的功能。

未完待续。。。


另外篇博客:

这样可以解决根节点的动画与2dx的action同时运作,但是无法解决子节点的问题。

完整的修改方案还需要增加这个部分的修改

[cpp]  view plain copy
  1. void CCBAnimationManager::runAction(CCNode *pNode, CCBSequenceProperty *pSeqProp, float fTweenDuration)  
  2. {  
  3.     CCArray *keyframes = pSeqProp->getKeyframes();  
  4.     int numKeyframes = keyframes->count();  
  5.       
  6.     if (numKeyframes > 1)  
  7.     {  
  8.         // Make an animation!  
  9.         CCArray *actions = CCArray::create();  
  10.           
  11.         CCBKeyframe *keyframeFirst = (CCBKeyframe*)keyframes->objectAtIndex(0);  
  12.         float timeFirst = keyframeFirst->getTime() + fTweenDuration;  
  13.           
  14.         if (timeFirst > 0)  
  15.         {  
  16.             actions->addObject(CCDelayTime::create(timeFirst));  
  17.         }  
  18.           
  19.         for (int i = 0; i < numKeyframes - 1; ++i)  
  20.         {  
  21.             CCBKeyframe *kf0 = (CCBKeyframe*)keyframes->objectAtIndex(i);  
  22.             CCBKeyframe *kf1 = (CCBKeyframe*)keyframes->objectAtIndex(i+1);  
  23.               
  24.             CCActionInterval *action = getAction(kf0, kf1, pSeqProp->getName(), pNode);  
  25.             if (action)  
  26.             {  
  27.                 // Apply easing  
  28.                 action = getEaseAction(action, kf0->getEasingType(), kf0->getEasingOpt());  
  29.                   
  30.                 actions->addObject(action);  
  31.             }  
  32.         }  
  33.           
  34.         CCFiniteTimeAction *seq = CCSequence::create(actions);  
  35.         // 修改  
  36.         const int childActionTag = 200;  
  37.         seq->setTag(childActionTag);  
  38.   
  39.         pNode->runAction(seq);  
  40.     }  
  41. }  

以及

[cpp]  view plain copy
  1. void CCBAnimationManager::runAnimationsForSequenceIdTweenDuration(int nSeqId, float fTweenDuration)  
  2. {  
  3.     CCAssert(nSeqId != -1, "Sequence id couldn't be found");  
  4.     // 修改部分  
  5.     const int currentActionTag = 1000;   
  6.     mRootNode->stopActionByTag(currentActionTag);  
  7.       
  8.     //mRootNode->stopAllActions();  
  9.       
  10.     CCDictElement* pElement = NULL;  
  11.     CCDICT_FOREACH(mNodeSequences, pElement)  
  12.     {  
  13.         CCNode *node = (CCNode*)pElement->getIntKey();  
  14.   
  15.         // 修改部分  
  16.         const int childActionTag = 200;  
  17.         node->stopActionByTag(childActionTag);  
  18.         //node->stopAllActions();  
  19.   
  20.         // Refer to CCBReader::readKeyframe() for the real type of value  
  21.         CCDictionary *seqs = (CCDictionary*)pElement->getObject();  
  22.         CCDictionary *seqNodeProps = (CCDictionary*)seqs->objectForKey(nSeqId);  
  23.           
  24.         set seqNodePropNames;  
  25.           
  26.         if (seqNodeProps)  
  27.         {  
  28.             // Reset nodes that have sequence node properties, and run actions on them  
  29.             CCDictElement* pElement1 = NULL;  
  30.             CCDICT_FOREACH(seqNodeProps, pElement1)  
  31.             {  
  32.                 const char *propName = pElement1->getStrKey();  
  33.                 CCBSequenceProperty *seqProp = (CCBSequenceProperty*)seqNodeProps->objectForKey(propName);  
  34.                 seqNodePropNames.insert(propName);  
  35.                   
  36.                 setFirstFrame(node, seqProp, fTweenDuration);  
  37.                 runAction(node, seqProp, fTweenDuration);  
  38.             }  
  39.         }  
  40.           
  41.         // Reset the nodes that may have been changed by other timelines  
  42.         CCDictionary *nodeBaseValues = (CCDictionary*)mBaseValues->objectForKey(pElement->getIntKey());  
  43.         if (nodeBaseValues)  
  44.         {  
  45.             CCDictElement* pElement2 = NULL;  
  46.             CCDICT_FOREACH(nodeBaseValues, pElement2)  
  47.             {  
  48.                 if (seqNodePropNames.find(pElement2->getStrKey()) == seqNodePropNames.end())  
  49.                 {  
  50.                     CCObject *value = pElement2->getObject();  
  51.                       
  52.                     if (value)  
  53.                     {  
  54.                        setAnimatedProperty(pElement2->getStrKey(), node, value, fTweenDuration);  
  55.                     }  
  56.                 }  
  57.             }  
  58.         }  
  59.     }  
  60.       
  61.     // Make callback at end of sequence  
  62.     CCBSequence *seq = getSequence(nSeqId);  
  63.     CCAction *completeAction = CCSequence::createWithTwoActions(CCDelayTime::create(seq->getDuration() + fTweenDuration),  
  64.                                                                 CCCallFunc::create(this, callfunc_selector(CCBAnimationManager::sequenceCompleted)));  
  65.   
  66.     // 修改部分  
  67.     completeAction->setTag(currentActionTag);  
  68.     mRootNode->runAction(completeAction);  
  69.       
  70.     // Set the running scene  
  71.   
  72.     if(seq->getCallbackChannel() != NULL) {  
  73.         CCAction* action = (CCAction *)actionForCallbackChannel(seq->getCallbackChannel());  
  74.         if(action != NULL) {  
  75.             mRootNode->runAction(action);  
  76.         }  
  77.     }   
  78.   
  79.     if(seq->getSoundChannel() != NULL) {  
  80.         CCAction* action = (CCAction *)actionForSoundChannel(seq->getSoundChannel());  
  81.         if(action != NULL) {  
  82.             mRootNode->runAction(action);  
  83.         }  
  84.     }  
  85.   
  86.     mRunningSequence = getSequence(nSeqId);  
  87. }  

你可能感兴趣的:(cocos2d-x)