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





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值