cocos2d-x滑动模块学习

来源:互联网 发布:万方数据库官网网址 编辑:程序博客网 时间:2024/05/23 19:17

1.首先我们来认识下cocos引擎类中的CCScrollView,有关于该类源码的介绍该文章有详细介绍:http://www.it165.net/pro/html/201406/15461.html

CCScrollView委托的介绍:
http://www.cocoachina.com/bbs/read.php?tid=217359

CCScrollView基础用法:
http://shahdza.blog.51cto.com/2410787/1544983/

2.源代码的功能还是比较简陋的,接下来我们自己写一个类来继承该类:XYScrollView
代码如下:
XYScrollView.h文件

#ifndef __XY__XYScrollView__#define __XY__XYScrollView__#include "cocos2d.h"#include "cocos-ext.h"USING_NS_CC;USING_NS_CC_EXT;class XYScrollView:public CCScrollView{public:    XYScrollView();    ~XYScrollView();    static XYScrollView *create(int Priority,CCSize size, CCNode* container = NULL);    CCRect getVisableRect();    CCPoint getContainLayerPoi();    virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent);private:    CCPoint m_minPoint;};#endif /* defined(__XY__XYScrollView__) */

XYScrollView.cpp文件

#include "XYScrollView.h"XYScrollView::XYScrollView(){}XYScrollView::~XYScrollView(){}XYScrollView *XYScrollView::create(int Priority,CCSize size, CCNode* container){    XYScrollView* pRet = new XYScrollView();    if (pRet && pRet->initWithViewSize(size, container))    {        pRet->setTouchPriority(Priority);        pRet->autorelease();    }    else    {        CC_SAFE_DELETE(pRet);    }    return pRet;}CCRect XYScrollView::getVisableRect(){    return CCRect(0,0, m_tViewSize.width, m_tViewSize.height);}CCPoint XYScrollView::getContainLayerPoi(){    if (m_pContainer)    {        return m_pContainer->getPosition();    }    else    {        return ccp(0,0);    }}//滑动到底部或者顶部时无法继续滑动void XYScrollView::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent){    CCPoint maxpoint=this->maxContainerOffset();    CCPoint minpoint=this->minContainerOffset();    CCPoint newPoint     = this->convertTouchToNodeSpace((CCTouch*)m_pTouches->objectAtIndex(0));    CCPoint moveDistance = ccpSub(newPoint, m_tTouchPoint);    switch (m_eDirection)    {        case kCCScrollViewDirectionVertical:            moveDistance = ccp(0.0f, moveDistance.y);            break;        case kCCScrollViewDirectionHorizontal:            moveDistance = ccp(moveDistance.x, 0.0f);            break;        default:            break;    }    int nowPx=getContainLayerPoi().x+moveDistance.x;    int nowPy=getContainLayerPoi().y+moveDistance.y;    if (getContainLayerPoi().equals(maxpoint)||getContainLayerPoi().equals(minpoint)) {        if (nowPx>maxpoint.x||nowPx<minpoint.x||nowPy>maxpoint.y||nowPy<minpoint.y) {            return;        }    }    CCScrollView::ccTouchMoved(pTouch, pEvent);}

3.好了现在基类已经完成了,我们来写一个具体的滑动窗口类:
XYListView,该类继承与XYScrollView
代码如下:
.h文件:

#ifndef __XY__XYListView__#define __XY__XYListView__#include "XYScrollView.h"#include "XYContainLayer.h"class XYListView:public CCLayerColor{public:    XYListView();    ~XYListView();    static XYListView* createWith(int Priority,CCSize size,CCArray *viewarr = NULL);    void resetarr(CCArray *arr, bool bIsVertical = true, bool bIsRefresh = true, int type = 0);    void resetListView(bool bIsVertical = true, bool bIsRefresh = true);    CCArray *m_viewarr;    XYScrollView *m_scrollview;    XYContainLayer *m_containlayer;    int scrollType;    CC_SYNTHESIZE(float, m_distence, Distence);    CC_SYNTHESIZE(float, m_topDistence, topDistence);    CC_SYNTHESIZE(float, m_leftDistence, leftDistence);private:    bool initWith(int Priority,CCSize size,CCArray *viewarr = NULL);    void createScroll(bool bIsVertical);    bool isInViewArr(CCNode* pNode);    CCSize m_size;    int m_Priority;    void updateVisable(float time);};#endif /* defined(__XY__XYListView__) */

