cocos2d-x之TestCPP例子解析(2)-ActionsTest



在這一篇,我們來詳細瞭解下動作例子

首先我們找到這個文件夾ActionsTest,就2個文件。


好的,我們運行測試程序,點擊ActionsTest菜單,進入動作測試,如下圖所示


這是動作測試的第一個圖層,右下角的MainMenu就是我們上一篇中TestScene的onEnter()中創建的!


首先我們來看頭文件

#ifndef _ActionsTest_H_
#define _ActionsTest_H_

#include "../testBasic.h"  //需要用的TestScene
////----#include "cocos2d.h"

USING_NS_CC;

//創建了一個枚舉,用於標識不同的動作
enum
{
    ACTION_MANUAL_LAYER = 0,
    ACTION_MOVE_LAYER,
    ACTION_SCALE_LAYER,
    ACTION_ROTATE_LAYER,
    ACTION_SKEW_LAYER,
    ACTION_ROTATIONAL_SKEW_LAYER,
    ACTION_ROTATIONAL_SKEW_VS_STANDARD_SKEW_LAYER,
    ACTION_SKEWROTATE_LAYER,
    ACTION_JUMP_LAYER,
    ACTION_CARDINALSPLINE_LAYER,
    ACTION_CATMULLROM_LAYER,
    ACTION_BEZIER_LAYER,
    ACTION_BLINK_LAYER,
    ACTION_FADE_LAYER,
    ACTION_TINT_LAYER,
    ACTION_ANIMATE_LAYER,
    ACTION_SEQUENCE_LAYER,
    ACTION_SEQUENCE2_LAYER,
    ACTION_SPAWN_LAYER,
    ACTION_REVERSE,
    ACTION_DELAYTIME_LAYER,
    ACTION_REPEAT_LAYER,
    ACTION_REPEATEFOREVER_LAYER,
    ACTION_ROTATETOREPEATE_LAYER,
    ACTION_ROTATEJERK_LAYER,
    ACTION_CALLFUNC_LAYER,
    ACTION_CALLFUNCND_LAYER,
    ACTION_REVERSESEQUENCE_LAYER,
    ACTION_REVERSESEQUENCE2_LAYER,
    ACTION_ORBIT_LAYER,
    ACTION_FLLOW_LAYER,
    ACTION_TARGETED_LAYER,
    PAUSERESUMEACTIONS_LAYER,
    ACTION_ISSUE1305_LAYER,
    ACTION_ISSUE1305_2_LAYER,
    ACTION_ISSUE1288_LAYER,
    ACTION_ISSUE1288_2_LAYER,
    ACTION_ISSUE1327_LAYER,
    ACTION_ISSUE1398_LAYER,
    ACTION_LAYER_COUNT,
    ACTION_REMOVE_SELF,
};

接下來是2個關鍵的類

class ActionsTestScene : public TestScene
{
public:
    virtual void runThisTest();//重載了該函數,在此用進行圖層替換
};

class ActionsDemo : public CCLayer//定義一個動作demo的基類,下面不同動作的layer的一些共同的操作再次實現
{
protected:
    CCSprite*    m_grossini;//中間那個光頭的男人
    CCSprite*    m_tamara;//左邊那個妹紙
    CCSprite*    m_kathia;//右邊那個爆炸頭的妹紙
public:
    virtual void onEnter();
    virtual void onExit();

    void centerSprites(unsigned int numberOfSprites);
    void alignSpritesLeft(unsigned int numberOfSprites);
    virtual std::string title();//返回總標題
    virtual std::string subtitle();//返回各動作的名稱

    void restartCallback(CCObject* pSender);//重置按鈕的響應函數
    void nextCallback(CCObject* pSender);//下一個按鈕的響應函數
    void backCallback(CCObject* pSender);//上一個按鈕的響應函數
};


在下面就是各個動作的類分別重載了onEnter和subtitle

class ActionManual : public ActionsDemo
{
public:
    virtual void onEnter();
    virtual std::string subtitle();
};

好的,現在我們來看下CPP文件

