MyScrollItem是CCScrollView容器内项的接口,MyScrollView主要处理添加子节点和事件的处理,MyScrollViewTestItem是对MyScrollItem实现的测试项,MyScrollViewTest测试类
/*MyScrollView.h*/ #ifndef _MY_SCROLL_VIEW_ #define _MY_SCROLL_VIEW_ #include "cocos2d.h" #include "CCScrollView.h" #include "ExtensionMacros.h" using namespace cocos2d; USING_NS_CC_EXT; class MyScrollItem : public CCNode { public: bool isSelected(CCTouch* pTouch); void touched(); virtual bool init(CCSize size); virtual void selected()=0; }; class MyScrollView : public CCLayer,public CCScrollViewDelegate { private: CCScrollView* m_pScrollView; CCNode* m_pContainer; CCSize m_itemSize; bool m_isScrolling; public: MyScrollView(); static MyScrollView* create(CCPoint pos,CCSize viewSize,CCScrollViewDirection dir); bool init(CCPoint pos,CCSize viewSize,CCScrollViewDirection dir); void addItem(MyScrollItem* item); virtual void registerWithTouchDispatcher(); virtual bool ccTouchBegan(CCTouch* pTouch,CCEvent* pEvent); virtual void ccTouchMoved(CCTouch* pTouch,CCEvent* pEvent); virtual void ccTouchEnded(CCTouch* pTouch,CCEvent* pEvent); virtual void scrollViewDidScroll(CCScrollView* view); virtual void scrollViewDidZoom(CCScrollView* view); virtual void draw(); }; #endif /*MyScrollView.cpp*/ #include "cocos2d.h" #include "CCScrollView.h" #include "MyScrollView.h" #include <stdio.h> using namespace cocos2d; using namespace cocos2d::extension; bool MyScrollItem::isSelected(CCTouch* pTouch) { CCPoint touch = this->convertTouchToNodeSpace(pTouch); CCSize size = this->boundingBox().size; // boundingBox()返回的是当前节点经过缩放旋转后在本地坐标的矩形 return CCRect(0,0,size.width,size.height).containsPoint(touch); } bool MyScrollItem::init(CCSize size) { if(!CCNode::init()) return false; this->setContentSize(size); return true; } void MyScrollItem::touched() { this->stopAllActions(); CCScaleTo* scaleTo1 = CCScaleTo::create(0.1f,0.9f); CCScaleTo* scaleTo2 = CCScaleTo::create(0.1f,1.0f); this->runAction(CCSequence::create(scaleTo1,scaleTo2,NULL)); } MyScrollView::MyScrollView(){} MyScrollView* MyScrollView::create(CCPoint pos,CCSize viewSize,CCScrollViewDirection dir) { MyScrollView* scrollview = new MyScrollView(); if(scrollview && scrollview->init(pos,viewSize,dir)) { scrollview->autorelease(); return scrollview; } return NULL; } bool MyScrollView::init(CCPoint pos,CCSize viewSize,CCScrollViewDirection dir) { if(!CCLayer::init()) return false; m_pScrollView = CCScrollView::create(viewSize); m_pContainer = CCNode::create(); m_pScrollView->setBounceable(false);//设置弹性效果 m_pScrollView->setContainer(m_pContainer);//设置容器 m_pScrollView->setTouchPriority(-1);//设置优先级 m_pScrollView->setTouchEnabled(true);//设置可触摸 m_pScrollView->setDirection(dir); //设置方向 m_pScrollView->setDelegate(this); //设置代理 m_pScrollView->setPosition(ccp(0,0)); /*CCLayerColor* layer = CCLayerColor::create(ccc4(255,0,0,255),viewSize.width,viewSize.height); layer->setPosition(pos); this->addChild(layer,1,100);*/ this->addChild(m_pScrollView); this->setTouchEnabled(true); this->setPosition(pos); return true; } void MyScrollView::registerWithTouchDispatcher() { CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this,0,true); } void MyScrollView::addItem(MyScrollItem* item) { CCPoint pos; int count = m_pContainer->getChildrenCount(); item->ignoreAnchorPointForPosition(false); item->setAnchorPoint(ccp(0.5f,0.5f)); if(count) { CCNode* endItem = m_pContainer->getChildByTag(count-1); pos = ccp(endItem->getPositionX()+m_itemSize.width,endItem->getPositionY()); } else { if(m_itemSize.width==0 || m_itemSize.height==0) m_itemSize = item->getContentSize(); pos = ccp(m_itemSize.width/2,m_itemSize.height/2); } item->setPosition(pos); m_pContainer->setContentSize(CCSizeMake(m_itemSize.width*(count+1),m_itemSize.height)); m_pContainer->addChild(item,1,count); } bool MyScrollView::ccTouchBegan(CCTouch* pTouch,CCEvent* pEvent) { m_isScrolling = false; if(m_pContainer->getChildrenCount()) { CCPoint touch = m_pContainer->convertTouchToNodeSpace(pTouch); MyScrollItem* item = (MyScrollItem*)m_pContainer->getChildByTag(touch.x/m_itemSize.width); if(item && item->isSelected(pTouch)) { item->touched(); return true; } } return false; } void MyScrollView::ccTouchMoved(CCTouch* pTouch,CCEvent* pEvent) { m_isScrolling = true; } void MyScrollView::ccTouchEnded(CCTouch* pTouch,CCEvent* pEvent) { if(!m_isScrolling) { CCPoint touch = m_pContainer->convertTouchToNodeSpace(pTouch); MyScrollItem* item = (MyScrollItem*)m_pContainer->getChildByTag(touch.x/m_itemSize.width); item->selected(); } } void MyScrollView::scrollViewDidScroll(CCScrollView* view) { char str[256]; sprintf(str,"pos=(%d,%d) ",m_pContainer->getPositionX(),m_pContainer->getPositionY()); OutputDebugString(str); } void MyScrollView::scrollViewDidZoom(CCScrollView* view) { } void MyScrollView::draw() { CCLayer::draw(); //int count = m_pContainer->getChildrenCount(); //m_pContainer->setPosition(ccp(0,0)); } /*ScrollViewTest.h*/ #ifndef _SCROLLVIEW_TEST_ #define _SCROLLVIEW_TEST_ #include "cocos2d.h" USING_NS_CC; #include"MyScrollView.h" class MyScrollViewTestItem : public MyScrollItem { public: static MyScrollViewTestItem* create(CCSize size); virtual bool init(CCSize size); virtual void selected(); }; class MyScrollViewTest : public CCLayer { public: CREATE_FUNC(MyScrollViewTest); bool init(); }; #endif /*ScrollViewTest.cpp*/ #include "cocos2d.h" #include "ScrollViewTest.h" #include "MyScrollView.h" #include <iostream> using namespace std; MyScrollViewTestItem* MyScrollViewTestItem::create(CCSize size) { MyScrollViewTestItem* item = new MyScrollViewTestItem(); if(item && item->init(size)) { item->autorelease(); return item; } CC_SAFE_DELETE(item); return NULL; } bool MyScrollViewTestItem::init(CCSize size) { if(!MyScrollItem::init(size)) return false; CCSprite* sprite = CCSprite::create("1.png"); sprite->setPosition(ccp(size.width/2,size.height/2)); this->addChild(sprite); return true; } void MyScrollViewTestItem::selected() { char str[256]; sprintf(str,"selected tag = %d ",this->getTag()); OutputDebugString(str); } bool MyScrollViewTest::init() { CCSize winSize = CCDirector::sharedDirector()->getWinSize(); CCSize viewSize = CCSizeMake(400,100); CCPoint pos = ccp(0,0); CCSize itemSize = CCSizeMake(100,100); MyScrollView* myScroll = MyScrollView::create(ccp(300,100),viewSize,kCCScrollViewDirectionHorizontal); for(int i=0;i<10;i++) { MyScrollViewTestItem* item = MyScrollViewTestItem::create(itemSize); myScroll->addItem(item); } this->addChild(myScroll); this->setPosition(pos); return true; } /*添加几个cocos2dx函数源码*/ void CCScrollView::addChild(CCNode * child, int zOrder, int tag) { child->ignoreAnchorPointForPosition(false); child->setAnchorPoint(ccp(0.0f, 0.0f)); if (m_pContainer != child) { m_pContainer->addChild(child, zOrder, tag); } else { CCLayer::addChild(child, zOrder, tag); } } 由此可以看出CCScrollView中只有m_pContainer一个子节点,向CCScrollView中添加节点也就是向m_pContainer节点。 void CCScrollView::setContentSize(const CCSize & size) { if (this->getContainer() != NULL) { this->getContainer()->setContentSize(size); this->updateInset(); } } 由此看出CCScrollView设置内容大小其实就是设置容器大小 void CCScrollView::setContainer(CCNode * pContainer) { this->removeAllChildrenWithCleanup(true); if (!pContainer) return; this->m_pContainer = pContainer; this->m_pContainer->ignoreAnchorPointForPosition(false); this->m_pContainer->setAnchorPoint(ccp(0.0f, 0.0f)); this->addChild(this->m_pContainer); this->setViewSize(this->m_tViewSize); } 由此看出CCScrollView添加容器时删除了自己的其他所有子节点 void CCScrollView::setViewSize(CCSize size) { m_tViewSize = size; CCLayer::setContentSize(size); } setViewSize才是设置CCScrollView本身的大小