cocos2d-x 3.1.1 学习笔记[17] 关于这些活动功能
供cocos2d-x通常使用的方法,我有一个好脸色。这项研究真的奖励。
向导首先,定义,实施一系列连续动作。
对于我们的行动能回调函数,我们必须申报并加以实施。
void callBack();
void callBack_1(Node* node);
void callBack_2(Node* node,const char* str); void Nice::callBack()
{
log("Nice::callBack()");
}
void Nice::callBack_1(Node* node)
{
log("This tag is %d",node->getTag());
}
void Nice::callBack_2(Node* node,const char* str)
{
log("This tag is %d, and str is %s",node->getTag(), str);
} //然后就開始创建我们伟大的精灵了。
sp_area = Sprite::create("newAlwaysShow.png");//sp_area is a class member ,Sprite* ap_area;
sp_area->setTag(1314);
auto sp_another = Sprite::create();
sp_another->setTag(520);
addChild(sp_another);
addChild(sp_area);
//翻滚吧。可爱的精灵们!
/*
CallFunc 创建的函数必须是无參数的
CallFuncN 创建的函数能够是一个至多个參数
*/
sp_area->runAction(Sequence::create(MoveTo::create(2, Vec2(200, 200)),
CallFunc::create(CC_CALLBACK_0(Nice::callBack, this)),
CallFuncN::create(CC_CALLBACK_1(Nice::callBack_2, this, "I have tow parameter")),
NULL));
//这样写完之后。发现runAction里面的东西好平淡(平淡有时候才不是真呢! ),于是我就瞎写一通。残忍的把它变成了这个样子。
sp_area->runAction(Sequence::create(MoveTo::create(2, Vec2(200, 200)),
CallFunc::create(CC_CALLBACK_0(Nice::callBack, this)),
CallFunc::create([&]()->void{log("Done1");log("This tag is %d", sp_area->getTag());}),
CallFunc::create(std::bind(&Nice::callBack, this)),
CallFuncN::create(CC_CALLBACK_1(Nice::callBack_1, this)),//1314
CallFuncN::create(CC_CALLBACK_0(Nice::callBack_1, this, sp_another)),//520
CallFuncN::create([](Node* node){log("this tag is %d", node->getTag());}),//1314
CallFuncN::create(std::bind(&Nice::callBack_1, this, sp_area)),//1314
CallFuncN::create(std::bind(&Nice::callBack_1, this, sp_another)),//520
CallFuncN::create(CC_CALLBACK_1(Nice::callBack_2, this, "I have tow parameter")),
NULL));
好吧,他如今已经面目全非了。事实上这么多行也仅仅是用到了两种方法而已,第一种lambda表达式。另外一种std::bind()。
(尼玛,你在逗我吗?不是还有CC_CALLBACK_0吗?)
额。既然这样就让我们来看下源代码吧。
// 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勾搭在一起了!
我们来看下这个到处勾搭的宏是怎么定义的~~~
#define CC_CALLBACK_0(__selector__,__target__, ...) std::bind(&__selector__,__target__, ##__VA_ARGS__)
#define CC_CALLBACK_0( 方法,目标, 可变參数) std::bind(&取方法的地址,目标, 可变參数)
PS:在定义宏的时候是不能用...来当作前面的...作为可变參数的,必需要使用##__VA_ARGS__这个伟大的第三者来替换掉
可变參数在整个cocos-x中也还是用到非常多的。比方创建Sequence::create就是运动了,不然你怎么能在创建一连串的动作的时候传入那么多的參数的说。
那么接下来就来看看源代码吧。
(又是源代码- -)
Sequece::create是分平台实现的(分为win和其它) #if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
// WP8 in VS2012 does not support nullptr in variable args lists and variadic templates are also not supported
typedef FiniteTimeAction* M;
static Sequence* create(M m1, std::nullptr_t listEnd) { return variadicCreate(m1, NULL); }
static Sequence* create(M m1, M m2, std::nullptr_t listEnd) { return variadicCreate(m1, m2, NULL); }
static Sequence* create(M m1, M m2, M m3, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, NULL); }
static Sequence* create(M m1, M m2, M m3, M m4, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, m4, NULL); }
static Sequence* create(M m1, M m2, M m3, M m4, M m5, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, m4, m5, NULL); }
static Sequence* create(M m1, M m2, M m3, M m4, M m5, M m6, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, m4, m5, m6, NULL); }
static Sequence* create(M m1, M m2, M m3, M m4, M m5, M m6, M m7, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, m4, m5, m6, m7, NULL); }
static Sequence* create(M m1, M m2, M m3, M m4, M m5, M m6, M m7, M m8, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, m4, m5, m6, m7, m8, NULL); }
static Sequence* create(M m1, M m2, M m3, M m4, M m5, M m6, M m7, M m8, M m9, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, m4, m5, m6, m7, m8, m9, NULL); }
static Sequence* create(M m1, M m2, M m3, M m4, M m5, M m6, M m7, M m8, M m9, M m10, std::nullptr_t listEnd) { return variadicCreate(m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, NULL); } // On WP8 for variable argument lists longer than 10 items, use the other create functions or variadicCreate with NULL as the last argument
static Sequence* variadicCreate(FiniteTimeAction* item, ...);
#else
static Sequence* create(FiniteTimeAction *action1, ...) CC_REQUIRES_NULL_TERMINATION;
#endif Sequence* Sequence::create(FiniteTimeAction *action1, ...)
{
va_list params;
va_start(params, action1); Sequence *ret = Sequence::createWithVariableList(action1, params);//传给了createWithVariableList让他来处理 va_end(params); return ret;
} Sequence* Sequence::createWithVariableList(FiniteTimeAction *action1, va_list args)
{
FiniteTimeAction *now;
FiniteTimeAction *prev = action1;
bool bOneAction = true; while (action1)
{
now = va_arg(args, FiniteTimeAction*);
//假设第二个动作存在
if (now)
{
prev = createWithTwoActions(prev, now);
bOneAction = false;
}
//假设第二个动作不存在
else
{
// If only one action is added to Sequence, make up a Sequence by adding a simplest finite time action.
if (bOneAction)
{
prev = createWithTwoActions(prev, ExtraAction::create());
}
break;
}
} return ((Sequence*)prev);
}
我们就依照他的思路来实现一个可变參数的函数
void manyArgument(int num, ...);
void Nice::manyArgument(int num, ...)
{
va_list params;
//va_start函数的第二个參数要和manyArgument的第一个參数一样
va_start(params, num); int now;
log("fist is %d", num);
while (true)
{
now = va_arg(params, int);
if (now != -1)
{
log("now is %d", now);
}
else
{
break;
}
} va_end(params);
}
manyArgument(1, 2, 3, 4, -1);
能够发现多个參数的的时候必需要有一个能够终止的条件(比如最后一个为-1)。可是假设在中途就要传入-1怎么办?
这个时候仅仅能把传入的參数改为int*
void manyArgument(int* num, ...);
然后再把最后终止的条件换为!= null,可是这样在传入參数的时候就麻烦(有得必有失)
void manyArgument(int* num, ...);
void Nice::manyArgument(int* num, ...)
{
va_list params;
//va_start函数的第二个參数要和manyArgument的第一个參数一样
va_start(params, num); int* now;
log("fist is %d", *num);
while (true)
{
now = va_arg(params, int*);
if (now != nullptr)
{
log("now is %d", *now);
}
else
{
break;
}
} va_end(params);
}
int arr[] {3,6,9,12};
manyArgument(arr, arr+1, arr+2, arr+3, nullptr);
接着试试定义一个可变參数得宏 ##__VA_ARGS__ 就代表着前面传入进来的可变參数
#define MANYARGUMENT(__num__, ...) manyArgument(__num__, ##__VA_ARGS__)
MANYARGUMENT(arr, arr+1, arr+2, nullptr);
别忘记我们还有std::placeholders::_1 占位没有玩过呢= =
auto add_num = std::bind(&Nice::add, this, std::placeholders::_1, std::placeholders::_2, 10);
log("sum is %d", add_num(1, 1));//12
log("sum is %d", add_num(1, 1, 2));//12
log("sum is %d", add_num(1, 1, 2, 4));//12
//不管怎么改变參数的第三位也是固定死了是10的,奇妙的是竟然能传入四个參数,明摆着就是仅仅认定前两个參数是有效的,后面的统统无效。
学到这里。
貌似对这个流程还是比較清楚的嘛。尽管可能还有很多其它的仅仅是没有发现,可是我们还有很多其它的时间没实用呀!
转摘请注明出处:http://blog.csdn.net/zhouyunxuan
版权声明:本文博主原创文章,博客,未经同意不得转载。
cocos2d-x 3.1.1 学习笔记[17] 关于这些活动功能的更多相关文章
- [XMPP]iOS聊天软件学习笔记[一]
@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/c ...
- cocos2d-x 3.1.1学习笔记[23]寻找主循环 mainloop
文章出自于 http://blog.csdn.net/zhouyunxuan cocos2d到底是怎样把场景展示给我们的,我一直非常好奇. 凭个人猜想,引擎内部的结构类似于这样 while(true ...
- cocos2d-x 3.1.1 学习笔记[3]Action 动作
这些动画貌似都非常多的样子,就所有都创建一次. 代码例如以下: /* 动画*/ auto sp = Sprite::create("card_bg_big_26.jpg"); Si ...
- cocos2d-x 3.1.1 学习笔记[2]Sprite 精灵
Sprite应该是用到最多的一个类吧.无法想像一个游戏没有精灵将怎样进行愉快的玩耍. Sprite继承于Node 和 TextureProtocol. Sprite是一个2d的图像. Sprite能够 ...
- cocos2d-x 3.1.1 学习笔记[21]cocos2d-x 创建过程
文章出自于 http://blog.csdn.net/zhouyunxuan RootViewController.h #import <UIKit/UIKit.h> @interfac ...
- cocos2d-x 3.1.1 学习笔记[4]GridActions 网格动画
文章写的 http://blog.csdn.net/zhouyunxuan 老样子.见代码. //GridActions can only used on NodeGrid auto nodeGri ...
- cocos2d-x 3.1.1 学习笔记[11] http请求 + json解析
//http须要引入的头文件和命名空间 #include <network/HttpClient.h> using namespace network; //json须要引入的头文件 #i ...
- [XMPP]iOS聊天软件学习笔记[四]
昨天完成了聊天界面,基本功能算告一段落 开发时间:五天(工作时间) 开发工具:xcode6 开发平台:iOS8 XMPP框架:XMPPFramework git clone https://githu ...
- [XMPP]iOS聊天软件学习笔记[三]
今天做了好友界面,其实xmpp内部已经写好很多扩展模块,所以使用起来还是很方便的 开发时间:五天(工作时间) 开发工具:xcode6 开发平台:iOS8 XMPP框架:XMPPFramework gi ...
随机推荐
- 一步一步学android之事件篇——单选按钮监听事件
在平常使用软件的时候,我们经常会碰见一些选择题,例如选择性别的时候,在男和女之间选,前面说过这个情况要用RadioGroup组件,那么点击了之后我们该怎么获取到选择的那个值呢,这就是今天要说的OnCh ...
- A Game of Thrones(6) - Catelyn
Of all the rooms in Winterfell’s Great Keep, Catelyn’s bedchambers(['bedtʃeɪmbə]卧室,寝室) were the hott ...
- Android消息推送(二)--基于MQTT协议实现的推送功能
国内的Android设备,不能稳定的使用Google GCM(Google Cloud Messageing)消息推送服务. 1. 国内的Android设备,基本上从操作系统底层开始就去掉了Googl ...
- EBS并发管理器请求汇总(按照并发消耗时间,等待时间,平均等待事件等汇总)
此数据集用于确定正在使用中并发管理器,并可与实际的在启动时分配的并发管理器.而且考虑完成状态为 正常/警告 的请求. select q.concurrent_queue_name, count(*) ...
- OpenStack_Swift源代码分析——ObjectReplicator源代码分析(2)
1.Replicator运行代码具体分析 上篇问中介绍了启动Replicator的详细过程,以下解说Replicator的运行代码的详细实现,首先看replicate方法: def replicate ...
- Java 实现二分(折半)插入排序
设有一个序列a[0],a[1]...a[n];当中a[i-1]前是已经有序的,当插入时a[i]时,利用二分法搜索a[i]插入的位置 效率:O(N^2),对于初始基本有序的序列,效率上不如直接插入排序: ...
- 【转】.net IL 指令解释速查
名称 说明 Add 将两个值相加并将结果推送到计算堆栈上. Add.Ovf 将两个整数相加,执行溢出检查,并且将结果推送到计算堆栈上. Add.Ovf.Un 将两个无符号整数值相加,执行溢出检查,并且 ...
- Kendo UI开发教程(16): Kendo MVVM 数据绑定(五) Events
本篇和Kendo UI开发教程(14): Kendo MVVM 数据绑定(三) Click类似,为事件绑定的一般形式.Events绑定支持将ViewModel的方法绑定到DOM元素的事件处理(如鼠标事 ...
- 在Button上、下、左、右位置加入图片和文字
转载请注明出处:http://blog.csdn.net/droyon/article/details/37564419 非常多人有如标题所述的需求,并且大多数人採用了自己定义组件攻克了需求,事实上还 ...
- java它们的定义ArrayList序列, 大神跳跃
一个list有两种类型的对象,今天有需求必须责令不同的约会对象,这里是代码 /** *@author xh1991101@163.com */ List<Message> messages ...