上一节我们学习了Sprite具体的特性,这一节让我们来继续讲解Action。Action可以使任何继承于Node的对象在一段时间内改变属。例如,可以使Sprite在一段时间内从一个Postion移动到另一个Position
auto moveTo = MoveTo::create(2,Vec2(50,10)); mySprite1->runAction(moveTo); auto moveBy = MoveBy::create(2,Vec2(20,0)); mySprite2->runAction(moveBy);通过上面的代码我们可以得知,如果要用Action改变一个Node的属性需要先通过Action的create函数创建一个指向这个Action的指针,然后再通过Node的runAction函数执行这个Action即可。下面是一个Action的具体应用,代码如下
auto dirs = Director::getInstance()->getRunningScene(); auto newSprite2 = Sprite::create("Blue_Front1.png"); newSprite2->setPosition(100,56); newSprite2->setName("sprite2"); newSprite2->setAnchorPoint(Vec2(0.5,0.5)); dirs->addChild(newSprite2,1); auto moveBy = MoveBy::create(2,Point(500,0)); auto moveTo = MoveTo::create(2,Point(300,56)); auto delay = DelayTime::create(2.0f); auto sequence = Sequence::create(moveBy,delay,NULL); auto sequence2 = Sequence::create(delay,moveTo,NULL); newSprite2->runAction(sequence); auto newSprite3 = Sprite::create("Blue_Front1.png"); newSprite3->setPosition(600,56); newSprite3->setName("sprite3"); newSprite3->setAnchorPoint(Vec2(0.5,0.5)); dirs->addChild(newSprite3,1); newSprite3->runAction(sequence2);运行效果的gif截图为
让我们结合代码与gif截图具体分析一下,3到7行创建一个Sprite并把它放到(100,56)这个位置上。9到11行创建了一个2两秒的MoveTy和一个两秒的MoveTo还有一个两秒的延时。13、14行将上面创建的Action组合放到两个Sequence中。16行执行了一个Sequence,它的效果是让原本在(100,56)位置上的Sprite在两秒内移动到(600,56),之后再延时2秒。18到24行创建了另一个Sprite,并把它放到(600,56)位置上,最后让他执行第二个Sequence,这次执行的效果是使这个Sprite先延时2秒,之后在2秒内从(600,56)移动到(300,56)。其它的Action如RoatateTo、RotateTy、ScaleTo、ScaleTy、FadeIn、FadeOut、TintTo、TintBy的使用方法都与之类似,这里就不一一讲述了。
现在着重讲解一下Animate,它可以用来创建动画效果,来看一段例子
auto dirs = Director::getInstance()->getRunningScene(); auto newSprite2 = Sprite::create("Blue_Front1.png"); newSprite2->setPosition(300,1); auto moveBy = MoveBy::create(2.0f,Vec2(500,0)); newSprite2->runAction(moveBy); Vector<SpriteFrame*> animFrames; animFrames.reserve(12); animFrames.pushBack(SpriteFrame::create("Blue_Front1.png",Rect(0,65,81))); animFrames.pushBack(SpriteFrame::create("Blue_Front2.png",81))); animFrames.pushBack(SpriteFrame::create("Blue_Front3.png",81))); animFrames.pushBack(SpriteFrame::create("Blue_Left1.png",81))); animFrames.pushBack(SpriteFrame::create("Blue_Left2.png",81))); animFrames.pushBack(SpriteFrame::create("Blue_Left3.png",81))); animFrames.pushBack(SpriteFrame::create("Blue_Back1.png",81))); animFrames.pushBack(SpriteFrame::create("Blue_Back2.png",81))); animFrames.pushBack(SpriteFrame::create("Blue_Back3.png",81))); animFrames.pushBack(SpriteFrame::create("Blue_Right1.png",81))); animFrames.pushBack(SpriteFrame::create("Blue_Right2.png",81))); animFrames.pushBack(SpriteFrame::create("Blue_Right3.png",81))); Animation* animation = Animation::createWithSpriteFrames(animFrames,0.1f); Animate* animate = Animate::create(animation); newSprite2->runAction(RepeatForever::create(animate));运行效果如下
13到26行先创建了一个SpriteFrame的容器,然后依次将12个SpriteFrame放入其中。28行用上面创建的容器生成Animation,29行生成一个Animate的Action,最后一行重复执行这个Action。这样就产生了动画效果。
Cocos2d-x中有一个Easing可以用来产生特殊的效果,用法如下
auto dirs = Director::getInstance(); auto newSprite2 = Sprite::create("Blue_Front1.png"); newSprite2->setPosition(100,0.5)); dirs->getRunningScene()->addChild(newSprite2,1); auto move = MoveBy::create(2,Point(200,dirs->getVisibleSize().height - newSprite2->getContentSize().height)); auto move_back = move->reverse(); auto move_ease_in = EaseBounceIn::create(move->clone()); auto move_ease_in_back = move_ease_in->reverse(); auto move_ease_out = EaseBounceOut::create(move->clone()); auto move_ease_out_back = move_ease_out->reverse(); auto delay = DelayTime::create(0.25f); auto seq1 = Sequence::create(move_ease_in,move_ease_in_back,delay->clone(),nullptr); newSprite2->runAction(RepeatForever::create(seq1));这段代码将产生弹跳的效果
这个例子用到了EaseBounceIn效果,还有一些其它效果如下
还有Sequence,这个也是我们需要经常用到的。Sequence可以执行一系列的Action,还有可执行函数和其它的Sequence,具体使用效果如下
auto dirs = Director::getInstance()->getRunningScene(); auto newSprite2 = Sprite::create("Blue_Front1.png"); newSprite2->setPosition(100,1); auto jump = JumpBy::create(0.5,Point(0,0),100,1); auto rotate = RotateBy::create(2.0f,10); auto callbackJump = CallFunc::create([](){ log("Jumped!"); }); auto callbackRotate = CallFunc::create([](){ log("Rotated!"); }); auto seq = Sequence::create(jump,callbackJump,rotate,callbackRotate,nullptr); newSprite2->runAction(RepeatForever::create(seq));这个例子中的Sprite先执行了JumpBy动作,然后执行一个回调函数,接着执行一个RoateBy动作,然后再执行一个回调函数,然后反复重复这些动作。效果如下
在执行Action的同时,回调函数中也打印出了一些信息
最后我们来说一下Spawn,Spawn可以使多个Action同时执行,产生叠加的效果,用法如下
auto dirs = Director::getInstance()->getRunningScene(); auto newSprite2 = Sprite::create("Blue_Front1.png"); newSprite2->setPosition(100,1); auto moveBy = MoveBy::create(10,Point(400,100)); auto fadeTo = FadeTo::create(2.0f,120.0f); auto mySpawn = Spawn::createWithTwoActions(moveBy,fadeTo); newSprite2->runAction(mySpawn);这个例子在使Action的移动过程中同时使Action褪色,效果如下
Action的常见用法我们已经讲完了,下一节我们会具体讲解Scene。