经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » 游戏设计 » 查看文章
?Cocos2d-x 学习笔记(16) 触摸事件与分发 EventTouch dispatchTouchEvent EventListenerTouch
来源:cnblogs  作者:深潮  时间:2019/8/7 8:34:21  对本文有异议

1. EventTouch

触摸事件的成员变量:枚举EventCode、存储Touch的容器。

不同的EventCode代表不同时机的触摸事件,能让监听器调用不同的回调函数。

  1. enum class EventCode
  2. {
  3. BEGAN,
  4. MOVED,
  5. ENDED,
  6. CANCELLED
  7. };
  1. static const int MAX_TOUCHES = 15;
       EventCode _eventCode;
  2. std::vector<Touch*> _touches;

这里涉及到了Touch类:

Touch类

封装了一个触摸信息,包括触摸点类型(单点/多点)、坐标、开始坐标、ID、3D触控压力等。有set get方法。

2. EventListenerTouch

触摸事件监听器根据触摸点touch类型的不同,分为单点触摸监听器/多点触摸监听器。

2.1 EventListenerTouchOneByOne

单点触摸监听器回调函数只能处理触摸事件中一个touch。

ID统一为:

  1. const std::string EventListenerTouchOneByOne::LISTENER_ID = "__cc_touch_one_by_one";

该类4个回调函数,根据触摸事件code不同分类:

  1. public:
  2. typedef std::function<bool(Touch*, Event*)> ccTouchBeganCallback;
  3. typedef std::function<void(Touch*, Event*)> ccTouchCallback;
  4. ccTouchBeganCallback onTouchBegan; //开始触摸
  5. ccTouchCallback onTouchMoved; //触摸并移动
  6. ccTouchCallback onTouchEnded; //结束触摸
  7. ccTouchCallback onTouchCancelled; //触摸取消

该类2个成员变量:

  1. private:
  2. std::vector<Touch*> _claimedTouches; //存储处理完BEGAN事件的回调函数的参数touch
  3. bool _needSwallow; //事件需要吞没,为true时停止事件向其他监听器分发,setSwallowTouches(bool)设置,默认为false

在add监听器到分发器时,首先需要对该监听器执行checkAvailable()。单点触摸监听器的checkAvailable()中,要求onTouchBegan需要存在。

2.2 EventListenerTouchAllAtOnce

多点触摸监听器回调函数能一次处理事件中所有touch。

ID为:

  1. const std::string EventListenerTouchAllAtOnce::LISTENER_ID = "__cc_touch_all_at_once";

4个回调函数:

  1. public:
  2. typedef std::function<void(const std::vector<Touch*>&, Event*)> ccTouchesCallback;
  3. ccTouchesCallback onTouchesBegan;
  4. ccTouchesCallback onTouchesMoved;
  5. ccTouchesCallback onTouchesEnded;
  6. ccTouchesCallback onTouchesCancelled;

checkAvailable()方法要求4个回调函数都要存在。

3. dispatchTouchEvent 

在dispatchEvent方法中,当参数事件为TOUCH类型,调用dispatchTouchEvent进行事件分发。

该方法首先对2个触摸监听器ID的容器Vector按优先级排序,之后获取触摸事件中所有touch,用容器保存:

如果2种监听器都存在,isNeedsMutableSet置true。

然后对单点触摸监听器分发事件

单点触摸事件分发的逻辑是,把触摸事件的每个touch依次传给所有排好序的单点触摸监听器,监听器执行定义的匿名函数,而不是监听器自带的_onEvent(单点触摸监听器init时_onEvent置nullptr)。

每个单点触摸监听器执行的回调函数运行流程大致如下:

简而言之,根据触摸事件code决定执行哪种回调函数,开始触摸对应的回调函数处理touch,对处理好的touch存储到监听器容器,以便还是该监听器执行后续的移动触摸/结束触摸的回调。移动触摸对应的回调函数处理touch。结束触摸对应回调函数处理touch,并从监听器touch容器删除开始触摸的touch,说明整个触摸流程结束了。

 

我们知道,当某个监听器的回调函数返回true时,事件将停止分发到后续监听器。

在单点触摸的监听器中,回调函数返回true时有2个情况:触摸事件停止/触摸事件被回调函数处理完成+已注册+监听器设置true吞没标志。

在单点触摸的监听器中,回调函数返回false时有这些情况:开始触摸的回调函数没有处理完事件/监听器对开始触摸没有回调方法/移动或结束触摸事件分发到无(对应的)开始触摸数据的监听器。

当事件停止,会直接退出当前分发,结束分发。

接下来对多点触摸监听器分发事件

多点触摸事件分发的逻辑是,每个需要多点触摸的touch已经存储在容器mutableTouches中,容器传给所有排好序的多点触摸监听器,监听器执行定义的匿名函数,而不是监听器自带的_onEvent(多点触摸监听器init时_onEvent置nullptr)。

单点触摸是将每个touch依次分发到所有监听器,多点触摸是将所有touch分发到所有监听器。

分发到事件的多点触摸监听器的匿名回调函数:通过对触摸事件code的判断,决定要执行自己监听器的哪个回调函数。当事件停止返回true,停止后续监听器接收事件。

4. 触摸事件分发时的Touch*容器 originalTouches mutableTouches

两个容器开始时都存储了本触摸事件的所有touch。

事件分发到单点触摸监听器,是遍历originalTouches,获取每个touch,再分发touch到监听器。

单点触摸回调函数中,如果一个touch在某个单点触摸监听器中处理完成,且_needSwallow为true,且存在多点触摸监听器,此时要从mutableTouches删除该touch。原因是_needSwallow为true说明本touch处理完后不再继续分发,而mutableTouches是需要分发到多点触摸监听器,故从mutableTouches中删除该touch。mutableTouches中的迭代器自动指向下一位。同时isSwallowed置true,即不用执行++mutableTouchesIter,迭代器已经实现了++操作。

还是上面的情况,如果没有多点触摸监听器,isSwallowed默认false,匿名回调函数返回true,停止本touch分发。接下来执行++mutableTouchesIter,和originalTouches一致。

简而言之,mutableTouches只在有多点触摸监听器的情况下可能发挥它独特的作用(只保存需要接下来多点触发的touch),否则和originalTouches无异,只是存储所有touch而已。

  1. if (isClaimed && listener->_isRegistered && listener->_needSwallow) //如果事件处理完成,监听器注册状态, 监听器吞没
  2. {
  3. if (isNeedsMutableSet) //单点多点触摸的监听器都有
  4. {
  5. mutableTouchesIter = mutableTouches.erase(mutableTouchesIter); //删除此触摸点信息
  6. isSwallowed = true; //
  7. }
  8. return true;
  9. }

       if (!isSwallowed)
             ++mutableTouchesIter;

      //接下来遍历下个touch

原文链接:http://www.cnblogs.com/deepcho/p/cocos2dx-eventtouch-dispatchtouchevent-eventlistenertouch.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号