戏谈cocos2d-x 2.0.4 Touch

先把跟Touch相关的类列一下: EAGLView  CCEGLView  CCEGLViewProtocol  EGLTouchDelegate  CCTouchDispatcher  CCTouchHandler  CCStandardTouchHandler  CCTargetedTouchHandler  CCTouchDelegate CCTargetedTouchDelegate  CCStandardTouchDelegate  CCLayer  CCTouch
EAGLView  真正的 view Cocosd-x 已经把各个平台的 view 已经封装成 EAGLView. EAGLView 中含有  
      1.  - ( void )touchesBegan:( NSSet  *)touches withEvent:( UIEvent  *)event      2.   - ( void )touchesMoved:( NSSet  *)touches withEvent:( UIEvent  *)event      3.   - ( void )touchesEnded:( NSSet  *)touches withEvent:( UIEvent  *)event      4.   - ( void )touchesCancelled:( NSSet  *)touches withEvent:( UIEvent  *)event
     上诉四个方法能直接监听反馈用户的点击事件。同时能获取点击的坐标,以及有几个手指点击移动,再分别通过调用CCEGLViewProtocol的以下四个方法
     1. virtual void handleTouchesBegin( int num, int ids[], float xs[], float ys[]);
     2. virtual void handleTouchesMove( int num, int ids[], float xs[], float ys[]);
      3 . virtual   void  handleTouchesEnd( int  num,  int  ids[],  float  xs[],  float  ys[]);
     4. virtual void handleTouchesCancel( int num, int ids[], float xs[], float ys[]);
     将touches***方法中的信息传递到handleTouches***方法中.(其中通过 cocos2d :: CCEGLView :: sharedOpenGLView ()-> handleTouches*** (i, ids, xs, ys)来调用以上四个方法, sharedOpenGLView返回的是CCEGLView,由于CCEGLView是 CCEGLViewProtocol的子类,不过 handleTouches***这些方法的主要逻辑处理还是在 CCEGLViewProtocol处理的)。CCEGLViewProtocol类中有个 EGLTouchDelegate * m_pDelegate属性,在 handleTouches*** 方法中主要是把触摸点point放到 CCTouch中,再把其放入CCSet中。通过m_pDelegate -> touches*** (&set, NULL )方法将CCSet信息传递给 CCTouchDispatcher。关于CCTouchDispatcher这个类,她可是出生于名门世家-EGLTouchDelegate,EGLTouchDelegate有四个我们熟悉的方法也就是:
      1. virtual void touchesBegan( CCSet * touches, CCEvent * pEvent) = 0 ;
     2. virtual void touchesMoved( CCSet * touches, CCEvent * pEvent) = 0 ;
     3. virtual void touchesEnded( CCSet * touches, CCEvent * pEvent) = 0 ;
     4. virtual void touchesCancelled( CCSet * touches, CCEvent * pEvent) = 0 ;

CCEvent继承于CCObject,关于CCTouch他也是继承于CCObject,她能获取
     1.CCPoint  getLocation()  const ;
     2. CCPoint  getPreviousLocation()  const ;
     3. CCPoint  getStartLocation()  const ;
     4. CCPoint  getDelta()  const ;
     5. CCPoint  getLocationInView()  const ;
     6. CCPoint  getPreviousLocationInView()  const ;
     7. CCPoint  getStartLocationInView()  const ;

