您好,登錄后才能下訂單哦!
直接上代碼,根據(jù)cocos2d-x 擴(kuò)展庫(kù)中的代碼改編的。
- //
- // MScrollView.h
- // Test ScrollView
- //
- // Created by Za aa on 13-4-25.
- //
- //
- #ifndef _MScrollView_h
- #define _MScrollView_h
- #include "cocos2d.h"
- using namespace cocos2d;
- //觸摸誤差
- const int TOUCH_DELTA = 5;
- //設(shè)置圖片修正時(shí)的移動(dòng)速度
- const float MOVE_SPEED = 1000;
- class MScrollView : public cocos2d::CCLayerColor
- {
- public:
- MScrollView();
- ~MScrollView();
- virtual bool init();
- //復(fù)寫繪圖函數(shù),每幀調(diào)用,添加了區(qū)域剔除
- void visit();
- //CREATE_FUNC(MScrollView);
- //自定義--------
- //從多個(gè)精靈創(chuàng)建
- static MScrollView * CreateWithSprite(float gap,CCSprite * p_w_picpathSprite,...);
- //修改剔除區(qū)域
- void setClipSize(float width,float height);
- //修改響應(yīng)區(qū)域
- void setTouchRect(CCRect touchRect){m_touchRect = touchRect;};
- //根據(jù)間距初始化子層精靈
- bool initGapForChild(float gap);
- //修正動(dòng)畫的函數(shù)
- void RAnimation(CCPoint pt);
- //拖動(dòng)精靈,跟隨手指移動(dòng)改變位置
- void draySprite(float delta);
- //滾動(dòng)到某一頁(yè)的函數(shù)
- void gotoPageAnimation(float page);
- //頁(yè)面滾動(dòng)動(dòng)畫,moveto 動(dòng)畫
- void ScrollAnimation(CCPoint offset,float time) ;
- //updata,用于如果拖動(dòng)就停止moveto 動(dòng)作
- void MoveToAnimation(float dt );
- // 添加一個(gè)回調(diào)函數(shù),用于停止動(dòng)畫
- void StopMoveToAnimation();
- //重寫觸屏相關(guān)函數(shù)----
- virtual void registerWithTouchDispatcher();
- virtual bool ccTouchBegan(CCTouch* touch, CCEvent* event);
- virtual void ccTouchMoved(CCTouch* touch, CCEvent* event);
- virtual void ccTouchEnded(CCTouch* touch, CCEvent* event);
- virtual void ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent);
- private:
- //是否按下后移動(dòng)
- bool m_dragging;
- //按下的點(diǎn)
- CCPoint m_touchDownPoint;
- //抬起點(diǎn)
- CCPoint m_touchUpPoint;
- //當(dāng)前的觸電
- CCPoint m_touchCurPoint;
- //子層容器,用于滾動(dòng)顯示
- CCLayer * m_Container;
- //保存所有精靈
- CCArray * m_spriteArray;
- //總頁(yè)數(shù)
- int m_page;
- //當(dāng)前頁(yè)數(shù)
- int m_curpage;
- //偏移動(dòng)畫的時(shí)間
- float m_time;
- //顯示區(qū)域
- // CCRect m_view;
- //顯示區(qū)域,區(qū)域外的將被剪切
- CCSize m_clipSize;
- //接收事件的區(qū)域
- CCRect m_touchRect;
- //點(diǎn)擊后的回調(diào)函數(shù)
- SEL_CallFunc m_fun;
- };
- #endif
- //
- // MScrollView.cpp
- // Test ScrollView
- //
- // Created by Za aa on 13-4-25.
- //
- //
- #include "MScrollView.h"
- MScrollView::MScrollView()
- {
- }
- MScrollView::~MScrollView()
- {
- //清空數(shù)組
- m_spriteArray->release();
- }
- MScrollView * MScrollView::CreateWithSprite(float gap,CCSprite *p_w_picpathSprite, ...)
- {
- MScrollView * pRet = new MScrollView();
- if (pRet && pRet->init())
- {
- //創(chuàng)建array,用于保存所有sprite
- pRet->m_spriteArray= CCArray::create();
- CC_SAFE_RETAIN(pRet->m_spriteArray);
- //-----------------------------------------------
- //將省略的sprite添加進(jìn)m_spriteArray 和 mscrollview中
- //----------------------------------------------
- //定義一個(gè)params變量,實(shí)際是一個(gè)指針,用于定位可變行參變量
- va_list params;
- //執(zhí)行本宏后,params指向第一個(gè)可變信參,p_w_picpathSprite為最后一個(gè)確定行參
- va_start(params, p_w_picpathSprite);
- //定義一個(gè)ccsprite 接收參數(shù)
- CCSprite * pNow = p_w_picpathSprite;
- while (true)
- {
- if (pNow)
- {
- //添加進(jìn)數(shù)組和層-----
- pRet->m_spriteArray->addObject(pNow);
- pRet->m_Container->addChild(pNow);
- //去下一個(gè)值
- pNow = va_arg(params, CCSprite *);
- }
- else
- {
- break;
- }
- }
- //清空
- va_end(params);
- //排列ccprite
- pRet->initGapForChild(gap);
- ////////////添加完成////////
- pRet->autorelease();
- return pRet;
- } \
- else
- {
- delete pRet;
- pRet = NULL;
- return NULL;
- }
- }
- bool MScrollView::init()
- {
- //////////////////////////////
- // 1. super init first
- // if ( !CCLayerColor::init() )
- if ( !CCLayerColor::CCLayerColor::initWithColor(ccc4(0xff,0x00,0x00,0x80), 100, 100))
- {
- return false;
- }
- //開(kāi)啟觸屏響應(yīng)
- this->setTouchEnabled(true);
- //添加顯示容器
- m_Container = CCLayer::create();
- m_Container->setAnchorPoint(ccp(0.0f,0.0f));
- m_Container->setPosition(ccp(0.0f, 0.0f));
- this->addChild(m_Container);
- //修改響應(yīng)區(qū)域,默認(rèn)是全屏
- CCSize screen = CCDirector::sharedDirector()->getWinSize();
- setTouchRect(CCRectMake(0, 0, screen.width, screen.height));
- //修改顯示區(qū)域,默認(rèn)為全屏
- this->setContentSize(screen);
- //修改剪切區(qū)域,默認(rèn)為全屏
- setClipSize(screen.width,screen.height);
- //默認(rèn)回調(diào)函數(shù)為空
- m_fun =NULL;
- return true;
- }
- void MScrollView::visit()
- {
- if (!m_bIsVisible)
- {
- return;
- }
- kmGLPushMatrix();
- if (m_pGrid && m_pGrid->isActive())
- {
- m_pGrid->beforeDraw();
- this->transformAncestors();
- }
- this->transform();
- //默認(rèn)情況下,剪裁是禁用的
- glEnable(GL_SCISSOR_TEST);//啟用剪裁測(cè)試
- float s = this->getScale();//當(dāng)前l(fā)ayer縮放的倍數(shù)
- s *= CCDirector::sharedDirector()->getContentScaleFactor();//獲取縮放倍率
- CCPoint screenPos = this->convertToWorldSpace(this->getParent()->getPosition());
- //默認(rèn)不設(shè)置Scissor的大小是整個(gè)視圖的大小
- glScissor((GLint)screenPos.x, (GLint)screenPos.y, (GLsizei)(m_clipSize.width*s), (GLsizei)(m_clipSize.height*s));
- //子節(jié)點(diǎn)處理
- if(m_pChildren)
- {
- ccArray *arrayData = m_pChildren->data;
- unsigned int i=0;
- for( ; i < arrayData->num; i++ )
- {
- CCNode *child = (CCNode*)arrayData->arr[i];
- if ( child->getZOrder() < 0 )
- {
- child->visit();
- }
- else
- {
- break;
- }
- }
- this->draw();
- for( ; i < arrayData->num; i++ )
- {
- CCNode* child = (CCNode*)arrayData->arr[i];
- child->visit();
- }
- } else
- {
- this->draw();
- }
- glDisable(GL_SCISSOR_TEST);//禁用剪裁測(cè)試
- if ( m_pGrid && m_pGrid->isActive())
- {
- m_pGrid->afterDraw(this);
- }
- kmGLPopMatrix();
- //
- }
- void MScrollView::setClipSize(float width,float height)
- {
- m_clipSize = CCSizeMake(width,height);
- }
- //TODO: 載顯示容器中排列精靈
- bool MScrollView::initGapForChild(float gap)
- {
- //用于判讀是否有元素
- if (m_spriteArray==NULL) return false;
- ///////////修改各個(gè)元素的位置
- //初始化當(dāng)前頁(yè)
- m_curpage = 0;
- //初始化總頁(yè)數(shù)
- m_page = m_spriteArray->count();
- CCSprite * sp = (CCSprite *)m_spriteArray->objectAtIndex(0);
- float spwidth = sp->boundingBox().size.width/2.0f;
- float spheight = sp->boundingBox().size.height/2.0f;
- //獲取一個(gè)中心點(diǎn)
- CCPoint pt = ccp(this->boundingBox().size.width/2.0f-spwidth,
- this->boundingBox().size.height/2.0f-spheight);
- float tY=pt.y;
- sp->setAnchorPoint(ccp(0,0));
- sp->setPosition(pt);
- for (int i = 1 ; i<m_page; i++)
- {
- spwidth = sp->boundingBox().size.width;
- pt =ccp(sp->getPositionX()+spwidth+gap,tY);
- sp = (CCSprite *)m_spriteArray->objectAtIndex(i);
- sp->setAnchorPoint(ccp(0,0));
- sp->setPosition(pt);
- }
- }
- //TODO: 滾動(dòng)修正
- void MScrollView::RAnimation(CCPoint pt)
- {
- int _page = m_curpage;
- //判斷移動(dòng)的方向
- float f =pt.x;
- if(f>0)
- {
- // 向左移動(dòng)
- CCLog("zuo ");
- _page ++;
- }
- else
- {
- //向→移動(dòng)
- CCLog("you");
- _page --;
- }
- if ( !(_page>m_page-1 || _page<0))
- {
- m_curpage = _page;
- }
- CCLog("_page is : %d",_page);
- CCLog(" page is : %d",m_page);
- CCLog(" curpage is : %d",m_curpage);
- gotoPageAnimation(m_curpage);
- }
- //TODO: 拖動(dòng)精靈,跟隨手指移動(dòng)改變位置
- void MScrollView::draySprite(float delta)
- {
- this->m_Container->setPosition(ccpAdd(this->m_Container->getPosition(), ccp(delta,0)));
- }
- //TODO: 滾動(dòng)到某一頁(yè)的動(dòng)畫
- void MScrollView::gotoPageAnimation(float page)
- {
- if (m_page == 0 ) return;
- //獲得當(dāng)前頁(yè)的精靈
- CCSprite * sp = (CCSprite *)this->m_spriteArray->objectAtIndex(page);
- //多移動(dòng)一小段距離讓sprite載正中間
- float _width = sp->boundingBox().size.width * 0.5f;
- _width = m_clipSize.width * 0.5f - _width;
- //獲取要到達(dá)的點(diǎn)
- CCPoint gotoPoint =ccp(-sp->getPositionX()+_width,this->m_Container->getPositionY());
- //計(jì)算移動(dòng)到點(diǎn)的時(shí)間
- float _length = ccpDistance(gotoPoint,m_Container->getPosition());
- float _time = _length / MOVE_SPEED;
- //滾動(dòng)到指定點(diǎn)
- ScrollAnimation(gotoPoint,_time);
- }
- //頁(yè)面滾動(dòng)動(dòng)畫,moveto 動(dòng)畫
- void MScrollView::ScrollAnimation(CCPoint offset,float time)
- {
- //如果是拖動(dòng)就停止這個(gè)動(dòng)作
- if (m_dragging)
- {
- this->unschedule(schedule_selector(MScrollView::MoveToAnimation));
- return;
- }
- ///////////////
- //創(chuàng)建移動(dòng)動(dòng)畫
- //////////////
- CCFiniteTimeAction * scroll,*expire;
- scroll = CCMoveTo::create(time,offset);
- //添加一個(gè)回調(diào)函數(shù)
- expire = CCCallFuncN::create(this, callfuncN_selector(MScrollView::StopMoveToAnimation));
- //運(yùn)行moveto動(dòng)畫
- m_Container->runAction(CCSequence::create(scroll, expire, NULL));
- //開(kāi)啟拖動(dòng)判讀
- this->schedule(schedule_selector(MScrollView::MoveToAnimation));
- }
- //updata,用于如果拖動(dòng)就停止moveto 動(dòng)作
- void MScrollView:: MoveToAnimation(float dt )
- {
- if (m_dragging)
- {
- this->m_Container->unscheduleAllSelectors();
- return;
- }
- }
- // // 添加一個(gè)回調(diào)函數(shù),用于停止動(dòng)畫
- void MScrollView:: StopMoveToAnimation()
- {
- // this->unschedule(schedule_selector(MoveToAnimation));
- this->m_Container->unscheduleAllSelectors();
- }
- //消息注冊(cè)
- void MScrollView::registerWithTouchDispatcher()
- {
- CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 0, false);
- }
- bool MScrollView::ccTouchBegan(cocos2d::CCTouch *touch, cocos2d::CCEvent *event)
- {
- if (!this->isVisible()) {return false;}
- //記錄按下的點(diǎn)
- m_touchDownPoint = CCDirector::sharedDirector()->convertToGL(touch->locationInView());
- if (!m_touchRect.containsPoint(m_touchDownPoint)){return false;}
- m_dragging = true;
- CCLog("CCtouchBegan");
- //
- return true;
- }
- void MScrollView::ccTouchMoved(CCTouch* touch, CCEvent* event)
- {
- CCLog("ccTouchMoved");
- if (!this->isVisible()){return;}
- m_touchCurPoint = CCDirector::sharedDirector()->convertToGL(touch->locationInView());
- if (!m_touchRect.containsPoint(m_touchCurPoint))
- {
- m_dragging = false;
- return ;
- }
- //如果不是按下后移動(dòng)
- if(m_dragging)
- {
- CCPoint moveDelta = ccpSub(m_touchCurPoint, m_touchDownPoint);
- draySprite(moveDelta.x);
- m_dragging = false;
- }
- else
- {
- draySprite(touch->getDelta().x);
- }
- // CCLog("ccTouchMoved,x is %f::y is %f",x,y);
- }
- void MScrollView::ccTouchEnded(CCTouch* touch, CCEvent* event)
- {
- if (!this->isVisible()){return;}
- m_touchUpPoint = CCDirector::sharedDirector()->convertToGL(touch->locationInView());
- if (!m_touchRect.containsPoint(m_touchUpPoint)){ m_dragging = false;return ;}
- //判定是點(diǎn)擊還是滑動(dòng),如果是點(diǎn)擊執(zhí)行點(diǎn)擊函數(shù),如果是滑動(dòng)執(zhí)行調(diào)整動(dòng)畫
- float off = ccpDistance(m_touchDownPoint,m_touchUpPoint);
- if (off < TOUCH_DELTA)
- {
- //觸發(fā)點(diǎn)擊事件
- m_fun;
- CCLog("touchclick");
- }
- else
- {
- // 滑動(dòng)糾正
- //觸發(fā)滑動(dòng)動(dòng)畫
- RAnimation(ccpSub(m_touchDownPoint,m_touchUpPoint));
- }
- }
- void MScrollView::ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent)
- {
- }
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。