cocos2d学习之tests实例场景切换(2)

来源:互联网 发布:罗技k260配对软件 编辑:程序博客网 时间:2024/06/05 07:48

以上界面是在上一篇文章的基础上制作的,本来想写点什么,可是模仿者那个tests例子,很快就做出来了,没什么好讲的。只是感觉c++的各种引入头文件或者类的定义的习惯和java不太一样,只是有些不习惯,慢慢来吧。

下面我们继续往下钻。

上次到了tests实例的主界面,往下,是重点,今天学习一下场景的动态切换。既Transitions Test这个标签点击之后诱发的各种场景切换。这个功能首先很实用,在游戏中,经常会有场景的变化,为了让场景设计不至于过于呆板,cocos2d-x给我们提供了很多的类来实现场景切换效果。等会儿将会用到。

首先,让我们从主界面一步步进去吧。

点击主界面上的Transitions Test标签,将会进入第一个场景。


这里没有任何切换效果,只是单纯的replace。

先看看如何进到这里面的吧。

void TestController::menuCallback(CCObject * pSender){    // get the userdata, it's the index of the menu item clicked    CCMenuItem* pMenuItem = (CCMenuItem *)(pSender);    int nIdx = pMenuItem->getZOrder() - 10000;    // create the test scene and run it    TestScene* pScene = CreateTestScene(nIdx);    if (pScene)    {        pScene->runThisTest();        pScene->release();    }}
以上是主界面上的menuItem的点击事件代码。看这代码,说白了就是创建一个场景,然后run它。再深一步,去看CreateTestScene方法,代码如下:

static TestScene* CreateTestScene(int nIdx){// 清空缓存CCDirector::sharedDirector()->purgeCachedData();TestScene* pScene = NULL;switch (nIdx){case TEST_ACTION_MANAGER:pScene = new ActionManagerTestScene();break;// 中间部分的代码过长,省略到这部分。如果需要完整代码,请参考Cocos2D-x 引擎目录下tests// 项目的controller.cpp 文件default:break;}return pScene;}

就是生成不同的Scene,先不管这些Scene有哪些不同,至少他们都是TestScene类型,这种类型还不太了解,点进去看看

class TestScene : public CCScene{public:     TestScene(bool bPortrait = false);    virtual void onEnter();    virtual void runThisTest() = 0;    // The CallBack for back to the main menu scene    virtual void MainMenuCallback(CCObject* pSender);protected:    bool m_bPortrait; // indicate if this test case requires portrait mode};

这个是它的定义,继承了CCScene,同时,重写了onEnter方法,在显示CCScene的时候,会自动加载这个方法。

去看下CCScene中的方法吧,既然主菜单上的哪些按钮点击之后弹出的场景都继承了它,那么它肯定会有一些通用的地方。下面是这个类的方法:

TestScene::TestScene(bool bPortrait):m_bPortrait(bPortrait){    if (m_bPortrait)    {        CCDirector::sharedDirector()->setDeviceOrientation(CCDeviceOrientationLandscapeRight);    }        CCScene::init();}void TestScene::onEnter(){    CCScene::onEnter();        CCLabelTTF* label = CCLabelTTF::labelWithString("MainMenu", "Arial", 20);    CCMenuItemLabel* pMenuItem = CCMenuItemLabel::itemWithLabel(label, this, menu_selector(TestScene::MainMenuCallback));    CCMenu* pMenu =CCMenu::menuWithItems(pMenuItem, NULL);    CCSize s = CCDirector::sharedDirector()->getWinSize();    pMenu->setPosition( CCPointZero );    pMenuItem->setPosition( CCPointMake( s.width - 50, 25) );    addChild(pMenu, 1);}void TestScene::MainMenuCallback(CCObject* pSender){    CCScene* pScene = CCScene::node();    CCLayer* pLayer = new TestController();    pLayer->autorelease();    pScene->addChild(pLayer);    CCDirector::sharedDirector()->replaceScene(pScene);}

首先是构造方法,貌似没啥用。

然后是onEnter方法,这个方法结合下面的MainMenuCallback方法,往所有场景中都加了一个"MainMenu"按钮,这个按钮可以让场景回到主界面。留意了一下,还真是这样。

好,下面就重点看runThisTest()方法了,因为生成了这个Scene之后,马上就执行了这个方法。进去看看。

一看,所有子类都有这个方法,由于我想等下看场景切换,所以我到TransitionsTestScene这个类下面去看。

void TransitionsTestScene::runThisTest(){    CCLayer * pLayer = new TestLayer1();    addChild(pLayer);    pLayer->release();    CCDirector::sharedDirector()->replaceScene(this);}

很简单的方法,new了个layer,然后放它进去这个Scene里面,然后运行这个Scene。TestLayer1也不过是继承了CCLayer的一个层对象,不是今天重点学习的对象,先不详细看它。但是还得看,因为它其中的按钮出发的点击事件,正是实现的场景的各种切换效果,所以,这是核心内容,。

现在,上面的场景已经出现了。下面可以研究场景切换了。

 CCMenuItemImage *item1 = CCMenuItemImage::itemFromNormalImage(s_pPathB1, s_pPathB2, this, menu_selector(TestLayer1::backCallback) ); CCMenuItemImage *item2 = CCMenuItemImage::itemFromNormalImage(s_pPathR1, s_pPathR2, this, menu_selector(TestLayer1::restartCallback) ); CCMenuItemImage *item3 = CCMenuItemImage::itemFromNormalImage(s_pPathF1, s_pPathF2, this, menu_selector(TestLayer1::nextCallback) );
以上三句话是Layer1中的三个按钮,我只想看三个点击事件是怎么实现的,我猜应该是先new 一个Scene,然后弄一个Layer放进去,放个不同的背景图片以示区分,然后replace掉这个Scene,下面我们去看看。

void TestLayer1::restartCallback(CCObject* pSender){    CCScene* s = new TransitionsTestScene();    CCLayer* pLayer = new TestLayer2();    s->addChild(pLayer);    CCScene* pScene = createTransition(s_nSceneIdx, TRANSITION_DURATION, s);    s->release();    pLayer->release();    if (pScene)    {        CCDirector::sharedDirector()->replaceScene(pScene);    }    }

我先看到了restartCallback方法,就是点击中间的圆点的触发事件,首先,new了一个TransitionTestScene,由于没有执行runTest方法,所以其实就是一个TestScene.,然后,放一个Layer2进去,到这里还和我想的一样,重点一句来了

 CCScene* pScene = createTransition(s_nSceneIdx, TRANSITION_DURATION, s);
这句话后面我的理解就是,通过刚才生成的Scene,给它包装,再生成一个新的Scene,后来把它显示出来,由于包装过了,所以显示的时候,会有一些效果。

还是去看看createTransition方法吧

CCTransitionScene* createTransition(int nIndex, ccTime t, CCScene* s){    // fix bug #486, without setDepthTest(false), FlipX,Y will flickers    CCDirector::sharedDirector()->setDepthTest(false);    switch(nIndex)    {    case 0: return CCTransitionJumpZoom::transitionWithDuration(t, s);    case 1: return CCTransitionFade::transitionWithDuration(t, s);    case 2: return FadeWhiteTransition::transitionWithDuration(t, s);    case 3: return FlipXLeftOver::transitionWithDuration(t, s);    case 4: return FlipXRightOver::transitionWithDuration(t, s);    case 5: return FlipYUpOver::transitionWithDuration(t, s);    case 6: return FlipYDownOver::transitionWithDuration(t, s);。。。。。。

看了这么几行,已经明白了,返回一个继承CCScene的CCTransitionScene,其中,case中调用不同的CCTransitionScene的子类的transitionWithDuration(t,s)方法,第一个参数是事件,第二个参数就是将要跳转的场景。
来生成效果场景。第一个参数T是过场动画时间,第二个参数s是刚才包装的Scene,其实也是跳转到的Scene,至于哪个类实现了哪个效果,自己一个个去试吧,貌似挺好玩的。。。

今天我会在我的只有一个主界面的打飞机游戏上加上一个场景切换效果,模拟进入游戏。

奋斗