您好,登錄后才能下訂單哦!
【嘮叨】
基本動(dòng)畫(huà)制作需要用到CCAnimation類,用于存儲(chǔ)動(dòng)畫(huà)相關(guān)的信息。以及由CCActionInterval繼承的CCAnimate動(dòng)畫(huà)動(dòng)作。
還有一些在創(chuàng)建動(dòng)畫(huà)動(dòng)作的過(guò)程中,可能會(huì)用到的一些類CCSpriteFrame、CCSpriteFrameCache、CCAnimationFrame、CCAnimationCache。
有關(guān)緩存類的詳細(xì),參見(jiàn)《三種緩存類》:http://shahdza.blog.51cto.com/2410787/1611766
本節(jié)的內(nèi)容可能比較復(fù)雜,需要掌握的東西比較多,大家慢慢理解吧。。。
【致謝】
http://zengrong.net/post/2006.htm
【小知識(shí)】
以下名詞術(shù)語(yǔ)對(duì)應(yīng)的中文名,純屬自己歪歪,只是為了方便自己記憶罷了。
CCSpriteFrame :精靈幀。 它是相對(duì)動(dòng)畫(huà)而產(chǎn)生的,其實(shí)就是一張紋理圖片。
CCAnimationFrame :動(dòng)畫(huà)幀。 由精靈幀與間隔幀數(shù)組成,是動(dòng)畫(huà)CCAnimation中的一幀。
CCSpriteFrameCache:精靈幀緩沖。用于存放精靈幀CCSpriteFrame的緩沖池。
CCAnimationCache :動(dòng)畫(huà)緩沖。 用于存放動(dòng)畫(huà)CCAnimation的緩沖池。
delayPerUnit :單位幀間隔。連續(xù)兩個(gè)動(dòng)畫(huà)幀之間的時(shí)間間隔。單位:秒。
delayUnits :間隔幀數(shù)。 當(dāng)前動(dòng)畫(huà)幀到下一個(gè)動(dòng)畫(huà)幀需要等待的單位幀間隔的個(gè)數(shù)。
【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 中獲得、釋放單例對(duì)象的方法:
> 使用 getInstance() 替代 sharedSpriteFrameCache()
> 使用 destroyInstance() 替代 purgeSharedSpriteFrameCache()
(3)Animation 中一些參數(shù)的變化:
> createWithSpriteFrames 中的參數(shù) CCArray 改為 Vector<SpriteFrame*>&
> create 中的參數(shù) CCArray 改為 Vector<AnimationFrame*>&
> setFrames()/getFrames() 中的參數(shù) CCArray 改為 Vector<AnimationFrame*>&
(4)Animation 中的函數(shù)變化:
> addSpriteFrameWithFileName(..) 改為 addSpriteFrameWithFile(...)
(5)其他變化不大。
【CCAnimation/CCAnimate】
1、預(yù)備知識(shí)
動(dòng)畫(huà)就和動(dòng)漫是類似的,制作動(dòng)畫(huà)時(shí),就需要用到好多圖片,單位幀間隔,以及每一個(gè)動(dòng)畫(huà)幀到下一個(gè)動(dòng)畫(huà)幀的間隔幀數(shù),然后按照幀間隔來(lái)進(jìn)行動(dòng)畫(huà)幀圖片的切換,從而形成了動(dòng)畫(huà)。
cocos2dx中的基本動(dòng)畫(huà)是由CCAnimation和CCAnimate兩個(gè)類的配合而完成的。
(1)CCAnimation:用于存儲(chǔ)動(dòng)畫(huà)相關(guān)的信息。其中包含用于動(dòng)畫(huà)的所有動(dòng)畫(huà)幀信息,單位幀的時(shí)間間隔,總幀數(shù),動(dòng)畫(huà)重復(fù)次數(shù)等等信息。
(2)CCAnimate :用于創(chuàng)建動(dòng)畫(huà)的CCAction動(dòng)作,需要CCAnimation作為創(chuàng)建的參數(shù)。
PS:Animation 只是存放了動(dòng)畫(huà)需要的數(shù)據(jù)信息。而執(zhí)行動(dòng)畫(huà)還是需要 Animate。
在講動(dòng)畫(huà)動(dòng)作之前,首先需要講解一下如下四個(gè)類與動(dòng)畫(huà)動(dòng)作有關(guān)的用法:
1.1、CCSpriteFrame精靈幀
用精靈幀來(lái)創(chuàng)建的CCAnimation。而實(shí)際上在CCAnimation初始化時(shí),是用精靈幀來(lái)創(chuàng)建一個(gè)動(dòng)畫(huà)幀CCAnimationFrame,且設(shè)置動(dòng)畫(huà)幀的間隔幀數(shù)DelayUnits為:1。
如:CCAnimation設(shè)置的單位幀間隔delayPerUnit = 0.2,
那么從當(dāng)前動(dòng)畫(huà)幀到下一個(gè)動(dòng)畫(huà)幀所需要延遲等待的時(shí)間間隔:0.2 * 1 = 0.2 秒。
// //創(chuàng)建精靈幀CCSpriteFrame數(shù)組 //用于在內(nèi)部創(chuàng)建動(dòng)畫(huà)幀CCAnimationFrame,從而創(chuàng)建CCAnimation CCArray* array = new CCArray(); //創(chuàng)建數(shù)組 char str[] = "xxx.png"; CCSpriteFrame* frame = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(str); //從精靈幀緩沖池中獲取一個(gè)精靈幀 array->addObject(frame); //將精靈幀添加到數(shù)組中 //
1.2、CCAnimationFrame動(dòng)畫(huà)幀
說(shuō)明:動(dòng)畫(huà)幀就是在精靈幀的基礎(chǔ)之上,設(shè)置了到下一幀需要的間隔幀數(shù),是動(dòng)畫(huà)CCAnimation中的一幀。其中設(shè)置動(dòng)畫(huà)幀的間隔幀數(shù):setDelayUnits來(lái)完成的。
如:CCAnimation設(shè)置的單位幀間隔delayPerUnit = 0.2,
而動(dòng)畫(huà)幀的設(shè)置的間隔幀數(shù)DelayUnits = 10,
那么當(dāng)前動(dòng)畫(huà)幀到下一個(gè)動(dòng)畫(huà)幀所需要延遲等待的時(shí)間間隔:0.2 * 10 = 2 秒。
// //創(chuàng)建動(dòng)畫(huà)幀CCAnimationFrame數(shù)組 CCArray* array = new CCArray(); //創(chuàng)建數(shù)組 char str[] = "xxx.png"; CCSpriteFrame* frame = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(str); //從精靈幀緩沖池中獲取一個(gè)精靈幀 CCAnimationFrame* animationFrame = new CCAnimationFrame(); //創(chuàng)建動(dòng)畫(huà)幀 animationFrame->setSpriteFrame(frame); //設(shè)置精靈幀 animationFrame->setDelayUnits(i); //設(shè)置到下一動(dòng)畫(huà)幀的間隔幀數(shù) array->addObject(animationFrame); //將動(dòng)畫(huà)幀添加到數(shù)組 //
1.3、CCSpriteFrameCache精靈幀緩沖
// //將Animation/grossini.plist加入到精靈幀緩沖池中 //也就是將動(dòng)畫(huà)需要用到的批圖片加到緩沖池中 //用于創(chuàng)建精靈幀 CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile("Animation/grossini.plist"); //
1.4、CCAnimationCache動(dòng)畫(huà)緩沖
通常情況下,對(duì)于一個(gè)精動(dòng)畫(huà),每次創(chuàng)建時(shí)都需要加載動(dòng)畫(huà)幀,按順序添加到數(shù)組,再創(chuàng)建對(duì)應(yīng)的動(dòng)畫(huà)CCAnimation類,這是一個(gè)非常煩瑣的計(jì)算過(guò)程。
對(duì)于使用頻率高的動(dòng)畫(huà),比如魚(yú)的游動(dòng),將其加入緩存可以有效降低每次創(chuàng)建的巨大消耗。
所欲將動(dòng)畫(huà)CCAnimation直接放在動(dòng)畫(huà)緩沖池中,當(dāng)需要執(zhí)行動(dòng)畫(huà)動(dòng)作時(shí),就直接從動(dòng)畫(huà)緩沖池中拿出來(lái),去創(chuàng)建初始化CCAnimation會(huì)非常方便。
// //動(dòng)畫(huà)命名為 Explosion,加入到動(dòng)畫(huà)緩沖中 CCAnimation* animation = CCAnimation::createWithSpriteFrames(arr,0.04); CCAnimationCache::sharedAnimationCache()->addAnimation(animation,"Explosion"); //直接從緩沖池中取出 Explosion 動(dòng)畫(huà) CCAnimation* animation = CCAnimationCache::sharedAnimationCache()->animationByName("Explosion"); //
2、CCAnimation
或許看了上面四個(gè)類后,大家可能會(huì)有點(diǎn)迷茫,接下來(lái)就將上面的類和CCAnimation關(guān)聯(lián)起來(lái)。
2.1、創(chuàng)建方法
// /** * 總共有三種創(chuàng)建方法: * (1)創(chuàng)建空動(dòng)畫(huà) * (2)使用精靈幀數(shù)組創(chuàng)建 * (3)使用動(dòng)畫(huà)幀數(shù)組創(chuàng)建 * 注意第二個(gè)方法是createWithSpriteFrames,而不是create。 */ //創(chuàng)建一個(gè)空動(dòng)畫(huà) CCAnimation::create(); //使用CCSpriteFrame精靈幀數(shù)組,單位幀間隔delay秒 //實(shí)際上在內(nèi)部創(chuàng)建了動(dòng)畫(huà)幀CCAnimationFrame,且間隔幀數(shù)為:1 CCAnimation::createWithSpriteFrames(CCArray* arrayOfSpriteFrameNames, float delay = 0.0f); //使用CCAnimationFrame動(dòng)畫(huà)幀數(shù)組,單位幀間隔delayPerUnit秒,重復(fù)次數(shù)loops //其中l(wèi)oops:0為執(zhí)行動(dòng)畫(huà);1為執(zhí)行一次,……,-1為無(wú)限循環(huán) static CCAnimation* create(CCArray *arrayOfAnimationFrameNames, float delayPerUnit, unsigned int loops = 1); //
2.2、添加動(dòng)畫(huà)幀函數(shù)
// /** * 總共有三種添加動(dòng)畫(huà)幀的方法: * (1)使用CCSpriteFrame * (2)使用圖片資源(jpg,png等) * (3)使用紋理圖片CCTexture2D * (4)直接設(shè)置動(dòng)畫(huà)幀數(shù)組setFrames */ //使用精靈幀來(lái)添加一個(gè)動(dòng)畫(huà)幀,間隔幀數(shù):1 void addSpriteFrame(CCSpriteFrame *pFrame); //使用圖片資源(jpg,png等)來(lái)添加一個(gè)動(dòng)畫(huà)幀,間隔幀數(shù):1 void addSpriteFrameWithFileName(const char *pszFileName); //從圖片紋理中截取CCRect部分區(qū)域的圖片,間隔幀數(shù):1 void addSpriteFrameWithTexture(CCTexture2D* pobTexture, const CCRect& rect); //直接設(shè)置動(dòng)畫(huà)幀CCAnimationFrames數(shù)組 void setFrames(CCArray* pAnimationFrames); CCArray* getFrames(); //
2.3、屬性設(shè)置
(1)單位幀間隔 setDelayPerUnit
(2)設(shè)置動(dòng)畫(huà)幀 setFrames
(3)當(dāng)動(dòng)畫(huà)結(jié)束時(shí),是否還原為第一幀 setRestoreOriginalFrame
(4)動(dòng)畫(huà)重復(fù)執(zhí)行次數(shù) setLoops
// /** * 單位幀間隔、間隔幀數(shù)、動(dòng)畫(huà)總時(shí)間 * setDelayPerUnit , getTotalDelayUnits , getDuration */ //設(shè)置單位幀間隔delayPerUnit秒 void setDelayPerUnit(float); float getDelayPerUnit(); //間隔幀數(shù)的總和totalDelayUnits //即:每個(gè)精靈幀到下一精靈幀的間隔幀數(shù)之和 float getTotalDelayUnits(); //動(dòng)畫(huà)總時(shí)間:delayPerUnit * totalDelayUnits float getDuration(); /** * 其他屬性設(shè)置 * setFrames , setRestoreOriginalFrame , setLoops */ //設(shè)置動(dòng)畫(huà)幀CCAnimationFrames數(shù)組 void setFrames(CCArray* pAnimationFrames); CCArray* getFrames(); //當(dāng)動(dòng)畫(huà)結(jié)束時(shí),是否還原為第一幀 void setRestoreOriginalFrame(bool); bool getRestoreOriginalFrame(); //動(dòng)畫(huà)執(zhí)行次數(shù) //0表示不執(zhí)行動(dòng)畫(huà),1表示執(zhí)行1次,……,-1表示無(wú)限循環(huán) void setLoops(unsigned int ); unsigned int getLoops(); //
3、CCAnimate
CCAnimate是用來(lái)真正執(zhí)行CCAnimation動(dòng)畫(huà)的動(dòng)作類。
創(chuàng)建及使用方法如下:
// //使用CCAnimation創(chuàng)建CCAnimate CCAnimate* animate = CCAnimate::create(animation); sprite->runAction(animate); //運(yùn)行動(dòng)畫(huà)動(dòng)作 //
【代碼實(shí)戰(zhàn)】
代碼資源來(lái)自官方TestCpp。
下面例舉創(chuàng)建動(dòng)畫(huà)動(dòng)作CCAnimation/CCAnimate的三種方式。
1、圖片資源
2、直接使用圖片資源
每個(gè)動(dòng)畫(huà)幀的間隔幀數(shù)均為: 1
單位幀間隔 : 2.0/14.0 秒
連續(xù)兩動(dòng)畫(huà)幀的時(shí)間間隔為: 2.0/14.0 * 1 秒
// //創(chuàng)建精靈sprite CCSprite* sprite = CCSprite::create("Animation/dance_00.png"); sprite->setPosition( mysize/2 ); this->addChild(sprite); //創(chuàng)建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); //添加動(dòng)畫(huà)幀 } //設(shè)置屬性 animation->setRestoreOriginalFrame(true); //還原第一幀 animation->setDelayPerUnit(2.0/14.0); //單位幀間隔 animation->setLoops(-1); //-1無(wú)限循環(huán) //創(chuàng)建CCAnimate CCAnimate* animate = CCAnimate::create(animation); //執(zhí)行動(dòng)畫(huà)動(dòng)作 sprite->runAction(animate); //
3、使用精靈幀
每個(gè)動(dòng)畫(huà)幀的間隔幀數(shù)均為: 1
單位幀間隔 : 2.0/14.0 秒
連續(xù)兩動(dòng)畫(huà)幀的時(shí)間間隔為: 2.0/14.0 * 1 秒
注意:使用精靈幀數(shù)組創(chuàng)建CCAnimation時(shí),是createWithSpriteFrames,不是create。
// //創(chuàng)建精靈sprite CCSprite* sprite = CCSprite::create("Animation/dance_00.png"); sprite->setPosition( mysize/2 ); this->addChild(sprite); //創(chuàng)建CCAnimation //將plist批處理的多張圖片,添加到精靈幀緩沖池中 CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile("Animation/grossini.plist"); //創(chuàng)建精靈幀CCSpriteFrame數(shù)組 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); } //使用精靈幀數(shù)組創(chuàng)建,單位幀間隔為2.0/14.0秒 CCAnimation* animation = CCAnimation::createWithSpriteFrames(array, 2.0/14.0); //屬性設(shè)置 animation->setRestoreOriginalFrame(true); //還原第一幀 animation->setLoops(-1); //無(wú)線循環(huán) //創(chuàng)建CCAnimate CCAnimate* animate = CCAnimate::create(animation); //執(zhí)行動(dòng)畫(huà)動(dòng)作 sprite->runAction(animate); //
4、使用動(dòng)畫(huà)幀
每個(gè)動(dòng)畫(huà)幀的間隔幀數(shù)均為: 1
單位幀間隔 : 0.2 秒
連續(xù)兩動(dòng)畫(huà)幀的時(shí)間間隔為: 0.2 * i 秒(第i個(gè)動(dòng)畫(huà)幀到第i+1個(gè)動(dòng)畫(huà)幀的延遲時(shí)間)
// //創(chuàng)建精靈sprite CCSprite* sprite = CCSprite::create("Animation/dance_00.png"); sprite->setPosition( mysize/2 ); this->addChild(sprite); //創(chuàng)建CCAnimation //將plist批處理的多張圖片,添加到精靈幀緩沖 CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile("Animation/grossini.plist"); //創(chuàng)建動(dòng)畫(huà)幀CCAnimationFrame數(shù)組 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); //設(shè)置精靈幀 animationFrame->setDelayUnits( i ); //設(shè)置間隔幀數(shù) array->addObject(animationFrame); } //使用動(dòng)畫(huà)幀數(shù)組創(chuàng)建,單位幀間隔0.2秒 CCAnimation* animation = CCAnimation::create(array, 0.2f); animation->setRestoreOriginalFrame(true); animation->setLoops(-1); //創(chuàng)建CCAnimate CCAnimate* animate = CCAnimate::create(animation); //執(zhí)行動(dòng)畫(huà)動(dòng)作 sprite->runAction(animate); //
5、運(yùn)行結(jié)果
6、分析與總結(jié)
(1)仔細(xì)觀察一下第三個(gè)和前兩個(gè)有什么區(qū)別?是不是動(dòng)作執(zhí)行越來(lái)越緩慢了?因?yàn)樽詈笠粡埵怯脛?dòng)畫(huà)幀創(chuàng)建的,并且我設(shè)置了每個(gè)動(dòng)畫(huà)幀的間隔幀數(shù)都不一樣,所以會(huì)有如上的效果。
(2)更多的使用方法,自行琢磨,加油!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。