cocos2-d-x之runAction与clone的不解之缘

前端之家收集整理的这篇文章主要介绍了cocos2-d-x之runAction与clone的不解之缘前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
<span style="white-space:pre">	</span>starSprite->runAction(path);
	_emitter->runAction(path);



当你像这样有两个节点同时调用path这样一个动作时,运行之后是否有疑惑————

为啥只有下面的_emitter执行了这个动作,而starSprite愣是纹丝不动呢?


老规矩(???什么时候说过的规矩。。。)最有效的办法还是看cocos的源代码去。


首先查看runAction

Action * Node::runAction(Action* action)
{
    CCASSERT( action != nullptr,"Argument must be non-nil");
    _actionManager->addAction(action,this,!_running);
    return action;
}


没多少内容,很容易猜到主要内容在addAction()函数当中


继续翻源码。。。

<pre name="code" class="cpp">void ActionManager::addAction(Action *action,Node *target,bool paused)
{
    CCASSERT(action != nullptr,"");                  //有效性判断
    CCASSERT(target != nullptr,"");

    tHashElement *element = nullptr;              //定义哈希表项的指针并置空
    // we should convert it to Ref*,because we save it as Ref*
    Ref *tmp = target;
    HASH_FIND_PTR(_targets,&tmp,element);           //通过这个指针找到对应的哈希表项返回给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);               //为哈希表项element申请内存以存放动画集
 
     CCASSERT(! ccArrayContainsObject(element->actions,action),"");        //判断action是否已在element的动画集中,确保只放一个action
     ccArrayAppendObject(element->actions,action);                           //将action放入element的动画集中
 
     action->startWithTarget(target);                        //根据当前node来执行此动画
}


 
 
 
 


根据注释应该看得大懂大致内容,并且我们知道了重要的一点,我们的问题是由最后一句引起的

 action->startWithTarget(target); 

查看cocos的文档我们可以知道:

当有节点执行一个动画时,这个node会变为这个action的target,且一个action都有且仅有一个target成员,所以假如在一个node调用一个action后,此action的target设为此node
但之后当有另一个node调用同样这个action时,此action的target又会变为这个node,由上面addAction函数可知,action运行是根据target的值来选择哪个node运行的,所以这个action只能被后面的node调用,那么解决办法就是,让后面的node通通调用动作的clone()函数


总结一句话:一个动作action无法被一块相同的区域调用runAction,想要让多个节点执行相同的action,可以让其他的节点全部调用action的clone()

如这样:

<pre name="code" class="cpp">        starSprite->runAction(path);
	_emitter->runAction(path->clone();

猜你在找的Cocos2d-x相关文章