【Problom】事情的起因是这样子的,我在一个函数中使用了scheduleOnce延时一秒调用callBack,如下:
this->scheduleOnce(schedule_selector(HelloWorld::callBack), 1.0);
函数callBack实现如下:
void HelloWorld::callBack(float dt) { this->scheduleOnce(schedule_selector(HelloWorld::callBack), 0.5); }
执行到callBack内时scheduleOnce并没有成功,输出如下:
CCScheduler#scheduleSelector. Selector already scheduled. Updating interval from: 0.0000 to 0.0000
原因是当前的scheduleOnce还没有执行完成。
【Solution】这种问题的解决办法就是把CCDelayTime和CCCallFunc拼接构造延迟事件调用,用法如下:
CCDelayTime * delayAction = CCDelayTime::create(dt); CCCallFunc * callFunc = CCCallFunc::create(pSelectorTarget, selector); this->runAction(CCSequence::createWithTwoActions(delayAction, callFunc));
【Note】
CCCallFunc家族四兄弟都用来创建带有回调函数的动作,区别主要在于回调函数的参数:
CCCallFunc * CCCallFunc::create(CCObject* pSelectorTarget,SEL_CallFunc selector); CCCallFuncN * CCCallFuncN::create(CCObject* pSelectorTarget,SEL_CallFuncN selector); CCCallFuncND * CCCallFuncND::create(CCObject* pSelectorTarget,SEL_CallFuncND selector, void* d); CCCallFuncO * CCCallFuncO::create(CCObject* pSelectorTarget, SEL_CallFuncO selector, CCObject* pObject)这四个类分别对应的是四种不同的 回调函数函数包装:
typedef void (SelectorProtocol::*SEL_CallFunc)(); typedef void (SelectorProtocol::*SEL_CallFuncN)(CCNode*); //接受一个动作的执行节点做参数 typedef void (SelectorProtocol::*SEL_CallFuncND)(CCNode*, void*); //接受动作的执行节点做参数和一个void指针做参数 typedef void (SelectorProtocol::*SEL_CallFuncO)(CCObject*); //接受一个Object指针做参数
例子如下:
void Test::func(); void Test::funcN(CCNode *node); void Test::funcND(CCNode *node,void *param); void Test::funcO(CCObject* obj); ...
CCAction *a1=CCCallFunc::create(this, callfunc_selector(Test::func)); this->runAction(a1); CCAction *a2=CCCallFuncN::create(this, callfuncN_selector(Test::funcN)); this->runAction(a2); int i; CCAction *a3=CCCallFuncND::create(this, callfuncND_selector(Test::funcND),(void*)&i); this->runAction(a3); CCObject *obj; CCAction *a4=CCCallFuncO::create(this, callfuncO_selector(Test::funcO),obj); this->runAction(a4);