Action ,也就是动作,让你的Node 对象动起来,比如移动,旋转,放缩,以及特效(波浪等等)
基本动作类
函数名 | 参数 | 作用 |
---|---|---|
MoveTo* MoveTo::create(float duration, const Vec2& position) | 动作完成需要时间,以及终点位置 | 移动(绝对移动),(3,4),表示终点位置就在(3,4) |
MoveBy* MoveBy::create(float duration, const Vec2& deltaPosition) | 第一个参数表示完成这个动作所需时间,第二个参数是相对移动的位置 | 相对移动(3,4) 表示相对当前位置向x正方向移动3,再向y正方向移动4 |
RotateBy* RotateBy::create(float duration, float deltaAngle) | 第二个参数是需要旋转的角度 | 旋转 (角度制) |
RotateTo | 相对旋转 | |
RotateBy | 绝对旋转 | |
ScaleTo | 缩放 | |
ScaleBy | 缩放(相对缩放) | |
EaseIn/EaseOut/EaseInOut | 参数:已定义的动作,加速比率,1,2,3,… | 加速,减速,先加速再减速 |
还有其他动作,比如弹跳,缓冲,网格动作,波浪特效等等
执行动作
基础代码:
HelloWorldScene.cpp
#include "HelloWorldScene.h"
#include "cocostudio/CocoStudio.h"
#include "ui/CocosGUI.h"
USING_NS_CC;
using namespace cocostudio::timeline;
Scene* HelloWorld::createScene()
{
// 'scene' is an autorelease object
auto scene = Scene::create();
// 'layer' is an autorelease object
auto layer = HelloWorld::create();
// add layer as a child to scene
scene->addChild(layer);
// return the scene
return scene;
}
// on "init" you need to initialize your instance
bool HelloWorld::init()
{
// 1. super init first
if ( !Layer::init() )
{
return false;
}
Size visibleSize = Director::getInstance()->getVisibleSize();
Vec2 origin = Director::getInstance()->getVisibleOrigin();
auto bg = Sprite::create("HelloWorld.png");
bg->setAnchorPoint(Vec2(0, 0));
addChild(bg);
auto guiziBootom = Sprite::create("J201.png");
guiziBootom->setPosition(origin.x + visibleSize.width /3-100, origin.y + visibleSize.height / 3);
addChild(guiziBootom);
auto guiziUp = Sprite::create("J201.png");
guiziUp->setPosition(origin.x + visibleSize.width / 3 - 100, origin.y + visibleSize.height /3+300);
addChild(guiziUp);
}
效果:
1. 单次执行
.runAction
以相对向右移动为例
.....
// 让在下面的鬼子向右移动
auto toRight=MoveBy::create(10, Vec2(600, 0));
guiziBootom->runAction(toRight);
.....
效果:
2. 动作序列
比如我想让一个sprite 对象,先向右移动,然后接着向上移动
需要使用Sequence,将有先后顺序的动作封装成一个序列**(注意最后一个参数必须是NULL)**
//1 . 让在下面的鬼子向右移动
auto toRight=MoveBy::create(10, Vec2(600, 0));
//guiziBootom->runAction(toRight);
auto toUp = MoveBy::create(4, Vec2(0, 300));
//2. 连续动作
guiziBootom->runAction(Sequence::create(toRight, toUp, NULL));
效果:
3. 重复执行
让这个鬼子移动到顶端,然后原路返回
RepeatForever::create();用来将动作转为重复动作,周期执行
// 3,重复动作
guiziBootom->runAction(RepeatForever::create(Sequence::create(toRight, toUp, toUp->reverse(), toRight->reverse(), NULL)));
效果:
4. 组合动作
(注意最后一个参数必须是NULL)
Spawn::create(action1,action2,NULL);
比如移动的同时旋转,比如抛物线运动,水平匀速,垂直方向匀加速
移动+旋转+缩放+抛物线(水平匀速,向上匀加速)吧
auto toUp = MoveBy::create(4, Vec2(0, 300));
auto rota = RotateBy::create(4, 360);// 4s 内完成360度旋转
auto scale= ScaleTo::create(4, 0.2);// 4s 内大小变成原来的0.2 倍
auto speedUpUp = EaseIn::create(toUp, 2);//向上加速
// guiziBootom->runAction(rota);
auto spawnAction= Spawn::create(rota, speedUpUp, toRight,scale,NULL);
guiziBootom->runAction(spawnAction);
效果:(我一定会回来的)
5. 曲线动作
CatmullRomTo/CatmullRomBy
比如我想让灰太狼沿着以下路径行进:
auto pointArray= PointArray::create(5);
pointArray->addControlPoint(Point(origin.x + 100, origin.y + 300));
pointArray->addControlPoint(Point(origin.x + 300, origin.y + 90));
pointArray->addControlPoint(Point(origin.x + 700, origin.y + 90));
pointArray->addControlPoint(Point(origin.x +800, origin.y + 200));
pointArray->addControlPoint(Point(origin.x + 900, origin.y + 300));
guiziBootom->runAction(CatmullRomTo::create(10, pointArray));
效果:
6. 动画帧,让人物动起来
Vector<SpriteFrame*> frames(8);// 存储动画帧
Sprite * temp;
char pngName[20];
for (int i = 0; i < 8; i++) {
sprintf(pngName, "J20%d.png", i + 1);
temp = Sprite::create(pngName);
frames.pushBack(temp->getSpriteFrame());
}
Animation * animation = Animation::createWithSpriteFrames(frames,0.3f);// 生成动画(每帧之间的间隔时间是0.3秒)
Animate * animate = Animate::create(animation);// 包装成action
guiziBootom->runAction(RepeatForever::create(animate));
效果:
有限次重复可以使用
Repeat::create(action,times); //将action 重复times 次
guiziBootom->runAction(Repeat::create(animate,4));
总结
- 动作序列和组合动作,前者是动作依次发生,后者是动作同时发生
- 曲线动作,比如在某些抛物线之类的,沿路径行走等等,不需要复杂算法去计算加速度的东西,只需要找到一条合适的曲线,让物体沿该曲线运动即可
- 重复动作:RepeatForever,在动画时,动作需要重复是比较有用
- 加速,弹跳:在实现球体撞击后的效果比较有用(这里没演示)