1:CCCallFunc CCCallFuncO CCCallFuncN CCCallFuncND 在cocos2dx\actions\CCActionInstant.h中定义
static CCCallFunc * create(CCObject* pSelectorTarget, SEL_CallFunc selector);
static CCCallFuncO * create(CCObject* pSelectorTarget, SEL_CallFuncO selector, CCObject* pObject);
static CCCallFuncN * create(CCObject* pSelectorTarget, SEL_CallFuncN selector);
static CCCallFuncND * create(CCObject* pSelectorTarget, SEL_CallFuncND selector, void* d);
pSelectorTarget:当前类this,selector不同的回调函数,以及不同的参数
2:selector:四种不同的回调函数的类型:SEL_CallFunc SEL_CallFuncO SEL_CallFuncN SEL_CallFuncND普通的函数需要转换成相应的回调函数类型,所以转换格式就有相应的4种
#define callfunc_selector(_SELECTOR) (SEL_CallFunc)(&_SELECTOR)
#define callfuncN_selector(_SELECTOR) (SEL_CallFuncN)(&_SELECTOR)
#define callfuncND_selector(_SELECTOR) (SEL_CallFuncND)(&_SELECTOR)
#define callfuncO_selector(_SELECTOR) (SEL_CallFuncO)(&_SELECTOR)
4个宏定义把普通的函数转换成特定的函数形式
具体的回调函数定义
typedef void (CCObject::*SEL_CallFunc)();
void callFunc();
typedef void (CCObject::*SEL_CallFuncN)(CCNode*);
void callFunc(CCNode * node);
typedef void (CCObject::*SEL_CallFuncND)(CCNode*, void*);
void callFunc(CCNode * node,void * data);
typedef void (CCObject::*SEL_CallFuncO)(CCObject*);
void callFunc(CCObject *object);
具体实现
CCSprite * sprite1 = CCSprite::create("Icon.png");
CCSprite * sprite2 = CCSprite::create("Icon.png");
CCSprite * sprite3 = CCSprite::create("Icon.png");
CCSprite * sprite4 = CCSprite::create("Icon.png");
sprite1->setTag(10);
sprite2->setTag(20);
sprite3->setTag(30);
sprite4->setTag(40);
CCFiniteTimeAction * action1 = CCSequence::create(CCMoveBy::create(2,ccp(200,0)),
CCCallFunc::create(this,callfunc_selector(HelloWorld::callFunc)),NULL);
CCFiniteTimeAction * action2 = CCSequence::create(CCMoveBy::create(3,ccp(300,0)),
CCCallFuncO::create(this,callfuncO_selector(HelloWorld::callFunc),sprite2),NULL);
CCFiniteTimeAction * action3 = CCSequence::create(CCMoveBy::create(4,ccp(400,0)),
CCCallFuncN::create(this,callfuncN_selector(HelloWorld::callFunc)),NULL);
CCFiniteTimeAction * action4 = CCSequence::create(CCMoveBy::create(5,ccp(500,0)),
CCCallFuncND::create(this,callfuncND_selector(HelloWorld::callFunc),(void *)0x555555),NULL);
sprite1->runAction(action1);
sprite2->runAction(action2);
sprite3->runAction(action3);
sprite4->runAction(action4);
void HelloWorld::callFunc()
{
CCLog("func()");
}
void HelloWorld::callFunc(CCObject *object)
{
CCLog("func(obj)----%d",((CCNode *)object)->getTag());
}
void HelloWorld::callFunc(CCNode * node)
{
CCLog("callfunc(node)-------%d",node->getTag());
}
void HelloWorld::callFunc(CCNode * node,void * data)
{
CCLog("callfunc(node,data)----%d--------%x",node->getTag(),data);
}
输出结果
func()
func(obj)----20
callfunc(node)-------30
callfunc(node,data)----40--------555555
从结果发现callFunc(ccnode * node)callFunc(CCNode * node,void * data) 这两个对调函数的node 就是对应的sprite3,sprite4即对应的调用者,而callFunc(CCObject *object)object是创建回调的时候,用户自己传进来的sprite2,前边两个函数回调函数的node 默认是执行者sprite,而这个却是自己传过来的,具体原因看下边分析
CCCallFunc CCCallFuncN CCCallFuncND
void CCCallFunc::execute() {
if (m_pCallFunc) {
(m_pSelectorTarget->*m_pCallFunc)();
}
if (m_nScriptHandler) {
CCScriptEngineManager::sharedManager()->getScriptEngine()->executeCallFuncActionEvent(this);
}
}
(m_pSelectorTarget->*m_pCallFunc)();传进来的对象和毁掉函数,直接调用,没有传回任何参数,就如同HelloWorld::callFunc()一样
void CCCallFuncN::execute() {
if (m_pCallFuncN) {
(m_pSelectorTarget->*m_pCallFuncN)(m_pTarget);
}
if (m_nScriptHandler) {
CCScriptEngineManager::sharedManager()->getScriptEngine()->executeCallFuncActionEvent(this, m_pTarget);
}
}
和上边相比多了一个参数m_pTarget,但是其创建的时候却是这样的:
static CCCallFuncN * create(CCObject* pSelectorTarget, SEL_CallFuncN selector);
没有传递参数,那么这个m_pTarget是个什么东东,并且又是从哪来的尼?
通过查找发现这个变量实在CCAction CCTimer类中定义
在CCAction.cpp可以发现m_pTarget其实是动作的执行者
在CCscheduler.cpp中发现m_pTarget其实是计时器的执行者
void CCScheduler::scheduleSelector(SEL_SCHEDULE pfnSelector, CCObject *pTarget, float fInterval, bool bPaused)
{
this->scheduleSelector(pfnSelector, pTarget, fInterval, kCCRepeatForever, 0.0f, bPaused);
}
void CCCallFuncND::execute() {
if (m_pCallFuncND) {
(m_pSelectorTarget->*m_pCallFuncND)(m_pTarget, m_pData);
}
}
定义的时候只传递了m_pData,m_pTarget和上边一样
这就解释了callFunc(ccnode * node)callFunc(CCNode * node,void * data) 这两个对调函数的node 就是对应的sprite3,sprite4即对应的调用者,明明没有传递调用者,回调里边却有调用者
void CCCallFuncO::execute() {
if (m_pCallFuncO) {
(m_pSelectorTarget->*m_pCallFuncO)(m_pObject);
}
}
回调函数传递了m_pObject,即程序员创建回调的时候传递的是什么东西,它就把这个东西毫无变化的传给回调,所以上边例子sprite2出现的情况就很好解释了
对于menuItem创建的时候 指定的回调,用到的menu_selector,对调函数
typedef void (CCObject::*SEL_MenuHandler)(CCObject* pSender);这个pSender其实就是对应的menuItem自己
void CCMenuItem::activate()
{
if (m_bEnabled)
{
if (m_pListener && m_pfnSelector)
{
(m_pListener->*m_pfnSelector)(this);
}
if (kScriptTypeNone != m_eScriptType)
{
CCScriptEngineManager::sharedManager()->getScriptEngine()->executeMenuItemEvent(this);
}
}
}
上边 我感觉已经分析的够详细了,附带参考http://xiandanboke.com.cn/cocos2d-xcccallfunc.html