上诉四个方法都是虚函数,真正的实现方法都在 CCTouchDispatcher中,但是在CCTouchDispatcher中的上诉四个方法其实也没干了什么大不了的事情,他们都做了相同的事情就是统一回调了CCTouchDispatcher中的 void CCTouchDispatcher ::touches( CCSet *pTouches, CCEvent *pEvent, unsigned int uIndex)方法,根据uIndex来区分是Began呢还是Moved等相关事件,所以上面讲了一堆,其实真正干事情的就只有 CCTouchDispatcher中的 touches方法,通过这个方法把触摸事件分发 出去,那怎么分发事件的呢?说道这,咱还是得回顾下其他知识。
  
     先聊聊 CCTouchDelegate吧,这位老祖宗还真是祖宗。它有一堆的虚函数
     /*******CCTargetedTouchDelegate 单点触摸*****/
     1. virtual   bool  ccTouchBegan( CCTouch  *pTouch,  CCEvent  *pEvent) { CC_UNUSED_PARAM (pTouch);  CC_UNUSED_PARAM (pEvent);  return   false ;};
     2. virtual void ccTouchMoved( CCTouch *pTouch, CCEvent *pEvent) { CC_UNUSED_PARAM (pTouch); CC_UNUSED_PARAM (pEvent);}
     3. virtual void ccTouchEnded( CCTouch *pTouch, CCEvent *pEvent) { CC_UNUSED_PARAM (pTouch); CC_UNUSED_PARAM (pEvent);}     4. virtual void ccTouchCancelled( CCTouch *pTouch, CCEvent *pEvent) { CC_UNUSED_PARAM (pTouch); CC_UNUSED_PARAM (pEvent);}
     /**********CCStandardTouchDelegate****多点触摸***********/
       5. virtual void ccTouchesBegan( CCSet *pTouches, CCEvent *pEvent) { CC_UNUSED_PARAM (pTouches); CC_UNUSED_PARAM (pEvent);}     6. virtual void ccTouchesMoved( CCSet *pTouches, CCEvent *pEvent) { CC_UNUSED_PARAM (pTouches); CC_UNUSED_PARAM (pEvent);}     7. virtual void ccTouchesEnded( CCSet *pTouches, CCEvent *pEvent) { CC_UNUSED_PARAM (pTouches); CC_UNUSED_PARAM (pEvent);}     8. virtual void ccTouchesCancelled( CCSet *pTouches, CCEvent *pEvent) { CC_UNUSED_PARAM (pTouches); CC_UNUSED_PARAM (pEvent);}
 
上诉CCTargetedTouchDelegate以及CCStandardTouchDelegate都是CCTouchDelegate的子类,分别对应于单点触摸以及多点触摸。当然CCTouchDelegate的子类还有CCLayer。CCLayer含有他爸的全部方法,也就是单点触摸,多点触摸的方法她都有了。当然不能同时响应单点触摸以及多点触摸,其实多点触摸也就包含了单点触摸。CCLayer是通过ccTouchesMode这个结构来区分单点触摸以及多点触摸的-kCCTouchesAllAtOnce/kCCTouchesOneByOne.

讲了半天的CCTouchDelegate以及子类,那它怎么跟CCTouchDispatcher勾搭上啊,其实很简单,就只需要到CCTouchDispatcher注册一下。接下来重点将下 CCLayer是怎么注册的。CCLayer藏的很深,她仅仅就是让我们通过CCLayer ::setTouchEnabled( bool enabled)这个方法设置下是否能触摸,她就去乖乖的到CCTouchDispatcher注册去了。
下面具体看看setTouchEnabled做了啥事情吧,他去找了 CCLayer中的 registerWithTouchDispatcher()这个方法,在这个方法中,他会去到 CCDirector中找到CCTouchDispatcher(CCTouchDispatcher * pDispatcher = CCDirector :: sharedDirector ()-> getTouchDispatcher () ),其实CCTouchDispatcher在CCDirector的初始化中,他就生出来了。找到CCTouchDispatcher后也就方便了,通过 ccTouchesMode这个值判断是去注册单点呢,还是多点呢,CCLayer中ccTouchesMode默认值是kCCTouchesAllAtOnce。具体方法:pDispatcher-> addStandardDelegate ( this , 0 );//标准多点触摸。pDispatcher-> addTargetedDelegate ( this , m_nTouchPriority , true );//正统的单点触摸,注意这个true,这玩意就是个火药桶,如果他是true的时候,你一玩完,就偷偷的把 CCSet中的CCTouch给释放了,具体要看证据还是得在 CCTouchDispatcher中的touches才能看到,当然他仅仅只针对单点触摸,谁叫你单点啊。