#include "ActionsTest.h"
#include "../testResource.h"
#include "cocos2d.h"
//可算用到了,這個就是我們在testBasic測試基類中定義的宏函數,定義了一個創建layerde的宏函數
TESTLAYER_CREATE_FUNC(ActionManual);
TESTLAYER_CREATE_FUNC(ActionMove);
TESTLAYER_CREATE_FUNC(ActionRotate);
TESTLAYER_CREATE_FUNC(ActionScale);
TESTLAYER_CREATE_FUNC(ActionSkew);
TESTLAYER_CREATE_FUNC(ActionRotationalSkew);
TESTLAYER_CREATE_FUNC(ActionRotationalSkewVSStandardSkew);
TESTLAYER_CREATE_FUNC(ActionSkewRotateScale);
TESTLAYER_CREATE_FUNC(ActionJump);
TESTLAYER_CREATE_FUNC(ActionCardinalSpline);
TESTLAYER_CREATE_FUNC(ActionCatmullRom);
TESTLAYER_CREATE_FUNC(ActionBezier);
TESTLAYER_CREATE_FUNC(ActionBlink);
TESTLAYER_CREATE_FUNC(ActionFade);
TESTLAYER_CREATE_FUNC(ActionTint);
TESTLAYER_CREATE_FUNC(ActionAnimate);
TESTLAYER_CREATE_FUNC(ActionSequence);
TESTLAYER_CREATE_FUNC(ActionSequence2);
TESTLAYER_CREATE_FUNC(ActionSpawn);
TESTLAYER_CREATE_FUNC(ActionReverse);
TESTLAYER_CREATE_FUNC(ActionDelayTime);
TESTLAYER_CREATE_FUNC(ActionRepeat);
TESTLAYER_CREATE_FUNC(ActionRepeatForever);
TESTLAYER_CREATE_FUNC(ActionRotateToRepeat);
TESTLAYER_CREATE_FUNC(ActionRotateJerk);
TESTLAYER_CREATE_FUNC(ActionCallFunc);
TESTLAYER_CREATE_FUNC(ActionCallFuncND);
TESTLAYER_CREATE_FUNC(ActionReverseSequence);
TESTLAYER_CREATE_FUNC(ActionReverseSequence2);
TESTLAYER_CREATE_FUNC(ActionRemoveSelf);
TESTLAYER_CREATE_FUNC(ActionOrbit);
TESTLAYER_CREATE_FUNC(ActionFollow);
TESTLAYER_CREATE_FUNC(ActionTargeted);
TESTLAYER_CREATE_FUNC(ActionMoveStacked);
TESTLAYER_CREATE_FUNC(ActionMoveJumpStacked);
TESTLAYER_CREATE_FUNC(ActionMoveBezierStacked);
TESTLAYER_CREATE_FUNC(ActionCardinalSplineStacked);
TESTLAYER_CREATE_FUNC(ActionCatmullRomStacked);
TESTLAYER_CREATE_FUNC(PauseResumeActions);
TESTLAYER_CREATE_FUNC(Issue1305);
TESTLAYER_CREATE_FUNC(Issue1305_2);
TESTLAYER_CREATE_FUNC(Issue1288);
TESTLAYER_CREATE_FUNC(Issue1288_2);
TESTLAYER_CREATE_FUNC(Issue1327);
TESTLAYER_CREATE_FUNC(Issue1398);


下面就是調用上面創建的宏函數了,一個靜態的layer指針數組,到時候替換圖層時就是從這裏面獲取layer指針了

static NEWTESTFUNC createFunctions[] = {
    CF(ActionManual),
    CF(ActionMove),
    CF(ActionRotate),
    CF(ActionScale),
    CF(ActionSkew),
    CF(ActionRotationalSkew),
    CF(ActionRotationalSkewVSStandardSkew),
    CF(ActionSkewRotateScale),
    CF(ActionJump),
    CF(ActionCardinalSpline),
    CF(ActionCatmullRom),
    CF(ActionBezier),
    CF(ActionBlink),
    CF(ActionFade),
    CF(ActionTint),
    CF(ActionAnimate),
    CF(ActionSequence),
    CF(ActionSequence2),
    CF(ActionRemoveSelf),
    CF(ActionSpawn),
    CF(ActionReverse),
    CF(ActionDelayTime),
    CF(ActionRepeat),
    CF(ActionRepeatForever),
    CF(ActionRotateToRepeat),
    CF(ActionRotateJerk),
    CF(ActionCallFunc),
    CF(ActionCallFuncND),
    CF(ActionReverseSequence),
    CF(ActionReverseSequence2),
    CF(ActionOrbit),
    CF(ActionFollow),
    CF(ActionTargeted),
    CF(ActionMoveStacked),
    CF(ActionMoveJumpStacked),
    CF(ActionMoveBezierStacked),
    CF(ActionCardinalSplineStacked),
    CF(ActionCatmullRomStacked),
    CF(PauseResumeActions),
    CF(Issue1305),
    CF(Issue1305_2),
    CF(Issue1288),
    CF(Issue1288_2),
    CF(Issue1327),
    CF(Issue1398)
};

