實現一個一個ITEM的拖動效果的控制項 TTSliderControl
實現代碼如下:
#include <iostream>#include "cocos2d.h"#include "cocos-ext.h"USING_NS_CC;USING_NS_CC_EXT;#include "ClientDefine.h"#include "vector"#include "string"using namespace std;typedef struct _SLIDER_INIT_STRUCT{ CCSize m_sliderSize;//控制項的尺寸 vector<CCNode *> m_nodes; //滾動的節點 int m_curCenterIndex;//當前最中間的節點下標,從0開始 }SLIDER_INIT_STRUCT;class TTSliderControl :public CCLayer{public: TTSliderControl(); ~TTSliderControl(); //實現裁剪 void visit(void); CREATE_FUNC(TTSliderControl) virtual bool init(); virtual void onEnter(); virtual void onExit(); virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent); virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent); virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent); virtual void ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent); //判斷是否是點擊在有效地區 bool isTouchInvalidated(CCTouch* touch); void initWithStruct(CCObject * pObj); //將某個index的node 移動到中間 void moveNodeToCenter(int index); //微調 將 node移動 offset void moveNodeOffset(float offset); //判斷UI當前中間的index是哪個 int getCurCenterIndexInUI(); public : SLIDER_INIT_STRUCT m_initS; //裡面的index是最終的資料 int m_curIndex; //這個index是 當前的資料 public: CC_SYNTHESIZE(SEL_CallFuncO, m_changeIndexSelector, ChangeIndexSelector); CC_SYNTHESIZE(CCNode *, m_target, Target);};
#include "TTSliderControl.h"TTSliderControl::TTSliderControl(){ m_target = NULL; m_changeIndexSelector = NULL; m_curIndex = -1;}TTSliderControl::~TTSliderControl(){ }//實現裁剪void TTSliderControl:: visit(void){ glEnable(GL_SCISSOR_TEST); CCPoint selfPos = this->getPosition(); CCSize selfContentSize = this->getContentSize(); CCLOG("selfPos = %d,%d, selfContentSize =%d,%d ", selfPos.x, selfPos.y ,selfContentSize.width, selfContentSize.height ); float scaleX = CCEGLView::sharedOpenGLView()->getScaleX(); float scaleY = CCEGLView::sharedOpenGLView()->getScaleY(); CCRect viewPortRect = CCEGLView::sharedOpenGLView()->getViewPortRect(); glScissor(selfPos.x *scaleX + viewPortRect.origin.x , selfPos.y * scaleY + viewPortRect.origin.y , selfContentSize.width*scaleX, selfContentSize.height*scaleY); CCNode::visit();//顯示父類的內容 glDisable(GL_SCISSOR_TEST);} bool TTSliderControl::init(){ //自己響應touch事件 CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, -128 -1, true); return true;} void TTSliderControl::onEnter(){ CCLayer::onEnter(); } void TTSliderControl::onExit(){ CCLayer::onExit(); CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);} bool TTSliderControl::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent){ if (isTouchInvalidated(pTouch)) { return true; } else { return false; }} void TTSliderControl::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent){ CCPoint prePos = CCDirector::sharedDirector()->convertToGL( pTouch->getPreviousLocationInView() ) ; prePos = convertToNodeSpace(prePos); CCPoint curPos = CCDirector::sharedDirector()->convertToGL(pTouch->getLocationInView() ); curPos = convertToNodeSpace(curPos); CCPoint offsetPos = ccpSub(curPos, prePos); if (offsetPos.x ) { moveNodeOffset(offsetPos.x); } } void TTSliderControl::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent){ //CCPoint endPos = convertTouchToNodeSpace(pTouch); //判斷當前 是哪個node在中間,然後滑動到這個node中心 int curIndexUI = getCurCenterIndexInUI(); if (curIndexUI != -1) { moveNodeToCenter(curIndexUI); }} void TTSliderControl::ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent){ }//判斷是否是點擊在有效地區bool TTSliderControl:: isTouchInvalidated(CCTouch* touch){ CCPoint touchLocation = touch->getLocation(); CCPoint localLocation = this->convertToNodeSpace(touchLocation); CCRect rc = CCRectMake( 0, 0, this->getContentSize().width, this->getContentSize().height ); if (rc.containsPoint(localLocation)) { return true; } else { return false; }} void TTSliderControl:: initWithStruct(CCObject * pObj){ if (pObj == NULL) { return ; } m_initS = * (SLIDER_INIT_STRUCT *)pObj; //判斷節點個數,如果為空白,那麼直接返回 if (m_initS.m_nodes.size() == 0 ) { return ; } //讓 centerIndx在合理的範圍內 if (m_initS.m_curCenterIndex < 0 ) { m_initS.m_curCenterIndex = 0; } if (m_initS.m_curCenterIndex >= m_initS.m_nodes.size() ) { m_initS.m_curCenterIndex = m_initS.m_nodes.size() -1 ; } //設定 控制項 的尺寸 this->setContentSize(m_initS.m_sliderSize); //將 nodes都添加到 this for ( int i = 0 ; i< m_initS.m_nodes.size() ; i ++) { CCNode * tempNode = m_initS.m_nodes.at(i); if (tempNode) { this->addChild(tempNode,2); } } //根據 centerIndex設定各個child node 的位置 moveNodeToCenter(m_initS.m_curCenterIndex);}//將某個index的node 移動到中間void TTSliderControl:: moveNodeToCenter(int index){ //讓 centerIndex在合理的範圍內 if (index < 0 ) { return ; } if (index >= m_initS.m_nodes.size() ) { return ; } m_initS.m_curCenterIndex = index; //遍曆 整個 m_nodes CCNode * centerSliderUnit = NULL; for (int i = 0 ; i < m_initS.m_nodes.size() ; i ++) { CCNode * sliderUnit = (CCNode *) m_initS.m_nodes.at(i); //預設 node的錨點為 (0,0) CCPoint newPoint; CCLOG("node size = %f,%f", sliderUnit->getContentSize().width ,sliderUnit->getContentSize().height ); newPoint.x = (i - m_initS.m_curCenterIndex) * sliderUnit->getContentSize().width ; newPoint.y = (this->getContentSize().height - sliderUnit->getContentSize().height ) * 0.5f; CCMoveTo * moveto = CCMoveTo::create(0.25f, newPoint); sliderUnit->runAction(moveto); } //如果是改變了index if (m_curIndex != m_initS.m_curCenterIndex) { if (m_target && m_changeIndexSelector) { (m_target->*m_changeIndexSelector)(this); } } m_curIndex = m_initS.m_curCenterIndex;}//微調 將 node移動 offsetvoid TTSliderControl:: moveNodeOffset(float offset){ //如果當前沒有node,直接返回 if (m_initS.m_nodes.size() == 0 ) { return ; } //如果,已經到最左邊,不再能夠往左移動,直接返回 CCNode * rightMostUnit = (CCNode *) m_initS.m_nodes.at(m_initS.m_nodes.size() -1); if (rightMostUnit->getPosition().x <= 0 && offset < 0 ) { return ; } //如果,已經到了最右邊,不再能夠往右移動,直接返回 CCNode * leftMostUnit = (CCNode *) m_initS.m_nodes.at(0); if (leftMostUnit->getPosition().x >= 0 && offset > 0) { return ; } //遍曆,所有的node都移動 int counter = m_initS.m_nodes.size(); for ( int i = 0 ; i < counter; i ++) { CCNode * tempNode = (CCNode *) m_initS.m_nodes.at(i); CCPoint oldPoint = tempNode->getPosition(); CCPoint newPoint = oldPoint; newPoint.x = oldPoint.x + offset; tempNode->setPosition(newPoint); } }//判斷UI當前中間的index是哪個int TTSliderControl:: getCurCenterIndexInUI(){ //如果當前沒有node,那麼直接返回-1 if (m_initS.m_nodes.size() == 0) { return -1; } //遍曆 int counter = m_initS.m_nodes.size(); for ( int i = 0 ; i<counter; i ++) { CCNode * tempNode = m_initS.m_nodes.at(i); CCPoint pos = tempNode->getPosition(); CCSize size = tempNode->getContentSize(); if ( (pos.x - size.width *0.5f) <= 0 && (pos.x + size.width * 0.5f) >= 0 ) { return i; } } return -1;}