cocos2dx 3.0 它 使用std::bind更换CC_CALLBACK_N
在cocos2dx 3.0 版本号,回调函数本质4一个CC_CALLBACK_N 替换功能。N的回调函数的参数的数量的代表
1.让我们来看看这些CC_CALLBACK_N怎么用
比方action的回调 ,CC_CALLBACK_0
auto animation = Animation::create();
auto animate = Animate::create(animation);
CallFunc* animateDone = CallFunc::create(CC_CALLBACK_0(PlaneLayer::removePlane,this));
auto sequence = Sequence::create(animate,animateDone,NULL);
sprite1->runAction(sequence); void PlaneLayer::removePlane(){
//.....
}
或者action带一个參数的回调:CC_CALLBACK_1,在这里,pSender就是动作的运行者sprite2
auto actionMove = MoveTo::create(randomDuration, Point(0, 0));
auto actionDone = CallFuncN::create(CC_CALLBACK_1(EnemyLayer::enemy1MoveFinished,this));
auto sequence = Sequence::create(actionMove,actionDone,NULL);
sprite2->runAction(sequence); void EnemyLayer::enemy1MoveFinished(Node* pSender){
Sprite* sprite2 = (Sprite*)pSender;
}
或者button的回调函数:CC_CALLBACK_1
auto pauseNormal = Sprite::create("game_pause_nor.png");
auto pausePressed = Sprite::create("game_pause_pressed.png");
auto menuItem = MenuItemSprite::create(pauseNormal,pausePressed,NULL,CC_CALLBACK_1(ControlLayer::menuPauseCallback,this));
menuItem->setPosition(Point::ZERO);
auto menuPause = Menu::create(menuItem,NULL);
menuPause->setPosition(Point::ZERO);
//回调函数
void ControlLayer::menuPauseCallback(Object* pSender)
{
//....
}
或者touch函数:CC_CALLBACK_2
//单点触摸
virtual bool onTouchBegan(Touch *touch, Event *unused_event);
virtual void onTouchMoved(Touch *touch, Event *unused_event);
virtual void onTouchEnded(Touch *touch, Event *unused_event);
virtual void onTouchCancelled(Touch *touch, Event *unused_event); auto dispatcher = Director::getInstance()->getEventDispatcher();
auto listener = EventListenerTouchOneByOne::create();
listener->onTouchBegan = CC_CALLBACK_2(GameLayer::onTouchBegan,this);
listener->onTouchMoved = CC_CALLBACK_2(GameLayer::onTouchMoved,this);
listener->onTouchEnded = CC_CALLBACK_2(GameLayer::onTouchEnded,this);
listener->setSwallowTouches(true);//不向下传递触摸
dispatcher->addEventListenerWithSceneGraphPriority(listener,this);
2.发现了上面的CallFunc和CallFucnN了没有。恩,先去LOL一把再接着写。
。
回来了。
让我先回口血,恩。接着写...
一般来说:
CallFunc用于 不带參数的,
CallFuncN 用于创建 带一个Node节点參数的,Node*节点參数是动作的运行者
CCCallFuncND 比CallFuncN多了一个參数,能够是随意类型的參数 void *,使用方法看以下
auto animation = AnimationCache::getInstance()->animationByName("Enemy1Blowup");
auto animate = Animate::create(animation);
CCCallFuncND* animateDone = CCCallFuncND::create(this,callfuncND_selector(EnemyLayer::removeEnemy1),(void*)enemy1);
auto sequence = Sequence::create(animate, animateDone,NULL);
Sprite* m_sprite = enemy1->getSprite();
m_sprite ->runAction(sequence);
void EnemyLayer::removeEnemy1(Node* pTarget, void* data){
Sprite* m_sprite = (Sprite*) pTarget; //node节点为动作的运行者
Enemy* enemy1 = (Enemy*)data; //我们传的自己定义数据enemy1
//...
}
事实上上面调用带两个參数的函数的这句代码:
CCCallFuncND* animateDone = CCCallFuncND::create(this,callfuncND_selector(EnemyLayer::removeEnemy1),(void*)enemy1);
我们还能够这样子写:
//写法1
CCCallFuncN* animateDone = CCCallFuncN::create(CC_CALLBACK_1(EnemyLayer::removeEnemy1,this,enemy1));
//写法2
CCCallFunc* animateDone = CCCallFunc::create(CC_CALLBACK_0(EnemyLayer::removeEnemy1,this,enemy1->getSprite(),enemy1));
//写法3,用std::bind
CCCallFuncN* animateDone = CCCallFuncN::create(std::bind(&EnemyLayer::removeEnemy1,this,enemy1->getSprite(),enemy1));
事实上上面的CC_CALLBACK_0 啊CC_CALLBACK_1 啊。都能够类似这么写,非常多种写法。原因是由于CC_CALLBACK_N有一个可变參数宏##__VA_ARGS__。
恩。是不是有点乱。记不住没关系,我也常常没记住,我们来详细看一下CC_CALLBACK_N究竟是神马玩意
// 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__)
是不是看到了std::bind、##__VA_ARGS__、std::placeholders::_1等等。这些都是神马玩意,
先解释一下:
##__VA_ARGS__是可变參数宏
std::placeholders::_1是參数占位符,表示第一个參数。以此类推
那std::bind是神马,不急我们先看一段代码
#include <iostream>
#include <functional>
using namespace std; typedef std::function<void ()> fp;
void g_fun()
{
cout<<"g_fun()"<<endl;
}
class A
{
public:
static void A_fun_static()
{
cout<<"A_fun_static()"<<endl;
}
void A_fun()
{
cout<<"A_fun()"<<endl;
}
void A_fun_int(int i)
{
cout<<"A_fun_int() "<<i<<endl;
} void A_fun_int_double(int i,int p)
{
cout<<"A_fun_int_double ()"<<i<<","<<p<<endl;
} //非静态类成员。由于含有this指针,所以须要使用bind
void init()
{
//绑定不带參数的函数
fp fp1=std::bind(&A::A_fun,this);
fp1();
} void init2()
{
typedef std::function<void (int)> fpi;
//绑定带一个參数的函数
fpi f=std::bind(&A::A_fun_int,this,std::placeholders::_1);//參数要使用占位符 std::placeholders::_1表示第一个參数
f(5);
} void init3(){
typedef std::function<void (int,double)> fpid;
//绑定带两个參数的函数
fpid f=std::bind(&A::A_fun_int_double,this,std::placeholders::_1,std::placeholders::_2);
f(5,10);
}
};
int main()
{
//绑定到全局函数
fp f2=fp(&g_fun);
f2(); //绑定到类静态成员函数
fp f1=fp(&A::A_fun_static);
f1(); A().init();
A().init2();
A().init3();
return 0;
}
然后看一下输出结果:
g_fun()
A_fun_static()
A_fun()
A_fun_int() 5
A_fun_int_double ()5,10
再解释一下:
std::function --> 绑定到全局函数/类静态成员函数(类静态成员函数与全局函数没有差别)
std::bind --> 绑定到类的非静态成员函数
到这里是不是有豁然开朗的感觉呢。哈哈,知道了bind函数怎么用。然后我们就能够使用std::bind替换CC_CALLBACK_N写法了
3.使用std:bind函数替换CC_CALLBACK_N:
比方我们要替换CC_CALLBACK_0
auto animation = Animation::create();
auto animate = Animate::create(animation);
//CallFunc* animateDone = CallFunc::create(CC_CALLBACK_0(PlaneLayer::removePlane,this));
CallFunc* animateDone = CallFunc::create(std::bind(&PlaneLayer::removePlane,this));//替换
auto sequence = Sequence::create(animate,animateDone,NULL);
sprite1->runAction(sequence); void PlaneLayer::removePlane(){
//.....
}
比方我们要替换带一个參数的CC_CALLBACK_1
auto actionMove = MoveTo::create(randomDuration, Point(0, 0));
//auto actionDone = CallFuncN::create(CC_CALLBACK_1(EnemyLayer::enemy1MoveFinished,this));
auto actionDone = CallFuncN::create(std::bind(&EnemyLayer::enemy1MoveFinished,this,enemy1));//替换
auto sequence = Sequence::create(actionMove,actionDone,NULL);
sprite2->runAction(sequence); void EnemyLayer::enemy1MoveFinished(Node* pSender){
Sprite* sprite2 = (Sprite*)pSender;
}
再比方调用两个參数的...
auto animation = AnimationCache::getInstance()->animationByName("Enemy1Blowup");
auto animate = Animate::create(animation);
//CCCallFuncND* animateDone = CCCallFuncND::create(this,callfuncND_selector(EnemyLayer::removeEnemy1),(void*)enemy1);
CCCallFuncN* animateDone = CCCallFuncN::create(std::bind(&EnemyLayer::removeEnemy1,this,enemy1->getSprite(),enemy1));//替换
auto sequence = Sequence::create(animate, animateDone,NULL);
Sprite* m_sprite = enemy1->getSprite();
m_sprite ->runAction(sequence);
void EnemyLayer::removeEnemy1(Node* pTarget, void* data){
Sprite* m_sprite = (Sprite*) pTarget; //node节点为动作的运行者
Enemy* enemy1 = (Enemy*)data; //我们传的自己定义数据enemy1
//...
}
哈哈,这下子非常清楚了吧。。再也不会混乱了。。
版权声明:本文博客原创文章,博客,未经同意,不得转载。
cocos2dx 3.0 它 使用std::bind更换CC_CALLBACK_N的更多相关文章
- cocos2dx[3.2](9) 新回调函数std::bind
自从3.0引用了C++11标准后,回调函数采用的新的函数适配器:std::function.std::bind. 而曾经的回调函数menu_selector.callfunc_selector.ccc ...
- C++11中std::bind的使用
std::bind: Each argument may either be bound to a value or be a placeholder: (1).If bound to a value ...
- c++11特性与cocos2d-x 3.0之std::bind与std::function
昨天同事让帮忙写一小功能,才发现cocos2d-x 3.0 和 cocos2d-x 3.0rc0 差别还是相当大的. 发现Label这一个控件,3.0就比rc0版本多了一个创建函数,更为关键的是3.0 ...
- Cocos2dx 3.0 过渡篇(二十六)C++11多线程std::thread的简单使用(上)
昨天练车时有一MM与我交替着练,聊了几句话就多了起来,我对她说:"看到前面那俩教练没?老色鬼两枚!整天调戏女学员."她说:"还好啦,这毕竟是他们的乐趣所在,你不认为教练每 ...
- cocos2d-x 3.0 事件处理
參考文章: star特530的CSDN博客:http://blog.csdn.net/star530/article/details/18325493 https://github.com/chuko ...
- cocos2d-x 3.0点击响应
迄今为止,发现cocos2d-x 3.0最让人惊艳的地方就是更改了点击事件机制.(ps:迄今只看了点击事件这块,捂嘴笑~~~) cocos2d-x 2.0 只有CCLayer有点击事件处理,需要注册, ...
- Cocos2d-x 3.0 屏幕触摸及消息分发机制
***************************************转载请注明出处:http://blog.csdn.net/lttree************************** ...
- C++11中的std::bind
C++11中的std::bind 最近在看看cocos2dx的源代码,发现了cocos2dx 3.0相对于2.0改动了很多,最大的改变就是大量的使用了C++11的特性,比如auto等.其中有一个关于回 ...
- 【浅析C++11】std::function和std::bind
目录 std::function可调用对象包装器 std::function基本用法 std::function/std::bind与抽象工厂.工厂方法的一点思考 std::function可调用对象 ...
随机推荐
- A simple Test Client built on top of ASP.NET Web API Help Page
Step 1: Install the Test Client package Install the WebApiTestClient package from the NuGet Package ...
- 【SQL】Oracle的PL/SQL语法及其拓展数据类型总结
PL/SQL语法 PL/SQL程序由三部分组成,声明部分.执行部分.异常处理部分. 模板: DECLARE /*变量声明*/ BEGIN /*程序主体*/ EXCEPTION /*异常处理部分*/ E ...
- 在Sql中使用Try Catch
原文:在Sql中使用Try Catch 今天在写sql中出现了!我想在sql使用trycatch吧! 哎..但是语法又记不住了! 那就清楚我们的google大师吧! 嘿,网上关于在sql中使用Try ...
- SQL Server -减少代码触发的负担
触发器是一张表的增删改操作,引起或触发对还有一张表的增删改操作,所以触发器便有3种类型.各自是deleted触发器.Update触发器,insert触发器 触发器又依据替换原来的增删改操作,还是在原来 ...
- mouseover与mouseenter与mousemove差额mouseout与mouseleave差额
<1> HTML <html> <head> <title></title> </head> <body> < ...
- C#内存分配学习
CLR内存分配分三大块区域:栈.GC堆.大对象堆. 一.线程堆栈(栈) 用于分配值类型实例.栈由操作系统进行管理,不受GC管理,当值类型不在其作用域(主要是指其所在函数内)时,其所占栈空间自动释放.栈 ...
- 第十六章——处理锁、阻塞和死锁(3)——使用SQLServer Profiler侦测死锁
原文:第十六章--处理锁.阻塞和死锁(3)--使用SQLServer Profiler侦测死锁 前言: 作为DBA,可能经常会遇到有同事或者客户反映经常发生死锁,影响了系统的使用.此时,你需要尽快侦测 ...
- hdu1381 Crazy Search(hash map)
题目意思: 给出一个字符串和字串的长度,求出该字符串的全部给定长度的字串的个数(不同样). 题目分析: 此题为简单的字符串哈hash map问题,能够直接调用STL里的map类. map<str ...
- netback于kthread遇到cpu affinity问题
最近的升级netback, 在测试过程中,查找vm全双工压力,rx的pps波动很厉害,见rx kthread尽管cpu affinity它是0-7 (dom0 8vcpu), 但往往,她去了物理破坏c ...
- WPF学习(7)命令
在上一篇中,我们学习了WPF的路由事件,而在本节将学习一个更为抽象且松耦合的事件版本,即命令.最明显的区别是,事件是与用户动作相关联的,而命令是那些与用户界面想分离的动作,例如我们最熟悉的剪切(Cut ...