下面就是那2個重要的類的定義了

static int sceneIdx=-1;//場景索引初始化
#define MAX_LAYER (sizeof(createFunctions) / sizeof(createFunctions[0]))//通過這種方式獲取數組的個數

static CCLayer* nextAction()//創建下一個動作layer
{
    sceneIdx++;
    sceneIdx = sceneIdx % MAX_LAYER;//當場景索引大於總場景數,回到第一個
    
    CCLayer* pLayer = (createFunctions[sceneIdx])();
    pLayer->init();
    pLayer->autorelease();
    
    return pLayer;
}

static CCLayer* backAction()
{
    sceneIdx--;
    int total = MAX_LAYER;
    if( sceneIdx < 0 )//與上面的類似,第一個圖層再往回滾就是最後一個
        sceneIdx += total;
    
    CCLayer* pLayer = (createFunctions[sceneIdx])();
    pLayer->init();
    pLayer->autorelease();
    
    return pLayer;
}

static CCLayer* restartAction()//重置圖層,重建創建一個當前圖層
{
    CCLayer* pLayer = (createFunctions[sceneIdx])();
    pLayer->init();
    pLayer->autorelease();
    
    return pLayer;
}

void ActionsTestScene::runThisTest()
{
    sceneIdx = -1;
    addChild(nextAction());

    CCDirector::sharedDirector()->replaceScene(this);
}


std::string ActionsDemo::title()
{
    return "ActionsTest";
}

std::string ActionsDemo::subtitle()
{
    return "";
}



void ActionsDemo::onEnter()
{
    CCLayer::onEnter();

    // Or you can create an sprite using a filename. only PNG is supported now. Probably TIFF too
    m_grossini = CCSprite::create(s_pPathGrossini);
    m_grossini->retain();

    m_tamara = CCSprite::create(s_pPathSister1); 
    m_tamara->retain();

    m_kathia = CCSprite::create(s_pPathSister2);
    m_kathia->retain();

    addChild(m_grossini, 1);
    addChild(m_tamara, 2);
    addChild(m_kathia, 3);

    m_grossini->setPosition(ccp(VisibleRect::center().x, VisibleRect::bottom().y+VisibleRect::getVisibleRect().size.height/3));
    m_tamara->setPosition(ccp(VisibleRect::center().x, VisibleRect::bottom().y+VisibleRect::getVisibleRect().size.height*2/3));
    m_kathia->setPosition(ccp(VisibleRect::center().x, VisibleRect::bottom().y+VisibleRect::getVisibleRect().size.height/2)); 

    // add title and subtitle
    std::string str = title();
    const char * pTitle = str.c_str();
    CCLabelTTF* label = CCLabelTTF::create(pTitle, "Arial", 32);
    addChild(label, 1);
    label->setPosition( ccp(VisibleRect::center().x, VisibleRect::top().y - 30) );

    std::string strSubtitle = subtitle();
    if( ! strSubtitle.empty() ) 
    {
        CCLabelTTF* l = CCLabelTTF::create(strSubtitle.c_str(), "Thonburi", 16);
        addChild(l, 1);
        l->setPosition( ccp(VisibleRect::center().x, VisibleRect::top().y - 60) );
    }    

    // add menu
    CCMenuItemImage *item1 = CCMenuItemImage::create(s_pPathB1, s_pPathB2, this, menu_selector(ActionsDemo::backCallback) );
    CCMenuItemImage *item2 = CCMenuItemImage::create(s_pPathR1, s_pPathR2, this, menu_selector(ActionsDemo::restartCallback) );
    CCMenuItemImage *item3 = CCMenuItemImage::create(s_pPathF1, s_pPathF2, this, menu_selector(ActionsDemo::nextCallback) );

    CCMenu *menu = CCMenu::create(item1, item2, item3, NULL);

    menu->setPosition(CCPointZero);
    item1->setPosition(ccp(VisibleRect::center().x - item2->getContentSize().width*2, VisibleRect::bottom().y+item2->getContentSize().height/2));
    item2->setPosition(ccp(VisibleRect::center().x, VisibleRect::bottom().y+item2->getContentSize().height/2));
    item3->setPosition(ccp(VisibleRect::center().x + item2->getContentSize().width*2, VisibleRect::bottom().y+item2->getContentSize().height/2));

    addChild(menu, 1);
}

