cocos2d-x 自己寫的一個scrollview 有待完善

 直接上代碼,根據cocos2d-x 擴展庫中的代碼改編的。

 

  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. //設置圖片修正時的移動速度 
  16. const float MOVE_SPEED = 1000; 
  17. class MScrollView : public cocos2d::CCLayerColor 
  18. public
  19.     MScrollView(); 
  20.     ~MScrollView(); 
  21.     virtual bool init(); 
  22.     //複寫繪圖函數,每幀調用,添加了區域剔除 
  23.     void visit(); 
  24.     //CREATE_FUNC(MScrollView); 
  25.      
  26.     //自定義-------- 
  27.     //從多個精靈創建 
  28.     static MScrollView * CreateWithSprite(float gap,CCSprite * p_w_picpathSprite,...); 
  29.      
  30.     //修改剔除區域 
  31.     void setClipSize(float width,float height); 
  32.      
  33.     //修改響應區域 
  34.     void setTouchRect(CCRect touchRect){m_touchRect = touchRect;}; 
  35.      
  36.     //根據間距初始化子層精靈 
  37.     bool initGapForChild(float gap); 
  38.      
  39.     //修正動畫的函數 
  40.     void RAnimation(CCPoint pt); 
  41.      
  42.     //拖動精靈,跟隨手指移動改變位置 
  43.     void draySprite(float delta); 
  44.      
  45.     //滾動到某一頁的函數 
  46.     void gotoPageAnimation(float page); 
  47.   
  48.     //頁面滾動動畫,moveto 動畫 
  49.     void ScrollAnimation(CCPoint offset,float time)    ; 
  50.      
  51.     //updata,用於如果拖動就停止moveto 動作 
  52.     void MoveToAnimation(float dt ); 
  53.      
  54.     // 添加一個回調函數,用於停止動畫 
  55.     void StopMoveToAnimation(); 
  56.      
  57.     //重寫觸屏相關函數----                       
  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.     //是否按下後移動 
  65.     bool m_dragging; 
  66.     //按下的點 
  67.     CCPoint m_touchDownPoint; 
  68.     //擡起點 
  69.     CCPoint m_touchUpPoint; 
  70.     //當前的觸電 
  71.     CCPoint m_touchCurPoint; 
  72.     //子層容器,用於滾動顯示 
  73.     CCLayer * m_Container; 
  74.     //保存所有精靈 
  75.     CCArray * m_spriteArray; 
  76.     //總頁數 
  77.     int m_page; 
  78.     //當前頁數 
  79.     int m_curpage; 
  80.     //偏移動畫的時間 
  81.     float m_time; 
  82.     //顯示區域 
  83.   //  CCRect m_view; 
  84.     //顯示區域,區域外的將被剪切 
  85.     CCSize m_clipSize; 
  86.     //接收事件的區域 
  87.     CCRect m_touchRect; 
  88.     //點擊後的回調函數 
  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.     //清空數組 
  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.         //創建array,用於保存所有sprite 
  21.         pRet->m_spriteArray= CCArray::create(); 
  22.         CC_SAFE_RETAIN(pRet->m_spriteArray); 
  23.         //----------------------------------------------- 
  24.         //將省略的sprite添加進m_spriteArray 和 mscrollview中 
  25.         //---------------------------------------------- 
  26.          
  27.         //定義一個params變量,實際是一個指針,用於定位可變行參變量  
  28.         va_list params; 
  29.         //執行本宏後,params指向第一個可變信參,p_w_picpathSprite爲最後一個確定行參  
  30.         va_start(params, p_w_picpathSprite); 
  31.          
  32.         //定義一個ccsprite 接收參數 
  33.         CCSprite * pNow = p_w_picpathSprite; 
  34.          
  35.         while (true
  36.         { 
  37.             if (pNow) 
  38.             { 
  39.                 //添加進數組和層----- 
  40.                 pRet->m_spriteArray->addObject(pNow); 
  41.                 pRet->m_Container->addChild(pNow); 
  42.                 //去下一個值 
  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.        //開啓觸屏響應 
  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.     //修改響應區域,默認是全屏 
  89.     CCSize screen = CCDirector::sharedDirector()->getWinSize(); 
  90.     setTouchRect(CCRectMake(0, 0, screen.width, screen.height)); 
  91.      
  92.     //修改顯示區域,默認爲全屏 
  93.     this->setContentSize(screen); 
  94.      
  95.     //修改剪切區域,默認爲全屏 
  96.     setClipSize(screen.width,screen.height); 
  97.      
  98.     //默認回調函數爲空 
  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.     //默認情況下,剪裁是禁用的 
  115.     glEnable(GL_SCISSOR_TEST);//啓用剪裁測試 
  116.      
  117.     float s = this->getScale();//當前layer縮放的倍數 
  118.     s *= CCDirector::sharedDirector()->getContentScaleFactor();//獲取縮放倍率 
  119.     CCPoint screenPos = this->convertToWorldSpace(this->getParent()->getPosition()); 
  120.     //默認不設置Scissor的大小是整個視圖的大小 
  121.     glScissor((GLint)screenPos.x, (GLint)screenPos.y, (GLsizei)(m_clipSize.width*s), (GLsizei)(m_clipSize.height*s)); 
  122.      
  123.     //子節點處理 
  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);//禁用剪裁測試 
  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.     ///////////修改各個元素的位置 
  172.    //初始化當前頁 
  173.     m_curpage = 0; 
  174.     //初始化總頁數 
  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.     //獲取一箇中心點 
  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: 滾動修正 
  200. void MScrollView::RAnimation(CCPoint pt) 
  201.     int _page = m_curpage; 
  202.      
  203.     //判斷移動的方向 
  204.     float f =pt.x; 
  205.     if(f>0) 
  206.     { 
  207.         // 向左移動 
  208.         CCLog("zuo "); 
  209.         _page ++; 
  210.                   
  211.     } 
  212.     else 
  213.     { 
  214.         //向→移動 
  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: 拖動精靈,跟隨手指移動改變位置 
  230. void MScrollView::draySprite(float delta) 
  231.     this->m_Container->setPosition(ccpAdd(this->m_Container->getPosition(), ccp(delta,0))); 
  232. }  
  233. //TODO: 滾動到某一頁的動畫 
  234. void MScrollView::gotoPageAnimation(float page) 
  235.     if (m_page == 0 ) return
  236.     //獲得當前頁的精靈 
  237.     CCSprite * sp  = (CCSprite *)this->m_spriteArray->objectAtIndex(page); 
  238.     //多移動一小段距離讓sprite載正中間 
  239.     float _width = sp->boundingBox().size.width * 0.5f; 
  240.     _width = m_clipSize.width * 0.5f - _width; 
  241.      
  242.     //獲取要到達的點 
  243.     CCPoint gotoPoint =ccp(-sp->getPositionX()+_width,this->m_Container->getPositionY()); 
  244.     //計算移動到點的時間 
  245.     float _length = ccpDistance(gotoPoint,m_Container->getPosition()); 
  246.      
  247.     float _time = _length / MOVE_SPEED; 
  248.     //滾動到指定點 
  249.      
  250.     ScrollAnimation(gotoPoint,_time); 
  251.      
  252.      
  253. //頁面滾動動畫,moveto 動畫 
  254.  void MScrollView::ScrollAnimation(CCPoint offset,float time) 
  255.     //如果是拖動就停止這個動作 
  256.     if (m_dragging) 
  257.     { 
  258.         this->unschedule(schedule_selector(MScrollView::MoveToAnimation)); 
  259.         return
  260.     } 
  261.     /////////////// 
  262.     //創建移動動畫 
  263.     ////////////// 
  264.     CCFiniteTimeAction * scroll,*expire; 
  265.     scroll = CCMoveTo::create(time,offset); 
  266.     //添加一個回調函數 
  267.       expire = CCCallFuncN::create(this, callfuncN_selector(MScrollView::StopMoveToAnimation)); 
  268.     //運行moveto動畫 
  269.     m_Container->runAction(CCSequence::create(scroll, expire, NULL)); 
  270.     //開啓拖動判讀 
  271.      this->schedule(schedule_selector(MScrollView::MoveToAnimation)); 
  272.      
  273.      
  274.  
  275. //updata,用於如果拖動就停止moveto 動作 
  276. void  MScrollView:: MoveToAnimation(float dt ) 
  277.     if (m_dragging) 
  278.     { 
  279.         this->m_Container->unscheduleAllSelectors(); 
  280.  
  281.         return
  282.     } 
  283.     
  284. // // 添加一個回調函數,用於停止動畫 
  285. void MScrollView:: StopMoveToAnimation() 
  286. //   this->unschedule(schedule_selector(MoveToAnimation)); 
  287.     this->m_Container->unscheduleAllSelectors(); 
  288. //消息註冊 
  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.     //記錄按下的點 
  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.     //如果不是按下後移動 
  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.     //判定是點擊還是滑動,如果是點擊執行點擊函數,如果是滑動執行調整動畫 
  333.     
  334.     float off = ccpDistance(m_touchDownPoint,m_touchUpPoint); 
  335.     if (off < TOUCH_DELTA) 
  336.     { 
  337.         //觸發點擊事件 
  338.         m_fun; 
  339.         CCLog("touchclick"); 
  340.         
  341.     } 
  342.     else 
  343.     { 
  344.         //  滑動糾正 
  345.         //觸發滑動動畫 
  346.         RAnimation(ccpSub(m_touchDownPoint,m_touchUpPoint)); 
  347.     } 
  348.   
  349.  
  350.      
  351.      
  352. void MScrollView::ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent) 
  353.      

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章