多个精灵播放同一个动画时的问题
代码摘要
// pSpReinit 在 2 次循环里代表 2 个精灵.
for (short j = 0; j < 2; j++)
{
for (short i = 0; i < THMAX_ANI_COUNT; i++)
{
if (0 == strcmp(m_arrpAniGroup[i]->szarrDesc, "batMove"))
{
pAniMoveTo = m_arrpAniGroup[i]->pAnimate;
break;
}
}
pSpReinit->pSpCharacter->runAction(pAniMoveTo);
pSpReinit->pSpCharacter->runAction(pSeMoveTo);
}
异常情况
在2次循环里,给精灵都加上了相同的帧动画Action,但是只有最后一个精灵才能播放这个动画。
分析
通过看源码runAction()
中的addAction()
,可以看到在action->startWithTarget(target);
里,一个action只能绑定一个精灵。
解决方案
将这个帧动画对象拷贝一份出来,成为独立不同的对象,就不会一个对象绑定到多个精灵上。
pSpReinit->pSpCharacter->runAction(pAniMoveTo->clone());
深度分析
对函数void ActionManager::addAction(Action *action, Node *target, bool paused)
进行深度分析。
// 源码
void ActionManager::addAction(Action *action, Node *target, bool paused)
{
CCASSERT(action != nullptr, "action can't be nullptr!");
CCASSERT(target != nullptr, "target can't be nullptr!");
if(action == nullptr || target == nullptr)
return;
tHashElement *element = nullptr;
// we should convert it to Ref*, because we save it as Ref*
Ref *tmp = target;
HASH_FIND_PTR(_targets, &tmp, element);
if (! element)
{
element = (tHashElement*)calloc(sizeof(*element), 1);
element->paused = paused;
target->retain();
element->target = target;
HASH_ADD_PTR(_targets, target, element);
}
actionAllocWithHashElement(element);
CCASSERT(! ccArrayContainsObject(element->actions, action), "action already be added!");
ccArrayAppendObject(element->actions, action);
action->startWithTarget(target);
}
- addAction函数读取或创建一个pElement哈希表项,一个pElement可以存放4个动画,超了则翻倍扩容。
- pElement是用来存放动画和用此动画的精灵的哈希表。一个pElement只能放一次动画,否则ASSERT,这也是为什么一个动画不能重复添加的原因(可能是为了省内存?)。
- 再设置这个动画是哪个精灵来使用,给后续的动画调用指导使用者。所以这里就是原因,因为只有帧动画Action是唯一的,有且只有一个,所以只能绑定一个精灵来使用。
- 上述循环的时候重复runAction, 也就是重复变换了使用者,只有最后一个使用者得到了这个Action。
- 执行动画的逻辑可能还要深度分析 ActionManage,runAction只是添加,具体实现还是在update里的每个tick去做.
- 该方法简要地说是对ActionManager的哈希链表_targets进行遍历,对遍历到的每个element的actions再遍历,对遍历到的action执行step(float dt)
参考:
- https://blog.csdn.net/TskyFree/article/details/8704479?utm_medium=distribute.pc_relevant.none-task-blog-2defaultbaidujs_baidulandingword~default-0-8704479-blog-48545257.235v43pc_blog_bottom_relevance_base7&spm=1001.2101.3001.4242.1&utm_relevant_index=3
- https://blog.csdn.net/iteye_3753/article/details/82443296
- https://www.jianshu.com/p/e9dfee41baff