• 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);来创建出相应的示例场景。本示例框架还演示了如何在纵方向上拖动一个菜单。

  • 相关阅读:
    typora的使用
    kibana解决Kibana server is not ready yet问题
    docker详细
    docker 启动报错:Docker.Core.Backend.BackendException: Error response from daemon: open \.pipedocker_e
    win10的docker配置nginx
    lombok常用注解
    关于前端项目cookie的获取
    使用apt安装docker
    linux下root用户和普通用户切换
    deepin系统安装与linux磁盘分区
  • 原文地址:https://www.cnblogs.com/Anzhongliu/p/6091973.html
Copyright © 2020-2023  润新知