1. 程式人生 > >【Cocos2dx】基本動作、動作序列與動作合併

【Cocos2dx】基本動作、動作序列與動作合併

之前幾篇關於Cocos2dx的文章都是從一些靜態的事物入手,比如控制元件、場景什麼的。其實,Cocos2dx中提供了大量動作實現方法,移動一個精靈並不是那麼費事,直接呼叫該方法即可,唯一的難點就是多個動作如何組合起來,下面用一個例子來說明這個問題。

做出如下的例項:

有一個已經被玩爛的自帶按鈕精靈,首先閃爍3下,之後向上移動,等待1秒之後向下跳動,之後旋轉緩慢下落。

這個效果很贊很贊,如果要用Flash等其它語言去搞不知道要浪費多少關鍵幀與程式碼,但是Cocos2dx實現起來就很簡單了。


製作過程如下:

首先還是新建一個用cpp語言寫的名為moveAction的Cocos2dx工程,開啟裡面proj.win32的HelloCpp.sln開始程式編寫,此步驟已經在此前文章多次提及,不會的可以參看《【Cocos2dx】Windows平臺下Cocos2dx 2.x的下載、安裝、配置,打造自己的Helloworld》(

點選開啟連結)。

之後,在AppDelegate.cpp關掉除錯資訊之後,直接對HelloWorldScene.cpp修改成如下,重點對其中的bool HelloWorld::init()函式進行修改:

#include "HelloWorldScene.h"

USING_NS_CC;

CCScene* HelloWorld::scene()
{
	// 'scene' is an autorelease object
	CCScene *scene = CCScene::create();

	// 'layer' is an autorelease object
	HelloWorld *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()
{
	//獲取螢幕的尺寸、位置資訊等      
	CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();    

	//設定精靈,並把精靈新增到舞臺的中央
	CCSprite *sprite=CCSprite::create("CloseSelected.png");
	sprite->setPosition(ccp(visibleSize.width/2,visibleSize.height/2));
	this->addChild(sprite);

	//設定動作
	//動作1
	CCFiniteTimeAction* action1=CCBlink::create(1.0f,3); //在一秒內閃爍三次
	//動作2
	CCFiniteTimeAction* action2_1=CCMoveBy::create(1.0f,ccp(0,100)); //在1秒內提升100px
	CCFiniteTimeAction* action2_2=CCMoveBy::create(1.0f,ccp(0,0)); //等待1秒
	CCFiniteTimeAction* action2_3=CCJumpBy::create(0.75f,ccp(0,-50),20,3); //在0.75秒內,先跳起20px再共落下50px,該動作重複3次,也就只最後會向下移動90px
	CCFiniteTimeAction* action2=CCSequence::create(action2_1, action2_2, action2_3 , NULL); //合併上述動作成動作序列Action2
	//動作3
	float action3_time=5.0f;
	CCFiniteTimeAction* action3_1=CCRotateBy::create(action3_time,-3600);//5秒內逆時針方向轉動-3600度
	CCFiniteTimeAction* action3_2=CCMoveTo::create(action3_time,ccp(visibleSize.width/2,sprite->getContentSize().height));//5秒內移到螢幕的底部
	CCFiniteTimeAction* action3=CCSpawn::create(action3_1,action3_2,NULL); //將上述兩個動作組合起來,即兩個動作同時進行

	//合併上述動作,並應用到精靈
	CCFiniteTimeAction* sequence=CCSequence::create(action1,action2,action3,NULL);
	sprite->runAction(sequence);
	return true;
}


void HelloWorld::menuCloseCallback(CCObject* pSender)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
	CCMessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert");
#else
	CCDirector::sharedDirector()->end();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
	exit(0);
#endif
#endif
}

其中,這裡有幾點是需要注意的。

(1)CCBlink、CCMoveBy、CCJumpBy、CCRotateBy、CCMoveTo皆是一些基本動作,CCSequence與CCSpawn則為這些動作的符合體。

(2)CCMoveBy與CCMoveTo的區別,就是“移動了”與“移動到”的區別。CCMoveBy是在(x,y)方向“移動了”(x_num,y_num)的座標,CCMoveTo是移動到(x,y)。

(3)原地停頓1秒,根本就不需要用到什麼定時器之類的複雜東西,就是要求精靈在1秒內在(x,y)方向各移動0px

(4)如何需要做完一個動作,再做一個動作,不可以不使用CCSequence。比如上述的程式碼的動作1,先上升100px再停1秒最後向下跳躍,如果不使用CCFiniteTimeAction* action2=CCSequence::create(action2_1, action2_2, action2_3 , NULL); 將其合併起來,精靈會不知道做什麼方向的移動。

(5)CCSequence與CCSpawn的區別,CCSequence是做完1個動作再做1個動作,CCSpawn則是所有動作,一起進行,所以被CCSpawn的動作,其執行時間應該是一致的。

(6)無論是CCSequence與CCSpawn,組合動作,皆需要注意,最後一個動作必須為NULL,否則會出現如下情況,無法過編譯,我也不知道是什麼回事:


(7)所有基本動作CCBlink、CCMoveBy、CCJumpBy、CCRotateBy、CCMoveTo與動作的集合體CCSequence、CCSpawn皆屬於CCFiniteTimeAction,雖然存在CCFiniteTimeAction是CCAction的子類的關係,如下圖:


然而並不能像Java中的ArrayList與List互換那樣,將CCFiniteTimeAction換成CCAction,雖然按理說子類可以換成其更抽象的父類,然而,我也不知道為何,更換之後也是無法通過編譯的,出現如下圖的情況,所以玩Cocos2dx的動作,還是好好用CCFiniteTimeAction: