cocos2d-x滑动模块学习

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实现效果如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值