您好,登錄后才能下訂單哦!
【嘮叨】
基本動畫制作需要用到CCAnimation類,用于存儲動畫相關的信息。以及由CCActionInterval繼承的CCAnimate動畫動作。
還有一些在創建動畫動作的過程中,可能會用到的一些類CCSpriteFrame、CCSpriteFrameCache、CCAnimationFrame、CCAnimationCache。
有關緩存類的詳細,參見《三種緩存類》:http://shahdza.blog.51cto.com/2410787/1611766
本節的內容可能比較復雜,需要掌握的東西比較多,大家慢慢理解吧。。。
【致謝】
http://zengrong.net/post/2006.htm
【小知識】
以下名詞術語對應的中文名,純屬自己歪歪,只是為了方便自己記憶罷了。
CCSpriteFrame :精靈幀。 它是相對動畫而產生的,其實就是一張紋理圖片。
CCAnimationFrame :動畫幀。 由精靈幀與間隔幀數組成,是動畫CCAnimation中的一幀。
CCSpriteFrameCache:精靈幀緩沖。用于存放精靈幀CCSpriteFrame的緩沖池。
CCAnimationCache :動畫緩沖。 用于存放動畫CCAnimation的緩沖池。
delayPerUnit :單位幀間隔。連續兩個動畫幀之間的時間間隔。單位:秒。
delayUnits :間隔幀數。 當前動畫幀到下一個動畫幀需要等待的單位幀間隔的個數。
【Demo下載】
https://github.com/shahdza/Cocos_LearningTest/tree/master/demo_%E5%9F%BA%E6%9C%AC%E5%8A%A8%E7%94%BBCCAnimation%26CCAnimate
【3.x】
(1)去掉 “CC”
(2)SpriteFrameCache、AnimationCache 中獲得、釋放單例對象的方法:
> 使用 getInstance() 替代 sharedSpriteFrameCache()
> 使用 destroyInstance() 替代 purgeSharedSpriteFrameCache()
(3)Animation 中一些參數的變化:
> createWithSpriteFrames 中的參數 CCArray 改為 Vector<SpriteFrame*>&
> create 中的參數 CCArray 改為 Vector<AnimationFrame*>&
> setFrames()/getFrames() 中的參數 CCArray 改為 Vector<AnimationFrame*>&
(4)Animation 中的函數變化:
> addSpriteFrameWithFileName(..) 改為 addSpriteFrameWithFile(...)
(5)其他變化不大。
【CCAnimation/CCAnimate】
1、預備知識
動畫就和動漫是類似的,制作動畫時,就需要用到好多圖片,單位幀間隔,以及每一個動畫幀到下一個動畫幀的間隔幀數,然后按照幀間隔來進行動畫幀圖片的切換,從而形成了動畫。
cocos2dx中的基本動畫是由CCAnimation和CCAnimate兩個類的配合而完成的。
(1)CCAnimation:用于存儲動畫相關的信息。其中包含用于動畫的所有動畫幀信息,單位幀的時間間隔,總幀數,動畫重復次數等等信息。
(2)CCAnimate :用于創建動畫的CCAction動作,需要CCAnimation作為創建的參數。
PS:Animation 只是存放了動畫需要的數據信息。而執行動畫還是需要 Animate。
在講動畫動作之前,首先需要講解一下如下四個類與動畫動作有關的用法:
1.1、CCSpriteFrame精靈幀
用精靈幀來創建的CCAnimation。而實際上在CCAnimation初始化時,是用精靈幀來創建一個動畫幀CCAnimationFrame,且設置動畫幀的間隔幀數DelayUnits為:1。
如:CCAnimation設置的單位幀間隔delayPerUnit = 0.2,
那么從當前動畫幀到下一個動畫幀所需要延遲等待的時間間隔:0.2 * 1 = 0.2 秒。
// //創建精靈幀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)更多的使用方法,自行琢磨,加油!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。