cocos2d-x 回调函数

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_pDatam_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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值