void ActionsDemo::onExit()
{
    m_grossini->release();
    m_tamara->release();
    m_kathia->release();

    CCLayer::onExit();
}

void ActionsDemo::restartCallback(CCObject* pSender)
{
    CCScene* s = new ActionsTestScene();
    s->addChild( restartAction() );
    CCDirector::sharedDirector()->replaceScene(s);
    s->release();
}

void ActionsDemo::nextCallback(CCObject* pSender)
{
    CCScene* s = new ActionsTestScene();
    s->addChild( nextAction() );
    CCDirector::sharedDirector()->replaceScene(s);
    s->release();
}

void ActionsDemo::backCallback(CCObject* pSender)
{
    CCScene* s = new ActionsTestScene();
    s->addChild( backAction() );
    CCDirector::sharedDirector()->replaceScene(s);
    s->release();
}
//這個函數用於指定需要幾位演員出場時如果要求居中對齊該怎麼站位
void ActionsDemo::centerSprites(unsigned int numberOfSprites){ CCSize s = CCDirector::sharedDirector()->getWinSize(); if( numberOfSprites == 0 ) { m_tamara->setVisible(false); m_kathia->setVisible(false); m_grossini->setVisible(false); } else if ( numberOfSprites == 1 ) { m_tamara->setVisible(false); m_kathia->setVisible(false); m_grossini->setPosition(ccp(s.width/2, s.height/2)); } else if( numberOfSprites == 2 ) { m_kathia->setPosition( ccp(s.width/3, s.height/2)); m_tamara->setPosition( ccp(2*s.width/3, s.height/2)); m_grossini->setVisible(false); } else if( numberOfSprites == 3 ) { m_grossini->setPosition( ccp(s.width/2, s.height/2)); m_tamara->setPosition( ccp(s.width/4, s.height/2)); m_kathia->setPosition( ccp(3 * s.width/4, s.height/2)); }}//這個函數用於指定需要幾位演員出場時如果要求居左對齊該怎麼站位。同上,只是位置略有差別。  void ActionsDemo::alignSpritesLeft(unsigned int numberOfSprites){ CCSize s = CCDirector::sharedDirector()->getWinSize(); if( numberOfSprites == 1 ) { m_tamara->setVisible(false); m_kathia->setVisible(false); m_grossini->setPosition(ccp(60, s.height/2)); } else if( numberOfSprites == 2 ) { m_kathia->setPosition( ccp(60, s.height/3)); m_tamara->setPosition( ccp(60, 2*s.height/3)); m_grossini->setVisible( false ); } else if( numberOfSprites == 3 ) { m_grossini->setPosition( ccp(60, s.height/2)); m_tamara->setPosition( ccp(60, 2*s.height/3)); m_kathia->setPosition( ccp(60, s.height/3)); }}


在下面就是一堆詳細動作類的重載,例如第一個

//------------------------------------------------------------------
//
// ActionManual
//
//------------------------------------------------------------------
void ActionManual::onEnter()
{
    ActionsDemo::onEnter();

    CCSize s = CCDirector::sharedDirector()->getWinSize();

    m_tamara->setScaleX( 2.5f);
    m_tamara->setScaleY( -1.0f);
    m_tamara->setPosition( ccp(100,70) );
    m_tamara->setOpacity( 128);//設置透明度,0-255,0爲

    m_grossini->setRotation( 120);
    m_grossini->setPosition( ccp(s.width/2, s.height/2));
    m_grossini->setColor( ccc3( 255,0,0));

    m_kathia->setPosition( ccp(s.width-100, s.height/2));
    m_kathia->setColor( ccBLUE);
}

std::string ActionManual::subtitle()
{
    return "Manual Transformation";
}

以下更加詳細內容再次不贅述了,已經有高手將每一段代碼都註釋了

傳送門在此:http://blog.csdn.net/honghaier/article/details/8266454





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章