.cpp文件:

#include "XYListView.h"XYListView::XYListView(){    m_containlayer = NULL;    m_viewarr = CCArray::create();    CC_SAFE_RETAIN(m_viewarr);    m_distence = 0;    m_topDistence = 0;    m_leftDistence = 0;    scrollType=0;}XYListView::~XYListView(){    CC_SAFE_RELEASE_NULL(m_viewarr);}XYListView* XYListView::createWith(int Priority,CCSize size,CCArray *viewarr){    XYListView *pview = new XYListView();    if (pview &&pview->initWith(Priority,size,viewarr))    {        pview->autorelease();    }    else    {        CC_SAFE_DELETE(pview);    }    return pview;}bool XYListView::initWith(int Priority,CCSize size,CCArray *viewarr){    if (!CCLayerColor::init())    {        return false;    }    m_size = size;    m_Priority = Priority;    m_scrollview = XYScrollView::create(Priority,size);    addChild(m_scrollview);    resetarr(viewarr);    schedule(schedule_selector(XYListView::updateVisable),0.1);    return true;}void XYListView::resetarr(CCArray *arr, bool bIsVertical, bool bIsRefresh, int type){    if (arr)    {        if (bIsRefresh && m_containlayer != NULL)        {            m_containlayer->removeFromParent();            m_containlayer = NULL;        }        m_viewarr->removeAllObjects();        m_viewarr->addObjectsFromArray(arr);        scrollType=type;        createScroll(bIsVertical);    }}void XYListView::resetListView(bool bIsVertical, bool bIsRefresh){    if (bIsRefresh && m_containlayer != NULL)    {        m_containlayer->removeFromParent();        m_containlayer = NULL;    }    createScroll(bIsVertical);}void XYListView::updateVisable(float time){    for (int i = 0; i<m_viewarr->count(); i++)    {        CCNode * node = (CCNode *)m_viewarr->objectAtIndex(i);        CCPoint poi = m_scrollview->convertToNodeSpace(m_containlayer->convertToWorldSpace(node->getPosition()));        CCRect rect = CCRect(poi.x, poi.y, node->getContentSize().width, node->getContentSize().height);        if (m_scrollview->getVisableRect().intersectsRect(rect))        {            node->setVisible(true);        }        else        {            node->setVisible(false);        }    }}void XYListView::createScroll(bool bIsVertical){    bool isRearrange = false;    if (m_containlayer != NULL)    {        isRearrange = true;    }    else    {        m_containlayer = XYContainLayer::create(m_Priority);        m_scrollview->setContainer(m_containlayer);        m_scrollview->setDirection(bIsVertical ? kCCScrollViewDirectionVertical :kCCScrollViewDirectionHorizontal);    }    int num = m_viewarr->count();    CCObject *obj = NULL;    if (bIsVertical)    {        float fheigh = 0;        CCARRAY_FOREACH(m_viewarr, obj)        {            CCNode *node = (CCNode*)obj;            fheigh += node->getContentSize().height*node->getScale()  + m_distence;        }        if (num > 0)        {            fheigh -= m_distence;            fheigh += 2*m_topDistence;        }        if (m_size.height> fheigh)        {            m_scrollview->setContentSize(m_size);            m_containlayer->setContentSize(m_size);        }        else        {            if(scrollType==1)            {                fheigh=fheigh-170;            }            m_scrollview->setContentSize(CCSize(m_size.width, fheigh));            m_containlayer->setContentSize(CCSize(m_size.width, fheigh));        }        float heigh = m_containlayer->getContentSize().height;        float curheigh = 0;        int XX=0;        int YY=0;        for (int i = 0; i<num; i++)        {            CCNode *cell = (CCNode*)m_viewarr->objectAtIndex(i);            cell->setAnchorPoint(ccp(0, 0));            if (i == 0)            {                curheigh += cell->getContentSize().height*cell->getScale() +m_topDistence;            }            else            {                curheigh += cell->getContentSize().height*cell->getScale()  + m_distence;            }            if(scrollType==1)            {                if(i>0)                {                    XX++;                    if(i%2==0)                    {                        XX=0;                        YY++;                    }                }                cell->setPosition(ccp((cell->getContentSize().width*cell->getScale()+20+m_leftDistence)*XX, fheigh-(cell->getContentSize().height*cell->getScale()+20)*YY-135));            }else if (scrollType==0)            {                cell->setPosition(ccp(0+m_leftDistence, heigh -curheigh));            }            if (cell->getParent() == NULL)            {                m_containlayer->addChild(cell);            }        }        CCArray* pArray = m_containlayer->getChildren();        if (pArray != NULL)        {            for (int i = 0; i < pArray->count(); i++)            {                CCNode* pNode = dynamic_cast<CCNode*>(pArray->objectAtIndex(i));                if (!this->isInViewArr(pNode))                {                    pNode->removeFromParent();                }            }        }        if (!isRearrange)        {            m_scrollview->setContentOffset(m_scrollview->minContainerOffset());        }    }    else    {        float fwidth = 0;        CCARRAY_FOREACH(m_viewarr, obj)        {            CCNode *node = (CCNode*)obj;            fwidth += node->getContentSize().width*node->getScale() + m_distence;        }        if (num > 0)        {            fwidth -= m_distence;            fwidth += 2*m_topDistence;        }        if (m_size.width> fwidth)        {            m_scrollview->setContentSize(m_size);            m_containlayer->setContentSize(m_size);        }        else        {            m_scrollview->setContentSize(CCSize(fwidth, m_size.height));            m_containlayer->setContentSize(CCSize(fwidth, m_size.height));        }        for (int i = 0; i<num; i++)        {            CCNode *cell = (CCNode*)m_viewarr->objectAtIndex(i);            cell->setAnchorPoint(ccp(0, 0));            cell->setPosition(ccp((cell->getContentSize().width*cell->getScale() + m_distence) * i+m_topDistence, m_leftDistence));            if (cell->getParent() == NULL)            {                m_containlayer->addChild(cell);            }        }        CCArray* pArray = m_containlayer->getChildren();        if (pArray != NULL)        {            for (int i = 0; i < pArray->count(); i++)            {                CCNode* pNode = dynamic_cast<CCNode*>(pArray->objectAtIndex(i));                if (!this->isInViewArr(pNode))                {                    pNode->removeFromParent();                }            }        }        if (!isRearrange)        {            m_scrollview->setContentOffset(m_scrollview->maxContainerOffset());        }    }}bool XYListView::isInViewArr(CCNode* pNode){    for (int i = 0; i < m_viewarr->count(); i++)    {        if (m_viewarr->objectAtIndex(i) == pNode)        {            return true;        }    }    return false;}

4.XYListView的用法介绍:

    CCNode* pNode = this->getChildByTag(520);    m_pListView= XYListView::createWith(-10, pNode->getContentSize());    m_pListView->setPosition(pNode->getPosition());    pNode->getParent()->addChild(m_pListView);    m_pListView->setDistence(10);    m_pListView->setleftDistence(10);    m_pListView->resetarr(pArr,false);    m_pListView->m_scrollview->setTouchEnabled(false);

pArr是什么东西呢?看了下面的代码你就清楚了:

    CCNo* pNode = CCNode::create();    arr->addObject(pNode);        pNode->setDelegate(this);

5.XYListView实现效果如下:

0 0
原创粉丝点击