cocos2dx[2.x](19)--基本動畫CCAnimation/CCAnimate
阿新 • • 發佈:2019-01-23
【嘮叨】
基本動畫製作需要用到CCAnimation類,用於儲存動畫相關的資訊。以及由CCActionInterval繼承的CCAnimate動畫動作。
還有一些在建立動畫動作的過程中,可能會用到的一些類CCSpriteFrame、CCSpriteFrameCache、CCAnimationFrame、CCAnimationCache。
有關快取類的詳細,參見《三種快取類》:http://shahdza.blog.51cto.com/2410787/1611766
本節的內容可能比較複雜,需要掌握的東西比較多,大家慢慢理解吧。。。
【小知識】
以下名詞術語對應的中文名,純屬自己歪歪,只是為了方便自己記憶罷了。i_f32.gif CCSpriteFrame :精靈幀。 它是相對動畫而產生的,其實就是一張紋理圖片。 CCAnimationFrame :動畫幀。 由精靈幀與間隔幀陣列成,是動畫CCAnimation中的一幀。 CCSpriteFrameCache:精靈幀緩衝。用於存放精靈幀CCSpriteFrame的緩衝池。 CCAnimationCache :動畫緩衝。 用於存放動畫CCAnimation的緩衝池。 delayPerUnit :單位幀間隔。連續兩個動畫幀之間的時間間隔。單位:秒。 delayUnits :間隔幀數。 當前動畫幀到下一個動畫幀需要等待的單位幀間隔的個數。
【3.x】
(1)去掉 “CC”
(2)SpriteFrameCache、AnimationCache 中獲得、釋放單例物件的方法:
使用getInstance() 替代 sharedSpriteFrameCache()
使用 destroyInstance() 替代 purgeSharedSpriteFrameCache()
(3)Animation 中一些引數的變化:
createWithSpriteFrames 中的引數 CCArray 改為 Vector
//建立精靈幀CCSpriteFrame陣列
//用於在內部建立動畫幀CCAnimationFrame,從而建立CCAnimation
CCArray* array = new CCArray(); //建立陣列
char str[] = "xxx.png";
CCSpriteFrame* frame = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(str); //從精靈幀緩衝池中獲取一個精靈幀
array->addObject(frame); //將精靈幀新增到陣列中
1.2、CCAnimationFrame動畫幀 說明:動畫幀就是在精靈幀的基礎之上,設定了到下一幀需要的間隔幀數,是動畫CCAnimation中的一幀。其中設定動畫幀的間隔幀數:setDelayUnits來完成的。 如:CCAnimation設定的單位幀間隔delayPerUnit = 0.2, 而動畫幀的設定的間隔幀數DelayUnits = 10, 那麼當前動畫幀到下一個動畫幀所需要延遲等待的時間間隔:0.2 * 10 = 2 秒。
//建立動畫幀CCAnimationFrame陣列
CCArray* array = new CCArray(); //建立陣列
char str[] = "xxx.png";
CCSpriteFrame* frame = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(str); //從精靈幀緩衝池中獲取一個精靈幀
CCAnimationFrame* animationFrame = new CCAnimationFrame(); //建立動畫幀
animationFrame->setSpriteFrame(frame); //設定精靈幀
animationFrame->setDelayUnits(i); //設定到下一動畫幀的間隔幀數
array->addObject(animationFrame); //將動畫幀新增到陣列
1.3、CCSpriteFrameCache精靈幀緩衝
//將Animation/grossini.plist加入到精靈幀緩衝池中
//也就是將動畫需要用到的批圖片加到緩衝池中
//用於建立精靈幀
CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile("Animation/grossini.plist");
1.4、CCAnimationCache動畫緩衝
通常情況下,對於一個精動畫,每次建立時都需要載入動畫幀,按順序新增到陣列,再建立對應的動畫CCAnimation類,這是一個非常煩瑣的計算過程。
對於使用頻率高的動畫,比如魚的遊動,將其加入快取可以有效降低每次建立的巨大消耗。
所欲將動畫CCAnimation直接放在動畫緩衝池中,當需要執行動畫動作時,就直接從動畫緩衝池中拿出來,去建立初始化CCAnimation會非常方便。
//動畫命名為 Explosion,加入到動畫緩衝中
CCAnimation* animation = CCAnimation::createWithSpriteFrames(arr,0.04);
CCAnimationCache::sharedAnimationCache()->addAnimation(animation,"Explosion");
//直接從緩衝池中取出 Explosion 動畫
CCAnimation* animation = CCAnimationCache::sharedAnimationCache()->animationByName("Explosion");
2、CCAnimation
或許看了上面四個類後,大家可能會有點迷茫,接下來就將上面的類和CCAnimation關聯起來。
2.1、建立方法
/**
* 總共有三種建立方法:
* (1)建立空動畫
* (2)使用精靈幀陣列建立
* (3)使用動畫幀陣列建立
* 注意第二個方法是createWithSpriteFrames,而不是create。
*/
//建立一個空動畫
CCAnimation::create();
//使用CCSpriteFrame精靈幀陣列,單位幀間隔delay秒
//實際上在內部建立了動畫幀CCAnimationFrame,且間隔幀數為:1
CCAnimation::createWithSpriteFrames(CCArray* arrayOfSpriteFrameNames, float delay = 0.0f);
//使用CCAnimationFrame動畫幀陣列,單位幀間隔delayPerUnit秒,重複次數loops
//其中loops:0為執行動畫;1為執行一次,……,-1為無限迴圈
static CCAnimation* create(CCArray *arrayOfAnimationFrameNames, float delayPerUnit, unsigned int loops = 1);
2.2、新增動畫幀函式
/**
* 總共有三種新增動畫幀的方法:
* (1)使用CCSpriteFrame
* (2)使用圖片資源(jpg,png等)
* (3)使用紋理圖片CCTexture2D
* (4)直接設定動畫幀陣列setFrames
*/
//使用精靈幀來新增一個動畫幀,間隔幀數:1
void addSpriteFrame(CCSpriteFrame *pFrame);
//使用圖片資源(jpg,png等)來新增一個動畫幀,間隔幀數:1
void addSpriteFrameWithFileName(const char *pszFileName);
//從圖片紋理中擷取CCRect部分割槽域的圖片,間隔幀數:1
void addSpriteFrameWithTexture(CCTexture2D* pobTexture, const CCRect& rect);
//直接設定動畫幀CCAnimationFrames陣列
void setFrames(CCArray* pAnimationFrames);
CCArray* getFrames();
2.3、屬性設定
(1)單位幀間隔 setDelayPerUnit
(2)設定動畫幀 setFrames
(3)當動畫結束時,是否還原為第一幀 setRestoreOriginalFrame
(4)動畫重複執行次數 setLoops
/**
* 單位幀間隔、間隔幀數、動畫總時間
* setDelayPerUnit , getTotalDelayUnits , getDuration
*/
//設定單位幀間隔delayPerUnit秒
void setDelayPerUnit(float);
float getDelayPerUnit();
//間隔幀數的總和totalDelayUnits
//即:每個精靈幀到下一精靈幀的間隔幀數之和
float getTotalDelayUnits();
//動畫總時間:delayPerUnit * totalDelayUnits
float getDuration();
/**
* 其他屬性設定
* setFrames , setRestoreOriginalFrame , setLoops
*/
//設定動畫幀CCAnimationFrames陣列
void setFrames(CCArray* pAnimationFrames);
CCArray* getFrames();
//當動畫結束時,是否還原為第一幀
void setRestoreOriginalFrame(bool);
bool getRestoreOriginalFrame();
//動畫執行次數
//0表示不執行動畫,1表示執行1次,……,-1表示無限迴圈
void setLoops(unsigned int );
unsigned int getLoops();
3、CCAnimate
CCAnimate是用來真正執行CCAnimation動畫的動作類。
建立及使用方法如下:
//使用CCAnimation建立CCAnimate
CCAnimate* animate = CCAnimate::create(animation);
sprite->runAction(animate); //執行動畫動作
【程式碼實戰】
程式碼資源來自官方TestCpp。
下面例舉建立動畫動作CCAnimation/CCAnimate的三種方式。
1、圖片資源
2、直接使用圖片資源
每個動畫幀的間隔幀數均為: 1
單位幀間隔 : 2.0/14.0 秒
連續兩動畫幀的時間間隔為: 2.0/14.0 * 1 秒
//建立精靈sprite
CCSprite* sprite = CCSprite::create("Animation/dance_00.png");
sprite->setPosition( mysize/2 );
this->addChild(sprite);
//建立CCAnimation
CCAnimation* animation = CCAnimation::create();
//直接新增圖片資源
for(int i =1; i <= 14; i++) {
char str[50];
sprintf(str, "Animation/dance_%02d.png", i);
animation->addSpriteFrameWithFileName(str); //新增動畫幀
}
//設定屬性
animation->setRestoreOriginalFrame(true); //還原第一幀
animation->setDelayPerUnit(2.0/14.0); //單位幀間隔
animation->setLoops(-1); //-1無限迴圈
//建立CCAnimate
CCAnimate* animate = CCAnimate::create(animation);
//執行動畫動作
sprite->runAction(animate);
3、使用精靈幀
每個動畫幀的間隔幀數均為: 1
單位幀間隔 : 2.0/14.0 秒
連續兩動畫幀的時間間隔為: 2.0/14.0 * 1 秒
注意:使用精靈幀陣列建立CCAnimation時,是createWithSpriteFrames,不是create。
//建立精靈sprite
CCSprite* sprite = CCSprite::create("Animation/dance_00.png");
sprite->setPosition( mysize/2 );
this->addChild(sprite);
//建立CCAnimation
//將plist批處理的多張圖片,新增到精靈幀緩衝池中
CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile("Animation/grossini.plist");
//建立精靈幀CCSpriteFrame陣列
CCArray* array = new CCArray();
for(int i =1; i <= 14; i++) {
char str[50];
sprintf(str, "grossini_dance_%02d.png", i);
CCSpriteFrame* frame = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(str);
array->addObject(frame);
}
//使用精靈幀陣列建立,單位幀間隔為2.0/14.0秒
CCAnimation* animation = CCAnimation::createWithSpriteFrames(array, 2.0/14.0);
//屬性設定
animation->setRestoreOriginalFrame(true); //還原第一幀
animation->setLoops(-1); //無線迴圈
//建立CCAnimate
CCAnimate* animate = CCAnimate::create(animation);
//執行動畫動作
sprite->runAction(animate);
4、使用動畫幀
每個動畫幀的間隔幀數均為: 1
單位幀間隔 : 0.2 秒
連續兩動畫幀的時間間隔為: 0.2 * i 秒(第i個動畫幀到第i+1個動畫幀的延遲時間)
//建立精靈sprite
CCSprite* sprite = CCSprite::create("Animation/dance_00.png");
sprite->setPosition( mysize/2 );
this->addChild(sprite);
//建立CCAnimation
//將plist批處理的多張圖片,新增到精靈幀緩衝
CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile("Animation/grossini.plist");
//建立動畫幀CCAnimationFrame陣列
CCArray* array = new CCArray();
for(int i =1; i <= 14; i++) {
char str[50];
sprintf(str, "grossini_dance_%02d.png", i);
CCSpriteFrame* frame = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(str);
CCAnimationFrame* animationFrame = new CCAnimationFrame();
animationFrame->setSpriteFrame(frame); //設定精靈幀
animationFrame->setDelayUnits( i ); //設定間隔幀數
array->addObject(animationFrame);
}
//使用動畫幀陣列建立,單位幀間隔0.2秒
CCAnimation* animation = CCAnimation::create(array, 0.2f);
animation->setRestoreOriginalFrame(true);
animation->setLoops(-1);
//建立CCAnimate
CCAnimate* animate = CCAnimate::create(animation);
//執行動畫動作
sprite->runAction(animate);
5、執行結果
6、分析與總結
(1)仔細觀察一下第三個和前兩個有什麼區別?是不是動作執行越來越緩慢了?因為最後一張是用動畫幀建立的,並且我設定了每個動畫幀的間隔幀數都不一樣,所以會有如上的效果。
(2)更多的使用方法,自行琢磨,加油!