今天要写一个关卡选择界面。 百度了下,采用了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__ */ |
|