溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

cocos2d-x 自己寫的一個(gè)scrollview 有待完善

發(fā)布時(shí)間:2020-08-06 01:37:35 來(lái)源:網(wǎng)絡(luò) 閱讀:2505 作者:83628410 欄目:游戲開(kāi)發(fā)

 直接上代碼,根據(jù)cocos2d-x 擴(kuò)展庫(kù)中的代碼改編的。

 

  1. // 
  2. //  MScrollView.h 
  3. //  Test ScrollView 
  4. // 
  5. //  Created by Za aa on 13-4-25. 
  6. // 
  7. // 
  8.  
  9. #ifndef _MScrollView_h 
  10. #define _MScrollView_h 
  11. #include "cocos2d.h" 
  12. using namespace cocos2d; 
  13. //觸摸誤差 
  14. const int TOUCH_DELTA = 5; 
  15. //設(shè)置圖片修正時(shí)的移動(dòng)速度 
  16. const float MOVE_SPEED = 1000; 
  17. class MScrollView : public cocos2d::CCLayerColor 
  18. public
  19.     MScrollView(); 
  20.     ~MScrollView(); 
  21.     virtual bool init(); 
  22.     //復(fù)寫繪圖函數(shù),每幀調(diào)用,添加了區(qū)域剔除 
  23.     void visit(); 
  24.     //CREATE_FUNC(MScrollView); 
  25.      
  26.     //自定義-------- 
  27.     //從多個(gè)精靈創(chuàng)建 
  28.     static MScrollView * CreateWithSprite(float gap,CCSprite * p_w_picpathSprite,...); 
  29.      
  30.     //修改剔除區(qū)域 
  31.     void setClipSize(float width,float height); 
  32.      
  33.     //修改響應(yīng)區(qū)域 
  34.     void setTouchRect(CCRect touchRect){m_touchRect = touchRect;}; 
  35.      
  36.     //根據(jù)間距初始化子層精靈 
  37.     bool initGapForChild(float gap); 
  38.      
  39.     //修正動(dòng)畫的函數(shù) 
  40.     void RAnimation(CCPoint pt); 
  41.      
  42.     //拖動(dòng)精靈,跟隨手指移動(dòng)改變位置 
  43.     void draySprite(float delta); 
  44.      
  45.     //滾動(dòng)到某一頁(yè)的函數(shù) 
  46.     void gotoPageAnimation(float page); 
  47.   
  48.     //頁(yè)面滾動(dòng)動(dòng)畫,moveto 動(dòng)畫 
  49.     void ScrollAnimation(CCPoint offset,float time)    ; 
  50.      
  51.     //updata,用于如果拖動(dòng)就停止moveto 動(dòng)作 
  52.     void MoveToAnimation(float dt ); 
  53.      
  54.     // 添加一個(gè)回調(diào)函數(shù),用于停止動(dòng)畫 
  55.     void StopMoveToAnimation(); 
  56.      
  57.     //重寫觸屏相關(guān)函數(shù)----                       
  58.     virtual void registerWithTouchDispatcher(); 
  59.     virtual bool ccTouchBegan(CCTouch* touch, CCEvent* event); 
  60.     virtual void ccTouchMoved(CCTouch* touch, CCEvent* event); 
  61.     virtual void ccTouchEnded(CCTouch* touch, CCEvent* event); 
  62.     virtual void ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent); 
  63. private
  64.     //是否按下后移動(dòng) 
  65.     bool m_dragging; 
  66.     //按下的點(diǎn) 
  67.     CCPoint m_touchDownPoint; 
  68.     //抬起點(diǎn) 
  69.     CCPoint m_touchUpPoint; 
  70.     //當(dāng)前的觸電 
  71.     CCPoint m_touchCurPoint; 
  72.     //子層容器,用于滾動(dòng)顯示 
  73.     CCLayer * m_Container; 
  74.     //保存所有精靈 
  75.     CCArray * m_spriteArray; 
  76.     //總頁(yè)數(shù) 
  77.     int m_page; 
  78.     //當(dāng)前頁(yè)數(shù) 
  79.     int m_curpage; 
  80.     //偏移動(dòng)畫的時(shí)間 
  81.     float m_time; 
  82.     //顯示區(qū)域 
  83.   //  CCRect m_view; 
  84.     //顯示區(qū)域,區(qū)域外的將被剪切 
  85.     CCSize m_clipSize; 
  86.     //接收事件的區(qū)域 
  87.     CCRect m_touchRect; 
  88.     //點(diǎn)擊后的回調(diào)函數(shù) 
  89.     SEL_CallFunc m_fun; 
  90.  
  91. }; 
  92.  
  93.  
  94. #endif 

 

  1. // 
  2. //  MScrollView.cpp 
  3. //  Test ScrollView 
  4. // 
  5. //  Created by Za aa on 13-4-25. 
  6. // 
  7. // 
  8.  
  9. #include "MScrollView.h" 
  10. MScrollView::MScrollView() 
  11.      
  12. MScrollView::~MScrollView() 
  13.     //清空數(shù)組 
  14.     m_spriteArray->release(); 
  15.     
  16. MScrollView * MScrollView::CreateWithSprite(float gap,CCSprite *p_w_picpathSprite, ...) 
  17.     MScrollView * pRet = new MScrollView(); 
  18.     if (pRet && pRet->init())  
  19.     { 
  20.         //創(chuàng)建array,用于保存所有sprite 
  21.         pRet->m_spriteArray= CCArray::create(); 
  22.         CC_SAFE_RETAIN(pRet->m_spriteArray); 
  23.         //----------------------------------------------- 
  24.         //將省略的sprite添加進(jìn)m_spriteArray 和 mscrollview中 
  25.         //---------------------------------------------- 
  26.          
  27.         //定義一個(gè)params變量,實(shí)際是一個(gè)指針,用于定位可變行參變量  
  28.         va_list params; 
  29.         //執(zhí)行本宏后,params指向第一個(gè)可變信參,p_w_picpathSprite為最后一個(gè)確定行參  
  30.         va_start(params, p_w_picpathSprite); 
  31.          
  32.         //定義一個(gè)ccsprite 接收參數(shù) 
  33.         CCSprite * pNow = p_w_picpathSprite; 
  34.          
  35.         while (true
  36.         { 
  37.             if (pNow) 
  38.             { 
  39.                 //添加進(jìn)數(shù)組和層----- 
  40.                 pRet->m_spriteArray->addObject(pNow); 
  41.                 pRet->m_Container->addChild(pNow); 
  42.                 //去下一個(gè)值 
  43.                 pNow = va_arg(params, CCSprite *); 
  44.             } 
  45.             else 
  46.             { 
  47.                 break
  48.             } 
  49.              
  50.         } 
  51.         //清空 
  52.         va_end(params); 
  53.          
  54.         //排列ccprite 
  55.         pRet->initGapForChild(gap); 
  56.          
  57.         ////////////添加完成//////// 
  58.         pRet->autorelease(); 
  59.         return pRet;  
  60.     } \ 
  61.     else  
  62.     {  
  63.         delete pRet;  
  64.         pRet = NULL;  
  65.         return NULL;  
  66.     }  
  67.      
  68.  
  69.  
  70.  
  71. bool MScrollView::init() 
  72.     ////////////////////////////// 
  73.     // 1. super init first 
  74.    // if ( !CCLayerColor::init() ) 
  75.     if ( !CCLayerColor::CCLayerColor::initWithColor(ccc4(0xff,0x00,0x00,0x80), 100, 100)) 
  76.     { 
  77.         return false
  78.     } 
  79.        //開(kāi)啟觸屏響應(yīng) 
  80.     this->setTouchEnabled(true); 
  81.      
  82.     //添加顯示容器 
  83.     m_Container = CCLayer::create(); 
  84.     m_Container->setAnchorPoint(ccp(0.0f,0.0f)); 
  85.     m_Container->setPosition(ccp(0.0f, 0.0f)); 
  86.     this->addChild(m_Container); 
  87.      
  88.     //修改響應(yīng)區(qū)域,默認(rèn)是全屏 
  89.     CCSize screen = CCDirector::sharedDirector()->getWinSize(); 
  90.     setTouchRect(CCRectMake(0, 0, screen.width, screen.height)); 
  91.      
  92.     //修改顯示區(qū)域,默認(rèn)為全屏 
  93.     this->setContentSize(screen); 
  94.      
  95.     //修改剪切區(qū)域,默認(rèn)為全屏 
  96.     setClipSize(screen.width,screen.height); 
  97.      
  98.     //默認(rèn)回調(diào)函數(shù)為空 
  99.     m_fun =NULL; 
  100.     return true
  101.      
  102. void MScrollView::visit() 
  103.     if (!m_bIsVisible) 
  104.     { 
  105.         return
  106.     } 
  107.     kmGLPushMatrix(); 
  108.     if (m_pGrid && m_pGrid->isActive()) 
  109.     { 
  110.         m_pGrid->beforeDraw(); 
  111.         this->transformAncestors(); 
  112.     } 
  113.     this->transform(); 
  114.     //默認(rèn)情況下,剪裁是禁用的 
  115.     glEnable(GL_SCISSOR_TEST);//啟用剪裁測(cè)試 
  116.      
  117.     float s = this->getScale();//當(dāng)前l(fā)ayer縮放的倍數(shù) 
  118.     s *= CCDirector::sharedDirector()->getContentScaleFactor();//獲取縮放倍率 
  119.     CCPoint screenPos = this->convertToWorldSpace(this->getParent()->getPosition()); 
  120.     //默認(rèn)不設(shè)置Scissor的大小是整個(gè)視圖的大小 
  121.     glScissor((GLint)screenPos.x, (GLint)screenPos.y, (GLsizei)(m_clipSize.width*s), (GLsizei)(m_clipSize.height*s)); 
  122.      
  123.     //子節(jié)點(diǎn)處理 
  124.     if(m_pChildren) 
  125.     { 
  126.         ccArray *arrayData = m_pChildren->data; 
  127.         unsigned int i=0; 
  128.          
  129.         for( ; i < arrayData->num; i++ ) 
  130.         { 
  131.             CCNode *child =  (CCNode*)arrayData->arr[i]; 
  132.             if ( child->getZOrder() < 0 ) 
  133.             { 
  134.                 child->visit(); 
  135.             } 
  136.             else 
  137.             { 
  138.                 break
  139.             } 
  140.         } 
  141.         this->draw(); 
  142.         for( ; i < arrayData->num; i++ ) 
  143.         { 
  144.             CCNode* child = (CCNode*)arrayData->arr[i]; 
  145.             child->visit(); 
  146.         } 
  147.          
  148.     } else 
  149.     { 
  150.         this->draw(); 
  151.     } 
  152.      
  153.     glDisable(GL_SCISSOR_TEST);//禁用剪裁測(cè)試 
  154.      
  155.     if ( m_pGrid && m_pGrid->isActive()) 
  156.     { 
  157.         m_pGrid->afterDraw(this); 
  158.     } 
  159.      
  160.     kmGLPopMatrix(); 
  161.      
  162.     // 
  163.      
  164.  
  165. void MScrollView::setClipSize(float width,float height) 
  166.     m_clipSize = CCSizeMake(width,height); 
  167. //TODO: 載顯示容器中排列精靈 
  168. bool MScrollView::initGapForChild(float gap) 
  169.     //用于判讀是否有元素 
  170.     if (m_spriteArray==NULL) return false
  171.     ///////////修改各個(gè)元素的位置 
  172.    //初始化當(dāng)前頁(yè) 
  173.     m_curpage = 0; 
  174.     //初始化總頁(yè)數(shù) 
  175.     m_page = m_spriteArray->count(); 
  176.      
  177.     CCSprite * sp = (CCSprite *)m_spriteArray->objectAtIndex(0); 
  178.    float spwidth = sp->boundingBox().size.width/2.0f; 
  179.     float spheight = sp->boundingBox().size.height/2.0f; 
  180.     //獲取一個(gè)中心點(diǎn) 
  181.     CCPoint pt = ccp(this->boundingBox().size.width/2.0f-spwidth, 
  182.                      this->boundingBox().size.height/2.0f-spheight); 
  183.     float tY=pt.y; 
  184.     sp->setAnchorPoint(ccp(0,0)); 
  185.     sp->setPosition(pt); 
  186.      
  187.     for (int i = 1 ; i<m_page; i++) 
  188.     { 
  189.         spwidth = sp->boundingBox().size.width; 
  190.         pt =ccp(sp->getPositionX()+spwidth+gap,tY); 
  191.               
  192.       sp = (CCSprite *)m_spriteArray->objectAtIndex(i); 
  193.         sp->setAnchorPoint(ccp(0,0)); 
  194.         sp->setPosition(pt); 
  195.          
  196.     } 
  197.      
  198.      
  199. //TODO: 滾動(dòng)修正 
  200. void MScrollView::RAnimation(CCPoint pt) 
  201.     int _page = m_curpage; 
  202.      
  203.     //判斷移動(dòng)的方向 
  204.     float f =pt.x; 
  205.     if(f>0) 
  206.     { 
  207.         // 向左移動(dòng) 
  208.         CCLog("zuo "); 
  209.         _page ++; 
  210.                   
  211.     } 
  212.     else 
  213.     { 
  214.         //向→移動(dòng) 
  215.         CCLog("you"); 
  216.         _page --; 
  217.         
  218.     } 
  219.      
  220.     if ( !(_page>m_page-1 || _page<0)) 
  221.     { 
  222.          m_curpage = _page; 
  223.     } 
  224.     CCLog("_page is : %d",_page); 
  225.     CCLog(" page is : %d",m_page); 
  226.     CCLog(" curpage is : %d",m_curpage); 
  227.     gotoPageAnimation(m_curpage); 
  228.  
  229. //TODO: 拖動(dòng)精靈,跟隨手指移動(dòng)改變位置 
  230. void MScrollView::draySprite(float delta) 
  231.     this->m_Container->setPosition(ccpAdd(this->m_Container->getPosition(), ccp(delta,0))); 
  232. }  
  233. //TODO: 滾動(dòng)到某一頁(yè)的動(dòng)畫 
  234. void MScrollView::gotoPageAnimation(float page) 
  235.     if (m_page == 0 ) return
  236.     //獲得當(dāng)前頁(yè)的精靈 
  237.     CCSprite * sp  = (CCSprite *)this->m_spriteArray->objectAtIndex(page); 
  238.     //多移動(dòng)一小段距離讓sprite載正中間 
  239.     float _width = sp->boundingBox().size.width * 0.5f; 
  240.     _width = m_clipSize.width * 0.5f - _width; 
  241.      
  242.     //獲取要到達(dá)的點(diǎn) 
  243.     CCPoint gotoPoint =ccp(-sp->getPositionX()+_width,this->m_Container->getPositionY()); 
  244.     //計(jì)算移動(dòng)到點(diǎn)的時(shí)間 
  245.     float _length = ccpDistance(gotoPoint,m_Container->getPosition()); 
  246.      
  247.     float _time = _length / MOVE_SPEED; 
  248.     //滾動(dòng)到指定點(diǎn) 
  249.      
  250.     ScrollAnimation(gotoPoint,_time); 
  251.      
  252.      
  253. //頁(yè)面滾動(dòng)動(dòng)畫,moveto 動(dòng)畫 
  254.  void MScrollView::ScrollAnimation(CCPoint offset,float time) 
  255.     //如果是拖動(dòng)就停止這個(gè)動(dòng)作 
  256.     if (m_dragging) 
  257.     { 
  258.         this->unschedule(schedule_selector(MScrollView::MoveToAnimation)); 
  259.         return
  260.     } 
  261.     /////////////// 
  262.     //創(chuàng)建移動(dòng)動(dòng)畫 
  263.     ////////////// 
  264.     CCFiniteTimeAction * scroll,*expire; 
  265.     scroll = CCMoveTo::create(time,offset); 
  266.     //添加一個(gè)回調(diào)函數(shù) 
  267.       expire = CCCallFuncN::create(this, callfuncN_selector(MScrollView::StopMoveToAnimation)); 
  268.     //運(yùn)行moveto動(dòng)畫 
  269.     m_Container->runAction(CCSequence::create(scroll, expire, NULL)); 
  270.     //開(kāi)啟拖動(dòng)判讀 
  271.      this->schedule(schedule_selector(MScrollView::MoveToAnimation)); 
  272.      
  273.      
  274.  
  275. //updata,用于如果拖動(dòng)就停止moveto 動(dòng)作 
  276. void  MScrollView:: MoveToAnimation(float dt ) 
  277.     if (m_dragging) 
  278.     { 
  279.         this->m_Container->unscheduleAllSelectors(); 
  280.  
  281.         return
  282.     } 
  283.     
  284. // // 添加一個(gè)回調(diào)函數(shù),用于停止動(dòng)畫 
  285. void MScrollView:: StopMoveToAnimation() 
  286. //   this->unschedule(schedule_selector(MoveToAnimation)); 
  287.     this->m_Container->unscheduleAllSelectors(); 
  288. //消息注冊(cè) 
  289. void MScrollView::registerWithTouchDispatcher() 
  290.     CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 0, false); 
  291. bool MScrollView::ccTouchBegan(cocos2d::CCTouch *touch, cocos2d::CCEvent *event) 
  292.     if (!this->isVisible()) {return false;} 
  293.     //記錄按下的點(diǎn) 
  294.     m_touchDownPoint = CCDirector::sharedDirector()->convertToGL(touch->locationInView()); 
  295.      
  296.     if (!m_touchRect.containsPoint(m_touchDownPoint)){return false;} 
  297.      
  298.     m_dragging = true
  299.     CCLog("CCtouchBegan"); 
  300.    //  
  301.      
  302.     return true
  303.      
  304.  void MScrollView::ccTouchMoved(CCTouch* touch, CCEvent* event) 
  305.     CCLog("ccTouchMoved"); 
  306.     if (!this->isVisible()){return;} 
  307.      
  308.     m_touchCurPoint = CCDirector::sharedDirector()->convertToGL(touch->locationInView()); 
  309.     if (!m_touchRect.containsPoint(m_touchCurPoint)) 
  310.     { 
  311.         m_dragging = false
  312.         return ; 
  313.     } 
  314.     //如果不是按下后移動(dòng) 
  315.     if(m_dragging) 
  316.     { 
  317.         CCPoint moveDelta = ccpSub(m_touchCurPoint, m_touchDownPoint); 
  318.         draySprite(moveDelta.x); 
  319.         m_dragging = false
  320.  
  321.     } 
  322.     else 
  323.     { 
  324.         draySprite(touch->getDelta().x); 
  325.     } 
  326.      
  327.    // CCLog("ccTouchMoved,x is %f::y is %f",x,y); 
  328. void MScrollView::ccTouchEnded(CCTouch* touch, CCEvent* event) 
  329.     if (!this->isVisible()){return;} 
  330.      m_touchUpPoint = CCDirector::sharedDirector()->convertToGL(touch->locationInView()); 
  331.     if (!m_touchRect.containsPoint(m_touchUpPoint)){ m_dragging = false;return ;} 
  332.     //判定是點(diǎn)擊還是滑動(dòng),如果是點(diǎn)擊執(zhí)行點(diǎn)擊函數(shù),如果是滑動(dòng)執(zhí)行調(diào)整動(dòng)畫 
  333.     
  334.     float off = ccpDistance(m_touchDownPoint,m_touchUpPoint); 
  335.     if (off < TOUCH_DELTA) 
  336.     { 
  337.         //觸發(fā)點(diǎn)擊事件 
  338.         m_fun; 
  339.         CCLog("touchclick"); 
  340.         
  341.     } 
  342.     else 
  343.     { 
  344.         //  滑動(dòng)糾正 
  345.         //觸發(fā)滑動(dòng)動(dòng)畫 
  346.         RAnimation(ccpSub(m_touchDownPoint,m_touchUpPoint)); 
  347.     } 
  348.   
  349.  
  350.      
  351.      
  352. void MScrollView::ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent) 
  353.      

 

向AI問(wèn)一下細(xì)節(jié)

免責(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)容。

AI