好了现在也注册到CCTouchDispatcher了,也是属于有身份的合法公民了,跟着政府就好。那现在我们就看这个政府CCTouchDispatcher是怎么管理这个触摸小国家的吧。CCTouchDispatcher管理这个国家也不是亲力亲为的,她也请了外援 CCTouchHandler,这个Handler还拖家带口的,有两个亲儿子 CCStandardTouchHandler以及CCTargetedTouchHandler。
CCTouchHandler主要干的啥事情呢?保存CCTouchDelegate以及 priority这两个东东。 CCTouchDelegate就不需要怎么说了,他到 CCTouchDispatcher一报到,CCTouchDispatcher二话不说,把 CCTouchDelegate 以及 CCTouchDelegate的 priority直接扔给 CCTouchHandler,给打包下。当然CCTouchHandler也不是蛮干,先看看CCTouchDelegate你是 CCTargetedTouchDelegate还是CCStandardTouchDelegate呀, CCTouchHandler验明了CCTouchDelegate的身份之后自己也不直接上去,而是叫自己的儿子 CCStandardTouchHandler以及CCTargetedTouchHandler两个活宝上去打包的。打包方法:
    1. static CCTouchHandler * handlerWithDelegate( CCTouchDelegate *pDelegate, int nPriority);//在该方法中会调用initWithDelegate
    2. virtual bool initWithDelegate( CCTouchDelegate *pDelegate, int nPriority);
对了关于上面两个方法对于CCStandardTouchHandler以及CCTargetedTouchHandler都有不同的个性化,特别是CCTargetedTouchHandler,谁叫他打包的是 CCTargetedTouchDelegate呀, CCTargetedTouchDelegate这玩意有个bSwallowsTouches,是否吞了该触摸。也就是在上文讲到的true,在 addTargetedDelegate中如果将 bSwallowsTouches设为true,则当你触发完事件后,她就把你从触发的点上删除。所以此处CCTargetedTouchHandler针对CCTargetedTouchDelegate的特殊需求,也得满足不是,我就把你的bSwallowsTouches一并打包和 CCTouchDelegate以及 nPriority。 CCTouchHandler通过两个乖儿子,把CCTouchDelegate相关属性一并打包,就去向 CCTouchDispatcher总理报到了。这到哪报到呢,就是上文说的 void CCTouchDispatcher ::addStandardDelegate( CCTouchDelegate *pDelegate, int nPriority)以及 void CCTouchDispatcher ::addTargetedDelegate( CCTouchDelegate *pDelegate, int nPriority, bool bSwallowsTouches)这两个方法啊。在这两个方法中都能将打包好的 CCTouchHandler,通过f orceAddHandler 这个方法,把她分别提交给 m_pStandardHandlers以及m_pTargetedHandlers两个CCArray *大官人那,哪天CCTouchDispatcher想找哪个 CCTouchHandler的时候,直接找两个大官人就好。好了上面说了一堆终于把 CCTouchDelegate跟CCTouchDispatcher不得不说的事情说完了。

终于得做点事情了,前面也谈到了当有触摸事件来的时候,不管是 Began还是Moved啥的,一并都去 void touches( CCSet *pTouches, CCEvent *pEvent, unsigned int uIndex);这个办事处。这地方也就相当于总理大衙门-中南海,不管是触摸的消息 CCSet,还是CCTouchHandler都得在这交代的一清二百。上文所说的m_pStandardHandlers以及m_pTargetedHandlers通过遍历找到CCTouchHandler,然后将CCTouchHandler总理处理的结果传递到下面各个小罗罗上。
1. pHandler-> getDelegate ()-> ccTouchBegan (pTouch, pEvent);
2.pHandler-> getDelegate ()-> ccTouchesBegan (pMutableTouches, pEvent);
pHandler-> getDelegate ()也就是被打包封装的CCTouchDispatcher,现在就是被解绑了而已。

好了,说到这关于细说touch事情也差不多结束了。。。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值