cocos2dx[3.2](9) 新回调函数std::bind
自从3.0引用了C++11标准后,回调函数采用的新的函数适配器:std::function、std::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);
}
//
cocos2dx[3.2](9) 新回调函数std::bind的更多相关文章
- cocos2dx[3.2](10) 新回调函数std::bind
在2.x中处理事件需要用到委托代理(delegate),相信学过2.x的触摸事件的同学,都知道创建和移除的流程十分繁琐. 而在3.x中由于加入了C++11的特性,而对事件的分发机制通过事件分发器Eve ...
- C++ 11新特性:std bind 原理简单图解(转载)
本文解释了bind 是如何工作的.为了清晰,我对图中的语法作了一些简化(例如,省略函数调用操作符的参数类型),并且简化了 bind 的实现. bind 可以用来将用户提供的需要一个参数的函数转换成不需 ...
- cocos2dx 3.0 它 使用std::bind更换CC_CALLBACK_N
在cocos2dx 3.0 版本号,回调函数本质4一个CC_CALLBACK_N 替换功能.N的回调函数的参数的数量的代表 1.让我们来看看这些CC_CALLBACK_N怎么用 比方action的回调 ...
- [C/C++11]_[初级]_[std::bind介绍和使用]
场景 1.C++11 引入了std::function 对象, 这个对象可以通过std::bind封装所有的函数, 并通过代理调用这个std::function的方式调用这个函数. 比如通过统一的方式 ...
- cocos2d-x 2.2.0 如何在lua中注册回调函数给C++
cocos2d-x内部使用tolua进行lua绑定,但是引擎并没有提供一个通用的接口让我们可以把一个lua函数注册给C++层面的回调事件.翻看引擎的lua绑定代码,我们可以仿照引擎中的方法来做.值得吐 ...
- 【Cocos2d-x 3.0 基础系列一】 各类回调函数写法汇总
一.button回调 1. Lambda 表达式,C++11 Lambda 赋予了Cocos2d-x 3.0创建回调函数的灵活性. auto itemNor = Sprite::create(&quo ...
- cocos2d-x 2.2.0 怎样在lua中注冊回调函数给C++
cocos2d-x内部使用tolua进行lua绑定.可是引擎并没有提供一个通用的接口让我们能够把一个lua函数注冊给C++层面的回调事件. 翻看引擎的lua绑定代码,我们能够仿照引擎中的方法来做. 值 ...
- cocos2dx中的假动作,又称动作回调函数
1.动作与动画的区别 动作是:定时器+属性的改变,是帧循环的累积效应 动画是:帧图片的播放效果,我们知道电影的播放就是快速播放的胶片,这就是动画的原理 2.假动作:又称动作回调函数 四大类假动作: c ...
- Cocos2d-x 3.0中 物理碰撞检測中onContactBegin回调函数不响应问题
好吧,事实上这篇也是暂时冒出来的,近期朋友要做个物理游戏,曾经做物理还是用box2d,呃.确实要花些功夫才干搞懂当中的精髓,可是听讲这套引擎又一次封装了一次.要easy非常多,所以就简单尝试了一下,感 ...
随机推荐
- 4.3 jmu-Java-03面向对象-06-继承覆盖综合练习-Person、Student、Employee、Company (20 分)中的一些问题
1.Employee类的equals 由于题目要求//首先调用父类的equals方法,如果返回true.再比较company与salary.//比较salary属性时,使用DecimalFormat ...
- ES修改最大分页数
curl -XPUT http://localhost:9200/my_index/_settings?preserve_existing=true -H 'Content-Type: applica ...
- 乱花渐入迷人眼------从解决jqueryEasyUI上传插件提交ajax请求谈网页调试
由于要给格斗男神写搏击俱乐部ERP系统,就要用到jquery Easyui插件规范数据和表单的录入,其中一项功能就是上传商品图片, 而且是在datagrid-detailview中使用filebox完 ...
- printf计算参数是从右到左压栈的(a++和++a的压栈的区别)
一.问题 c++代码: #include <iostream> #include <stdio.h> using namespace std; int main(){ ; co ...
- electron限制只启动一个应用
electron限制只启动一个应用 // ========================================================== // 限制只可以打开一个应用,2.x的文 ...
- JavaScript 函数——语法,调用,返回值,局部变量,全局变量,未声明变量
JavaScript 函数是被设计为执行特定任务的代码块. JavaScript 函数会在某代码调用它时被执行. ㈠函数 ⑴什么是函数 函数是由事件驱动的或者当它被调用时执行的可重复使用的代码块. ⑵ ...
- HTML标签与属性
HTML中常用的一些标签和属性. 1.lang属性:搜索引擎 en:英文, zh:中文 2.meta:元数据 charset属性:字符集编码方式 3.h1~h6:标题 一级标题 ...
- 关系型数据库(四),引擎MyISAM和InnoDB
目录 1.MyISAM和InnoDB关于锁方面的区别是什么 2.MYSQL的两个常用存储引擎 3.MyISAM应用场景 4.InnoDB适合场景 四.引擎MyISAM和InnoDB 1.MyISAM和 ...
- poj 2559 Largest Rectangle(单调栈)
Largest Rectangle in a Histogram Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 26549 ...
- 微信支付(公众号)爬坑记,包含 total_fee 失败和 JSAPI 签名验证失败等等
做商城类网站不免会需要做支付功能,目前在中国大陆通用的做法就是使用支付宝支付和微信支付,上一篇博文已经讲个支付宝支付. 这篇文章来讲一讲微信支付,微信支付的方式有很多种,本文主要讲 JSAPI 支付的 ...