最近有个需求是一个卡牌同时执行两个动作,一个repearForever的跳着向前移动,还有一个卡牌翻转的动作。
有个需求是使用道具让卡牌停止跳着移动,而卡牌可以翻转。持续5s后,卡牌继续跳着向前。
试了一些方法,也百度了一些方法,并看了源码,没找到合适的引擎自带方法。
有说stopActionBrTag(TAG);然后重新runAction()该动作的,但实际并不是想要的效果,比如牌刚好跳在最高点时,再次runAction()的时候,会从最高点开始运动。
如果纪录position的话,会瞬移,而且有其他动作也在改变positoin的话,控制起来会很困难。
于是改了下源代码。只看前两步即可。其中步骤4之后是由于我用的CocosCreator,需要用js代码掉用c++的代码。
----1.CCAction.h(2d/actions/CCAction.h)添加变量&get/set:
class CC_DLL Action :public Ref,public Clonable
{
public:
/** 控制动作暂停并继续的标志位 evanFlag */
bool evanFlag;
inline int getEvanFlag()const { returnevanFlag; }
inline void setEvanFlag(bool _evanFlag) {evanFlag = _evanFlag; }
/** Default tag used for all the actions. */
static constint INVALID_TAG = -1;
/**
* @js NA
* @lua NA
*/
virtual std::string description()const;
----2.CCActionManager.cpp(2d/actions/CCActionManager.cpp)类中
voidActionManager::update(float dt)方法添加代码:
if (_currentTarget->currentAction->evanFlag) {
continue;
}
添加后代码:
// main loop
void ActionManager::update(float dt)
{
for (tHashElement *elt =_targets; elt != nullptr; )
{
_currentTarget = elt;
_currentTargetSalvaged =false;
if (!_currentTarget->paused)
{
// The 'actions' MutableArray may change while inside this loop.
for (_currentTarget->actionIndex =0; _currentTarget->actionIndex <_currentTarget->actions->num;
_currentTarget->actionIndex++)
{
_currentTarget->currentAction = (Action*)_currentTarget->actions->arr[_currentTarget->actionIndex];
if (_currentTarget->currentAction ==nullptr)
{
continue;
}
_currentTarget->currentActionSalvaged =false;
//evanFlag
if (_currentTarget->currentAction->evanFlag) {
continue;
}
_currentTarget->currentAction->step(dt);
if (_currentTarget->currentActionSalvaged)
{
// The currentAction told the node to remove it. To prevent the action from
// accidentally deallocating itself before finishing its step, we retained
// it. Now that step is done, it's safe to release it.
_currentTarget->currentAction->release();
} else
if (_currentTarget->currentAction->isDone())
{
_currentTarget->currentAction->stop();
Action *action = _currentTarget->currentAction;
// Make currentAction nil to prevent removeAction from salvaging it.
_currentTarget->currentAction =nullptr;
removeAction(action);
}
_currentTarget->currentAction =nullptr;
}
}
// elt, at this moment, is still valid
// so it is safe to ask this here (issue #490)
elt = (tHashElement*)(elt->hh.next);
// only delete currentTarget if no actions were scheduled during the cycle (issue #481)
if (_currentTargetSalvaged &&_currentTarget->actions->num ==0)
{
deleteHashElement(_currentTarget);
}
////if some node refrence 'target', it's refrence count >= 2 (issues #14050)
else if(_currentTarget->target->getReferenceCount() ==1)
{
deleteHashElement(_currentTarget);
}
}
// issue #635
_currentTarget =nullptr;
}
----3.使用:
sprite =Sprite::create("new/btn/btn_2_cheng_n.png");
this->addChild(sprite);
sprite->setPosition(Vec2(200,200));
auto moveBy = MoveBy::create(2,Vec2(20, 20));
auto moveBack = moveBy->reverse();
auto sequence = Sequence::create(moveBy, moveBack, NULL);
auto repeat = RepeatForever::create(sequence);
repeat->setTag(9);
auto scaleBy = ScaleBy::create(2,1.1);
auto scaleBack = scaleBy->reverse();
auto sequence1 = Sequence::create(scaleBy, scaleBack, NULL);
auto repeat1 = RepeatForever::create(sequence1);
sprite->runAction(repeat);
sprite->runAction(repeat1);
sprite->getActionByTag(9)->evanFlag = true;//暂停
sprite->getActionByTag(9)->evanFlag = false;//继续
-----------------js-binding------------------
----4.jsb_cocos2dx_auto.cpp(auto/jsb_cocos2dx_auto.cpp)中添加方法:
我加在了js_cocos2dx_Action_setTag()方法之后,大概12575行。
//evanFlag
bool js_cocos2dx_Action_setEvanFlag(JSContext *cx,uint32_t argc, jsval *vp)
{
JS::CallArgs args =JS::CallArgsFromVp(argc, vp);
bool ok = true;
JS::RootedObject obj(cx, args.thisv().toObjectOrNull());
js_proxy_t *proxy = jsb_get_js_proxy(obj);
cocos2d::Action* cobj = (cocos2d::Action *)(proxy ? proxy->ptr :NULL);
JSB_PRECONDITION2( cobj, cx,false, "js_cocos2dx_Action_setEvanFlag : Invalid Native Object");
if (argc == 1) {
bool arg0;
arg0 = JS::ToBoolean(args.get(0));
JSB_PRECONDITION2(ok, cx,false, "js_cocos2dx_Action_setEvanFlag : Error processing arguments");
cobj->setEvanFlag(arg0);
args.rval().setUndefined();
return true;
}
JS_ReportError(cx,"js_cocos2dx_Action_setEvanFlag : wrong number of arguments: %d, was expecting %d", argc,1);
return false;
}
---- 5 .jsb_cocos2dx_auto.cpp(auto/jsb_cocos2dx_auto.cpp)中
js_register_cocos2dx_Action()方法添加代码:
同样,我加在了setTag之后,添加完上述方法后大概12738行。
JS_FN("setEvanFlag",js_cocos2dx_Action_setEvanFlag,1, JSPROP_PERMANENT |JSPROP_ENUMERATE),
----6.js代码中掉用: var action = cc.director.getActionManager().getActionByTag(9, this.node);
action.setEvanFlag(true);//暂停
action.setEvanFlag(false);//继续