在这一篇,我们来详细了解下动作例子
首先我们找到这个文件夹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);//上一个按钮的响应函数
};
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