• cocos2dx[3.2](9) 新回调函数std::bind


        自从3.0引用了C++11标准后,回调函数采用的新的函数适配器:std::functionstd::bind

        而曾经的回调函数menu_selector、callfunc_selector、cccontrol_selector等都已经被无情的抛弃了。

        取而代之的则是一系列的CC_CALLBACK_*

    【致谢】

        http://blog.csdn.net/crayondeng/article/details/18767407

        http://blog.csdn.net/star530/article/details/21245565


    【std::bind】

    0、std::bind

        请参照上面两篇文章。   

    1、CC_CALLBACK_*

        cocos2dx总共使用了4个std::bind的宏定义,其重点就在于使用了std::bind进行函数适配

        > std::placeholders::_1 :不定参数。不事先指定,而是在调用的时候传入。

        > ##__VA_ARGS__         :可变参数列表。

    //
    // new callbacks based on C++11
    #define CC_CALLBACK_0(__selector__,__target__, ...) std::bind(&__selector__,__target__, ##__VA_ARGS__)
    #define CC_CALLBACK_1(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, ##__VA_ARGS__)
    #define CC_CALLBACK_2(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, std::placeholders::_2, ##__VA_ARGS__)
    #define CC_CALLBACK_3(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, ##__VA_ARGS__)
    //

    2、变更的回调函数

        > 动作函数  :CallFunc/CallFuncN

                      callfunc_selector / callfuncN_selector / callfuncND_selector

        > 菜单项回调menu_selector

        > 触摸事件  onTouchBegan / onTouchMoved / onTouchEnded

      2.1、动作函数CallFunc

        可以直接使用CC_CALLBACK_0、CC_CALLBACK_1,也可以直接使用std::bind。

        > CallFunc :使用CC_CALLBACK_0。不带任何不定参数。

        > CallFuncN:使用CC_CALLBACK_1。需要默认传入不定参数 placeholders::_1,其值为:调用该动作的对象(如sprite->runAction(callfun),那么默认的一个不定参数 _1 为 sprite)。

    //
    /**
     *	函数动作
     *		- CallFunc
     *		- CallFuncN
     *		- CallFuncND与CallFuncO已被遗弃,请使用CallFuncN替代
     */
    //2.x版本
    	CallFunc::create    (this, callfunc_selector  (HelloWorld::callback0) );
    	CCCallFuncN::create (this, callfuncN_selector (HelloWorld::callback1) );
    	CCCallFuncND::create(this, callfuncND_selector(HelloWorld::callback2), (void *)10 );
    	
    	//回调函数
    	void HelloWorld::callback0() { }                     //CCCallFunc回调函数
    	void HelloWorld::callback1(CCNode* node) { }         //CCCallFuncN回调函数
    	void HelloWorld::callback2(CCNode* node,void* a) { } //CCCallFuncND回调函数,参数必须为void*
    
    
    //3.x版本
    	//使用 CC_CALLBACK_*
    	CallFunc::create ( CC_CALLBACK_0(HelloWorld::callback0, this) );
    	CallFuncN::create( CC_CALLBACK_1(HelloWorld::callback1, this) );
    	CallFuncN::create( CC_CALLBACK_1(HelloWorld::callback2, this, 0.5));
    	
    	//使用 std::bind
    	//其中sprite为执行动作的精灵
    	CallFunc::create (std::bind(&HelloWorld::callback0, this ) );
    	CallFuncN::create(std::bind(&HelloWorld::callback1, this, sprite);
    	CallFuncN::create(std::bind(&HelloWorld::callback2, this, sprite, 0.5));
    	
    	//回调函数
    	void HelloWorld::callback0() { }
    	void HelloWorld::callback1(Node* node) { }
    	void HelloWorld::callback2(Node* node, float a) { }	//可自定义参数类型float
    	
    //

        

        当然,如果你对于std::bind很熟悉的话,对于CallFunc、CallFuncN回调函数的绑定,也可以全部都使用std::bind。

        如下所示:

    //
    	//callback0
    	CallFunc::create(std::bind(&HelloWorld::callback0, this));
    	
    	//callback1
    	CallFunc::create (std::bind(&HelloWorld::callback1, this, sprite));
    	CallFuncN::create(std::bind(&HelloWorld::callback1, this, std::placeholders::_1));
    
    	//callback2
    	CallFunc::create (std::bind(&HelloWorld::callback2, this, sprite, 0.5));
    	CallFuncN::create(std::bind(&HelloWorld::callback2, this, std::placeholders::_1, 0.5));
    	
    
    	//回调函数
    	void HelloWorld::callback0() { }
    	void HelloWorld::callback1(Node* node) { }
    	void HelloWorld::callback2(Node* node, float a) { }	//可自定义参数类型float
    //

      2.2、菜单项回调menu_selector

        使用CC_CALLBACK_1,也可以直接使用std::bind。

    //
    //2.x版本
    	MenuItemImage::create("1.png", "2.png", this, menu_selector(HelloWorld::callback));
    	
    	
    //3.x版本
    	//CC_CALLBACK_1
    	MenuItemImage::create("1.png", "2.png", CC_CALLBACK_1(HelloWorld::callback1, this));
    	//std::bind
    	MenuItemImage::create("1.png", "2.png", std::bind(&HelloWorld::callback1, this, std::placeholders::_1));
    
    		
    //回调函数
    	void HelloWorld::callback(Node* sender) { }
    //

      2.3、触控事件回调

        使用CC_CALLBACK_2

    //
    	//创建一个事件监听器类型为 单点触摸
    	auto touchLisner = EventListenerTouchOneByOne::create();
    
    	//绑定事件
    	touchLisner->onTouchBegan = CC_CALLBACK_2(HelloWorld::onTouchBegan, this);
    	touchLisner->onTouchMoved = CC_CALLBACK_2(HelloWorld::onTouchMoved, this);
    	touchLisner->onTouchEnded = CC_CALLBACK_2(HelloWorld::onTouchEnded, this);
    
    	//回调函数
    	virtual bool HelloWorld::onTouchBegan(Touch *touch, Event *unused_event); 
    	virtual void HelloWorld::onTouchMoved(Touch *touch, Event *unused_event); 
    	virtual void HelloWorld::onTouchEnded(Touch *touch, Event *unused_event);
    //

    3、未变更的回调函数

      3.1、定时器回调schedule_selector

        依旧使用schedule_selector

    //
    	//定时器
    	schedule(schedule_selector(HelloWorld::update), 1.0/60.0);
    
    	//回调函数
    	void HelloWorld::update(float dt) { }
    //

      3.2、按钮事件回调cccontrol_selector

        依旧使用cccontrol_selector

    //
    	//按钮事件绑定
    	button->addTargetWithActionForControlEvents(this, cccontrol_selector(HelloWorld::callback), Control::EventType::TOUCH_DOWN);
    	
    	//回调函数
    	void HelloWorld::callback(Node* sender, Control::EventType controlEvent) { }
    //

    4、扩展回调函数

        在3.x版本中,事件的回调函数可以带任意个自定义的参数啦。

        举个栗子:(以菜单项回调函数为例)

            请看回调函数callback4。

    //
    	auto sprite = Sprite::create("CloseNormal.png");
    	sprite->setPosition(Vec2(visibleSize / 2) );
    	this->addChild(sprite);
    
    
    	auto itemImage = MenuItemImage::create(
    				"CloseNormal.png", 
    				"CloseNormal.png", 
    				std::bind(&HelloWorld::callback4, this, std::placeholders::_1, sprite, 10, 0.5));
    	itemImage->setPosition(Vec2(visibleSize / 4));
    	auto pMenu = Menu::create(itemImage, NULL);
    	pMenu->setPosition(Vec2::ZERO);
    	this->addChild(pMenu);
    	
    	
    	//回调函数
    	void HelloWorld::callback4(Node* sender, Sprite* bg, int a, float b)
    	{
    		bg->setScale(a * b);
    	}
    //
  • 相关阅读:
    TOJ 2776 CD Making
    int型、long型和long long型
    Hadoop HA- hadoop集群部署
    大数据之路- Hadoop环境搭建(Linux)
    Hadoop HA- zookeeper安装配置
    Zookeeper- Error contacting service. It is probably not running解决方案和原理
    大数据- 自定义Log4j日记
    Hadoop- Hadoop环境搭建
    域名解析
    JAVA- JDBC之DBHelper
  • 原文地址:https://www.cnblogs.com/lmx282110xxx/p/10798688.html
Copyright © 2020-2023  润新知