【cocos2d-x 3.x 学习与应用总结】3: CallFunc系列
来源:互联网 发布:薛之谦淘宝衣服贵吗 编辑:程序博客网 时间:2024/05/17 08:44
前言
前段时间写STL系列的文章的感受是,技术这东西你说深就深,说浅也浅。拿一个STL算法来说,对它的描述可以简单到给出几个示例用法,把代码往上一贴,OK搞定。或者也可以写的深入一些,分析一下它的源代码实现,分析一下它的效率、边界条件检测、线程安全性等等方面,再加上组织语言,一两个小时都是不够的。虽说现在我年纪轻轻,但是空闲时间并不多,而技术的东西实在太多,所以要做到详略得当,把握住重点,不能所有的东西都写的面面俱到。对于有价值的技术点,因为时间有限,我可以先写一下它的基础含义,假设它的深度有七层,我先写到一、二层,以后有时间或者碰巧对它有新的领悟的时候,再来继续在这一点上写,重复这个过程直到完成七层。今天开始《C++ STL学习与应用总结》系列的文章更新频率会开始降低,近期开始重点写cocos的东西了。
今天在YouTube上看到一个非常好的VIM视频,这几天打算录一个翻版分享出来,提醒自己别忘了。
今晚肚子疼头也疼,先挖个坑,明天来填。这篇文章将写一下cocos中的CallFunc系列“动作”用法和注意事项。
现在是2015年最后一天的最后一个小时了,时间不等人,点滴积累要坚持下去。现在开始填昨天的坑。
CallFunc系列对象是Action的一种,具体来说它是瞬时动作(ActionInstant)的一种,其它的瞬时动作还包括Show, Hide, ToggleVisibility, RemoveSelf, FlipX, FlipY, Place等,这么多的瞬时动作,为什么把CallFunc提取出来呢,它有什么好说的呢?
首先是从使用频率上来看的,CallFunc通常和DelayTime一起组成一个Sequence来实现一种延迟调用的效果,这种动作序列在实际开发中很常用。
其次,是从CallFunc的构造方式上来看,它的create方法接受的参数类型比较有代表性。这个参数是一个std::function类型的对象,std::function可以使用C++中任何的Callable来构造,具体包括函数(函数指针,函数引用)、函数对象、闭包(lambda表达式)等一些可调用的对象,这要归功于C++11带来的便利。3.x版本对C++11新特性和标准库的使用使得它比2.x版本在创建回调(包括CallFunc系列, Menu Callback系列, Scheduler系列)方面灵活了很多。这篇文章说CallFunc,也是因为CallFunc的创建方式能很好体现3.x新的创建回调的灵活方式。
前面写的几篇cocos的文章代码示例代码是自己写的,我觉得有些浪费时间,不如直接拿cocos官方示例代码来说,剩下的时间还是自己写游戏更好,在实战中对技术点的体会也会更深刻。
为了不在编写示例代码上花费更多的时间和精力,今后的总结里我会尽可能的使用cocos官方的示例代码。测试代码所在文件路径是相对于cocos2d-x-3.x/tests/cpp-tests/Classes
这个目录的。
CallFunc的基本用法
对CallFunc的使用主要是掌握怎么调用create()方法来创建它,create()方法的原型如下:
// create参数是一个std::function<void()>类型对象的常引用static CallFunc * create(const std::function<void()>& func);
创建std::function
void ActionCallFunction::onEnter(){ ActionsDemo::onEnter(); // 居中放置三个测试用的精灵 centerSprites(3); // 动作序列1: 移动2秒 + 两个CallFunc, // 第一个CallFunc使用bind来构造一个std::function<void()>类型的对象. // 第二个CallFunc使用lambda来构造一个std::function<void()>类型的对象 // 两个CallFunc的回调函数都是一个用一个不带参数的函数来构造的, // 第一个bind,把一个不带参数的成员函数ActionCallFunction::callback1, 适配成std::function<void()>. // 第二个,lambda的定义则直接是一个不带参数的函数, 以引用的方式捕获了外层作用域里的this。 auto action1 = Sequence::create( MoveBy::create(2, Vec2(200,0)), CallFunc::create( std::bind(&ActionCallFunction::callback1, this) ), CallFunc::create( // lambda [&](){ auto s = Director::getInstance()->getWinSize(); auto label = Label::createWithTTF("called:lambda callback", "fonts/Marker Felt.ttf", 16.0f); label->setPosition(s.width/4*1,s.height/2-40); this->addChild(label); } ), nullptr); // 动作序列2: 缩放两秒 + 淡出两秒 + 回调 // 这里的回调是用bind来构造的,bind把一个接收Node*类型形参的成员函数ActionCallFunction::callback2, // 适配成一个CallFunc需要的std::function<void()>类型的对象。 // bind把_tamara绑定到形参Node*上面。 auto action2 = Sequence::create( ScaleBy::create(2 , 2), FadeOut::create(2), CallFunc::create( std::bind(&ActionCallFunction::callback2, this, _tamara) ), nullptr); // 动作序列3: 缩放3秒 + 淡出2秒 + 回调 // 回调同样是使用bind来创建,这次是把一个接收两个参数:Node*和int的成员函数ActionCallFunction::callback3, // 适配成一个std::function<void()>类型的对象 auto action3 = Sequence::create( RotateBy::create(3 , 360), FadeOut::create(2), CallFunc::create( std::bind(&ActionCallFunction::callback3, this, _kathia, 42) ), nullptr); _grossini->runAction(action1); _tamara->runAction(action2); _kathia->runAction(action3);}void ActionCallFunction::callback1(){ auto s = Director::getInstance()->getWinSize(); auto label = Label::createWithTTF("callback 1 called", "fonts/Marker Felt.ttf", 16.0f); label->setPosition(s.width/4*1,s.height/2); addChild(label);}void ActionCallFunction::callback2(Node* sender){ auto s = Director::getInstance()->getWinSize(); auto label = Label::createWithTTF("callback 2 called", "fonts/Marker Felt.ttf", 16.0f); label->setPosition(s.width/4*2,s.height/2); addChild(label); CCLOG("sender is: %p", sender);}void ActionCallFunction::callback3(Node* sender, long data){ auto s = Director::getInstance()->getWinSize(); auto label = Label::createWithTTF("callback 3 called", "fonts/Marker Felt.ttf", 16.0f); label->setPosition(s.width/4*3,s.height/2); addChild(label); CCLOG("target is: %p, data is: %ld", sender, data);}
上面的例子中所有的使用bind来创建回调的地方都可以用这个cocos的一个宏来代替,它就是CC_CALLBACK_0
.
使用CC_CALLBACK_0
来改写上面三个回调的创建:
auto action1 = Sequence::create( MoveBy::create(2, Vec2(200,0)), //CallFunc::create(std::bind(&ActionCallFunction::callback1, this)), 原来的方式 CallFunc::create(CC_CALLBACK_0(ActionCallFunction::callback1, this)), CallFunc::create( // lambda [&](){ auto s = Director::getInstance()->getWinSize(); auto label = Label::createWithTTF("called:lambda callback", "fonts/Marker Felt.ttf", 16.0f); label->setPosition(s.width/4*1,s.height/2-40); this->addChild(label); } ), nullptr); auto action2 = Sequence::create( ScaleBy::create(2 , 2), FadeOut::create(2), //CallFunc::create(std::bind(&ActionCallFunction::callback2, this, _tamara)), 原来的方式 CallFunc::create(CC_CALLBACK_0(ActionCallFunction::callback2, this, _tamara)), nullptr); auto action3 = Sequence::create( RotateBy::create(3 , 360), FadeOut::create(2), //CallFunc::create(std::bind(&ActionCallFunction::callback3, this, _kathia, 42)), 原来的方式 CallFunc::create(CC_CALLBACK_0(ActionCallFunction::callback3, this, _kathia, 42)), nullptr);
关于CC_CALLBACK_0
的使用请参考【cocos2d-x 3.x 学习与应用总结】4: 理解CC_CALLBACK_0, CC_CALLBACK_1, CC_CALLBACK_2, CC_CALLBACK_3.
CallFuncN的基本用法
CallFuncN::create的原型:
static CallFuncN * create(const std::function<void(Node*)>& func);
CallFuncN与CallFunc的区别仅仅在于前者的function回调需要一个Node*类型的参数。
void ActionCallFuncN::onEnter(){ ActionsDemo::onEnter(); centerSprites(1); auto action = Sequence::create( MoveBy::create(2.0f, Vec2(150,0)), CallFuncN::create( CC_CALLBACK_1(ActionCallFuncN::callback, this)), nullptr); _grossini->runAction(action); // 其实,使用CallFunc也能达到这个效果: auto actionUseCallfunc = Sequence::create( MoveBy::create(2.0, Vec2(150, 0)), CallFunc::create( CC_CALLBACK_0(ActionCallFuncN::callback, this, _grossini)), nullptr); _grossini->runAction(actionUseCallfunc);}void ActionCallFuncN::callback(Node* sender ){ auto a = JumpBy::create(5, Vec2(0,0), 100, 5); sender->runAction(a);}
CallFuncND的基本用法
// CallFuncND不再需要了,可以使用std::bind来模拟。// CallFuncND is no longer needed. It can simulated with std::bind()void ActionCallFuncND::onEnter(){ // ActionCallFuncND::doRemoveFromParentAndCleanup本来是需要两个参数:(Node*, bool), 使用CC_CALLBACK_1把第二个参数绑定为true, // 这样就变成了一个仅需要一个Node*参数的函数。 auto action = Sequence::create( MoveBy::create(2.0f, Vec2(200,0)), CallFuncN::create( CC_CALLBACK_1(ActionCallFuncND::doRemoveFromParentAndCleanup, this, true)), nullptr); _grossini->runAction(action);}void ActionCallFuncND::doRemoveFromParentAndCleanup(Node* sender, bool cleanup){ _grossini->removeFromParentAndCleanup(cleanup);}
作者水平有限,对相关知识的理解和总结难免有错误,还望给予指正,非常感谢!
在这里也能看到这篇文章:github博客, CSDN博客, 欢迎访问
- 【cocos2d-x 3.x 学习与应用总结】3: CallFunc系列
- cocos2d-x 3.x CallFunc
- 【cocos2d-x 3.x 学习与应用总结】2: 在cocos2d-x中使用ccbi
- cocos2d-x学习笔记(11)回调CallFunc,lambda
- 【cocos2d-x 2.x 学习与应用总结】12: cocos2d-x预定义shader源码
- 【cocos2d-x 3.x 学习与应用总结】4: 理解CC_CALLBACK_0, CC_CALLBACK_1, CC_CALLBACK_2, CC_CALLBACK_3
- 【cocos2d-x 3.x 学习与应用总结】4: 使用cocos compile编译apk
- 【cocos2d-x 3.x 学习与应用总结】4: 理解CC_CALLBACK_0, CC_CALLBACK_1, CC_CALLBACK_2, CC_CALLBACK_3
- 【cocos2d-x 3.x 学习与应用总结】4: 理解CC_CALLBACK_0, CC_CALLBACK_1, CC_CALLBACK_2, CC_CALLBACK_3
- 【cocos2d-x 学习与应用总结】最近一段时间使用cocos2d-x lua的总结
- 【cocos2d-x 2.x 学习与应用总结】10: cocos2d-x自带的shader及其使用
- cocos2d-x 学习应用
- 【cocos2d-x 2.x 学习与应用总结】11: 理解CCGLProgram
- 【cocos2d-x 2.x 学习与应用总结】13: 借助CCGLProgram实现自定义绘制
- 【cocos2d-x 2.x 学习与应用总结】14: 自定义shader绘制混合颜色的矩形
- Cocos2d-x 3.x 图形学渲染系列总结
- cocos2d-x学习日志(4) -- CCCallFunc系列函数的应用
- Cocos2d-x 3.0final 终结者系列教程18-关于V3中CallFunc::create的新的使用方法
- android之旅17 四大组件之服务基本概念
- response-实现验证码
- Swift 实现 iOS 类似微信输入框跟随键盘弹出的效果
- LeetCode: 008-Contains Duplicate
- 静态成员变量初始化问题
- 【cocos2d-x 3.x 学习与应用总结】3: CallFunc系列
- IM系统框架
- 给JFinal添加 Sqlite 数据库支持
- 点击弹出导航导航按钮菜单
- 两种网络数据格式的比较
- JAVA设计模式单例模式(懒汉式和饿汉式)
- 为什么IT行业仍然这么火?
- python+selenium
- 实现ListView图文混排 ——解析JSON到List中