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);
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函数结构如下:[](){}。
它只有三对符号和一个分号,分别的作用是:
[]符号,表示要开始一个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,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(持续动作)。