【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: