cocos2d-x学习笔记(11)回调CallFunc,lambda

CallFunc是一个看不见的动作,它的作用就是回调一个函数,它的动作就是调用这个函数,这就是它所有的使命。
Sprite* sprite=Sprite::create("sprite.png");	
	sprite->setPosition(Point(visibleSize.width/2,visibleSize.height/2));
	this->addChild(sprite,1);

	MoveTo* moveToHome=MoveTo::create(10.0f,Point(visibleSize.width,
		visibleSize.height/2));

	auto callbackFunc=[&](){
		backHome();
	};
	CallFunc* callFunc=CallFunc::create(callbackFunc);

	Action* actions=Sequence::create(moveToHome,callFunc,NULL);


	sprite->runAction(actions);

backHome函数的实现代码:

void HelloWorld::backHome(){
	Size visibleSize=Director::getInstance()->getVisibleSize();
	Label* label=Label::create("I am home!","Arial",35);
	label->setPosition(Point(visibleSize.width/2,visibleSize.height/2));
	this->addChild(label);
}

其实callbackFunc就是lambda函数,这是C++,与Cosos2d-x本身无关,但是从Cocos2d-x 3.0才开始支持这种类型的函数回调。

lambda表达式就是JavaScript语言中的匿名函数,Java中的匿名内部类就是在表达式中直接声明函数,而不是独立声明函数。

一个最简单的lambda函数结构如下:[](){}。

它只有三对符号和一个分号,分别的作用是:

[]符号,表示要开始一个lambda函数;

()符号,里面填写函数的参数;

{}符号,和所有的{}符号一样,用来包围函数体的内容;


在回调函数里创建一个精灵:

auto callbackFunc=[&](){
		Sprite* sprite=Sprite::create("sprite.png");
		sprite->setPosition(Point(200,200));
		this->addChild(sprite);
	};
	CallFunc* callFunc=CallFunc::create(callbackFunc);


	this->runAction(callFunc);
当我们想在lambda函数里使用外部的变量是,需要指定捕获模式。

在[]符号里加上指定的符号,就能指定变量捕获模式,常用的捕获模式:

[]:不截获任何变量;

[&]:截取外部作用域中所有变量,并且作为引用在lambda函数中使用,可以简单地理解为,只要变量没有被释放,那么在lambda函数中都可以使用。但是局部变量不可以使用,因为局部变量会被释放。

[=]:截取外部作用域中所有变量,并复制一份在lambda函数中使用,即使外部变量的值改变了,但是lambda函数执行的时候,依旧是复制时的值。

[=,&hehe]:和[=]功能一样,但是对hehe变量使用引用(也就是[&]的方式)。

[hehe]:和[=]功能一样,但是只针对hehe变量,其他变量忽略。



	Sprite* sprite=Sprite::create("sprite.png");	
	sprite->setPosition(Point(visibleSize.width/2,visibleSize.height/2));
	this->addChild(sprite,1);

	auto func=[&](){
		sprite->setScale(2);
	};

	CallFunc* callFunc=CallFunc::create(func);

	this->runAction(callFunc);
创建一个精灵,然后希望在func函数被调用时改变精灵的缩放值。

以上代码运行时,会报错。因为使用的是[&],这种模式无法在lambda函数里使用局部变量,因为局部变量在调用lambda函数前已经被释放了。这个精灵本身是没有被释放的,因为它已经在场景中了。但是sprite这个局部变量被释放了,它只是一个指针,它指向的内容没有被释放,但是它本身被释放了。

所以需要使用[=]模式,这种模式会复制一份变量,代码中的[&]改为[=]就能正常运行。


lambda函数称之为匿名函数,可以把lambda函数直接作为参数传递

CallFunc* callFunc=CallFunc::create([](){log("Normal");});




我们大部分时间使用的都是FiniteTimeAction,它包含两个大类,分别是ActionInstant(瞬时动作)和ActionInterval(持续动作)。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值