溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

cocos2dx基礎(chǔ)篇(24)——基本動(dòng)畫(huà)CCAnimation/CCAnimate

發(fā)布時(shí)間:2020-06-18 14:26:39 來(lái)源:網(wǎng)絡(luò) 閱讀:16970 作者:shahdza 欄目:開(kāi)發(fā)技術(shù)

【嘮叨】

    基本動(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)的中文名,純屬自己歪歪,只是為了方便自己記憶罷了。cocos2dx基礎(chǔ)篇(24)——基本動(dòng)畫(huà)CCAnimation/CCAnimate

    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、圖片資源

cocos2dx基礎(chǔ)篇(24)——基本動(dòng)畫(huà)CCAnimation/CCAnimate


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é)果

cocos2dx基礎(chǔ)篇(24)——基本動(dòng)畫(huà)CCAnimation/CCAnimate


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)更多的使用方法,自行琢磨,加油!cocos2dx基礎(chǔ)篇(24)——基本動(dòng)畫(huà)CCAnimation/CCAnimate



向AI問(wèn)一下細(xì)節(jié)

免責(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)容。

AI