您好,登錄后才能下訂單哦!
直接上代碼,根據cocos2d-x 擴展庫中的代碼改編的。
- //
- // 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;
- //設置圖片修正時的移動速度
- const float MOVE_SPEED = 1000;
- class MScrollView : public cocos2d::CCLayerColor
- {
- public:
- MScrollView();
- ~MScrollView();
- virtual bool init();
- //復寫繪圖函數,每幀調用,添加了區域剔除
- void visit();
- //CREATE_FUNC(MScrollView);
- //自定義--------
- //從多個精靈創建
- static MScrollView * CreateWithSprite(float gap,CCSprite * p_w_picpathSprite,...);
- //修改剔除區域
- void setClipSize(float width,float height);
- //修改響應區域
- void setTouchRect(CCRect touchRect){m_touchRect = touchRect;};
- //根據間距初始化子層精靈
- bool initGapForChild(float gap);
- //修正動畫的函數
- void RAnimation(CCPoint pt);
- //拖動精靈,跟隨手指移動改變位置
- void draySprite(float delta);
- //滾動到某一頁的函數
- void gotoPageAnimation(float page);
- //頁面滾動動畫,moveto 動畫
- void ScrollAnimation(CCPoint offset,float time) ;
- //updata,用于如果拖動就停止moveto 動作
- void MoveToAnimation(float dt );
- // 添加一個回調函數,用于停止動畫
- void StopMoveToAnimation();
- //重寫觸屏相關函數----
- 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:
- //是否按下后移動
- bool m_dragging;
- //按下的點
- CCPoint m_touchDownPoint;
- //抬起點
- CCPoint m_touchUpPoint;
- //當前的觸電
- CCPoint m_touchCurPoint;
- //子層容器,用于滾動顯示
- CCLayer * m_Container;
- //保存所有精靈
- CCArray * m_spriteArray;
- //總頁數
- int m_page;
- //當前頁數
- int m_curpage;
- //偏移動畫的時間
- float m_time;
- //顯示區域
- // CCRect m_view;
- //顯示區域,區域外的將被剪切
- CCSize m_clipSize;
- //接收事件的區域
- CCRect m_touchRect;
- //點擊后的回調函數
- SEL_CallFunc m_fun;
- };
- #endif
- //
- // MScrollView.cpp
- // Test ScrollView
- //
- // Created by Za aa on 13-4-25.
- //
- //
- #include "MScrollView.h"
- MScrollView::MScrollView()
- {
- }
- MScrollView::~MScrollView()
- {
- //清空數組
- m_spriteArray->release();
- }
- MScrollView * MScrollView::CreateWithSprite(float gap,CCSprite *p_w_picpathSprite, ...)
- {
- MScrollView * pRet = new MScrollView();
- if (pRet && pRet->init())
- {
- //創建array,用于保存所有sprite
- pRet->m_spriteArray= CCArray::create();
- CC_SAFE_RETAIN(pRet->m_spriteArray);
- //-----------------------------------------------
- //將省略的sprite添加進m_spriteArray 和 mscrollview中
- //----------------------------------------------
- //定義一個params變量,實際是一個指針,用于定位可變行參變量
- va_list params;
- //執行本宏后,params指向第一個可變信參,p_w_picpathSprite為最后一個確定行參
- va_start(params, p_w_picpathSprite);
- //定義一個ccsprite 接收參數
- CCSprite * pNow = p_w_picpathSprite;
- while (true)
- {
- if (pNow)
- {
- //添加進數組和層-----
- pRet->m_spriteArray->addObject(pNow);
- pRet->m_Container->addChild(pNow);
- //去下一個值
- 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;
- }
- //開啟觸屏響應
- 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);
- //修改響應區域,默認是全屏
- CCSize screen = CCDirector::sharedDirector()->getWinSize();
- setTouchRect(CCRectMake(0, 0, screen.width, screen.height));
- //修改顯示區域,默認為全屏
- this->setContentSize(screen);
- //修改剪切區域,默認為全屏
- setClipSize(screen.width,screen.height);
- //默認回調函數為空
- 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();
- //默認情況下,剪裁是禁用的
- glEnable(GL_SCISSOR_TEST);//啟用剪裁測試
- float s = this->getScale();//當前layer縮放的倍數
- s *= CCDirector::sharedDirector()->getContentScaleFactor();//獲取縮放倍率
- CCPoint screenPos = this->convertToWorldSpace(this->getParent()->getPosition());
- //默認不設置Scissor的大小是整個視圖的大小
- glScissor((GLint)screenPos.x, (GLint)screenPos.y, (GLsizei)(m_clipSize.width*s), (GLsizei)(m_clipSize.height*s));
- //子節點處理
- 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);//禁用剪裁測試
- 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;
- ///////////修改各個元素的位置
- //初始化當前頁
- m_curpage = 0;
- //初始化總頁數
- 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;
- //獲取一個中心點
- 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: 滾動修正
- void MScrollView::RAnimation(CCPoint pt)
- {
- int _page = m_curpage;
- //判斷移動的方向
- float f =pt.x;
- if(f>0)
- {
- // 向左移動
- CCLog("zuo ");
- _page ++;
- }
- else
- {
- //向→移動
- 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: 拖動精靈,跟隨手指移動改變位置
- void MScrollView::draySprite(float delta)
- {
- this->m_Container->setPosition(ccpAdd(this->m_Container->getPosition(), ccp(delta,0)));
- }
- //TODO: 滾動到某一頁的動畫
- void MScrollView::gotoPageAnimation(float page)
- {
- if (m_page == 0 ) return;
- //獲得當前頁的精靈
- CCSprite * sp = (CCSprite *)this->m_spriteArray->objectAtIndex(page);
- //多移動一小段距離讓sprite載正中間
- float _width = sp->boundingBox().size.width * 0.5f;
- _width = m_clipSize.width * 0.5f - _width;
- //獲取要到達的點
- CCPoint gotoPoint =ccp(-sp->getPositionX()+_width,this->m_Container->getPositionY());
- //計算移動到點的時間
- float _length = ccpDistance(gotoPoint,m_Container->getPosition());
- float _time = _length / MOVE_SPEED;
- //滾動到指定點
- ScrollAnimation(gotoPoint,_time);
- }
- //頁面滾動動畫,moveto 動畫
- void MScrollView::ScrollAnimation(CCPoint offset,float time)
- {
- //如果是拖動就停止這個動作
- if (m_dragging)
- {
- this->unschedule(schedule_selector(MScrollView::MoveToAnimation));
- return;
- }
- ///////////////
- //創建移動動畫
- //////////////
- CCFiniteTimeAction * scroll,*expire;
- scroll = CCMoveTo::create(time,offset);
- //添加一個回調函數
- expire = CCCallFuncN::create(this, callfuncN_selector(MScrollView::StopMoveToAnimation));
- //運行moveto動畫
- m_Container->runAction(CCSequence::create(scroll, expire, NULL));
- //開啟拖動判讀
- this->schedule(schedule_selector(MScrollView::MoveToAnimation));
- }
- //updata,用于如果拖動就停止moveto 動作
- void MScrollView:: MoveToAnimation(float dt )
- {
- if (m_dragging)
- {
- this->m_Container->unscheduleAllSelectors();
- return;
- }
- }
- // // 添加一個回調函數,用于停止動畫
- void MScrollView:: StopMoveToAnimation()
- {
- // this->unschedule(schedule_selector(MoveToAnimation));
- this->m_Container->unscheduleAllSelectors();
- }
- //消息注冊
- void MScrollView::registerWithTouchDispatcher()
- {
- CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 0, false);
- }
- bool MScrollView::ccTouchBegan(cocos2d::CCTouch *touch, cocos2d::CCEvent *event)
- {
- if (!this->isVisible()) {return false;}
- //記錄按下的點
- 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 ;
- }
- //如果不是按下后移動
- 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 ;}
- //判定是點擊還是滑動,如果是點擊執行點擊函數,如果是滑動執行調整動畫
- float off = ccpDistance(m_touchDownPoint,m_touchUpPoint);
- if (off < TOUCH_DELTA)
- {
- //觸發點擊事件
- m_fun;
- CCLog("touchclick");
- }
- else
- {
- // 滑動糾正
- //觸發滑動動畫
- RAnimation(ccpSub(m_touchDownPoint,m_touchUpPoint));
- }
- }
- void MScrollView::ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent)
- {
- }
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。