加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

cocos2dx3.0自定义回调函数,传递自己想要的参数

发布时间:2020-12-14 20:19:17 所属栏目:百科 来源:网络整理
导读:近日 ,由于自己需要用到一个特效道具,show完特效后会删除场上几个同一类的精灵,为避免同时使用这两个道具时,产生冲突,导致前一个特效的精灵未被删除,所以想了个自定义回调函数的方法,众所周知,定义一个回调函数的用法大致是: __String* draw = __Str

近日,由于自己需要用到一个特效道具,show完特效后会删除场上几个同一类的精灵,为避免同时使用这两个道具时,产生冲突,导致前一个特效的精灵未被删除,所以想了个自定义回调函数的方法,众所周知,定义一个回调函数的用法大致是:

__String* draw = __String::create("1");
    draw->retain();
    for (auto sprite : _sp)
    {
        i++;
        auto time=DelayTime::create(0.002f * i);
        auto call = __CCCallFuncND::create(this,callfuncND_selector(gameLayer::showLine),draw);//callfuncND_selector算是一个比较常见的,传递一个void类型的参数

        sprite->setTag((int)_sp.size());
        sprite->runAction(Sequence::create(time,call,NULL));
    }

但是翻遍底层逻辑,回调函数里边并不支持别的类型,转到callfuncND_selector的定义处,我们可以清楚的看到:

class Node;

typedef void (Ref::*SEL_CallFunc)();
typedef void (Ref::*SEL_CallFuncN)(Node*);
typedef void (Ref::*SEL_CallFuncND)(Node*,void*);
typedef void (Ref::*SEL_CallFuncO)(Ref*);
typedef void (Ref::*SEL_MenuHandler)(Ref*);
typedef void (Ref::*SEL_SCHEDULE)(float);

#define callfunc_selector(_SELECTOR) static_cast<cocos2d::SEL_CallFunc>(&_SELECTOR)
#define callfuncN_selector(_SELECTOR) static_cast<cocos2d::SEL_CallFuncN>(&_SELECTOR)
#define callfuncND_selector(_SELECTOR) static_cast<cocos2d::SEL_CallFuncND>(&_SELECTOR)
#define callfuncO_selector(_SELECTOR) static_cast<cocos2d::SEL_CallFuncO>(&_SELECTOR)
#define menu_selector(_SELECTOR) static_cast<cocos2d::SEL_MenuHandler>(&_SELECTOR)
#define schedule_selector(_SELECTOR) static_cast<cocos2d::SEL_SCHEDULE>(&_SELECTOR)

其中只支持void,node,ref以及float等类型,而我现在需要一个能够传递Vector的回调函数,所以只有自己重写一个了,因为正好callfuncND_selector满足我需要的格式,传递一个psender,以及一个void类型的函数,所以可以抄袭这个类:

class CC_DLL  __CCCallFuncND : public CallFunc
{
public:
    /** creates the action with the callback and the data to pass as an argument */
    CC_DEPRECATED_ATTRIBUTE static __CCCallFuncND * create(Ref* target,SEL_CallFuncND selector,void* d);
    
    //
    // Overrides
    //
	virtual __CCCallFuncND* clone() const override;
    virtual void execute() override;
    
protected:
    __CCCallFuncND() {}
    virtual ~__CCCallFuncND() {}
    
    /** initializes the action with the callback and the data to pass as an argument */
    bool initWithTarget(Ref* target,void* d);

    SEL_CallFuncND _callFuncND;
    void* _data;

private:
    CC_DISALLOW_COPY_AND_ASSIGN(__CCCallFuncND);
};

将自己需要的回调函数重写:

//重写动作回调函数
typedef void (Ref::*ZYFun)(Node*,Vector<Mysprite*>);//将ZYFun声明为带node,和一个容器的函数,其中Mysprite是我自定义的类,继承自Sprite
#define zy_selector(_SELECTOR) static_cast<::ZYFun>(&_SELECTOR)//再宏定义zy_selector回调形式
class CC_DLL  __ZYCallFuncND : public CallFunc  //重写回调函数的类,取名叫__ZYcallFuncND类似<span style="font-family: Menlo;">__CCCallFuncND</span>
{
public:
//    CC_DEPRECATED_ATTRIBUTE
    static __ZYCallFuncND * create(Ref* target,ZYFun selector,Vector<Mysprite*> d);//将参数换成自己的,传递的内容换成自定义的容器形式
    virtual __ZYCallFuncND* clone() const override;
    virtual void execute() override;
    
protected:
    __ZYCallFuncND() {}
    virtual ~__ZYCallFuncND() {}
    
    /** initializes the action with the callback and the data to pass as an argument */
    bool initWithTarget(Ref* target,Vector<Mysprite*> d);
    
    ZYFun _callFuncND;
    Vector<Mysprite*> _data;
    
private:
    CC_DISALLOW_COPY_AND_ASSIGN(__ZYCallFuncND);
};
再看下cpp文件:

//__ZYCallFuncND自定义的回调函数
__ZYCallFuncND * __ZYCallFuncND::create(Ref* target,Vector<Mysprite*> d)
{
    __ZYCallFuncND* ret = new __ZYCallFuncND();
    
    if (ret && ret->initWithTarget(target,selector,d))
    {
        ret->autorelease();
        return ret;
    }
    
    CC_SAFE_DELETE(ret);
    return nullptr;
}

bool __ZYCallFuncND::initWithTarget(Ref* target,Vector<Mysprite*> d)
{
    if (CallFunc::initWithTarget(target))
    {
        _data = d;
        _callFuncND = selector;
        return true;
    }
    
    return false;
}

void __ZYCallFuncND::execute()
{
    if (_callFuncND)
    {
        (_selectorTarget->*_callFuncND)(_target,_data);
    }
}

__ZYCallFuncND * __ZYCallFuncND::clone() const
{
    // no copy constructor
    auto a = new __ZYCallFuncND();
    
    if( _selectorTarget)
    {
        a->initWithTarget(_selectorTarget,_callFuncND,_data);
    }
    
    a->autorelease();
    return a;
}

最后你就可以使用自己的回调函数形式,顺利的传入自己的容器了:

if (_spp.size()>0)
    {
        auto call = __ZYCallFuncND::create(this,zy_selector(gameLayer::boomefover),_spp);
        auto timee=DelayTime::create(0.3);
        this->runAction(Sequence::create(timee,NULL));
    }

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读