分享

cocos2d-x 关卡选择界面(CCScrollView的使用)

 魂唱 2015-03-13
         今天要写一个关卡选择界面。 
         百度了下,采用了CCScrollView来实现。 
         具体CCScrollView的使用就不介绍了。 百度大把。(关键字: CCScrollView详解) 
         这里,主要通过一个实例介绍菜单界面的实现。 
         先看效果图。如下: 
           
         1.先从 http://pan.baidu.com/share/link?shareid=2511857370&uk=2685725110 中下载需要的资源和源码 
         或者:http://download.csdn.net/detail/hj3601947/7745639 
         代码如下: 
         CCCGameScrollViewDelegate.h  
          
        #pragma once
        
        #ifndef _H_CCGAMESCROLLVIEW_H_
        #define _H_CCGAMESCROLLVIEW_H_
        
        #include "cocos2d.h"
        #include "cocos-ext.h"
        USING_NS_CC;
        USING_NS_CC_EXT;
        
        // 校正滑动动画速度
        #define ADJUST_ANIM_VELOCITY 2000
        
        class CCCGameScrollViewDelegate
         : public cocos2d::extension::CCScrollViewDelegate
        {
        public:
         virtual bool scrollViewInitPage(cocos2d::CCNode *pScroll, cocos2d::CCNode *pPage, int nPage) = 0;
         virtual void scrollViewClick(const cocos2d::CCPoint &oOffset, const cocos2d::CCPoint &oPoint , cocos2d::CCNode *pPage, int nPage ) = 0;
         virtual void scrollViewScrollEnd(cocos2d::CCNode *pPage, int nPage) = 0;
        };
        
        class CCCGameScrollView
         : public cocos2d::extension::CCScrollView
        {
        public:
         CCCGameScrollView();
         ~CCCGameScrollView();
        public:
         CREATE_FUNC(CCCGameScrollView);
        
         bool init();
        
         bool createContainer(CCCGameScrollViewDelegate *pDele, int nCount, const cocos2d::CCSize &oSize );
        
         virtual bool ccTouchBegan( cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent );
        
         virtual void ccTouchMoved( cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent );
        
         virtual void ccTouchEnded( cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent );
        
         virtual void ccTouchCancelled( cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent );
        
         virtual void setDirection(CCScrollViewDirection eDirection);
        
         void setCurPage(int nPage);
         void scrollToPage(int nPage);
         void scrollToNextPage();
         void scrollToPrePage();
         int getPageCount();
         int getCurPage();
         CCNode *getPage(int nPage);
        protected:
         void adjustScrollView(const cocos2d::CCPoint &oBegin, const cocos2d::CCPoint &oEnd);
        
         virtual void onScrollEnd(float fDelay);
        protected:
         int m_nPageCount;
         int m_nPrePage;
         cocos2d::CCPoint m_BeginOffset;
         cocos2d::CCSize m_CellSize;
         float m_fAdjustSpeed;
         bool m_bSetDirection;
         int m_nCurPage;
        };
        
        #endif 
         
         CCCGameScrollViewDelegate.cpp  
          
        #include "CCGameScrollView.h"
        
        
        CCCGameScrollView::CCCGameScrollView()
         : m_fAdjustSpeed(ADJUST_ANIM_VELOCITY)
         , m_bSetDirection(false)
         , m_nCurPage(0)
        {
        
        }
        
        CCCGameScrollView::~CCCGameScrollView()
        {
        
        }
        
        
        
        bool CCCGameScrollView::init()
        {
         if (!CCScrollView::init())
         {
         return false;
         }
        
         return true;
        }
        
        
        bool CCCGameScrollView::ccTouchBegan( CCTouch *pTouch, CCEvent *pEvent )
        {
         m_BeginOffset = getContentOffset();
         return CCScrollView::ccTouchBegan(pTouch, pEvent);
        }
        
        void CCCGameScrollView::ccTouchMoved( CCTouch *pTouch, CCEvent *pEvent )
        {
         CCScrollView::ccTouchMoved(pTouch, pEvent);
        }
        
        void CCCGameScrollView::ccTouchEnded( CCTouch *pTouch, CCEvent *pEvent )
        {
         CCPoint touchPoint = pTouch->getLocationInView();
         touchPoint = CCDirector::sharedDirector()->convertToGL( touchPoint );
        
         CCScrollView::ccTouchEnded(pTouch, pEvent);
        
         CCPoint m_EndOffset = getContentOffset();
        
         //点击Page的功能
         if (m_BeginOffset.equals(m_EndOffset))
         {
         int nPage = -1;
         if (m_eDirection == kCCScrollViewDirectionHorizontal)
         {
         nPage = abs(m_EndOffset.x / (int)m_CellSize.width);
         }
         else
         {
         nPage = abs(m_EndOffset.y / (int)m_CellSize.height);
         }
         CCCGameScrollViewDelegate *pDele = (CCCGameScrollViewDelegate *)m_pDelegate;
         CCNode *pPgae = m_pContainer->getChildByTag(nPage);
         CCRect rcContent;
         rcContent.origin = pPgae->getPosition();
         rcContent.size = pPgae->getContentSize();
         rcContent.origin.x -= rcContent.size.width / 2;
         rcContent.origin.y -= rcContent.size.height / 2;
        
         CCPoint pos = touchPoint;
         if (m_eDirection == kCCScrollViewDirectionHorizontal)
         {
         pos.x += nPage * m_CellSize.width;
         }
         else
         {
         pos.y -= nPage * m_CellSize.height;
         }
        
         if (rcContent.containsPoint(pos))
         {
         pDele->scrollViewClick(m_EndOffset, touchPoint, pPgae, nPage);
         }
         return ;
         }
        
         //自动调整
         adjustScrollView(m_BeginOffset, m_EndOffset);
        }
        
        void CCCGameScrollView::ccTouchCancelled( CCTouch *pTouch, CCEvent *pEvent )
        {
         CCScrollView::ccTouchCancelled(pTouch, pEvent);
        
         CCPoint m_EndOffset = getContentOffset();
         adjustScrollView(m_BeginOffset, m_EndOffset);
        }
        
        
        void CCCGameScrollView::adjustScrollView( const cocos2d::CCPoint &oBegin, const cocos2d::CCPoint &oEnd)
        {
         int nPage = 0;
         int nAdjustPage = 0;
        
         if (m_eDirection == kCCScrollViewDirectionHorizontal)
         {
         nPage = abs(oBegin.x / (int)m_CellSize.width);
         int nDis = oEnd.x - oBegin.x;
        
         if (nDis < -getViewSize().width / 5)
         {
         nAdjustPage = nPage + 1;
         }
         else if (nDis > getViewSize().width / 5)
         {
         nAdjustPage = nPage - 1;
         }
         else
         {
         nAdjustPage = nPage;
         }
         }
         else
         {
         nPage = abs(oBegin.y / (int)m_CellSize.height);
         int nDis = oEnd.y - oBegin.y;
        
         if (nDis < -getViewSize().height / 5)
         {
         nAdjustPage = nPage - 1;
         }
         else if (nDis > getViewSize().height / 5)
         {
         nAdjustPage = nPage + 1;
         }
         else
         {
         nAdjustPage = nPage;
         }
         }
        
         nAdjustPage = MIN(nAdjustPage, m_nPageCount - 1);
         nAdjustPage = MAX(nAdjustPage, 0);
        
         scrollToPage(nAdjustPage);
        }
        
        
        void CCCGameScrollView::scrollToPage( int nPage )
        {
         // 关闭CCScrollView中的自调整
         unscheduleAllSelectors();
        
         CCPoint oOffset = getContentOffset();
         // 调整位置
         CCPoint adjustPos;
         if (m_eDirection == kCCScrollViewDirectionHorizontal)
         {
         adjustPos = ccp(-m_CellSize.width * nPage, 0);
         }
         else
         {
         adjustPos = ccp(0, m_CellSize.height * nPage);
         }
         // 调整动画时间
         float adjustAnimDelay = ccpDistance(adjustPos, oOffset) / m_fAdjustSpeed;
        
         // 调整位置
         setContentOffsetInDuration(adjustPos, adjustAnimDelay);
        
         if (nPage != m_nCurPage)
         {
         m_nCurPage = nPage;
         scheduleOnce(schedule_selector(CCCGameScrollView::onScrollEnd), adjustAnimDelay);
         }
        }
        
        
        void CCCGameScrollView::onScrollEnd(float fDelay)
        {
         CCCGameScrollViewDelegate *pDele = (CCCGameScrollViewDelegate *)m_pDelegate;
         pDele->scrollViewScrollEnd(m_pContainer->getChildByTag(m_nCurPage), m_nCurPage);
        }
        
        
        
        void CCCGameScrollView::scrollToNextPage()
        {
         int nCurPage = getCurPage();
         if (nCurPage >= m_nPageCount - 1)
         {
         return ;
         }
         scrollToPage(nCurPage + 1);
        }
        
        void CCCGameScrollView::scrollToPrePage()
        {
         int nCurPage = getCurPage();
         if (nCurPage <= 0)
         {
         return ;
         }
         scrollToPage(nCurPage - 1);
        }
        
        
        bool CCCGameScrollView::createContainer(CCCGameScrollViewDelegate *pDele, int nCount, const cocos2d::CCSize &oSize )
        {
         CCAssert(m_bSetDirection, "must call setDirection first!!!");
         m_nPageCount = nCount;
         m_CellSize = oSize;
         setDelegate(pDele);
        
         CCLayer *pContainer = CCLayer::create();
        
         CCSize winSize = CCDirector::sharedDirector()->getVisibleSize();
         for (int i = 0; i < nCount; ++i)
         {
         CCNode *pNode = CCNode::create();
         pDele->scrollViewInitPage(this, pNode, i);
        
         CCObject *pObj = NULL;
        
         if (m_eDirection == kCCScrollViewDirectionHorizontal)
         {
         pNode->setPosition(ccp(winSize.width / 2 + i * oSize.width, winSize.height / 2));
         }
         else
         {
         pNode->setPosition(ccp(winSize.width / 2, winSize.height / 2 - i * oSize.height));
         }
         CCSize oMaxSize;
         CCARRAY_FOREACH(pNode->getChildren(), pObj)
         {
         CCNode *pNode = (CCNode *)pObj;
         oMaxSize.width = MAX(oMaxSize.width, pNode->getContentSize().width);
         oMaxSize.height = MAX(oMaxSize.height, pNode->getContentSize().height);
         }
         pNode->setContentSize(oMaxSize);
         pNode->setTag(i);
         pContainer->addChild(pNode);
         }
        
         setContainer(pContainer);
        
         return true;
        }
        
        int CCCGameScrollView::getCurPage()
        {
         return m_nCurPage;
        }
        
        void CCCGameScrollView::setCurPage( int nPage )
        {
         CCAssert(m_nCurPage >= 0 && m_nCurPage < m_nPageCount, "");
        
         if (m_eDirection == kCCScrollViewDirectionHorizontal)
         {
         setContentOffset(ccp(-nPage * m_CellSize.width, 0));
         }
         else
         {
         setContentOffset(ccp(0, nPage * m_CellSize.height));
         }
         m_nCurPage = nPage;
        }
        
        int CCCGameScrollView::getPageCount()
        {
         return m_nPageCount;
        }
        
        CCNode *CCCGameScrollView::getPage( int nPage )
        {
         return m_pContainer->getChildByTag(nPage);
        }
        
        void CCCGameScrollView::setDirection( CCScrollViewDirection eDirection )
        {
         CCAssert(eDirection != kCCScrollViewDirectionBoth, "Does not suppost kCCScrollViewDirectionBoth!!!");
         CCScrollView::setDirection(eDirection);
         m_bSetDirection = true;
        }
        
         CMenuScene.h
         
         
          
        #pragma once
        
        #ifndef _H_MENUSCENE_H_
        #define _H_MENUSCENE_H_
        
        #include "cocos2d.h"
        USING_NS_CC;
        
        class CMenuScene
         : public CCLayer
        {
        public:
         CMenuScene();
         ~CMenuScene();
        public:
         CREATE_FUNC(CMenuScene);
        
        
         bool init();
         void menuCloseCallback(CCObject* pSender);
        };
        
        #endif
        
         
         
         CMenuScene.cpp 
          
        #include "MenuScene.h"
        #include "ThemeSelect.h"
        
        CMenuScene::CMenuScene()
        {
        
        }
        
        CMenuScene::~CMenuScene()
        {
        
        }
        
        bool CMenuScene::init()
        {
         if (!CCLayer::init())
         {
         return false;
         }
         CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
         CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();
        
         //CCLayerGradient* pBacjGround=CCLayerGradient::create(ccc4(255,0,0,255),ccc4(0,0,255,255));
        
         CCLayerColor* pBacjGround=CCLayerColor::create(ccc4(55,53,58,255));
        
         addChild(pBacjGround);
        
        
         CCLabelTTF *pLabel = CCLabelTTF::create("Start", "Arial", 48);
         pLabel->setPosition(ccp(origin.x + visibleSize.width/2,
         origin.y + visibleSize.height - pLabel->getContentSize().height-20));
         addChild(pLabel);
        
        
         CCMenuItemImage *pCloseItem = CCMenuItemImage::create(
         "start_n.png",
         "start_s.png",
         this,
         menu_selector(CMenuScene::menuCloseCallback));
        
         pCloseItem->setPosition(ccp(origin.x + visibleSize.width/2 ,
         origin.y + visibleSize.height/2));
        
         CCMenu* pMenu = CCMenu::create(pCloseItem, NULL);
         pMenu->setPosition(CCPointZero);
         this->addChild(pMenu, 1);
        
        
         return true;
        }
        
        void CMenuScene::menuCloseCallback(CCObject* pSender)
        {
         CCScene* pScene=CCScene::create();
         pScene->addChild(CThemeSelectLayer::create());
         CCDirector::sharedDirector()->replaceScene(CCTransitionFade::create(1.0f,pScene));
        }
         CThemeSelectLayer.h
         
         
          
        #pragma once
        
        #ifndef _H_LEVELSELECT_H_
        #define _H_LEVELSELECT_H_
        
        #include "CCGameScrollView.h"
        
        class CThemeSelectLayer
         : public CCCGameScrollViewDelegate
         , public CCLayer
        {
        public:
         CThemeSelectLayer();
         ~CThemeSelectLayer();
        public:
         CREATE_FUNC(CThemeSelectLayer);
        
         bool init();
        
         virtual void scrollViewDidScroll( cocos2d::extension::CCScrollView *view );
        
         virtual void scrollViewDidZoom( cocos2d::extension::CCScrollView *view );
        
         virtual bool scrollViewInitPage( cocos2d::CCNode *pScroll, cocos2d::CCNode *pPage, int nPage );
        
         virtual void scrollViewClick( const cocos2d::CCPoint &oOffset, const cocos2d::CCPoint &oPoint , cocos2d::CCNode *pPage, int nPage );
        
         virtual void scrollViewScrollEnd( cocos2d::CCNode *pPage, int nPage );
        
        private:
         CCCGameScrollView *m_ScrollView;
        };
        
        #endif//_H_LEVELSELECT_H_
         
         
         
          
         CThemeSelectLayer.cpp 
          
        #include "ThemeSelect.h"
        #include "MenuScene.h"
        
        USING_NS_CC;
        USING_NS_CC_EXT;
        
        CThemeSelectLayer::CThemeSelectLayer()
        {
        
        }
        
        CThemeSelectLayer::~CThemeSelectLayer()
        {
        
        }
        
        
        void CThemeSelectLayer::scrollViewDidScroll( CCScrollView *view )
        {
        
        }
        
        void CThemeSelectLayer::scrollViewDidZoom( CCScrollView *view )
        {
        
        }
        
        //初始化每个单独页面,pPage为这个页面的容器,nPage是这个页面的ID
        bool CThemeSelectLayer::scrollViewInitPage( cocos2d::CCNode *pScroll, cocos2d::CCNode *pPage, int nPage )
        {
         CCString str;
         str.initWithFormat("%03d.png", nPage + 1);
         CCSprite *sprite = CCSprite::create(str.getCString());
         pPage->addChild(sprite);
        
         return true;
        }
        
        //点击某个页面的处理
        void CThemeSelectLayer::scrollViewClick( const cocos2d::CCPoint &oOffset, const cocos2d::CCPoint &oPoint , cocos2d::CCNode *pPage, int nPage )
        {
         switch(nPage)
         {
         case 0:
         {
         //切换场景
         CCScene* pScene=CCScene::create();
         pScene->addChild(CMenuScene::create());
         CCDirector::sharedDirector()->replaceScene(pScene);
         }
         break;
         case 1:
         {
         //滚动到某个页面
         m_ScrollView->scrollToPage(2);
         }
         break;
         case 2:
         {
         //设置当前页面
         m_ScrollView->setCurPage(3);
         }
         break;
         }
        
        }
        
        //每一次滑动后结束的回调,可以在这里处理一些事情
        void CThemeSelectLayer::scrollViewScrollEnd( cocos2d::CCNode *pPage, int nPage )
        {
         CCLog("Current Page=%d", nPage);
        }
        
        
        bool CThemeSelectLayer::init()
        {
         if(!CCLayer::init())
         {
         return false;
         }
        
        
         // CCScrollView
         m_ScrollView = CCCGameScrollView::create(); //创建一个scrollview
         m_ScrollView->setDirection(kCCScrollViewDirectionHorizontal);  //设置滚动的方向,目前来说只能横方向和纵方向
        
         //this,页面的数量,每个页面的尺寸(影响页面间的距离)
         m_ScrollView->createContainer(this, 5, CCSizeMake(CCDirector::sharedDirector()->getVisibleSize().width * 0.8, CCDirector::sharedDirector()->getVisibleSize().height));
         //一般是原点
         m_ScrollView->setPosition(ccp(0, 0));
         //视口的尺寸(一般是屏幕的尺寸)
         m_ScrollView->setViewSize(CCDirector::sharedDirector()->getVisibleSize());
        
         this->addChild(m_ScrollView);
        
        
         return true;
        }
        
         最后添加一个
         
         
         AppMacros.h文件 
          
         #ifndef __APPMACROS_H__ #define __APPMACROS_H__ #include "cocos2d.h" #define DESIGN_RESOLUTION_480X320 0 #define DESIGN_RESOLUTION_1024X768 1 #define DESIGN_RESOLUTION_2048X1536 2  /* If you want to switch design resolution, change next line */ #define TARGET_DESIGN_RESOLUTION_SIZE DESIGN_RESOLUTION_480X320  typedef struct tagResource { cocos2d::CCSize size; char directory[100]; }Resource;  static Resource smallResource = { cocos2d::CCSizeMake(720, 960), "iphone" }; static Resource mediumResource = { cocos2d::CCSizeMake(1024, 768), "ipad" }; static Resource largeResource = { cocos2d::CCSizeMake(2048, 1536), "ipadhd" };  #if (TARGET_DESIGN_RESOLUTION_SIZE == DESIGN_RESOLUTION_480X320) static cocos2d::CCSize designResolutionSize = cocos2d::CCSizeMake(720, 960); #elif (TARGET_DESIGN_RESOLUTION_SIZE == DESIGN_RESOLUTION_1024X768) static cocos2d::CCSize designResolutionSize = cocos2d::CCSizeMake(1024, 768); #elif (TARGET_DESIGN_RESOLUTION_SIZE == DESIGN_RESOLUTION_2048X1536) static cocos2d::CCSize designResolutionSize = cocos2d::CCSizeMake(2048, 1536); #else #error unknown target design resolution! #endif   // The font size 24 is designed for small resolution, so we should change it to fit for current design resolution #define TITLE_FONT_SIZE (cocos2d::CCEGLView::sharedOpenGLView()->getDesignResolutionSize().width / smallResource.size.width * 24)   #endif /* __APPMACROS_H__ */  
           
           
           
           
            
          
         

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多