cocos2dx暫停某個action動作並恢復&簡單的js-binding
最近有個需求是一個卡牌同時執行兩個動作,一個repearForever的跳著向前移動,還有一個卡牌翻轉的動作。
有個需求是使用道具讓卡牌停止跳著移動,而卡牌可以翻轉。持續5s後,卡牌繼續跳著向前。
試了一些方法,也百度了一些方法,並看了原始碼,沒找到合適的引擎自帶方法。
有說stopActionBrTag(TAG);然後重新runAction()該動作的,但實際並不是想要的效果,比如牌剛好跳在最高點時,再次runAction()的時候,會從最高點開始運動。
如果紀錄position的話,會瞬移,而且有其他動作也在改變positoin的話,控制起來會很困難。
於是改了下原始碼。只看前兩步即可。其中步驟4之後是由於我用的CocosCreator,需要用js程式碼掉用c++的程式碼。
----1.CCAction.h(2d/actions/CCAction.h)新增變數&get/set:
classCC_DLL Action :publicRef,publicClonable
{
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);//繼續