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