Cocos2d-x 与Cocosbuilder结合使用的一些技巧
2014-10-27 13:48
489 查看
转自: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()代码即可,如下:
第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
plaincopy
void CCBAnimationManager::runAction(CCNode *pNode, CCBSequenceProperty *pSeqProp, float fTweenDuration)
{
CCArray *keyframes = pSeqProp->getKeyframes();
int numKeyframes = keyframes->count();
if (numKeyframes > 1)
{
// Make an animation!
CCArray *actions = CCArray::create();
CCBKeyframe *keyframeFirst = (CCBKeyframe*)keyframes->objectAtIndex(0);
float timeFirst = keyframeFirst->getTime() + fTweenDuration;
if (timeFirst > 0)
{
actions->addObject(CCDelayTime::create(timeFirst));
}
for (int i = 0; i < numKeyframes - 1; ++i)
{
CCBKeyframe *kf0 = (CCBKeyframe*)keyframes->objectAtIndex(i);
CCBKeyframe *kf1 = (CCBKeyframe*)keyframes->objectAtIndex(i+1);
CCActionInterval *action = getAction(kf0, kf1, pSeqProp->getName(), pNode);
if (action)
{
// Apply easing
action = getEaseAction(action, kf0->getEasingType(), kf0->getEasingOpt());
actions->addObject(action);
}
}
CCFiniteTimeAction *seq = CCSequence::create(actions);
// 修改
const int childActionTag = 200;
seq->setTag(childActionTag);
pNode->runAction(seq);
}
}
以及
[cpp] view
plaincopy
void CCBAnimationManager::runAnimationsForSequenceIdTweenDuration(int nSeqId, float fTweenDuration)
{
CCAssert(nSeqId != -1, "Sequence id couldn't be found");
// 修改部分
const int currentActionTag = 1000;
mRootNode->stopActionByTag(currentActionTag);
//mRootNode->stopAllActions();
CCDictElement* pElement = NULL;
CCDICT_FOREACH(mNodeSequences, pElement)
{
CCNode *node = (CCNode*)pElement->getIntKey();
// 修改部分
const int childActionTag = 200;
node->stopActionByTag(childActionTag);
//node->stopAllActions();
// Refer to CCBReader::readKeyframe() for the real type of value
CCDictionary *seqs = (CCDictionary*)pElement->getObject();
CCDictionary *seqNodeProps = (CCDictionary*)seqs->objectForKey(nSeqId);
set<string> 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(currentActionTag);
mRootNode->runAction(completeAction);
// Set the running scene
if(seq->getCallbackChannel() != NULL) {
CCAction* action = (CCAction *)actionForCallbackChannel(seq->getCallbackChannel());
if(action != NULL) {
mRootNode->runAction(action);
}
}
if(seq->getSoundChannel() != NULL) {
CCAction* action = (CCAction *)actionForSoundChannel(seq->getSoundChannel());
if(action != NULL) {
mRootNode->runAction(action);
}
}
mRunningSequence = getSequence(nSeqId);
}
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<string> 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
plaincopy
void CCBAnimationManager::runAction(CCNode *pNode, CCBSequenceProperty *pSeqProp, float fTweenDuration)
{
CCArray *keyframes = pSeqProp->getKeyframes();
int numKeyframes = keyframes->count();
if (numKeyframes > 1)
{
// Make an animation!
CCArray *actions = CCArray::create();
CCBKeyframe *keyframeFirst = (CCBKeyframe*)keyframes->objectAtIndex(0);
float timeFirst = keyframeFirst->getTime() + fTweenDuration;
if (timeFirst > 0)
{
actions->addObject(CCDelayTime::create(timeFirst));
}
for (int i = 0; i < numKeyframes - 1; ++i)
{
CCBKeyframe *kf0 = (CCBKeyframe*)keyframes->objectAtIndex(i);
CCBKeyframe *kf1 = (CCBKeyframe*)keyframes->objectAtIndex(i+1);
CCActionInterval *action = getAction(kf0, kf1, pSeqProp->getName(), pNode);
if (action)
{
// Apply easing
action = getEaseAction(action, kf0->getEasingType(), kf0->getEasingOpt());
actions->addObject(action);
}
}
CCFiniteTimeAction *seq = CCSequence::create(actions);
// 修改
const int childActionTag = 200;
seq->setTag(childActionTag);
pNode->runAction(seq);
}
}
以及
[cpp] view
plaincopy
void CCBAnimationManager::runAnimationsForSequenceIdTweenDuration(int nSeqId, float fTweenDuration)
{
CCAssert(nSeqId != -1, "Sequence id couldn't be found");
// 修改部分
const int currentActionTag = 1000;
mRootNode->stopActionByTag(currentActionTag);
//mRootNode->stopAllActions();
CCDictElement* pElement = NULL;
CCDICT_FOREACH(mNodeSequences, pElement)
{
CCNode *node = (CCNode*)pElement->getIntKey();
// 修改部分
const int childActionTag = 200;
node->stopActionByTag(childActionTag);
//node->stopAllActions();
// Refer to CCBReader::readKeyframe() for the real type of value
CCDictionary *seqs = (CCDictionary*)pElement->getObject();
CCDictionary *seqNodeProps = (CCDictionary*)seqs->objectForKey(nSeqId);
set<string> 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(currentActionTag);
mRootNode->runAction(completeAction);
// Set the running scene
if(seq->getCallbackChannel() != NULL) {
CCAction* action = (CCAction *)actionForCallbackChannel(seq->getCallbackChannel());
if(action != NULL) {
mRootNode->runAction(action);
}
}
if(seq->getSoundChannel() != NULL) {
CCAction* action = (CCAction *)actionForSoundChannel(seq->getSoundChannel());
if(action != NULL) {
mRootNode->runAction(action);
}
}
mRunningSequence = getSequence(nSeqId);
}
相关文章推荐
- 使用CocosBuilder2.1结合cocos2d-x2.0.3创建动画场景
- 使用CocosBuilder2.1结合cocos2d-x2.0.3创建动画场景
- 使用CocosBuilder2.1结合cocos2d-x2.0.3创建动画场景
- 使用CocosBuilder2.1结合cocos2d-x2.0.3创建动画场景
- 使用CocosBuilder2.1结合cocos2d-x2.0.3创建动画场景
- 如何使用CocosBuilder2.1结合cocos2d-x2.0.3创建动画场景 分享0
- 如何使用CocosBuilder2.1结合cocos2d-x2.0.3创建动画场景
- cocos2d-x结合cocosbuilder,不同屏幕适配小结
- [cocos2dx开发技巧4]工具CocosBuilder的使用--复杂动画
- Cocos2d场景编辑器CocosBuilder使用教程
- Cocos2d-x——CocosBuilder官方帮助文档翻译1 使用自定义类
- Cocos2d-x CocosBuilder使用教程(二)连接自定义类
- [cocos2dx开发技巧2]工具CocosBuilder的使用--集成
- 图文并茂使用CocosBuilder制作Cocos2D游戏
- cocos2d-x-2.0.4中使用CocosBuilder创建动画注意的问题
- Cocos2d-x CocosBuilder使用教程(一)HelloCocosBuilder
- cocos2d-x js binding tips 1 使用cocosbuilder导入jsb后无法响应触摸的问题
- Web Service与DWR结合使用时的一些技巧
- [cocos2dx开发技巧1]工具CocosBuilder的使用--demo介绍
- [cocos2dx开发技巧2]工具CocosBuilder的使用--集成