zoukankan      html  css  js  c++  java
  • Cocos2d-x 2.0 TestCpp框架源码分析

     好的引擎,会提供一系列完整的功能示例,Cocos2d-x之所以能得到很多人的喜爱,其重要的原因是它提供了丰富而易学的示例。在cocos2d-2.0-x-2.0.2中这些示例被放在一个名叫TestCpp的工程中,为了更好的学习Cocos2d-x的功能示例,我们今天来学习一下这个工程的框架结构。

     

             在VS的解决方案里展开TestCpp工程,其下有43个示例目录,除此之前还有几个文件:

     

    AppDelegate.h/cpp : 程序控制类AppDelegate 。

    controller.h/cpp:示例场景管理类TestController,用于显示所有示例的菜单。

    testBasic.h/cpp:示例场景基类TestScene,用于返回到主界面场景。

    testResource.h:文件资源名称字符串定义头文件

    tests.h:示例总头文件

    main.h/cpp:主函数及头文件

     

              所有的示例都是写在单独的由TestScene派生场景类中,在这些场景中加入一些由CCLayer派生的示例对象来实现相应功能的展示。

     

              与HelloWorld一样,我们需要在main.cpp中创建AppDelegate实例,并设置窗口大小,启动游戏程序。


    [cpp]
    #include "main.h" 
    #include "AppDelegate.h" 
    #include "CCEGLView.h" 
    USING_NS_CC; 
    //WIN32程序主函数 
    int APIENTRY _tWinMain(HINSTANCE hInstance, 
                           HINSTANCE hPrevInstance, 
                           LPTSTR    lpCmdLine, 
                           int       nCmdShow) 

        UNREFERENCED_PARAMETER(hPrevInstance); 
        UNREFERENCED_PARAMETER(lpCmdLine); 
        //实例化一个Cocos2d-x程序对象 
        AppDelegate app; 
        //创建OpenGL视窗并设置窗口大小 
        CCEGLView* eglView = CCEGLView::sharedOpenGLView(); 
        eglView->setFrameSize(480, 320); 
        //运行程序对象 
        return CCApplication::sharedApplication()->run(); 

     

        在AppDelegate.cpp中的boolAppDelegate::applicationDid。FinishLaunching()函数中创建场景并运行场景

    [cpp] 
    bool AppDelegate::applicationDidFinishLaunching() 

        // 取得当前显示设备指针并设置其OpenGL视窗 
        CCDirector *pDirector = CCDirector::sharedDirector(); 
        pDirector->setOpenGLView(CCEGLView::sharedOpenGLView()); 
        //取得当前运行硬件平台 
        TargetPlatform target = getTargetPlatform(); 
        //如果是IPAD 
        if (target == kTargetIpad) 
        { 
            //如果能启动高清屏,使用高精度资源,否则使用一般精度资源 
            if (pDirector->enableRetinaDisplay(true)) 
            { 
                CCFileUtils::sharedFileUtils()->setResourceDirectory("ipadhd"); 
            } 
            else  
            { 
                CCFileUtils::sharedFileUtils()->setResourceDirectory("ipad"); 
            } 
        } 
        //如果是Iphone 
        else if (target == kTargetIphone) 
        { 
            //如果能启动高清屏,使用高精度资源 
            if (pDirector->enableRetinaDisplay(true)) 
            { 
                CCFileUtils::sharedFileUtils()->setResourceDirectory("hd"); 
            } 
        } 
     
        // 设置FPS信息显示 
        pDirector->setDisplayStats(true); 
     
        //设置帧间隔时间 
        pDirector->setAnimationInterval(1.0 / 60); 
        //在这里创建一个场景 
        CCScene * pScene = CCScene::create(); 
        //实例化一个TestController,它是一个CCLayer。 
        CCLayer * pLayer = new TestController(); 
        //设置由内存管理器来进行自动回收,不必手动DELETE 
        pLayer->autorelease(); 
        //将它放置到场景中 
        pScene->addChild(pLayer); 
        //运行这个新创建的场景。 
        pDirector->runWithScene(pScene); 
     
        return true; 

     

        下面我们来看一下testBase.h/cpp,这里面有一个所有示例都要用到的场景基类TestScene。

    [cpp] 
    #ifndef _TEST_BASIC_H_ 
    #define _TEST_BASIC_H_ 
    //Cocos2d头文件 
    #include "cocos2d.h" 
    //使用Cocos2d命名空间 
    USING_NS_CC; 
    using namespace std; 
     
    class TestScene : public CCScene 

    public:  
        //构造 
        TestScene(bool bPortrait = false); 
        //场景被加载时的回调函数 
        virtual void onEnter(); 
        //自定义的虚函数,用于运行场景。 
        virtual void runThisTest() = 0; 
        //返回主界面的菜单按钮响应回调函数。 
        virtual void MainMenuCallback(CCObject* pSender); 
    }; 
     
    #endif 

    cpp文件:


    [cpp] 
    #include "testBasic.h" 
    #include "controller.h" 
    //构造函数 
    TestScene::TestScene(bool bPortrait) 

         
        CCScene::init(); 

    //场景被加载时的回调函数 
    void TestScene::onEnter() 

        CCScene::onEnter(); 
     
          //#if (CC_TARGET_PLATFORM == CC_PLATFORM_MARMALADE) 
    //    CCLabelBMFont* label = CCLabelBMFont::create("MainMenu",  "fonts/arial16.fnt"); 
    //#else 
        //创建一个文字标签,显示“MainMenu”字符串 
        CCLabelTTF* label = CCLabelTTF::create("MainMenu", "Arial", 20); 
    //#endif 
        //增加一个菜单标签,设定其被按下时的回调函数,用于返回到主界面 
        CCMenuItemLabel* pMenuItem = CCMenuItemLabel::create(label, this, menu_selector(TestScene::MainMenuCallback)); 
        //将菜单标签加入创建的菜单中,并设置相应位置。 
        CCMenu* pMenu =CCMenu::create(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::create(); 
        //新创建一个TestController对象 
        CCLayer* pLayer = new TestController(); 
        pLayer->autorelease(); 
        //将它放入新创建的场景中并运行。 
        pScene->addChild(pLayer); 
        CCDirector::sharedDirector()->replaceScene(pScene); 

     

             在TestScene中,提供了一个可以被点击的标签MainMenu,从字面意思就知道点击它可以返回主菜单界面,这个主菜单在哪呢?就是TestController。

    [cpp] 
    #ifndef _CONTROLLER_H_ 
    #define _CONTROLLER_H_ 
     
    #include "cocos2d.h" 
     
    USING_NS_CC; 
     
    class TestController : public CCLayer 

    public: 
        //构造 
        TestController(); 
        //析构 
        ~TestController(); 
        //菜单项响应回调函数 
        void menuCallback(CCObject * pSender); 
        //关闭程序响应回调函数 
        void closeCallback(CCObject * pSender); 
        //按下触点响应函数。 
        virtual void ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent); 
        //按下状态移动触点响应函数。 
        virtual void ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent); 
     
    private: 
        //接下状态移动触点的开始位置 
        CCPoint m_tBeginPos; 
        //主菜单 
        CCMenu* m_pItemMenu; 
    }; 
     
    #endif 
    进入Cpp看一下:
    [cpp] 
    #include "controller.h" 
    #include "testResource.h" 
    #include "tests.h" 
    //菜单项的行间距 ,设40点 
    #define LINE_SPACE          40 
    //创建一个当前触点位置变量,初始化为左下角位置。 
    static CCPoint s_tCurPos = CCPointZero; 
    //创建指定的示例场景 
    static TestScene* CreateTestScene(int nIdx) 

        //先清空一下显示设备使用的数据 
        CCDirector::sharedDirector()->purgeCachedData(); 
     
        //定义TestScene指针用于接收创建的示例场景 
        TestScene* pScene = NULL; 
        //跟据参数来创建相应的TestScene派生类对象。 
        switch (nIdx) 
        { 
        case TEST_ACTIONS://动画处理 
            pScene = new ActionsTestScene(); break; 
        case TEST_TRANSITIONS://场景切换 
            pScene = new TransitionsTestScene(); break; 
         case TEST_PROGRESS_ACTIONS://进度动画控制 
             pScene = new ProgressActionsTestScene(); break; 
        case TEST_EFFECTS://特效演示 
            pScene = new EffectTestScene(); break; 
        case TEST_CLICK_AND_MOVE://拖动演示 
            pScene = new ClickAndMoveTestScene(); break; 
        case TEST_ROTATE_WORLD://旋转CCLayer 
            pScene = new RotateWorldTestScene(); break; 
        case TEST_PARTICLE://粒子系统 
            pScene = new ParticleTestScene(); break; 
        case TEST_EASE_ACTIONS://多样化运动动画 
            pScene = new ActionsEaseTestScene(); break; 
        case TEST_MOTION_STREAK://拖尾动画效果 
            pScene = new MotionStreakTestScene(); break; 
        case TEST_DRAW_PRIMITIVES://基本图形绘制 
            pScene = new DrawPrimitivesTestScene(); break; 
        case TEST_COCOSNODE://结点控制 
            pScene = new CocosNodeTestScene(); break; 
        case TEST_TOUCHES://触屏处理 
            pScene = new PongScene(); break; 
        case TEST_MENU://菜单处理 
            pScene = new MenuTestScene(); break; 
        case TEST_ACTION_MANAGER://动画管理 
            pScene = new ActionManagerTestScene(); break; 
        case TEST_LAYER://CCLayer功能展示 
            pScene = new LayerTestScene(); break; 
        case TEST_SCENE://CCScene功能展示 
            pScene = new SceneTestScene(); break; 
        case TEST_PARALLAX://视角控制 
            pScene = new ParallaxTestScene(); break; 
        case TEST_TILE_MAP://基于格子的地图 
            pScene = new TileMapTestScene(); break; 
        case TEST_INTERVAL://时间控制 
            pScene = new IntervalTestScene(); break; 
        case TEST_CHIPMUNKACCELTOUCH://ChipMunk物理引擎与多点触屏 
    #if (CC_TARGET_PLATFORM != CC_PLATFORM_MARMALADE) 
            pScene = new ChipmunkAccelTouchTestScene(); break; 
    #else 
    #ifdef MARMALADEUSECHIPMUNK 
    #if    (MARMALADEUSECHIPMUNK == 1) 
            pScene = new ChipmunkAccelTouchTestScene();  
    #endif 
            break; 
    #endif 
    #endif 
        case TEST_LABEL://文字标签 
            pScene = new AtlasTestScene(); break; 
        case TEST_TEXT_INPUT://输入处理 
            pScene = new TextInputTestScene(); break; 
        case TEST_SPRITE://精灵功能展示 
            pScene = new SpriteTestScene(); break; 
        case TEST_SCHEDULER://动画的时间调度 
            pScene = new SchedulerTestScene(); break; 
        case TEST_RENDERTEXTURE://渲染到纹理 
            pScene = new RenderTextureScene(); break; 
        case TEST_TEXTURE2D://纹理功能展示 
            pScene = new TextureTestScene(); break; 
        case TEST_BOX2D://Box2D物理引擎展示 
            pScene = new Box2DTestScene(); break; 
        case TEST_BOX2DBED: //Box2D物理引擎展示[物体的固定与连接] 
            pScene = new Box2dTestBedScene(); break; 
        case TEST_EFFECT_ADVANCE://高级屏幕效果 
            pScene = new EffectAdvanceScene(); break; 
        case TEST_ACCELEROMRTER://加速度 
            pScene = new AccelerometerTestScene(); break; 
    #if (CC_TARGET_PLATFORM != CC_PLATFORM_BADA) 
        case TEST_KEYPAD://键区处理 
            pScene = new KeypadTestScene(); break; 
    #endif 
        case TEST_COCOSDENSHION://声效控制 
            pScene = new CocosDenshionTestScene(); break; 
        case TEST_PERFORMANCE://性能测试 
            pScene = new PerformanceTestScene(); break; 
        case TEST_ZWOPTEX://ZWOPTEX动国 
            pScene = new ZwoptexTestScene(); break; 
    #if (CC_TARGET_PLATFORM != CC_PLATFORM_MARMALADE) 
    // bada don't support libcurl 
    #if (CC_TARGET_PLATFORM != CC_PLATFORM_BADA) 
        case TEST_CURL://网络通信基本演示 
            pScene = new CurlTestScene(); break; 
    #endif 
    #endif 
        case TEST_USERDEFAULT://用户日志保存示例 
            pScene = new UserDefaultTestScene(); break; 
        case TEST_BUGS://BUG示例 
            pScene = new BugsTestScene(); break; 
        case TEST_FONTS://字体演示 
            pScene = new FontTestScene(); break; 
        case TEST_CURRENT_LANGUAGE://获取当前语言 
            pScene = new CurrentLanguageTestScene(); break; 
    #if (CC_TARGET_PLATFORM != CC_PLATFORM_MARMALADE) 
        case TEST_TEXTURECACHE: pScene = new TextureCacheTestScene(); break; 
    #endif 
        case TEST_EXTENSIONS: 
            {   //更多扩展实例 
                pScene = new ExtensionsTestScene(); 
            } 
            break; 
        case TEST_SHADER://使用Shader的渲染演示 
            pScene = new ShaderTestScene(); 
            break; 
        case TEST_MUTITOUCH://多点触屏 
            pScene = new MutiTouchTestScene(); 
            break; 
        default: 
            break; 
        } 
        //返回创建的场景 
        return pScene; 

    //构造函数 
    TestController::TestController() 
    : m_tBeginPos(CCPointZero) 

        // 加入一个关闭菜单按钮 
        CCMenuItemImage *pCloseItem = CCMenuItemImage::create(s_pPathClose, s_pPathClose, this, menu_selector(TestController::closeCallback) ); 
        //创建一个菜单放置关闭按钮 
        CCMenu* pMenu =CCMenu::create(pCloseItem, NULL); 
        CCSize s = CCDirector::sharedDirector()->getWinSize(); 
        //设置这个菜单位置 
        pMenu->setPosition( CCPointZero ); 
        pCloseItem->setPosition(CCPointMake( s.width - 30, s.height - 30)); 
     
        //新建一个测试项菜单,将所有代表测试场景的菜单标签项加入菜单 
        m_pItemMenu = CCMenu::create(); 
        // 
        for (int i = 0; i < TESTS_COUNT; ++i) 
        { 
    // #if (CC_TARGET_PLATFORM == CC_PLATFORM_MARMALADE) 
    //         CCLabelBMFont* label = CCLabelBMFont::create(g_aTestNames[i].c_str(),  "fonts/arial16.fnt"); 
    // #else 
            CCLabelTTF* label = CCLabelTTF::create(g_aTestNames[i].c_str(), "Arial", 24); 
    // #endif         
            CCMenuItemLabel* pMenuItem = CCMenuItemLabel::create(label, this, menu_selector(TestController::menuCallback)); 
            //将代表测试场景的菜单标签加入菜单中,以i+10000的值做为Z值。 
            m_pItemMenu->addChild(pMenuItem, i + 10000); 
            //设置代表测试场景的菜单标签在测试项菜单层的位置 
            pMenuItem->setPosition( CCPointMake( s.width / 2, (s.height - (i + 1) * LINE_SPACE) )); 
        } 
        //设置测试项菜单的大小 
        m_pItemMenu->setContentSize(CCSizeMake(s.width, (TESTS_COUNT + 1) * (LINE_SPACE))); 
        //设置测试项菜单的位置 
        m_pItemMenu->setPosition(s_tCurPos); 
        //将测试项菜单放入当前CCLayer 
        addChild(m_pItemMenu); 
        //设置开启触屏事件响应 
        setTouchEnabled(true); 
        //将关闭按钮项菜单放入当前CCLayer 
        addChild(pMenu, 1); 
     

     
    TestController::~TestController() 


    //点击菜单项的事件响应函数 
    void TestController::menuCallback(CCObject * pSender) 

        // 取得菜单项 
        CCMenuItem* pMenuItem = (CCMenuItem *)(pSender); 
        //取得Z值,减10000算出是第几个菜单项 
        int nIdx = pMenuItem->getZOrder() - 10000; 
     
        //创建相应的场景 
        TestScene* pScene = CreateTestScene(nIdx); 
        if (pScene) 
        { 
            //运行当前测试场景 
            pScene->runThisTest(); 
            //runThisTest中会对其引用计数加1变为2,这里做一次引用计数减1操作,以保证后面再释放场景时可以正常的释放。 
            pScene->release(); 
        } 

    //点击关闭按钮时的响应处理 
    void TestController::closeCallback(CCObject * pSender) 

        //退出程序 
        CCDirector::sharedDirector()->end(); 
    #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS
        exit(0); 
    #endif 

    //触点按下时的响应处理 
    void TestController::ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent) 

        //获取第一个触点位置 
        CCSetIterator it = pTouches->begin(); 
        CCTouch* touch = (CCTouch*)(*it); 
        //将位置保存到变量m_tBeginPos中。 
        m_tBeginPos = touch->getLocation();     

    //触点 
    void TestController::ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent) 

        //获取第一个触点位置 
        CCSetIterator it = pTouches->begin(); 
        CCTouch* touch = (CCTouch*)(*it); 
        //取得这个位置与上一帧移动的Y值之差,即在纵方向的偏移。 
        CCPoint touchLocation = touch->getLocation();     
        float nMoveY = touchLocation.y - m_tBeginPos.y; 
        //计算菜单在纵方向上也移动相应值后的新位置。 
        CCPoint curPos  = m_pItemMenu->getPosition(); 
        CCPoint nextPos = ccp(curPos.x, curPos.y + nMoveY); 
        //这里对新位置的有效范围做个限定 
        CCSize winSize = CCDirector::sharedDirector()->getWinSize(); 
        if (nextPos.y < 0.0f) 
        { 
            m_pItemMenu->setPosition(CCPointZero); 
            return; 
        } 
     
        if (nextPos.y > ((TESTS_COUNT + 1)* LINE_SPACE - winSize.height)) 
        { 
            m_pItemMenu->setPosition(ccp(0, ((TESTS_COUNT + 1)* LINE_SPACE - winSize.height))); 
            return; 
        } 
        //更新菜单到新位置 
        m_pItemMenu->setPosition(nextPos); 
        //记录当前位置为旧位置。 
        m_tBeginPos = touchLocation; 
        s_tCurPos   = nextPos; 

     

             总结:示例框架展示了一个菜单,每个菜单项代表了一个示例工程,菜单项的Z值是递增排列的。点击菜单项响应TestController::menuCallback函数,此函数通过减去Z值基数可以取得菜单项的索引,并通过CreateTestScene(nIdx);来创建出相应的示例场景。本示例框架还演示了如何在纵方向上拖动一个菜单。

  • 相关阅读:
    hdu6229 Wandering Robots 2017沈阳区域赛M题 思维加map
    hdu6223 Infinite Fraction Path 2017沈阳区域赛G题 bfs加剪枝(好题)
    hdu6438 Buy and Resell 买卖物品 ccpc网络赛 贪心
    hdu6441 Find Integer 求勾股数 费马大定理
    bzoj 1176 Mokia
    luogu 3415 祭坛
    bzoj 1010 玩具装箱
    bzoj 3312 No Change
    luogu 3383【模板】线性筛素数
    bzoj 1067 降雨量
  • 原文地址:https://www.cnblogs.com/Anzhongliu/p/6091973.html
Copyright © 2011-2022 走看看