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));
效果:
總結
- 動作序列和組合動作,前者是動作依次發生,後者是動作同時發生
- 曲線動作,比如在某些拋物線之類的,沿路徑行走等等,不需要複雜算法去計算加速度的東西,只需要找到一條合適的曲線,讓物體沿該曲線運動即可
- 重複動作:RepeatForever,在動畫時,動作需要重複是比較有用
- 加速,彈跳:在實現球體撞擊後的效果比較有用(這裏沒演示)