1、概述

游戏也好,程序也好,只有能与用户交互才有意义。手机上的交互大致可以分为两部分:点击和输入。其中点击更为重要,几乎是游戏中全部的交互。在Cocos2d-x 3.0中,更改了dispatch机制。同时加入了两种新的交互形式:listener 和touchEvent回调。加上先前版本中的点击函数回调,与重写layer层的touch消息响应,构成了一个相对完整的交互模式。先上一张Demo的图:

2、四种点击

1、函数回调

函数回调是最简单的响应形式,一直以来被用于MenuItem中的点击处理。在新版本中,此处发生了些小改变。我们可以看到在生成的程序中相关代码是这样的:
[cpp] view plaincopyprint?
  1. // a selector callback
  2. void menuCloseCallback(Object* pSender);
  3. auto closeItem = MenuItemImage::create("CloseNormal.png","CloseSelected.png",
  4. CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));
  5. void HelloWorld::menuCloseCallback(Object* pSender)
  6. {
  7. Director::getInstance()->end();
  8. #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
  9. exit(0);
  10. #endif
  11. }

其中CC_CALLBACK_1宏是将函数与对象绑定在一起,1表示这个函数有一个参数。当点击这个按钮时,会调用这个回调函数。

除了基于c++11的这个形式的改变,使用方法与先前相同。

此种方式已经被舍弃,可以使用第四种方法做替代。

2、Layer的touch消息响应

     虽然重写了底层的dispatch,但对这层的使用影响并不大。我们同样需要重写:

[cpp] view plaincopyprint?
  1. //单点响应
  2. virtual bool onTouchBegan(Touch* touch, Event  *event) override;
  3. virtual void onTouchMoved(Touch* touch, Event  *event) override;
  4. virtual void onTouchEnded(Touch* touch, Event  *event) override;
  5. virtual void onTouchCancelled(Touch *touch, Event *event) override;
  6. //多点响应
  7. virtual bool onTouchesBegan(Touch* touch, Event  *event) override;
  8. virtual void onTouchesMoved(Touch* touch, Event  *event) override;
  9. virtual void onTouchesEnded(Touch* touch, Event  *event) override;
  10. virtual void onTouchesCancelled(Touch *touch, Event *event) override;

重写这些函数来对layer的点击做处理。当然,我们需要:

[cpp] view plaincopyprint?
  1. setTouchEnabled(true)。

此外有个小改动。对于单点触控响应,可以调用:

[cpp] view plaincopyprint?
  1. //设置为单点响应
  2. setTouchMode(Touch::DispatchMode::ONE_BY_ONE);
  3. //设置为多点响应(默认)
  4. setTouchMode(Touch::DispatchMode::ALL_AT_ONCE);

进行设置,而不需要再用设置Delegate的方式来做了。

3、TouchEvent响应

这是新加入的响应方式。它主要是使用在UIWidget上的。可以将其看做是函数回调的一个扩展,为更多的响应处理提供可能。使用方法大致是:
[cpp] view plaincopyprint?
  1. //声明
  2. void touchButton(Object* object,TouchEventType type);
  3. //挂接到控件上
  4. uiButton->addTouchEventListener(this,toucheventselector(HelloWorld::touchButton));
  5. //实现
  6. void HelloWorld::touchButton(Object* object,TouchEventType type)
  7. {
  8. LabelTTF* label;
  9. switch (type)
  10. {
  11. case TouchEventType::TOUCH_EVENT_BEGAN:
  12. label = static_cast<LabelTTF*>(getChildByTag(11));
  13. label->setString("按下按钮");
  14. break;
  15. case TouchEventType::TOUCH_EVENT_MOVED:
  16. label = static_cast<LabelTTF*>(getChildByTag(11));
  17. label->setString("按下按钮移动");
  18. break;
  19. case TouchEventType::TOUCH_EVENT_ENDED:
  20. label = static_cast<LabelTTF*>(getChildByTag(11));
  21. label->setString("放开按钮");
  22. break;
  23. case TouchEventType::TOUCH_EVENT_CANCELED:
  24. label = static_cast<LabelTTF*>(getChildByTag(11));
  25. label->setString("取消点击");
  26. break;
  27. default:
  28. break;
  29. }
  30. }

因为所有的UIWidget都要添加到UILayer上,而UILayer通常作为UI的Widget都会在最上层,所以可以“基本上”认为这种使用方式会优先于其他方式处理点击消息。因为UILayer也会有层级的改变,比如它和MenuItem之间的关系。所以说“基本上”。

4、Listener消息响应方式

这种实现也是新加入的。它更像是点击的一个层次过滤器。点击时,在listener队里中进行过滤。每一个listener检查自己保存的touch消息响应是否会被触发。一层一层过滤,最后在到Layer的touch消息响应。

我觉得它的设计的初衷是为任意sprite提供一套自己制定的点击响应。但这样的实现仍然要写很多条件判断,没有能够控件化。可能我的理解有些偏差,欢迎讨论。

它被设计成一个全局点击响应控制。具体的用法大致是这样:

[cpp] view plaincopyprint?
  1. //auto dispatcher = EventDispatcher::getInstance();
  2. //  auto myListener = EventListenerTouch::create(Touch::DispatchMode::ONE_BY_ONE);
  3. auto dispatcher = Director::getInstance()->getEventDispatcher();
  4. auto myListener = EventListenerTouchOneByOne::create();
  5. //如果不加入此句消息依旧会向下传递
  6. myListener->setSwallowTouches(true);
  7. myListener->onTouchBegan = [=](Touch* touch,Event* event)
  8. {
  9. //some check
  10. if (pass)
  11. {
  12. return true;
  13. }
  14. return false;
  15. };
  16. myListener->onTouchMoved = [=](Touch* touch,Event* event)
  17. {
  18. //do something
  19. };
  20. myListener->onTouchEnded = [=](Touch* touch,Event* event)
  21. {
  22. //do something
  23. };
  24. dispatcher->addEventListenerWithSceneGraphPriority(myListener,mySprite1);
  25. dispatcher->addEventListenerWithSceneGraphPriority(myListener,mySprite2);

其原理是在dispatcher中检查listener列表,例如myListener或加进来的其他listener。然后每个listener检查自己中的Item看能否达到检查条件,例如:mySprite1,mySprite2。然后执行相应的操作。但这样的话,当控件很多的时候,每一次事件都进行这种双链表的检查操作不知会不会影响些性能?

转载于:https://www.cnblogs.com/niwococo/p/4012829.html

cocos2dx 开发成长之路 004相关推荐

  1. 掌握未来趋势的前端开发成长之路

    前端开发成长之路     入门         1.WEB 网页基础.编程基础             HTML5+CSS3入门                 课程内容:               ...

  2. 音视频开发成长之路—进阶之路3个重要知识点丨WebRTC丨FFmpeg丨SRS流媒体服务器丨C++音视频丨嵌入式音视频

    音视频开发成长之路-进阶之路3个重要知识点 视频讲解如下,点击观看: 音视频开发成长之路-进阶之路3个重要知识点丨WebRTC丨FFmpeg丨SRS流媒体服务器丨C++音视频丨嵌入式音视频 音视频高级 ...

  3. 【All Right,你现在看到的是,来自于一名初中生的自学开发成长之路】

    All Right,你现在看到的是,来自于一名初中生的自学开发成长之路 萌芽时期 初次上手 在那时,我就认为自己会编程了,会了之后干啥呢? 想专业,先从自己下手,而不是IDE 自己解决不了,总有人能解 ...

  4. 大二女生web开发成长之路——讲述我从软妹子到女汉子的进阶过程

    学习和实践前端一年时间,几乎天天在工作室和一群屌丝男程序员一起学习.开发.这种潜移默化的环境下,编码提高了,节操也细碎了. 一年前,娇滴滴的还是工作室里面小师妹一枚,软软的软件工程妹子,做不到人见人爱 ...

  5. 音视频开发成长之路与音视频知识总结

    音视频涉及语音信号处理.数字图像处理.信息论.封装格式.编解码.流媒体协议.网络传输.渲染.算法等.在现实生活中,音视频扮演着越来越重要的角色,比如视频会议.直播.短视频.播放器.语音聊天等.因此,从 ...

  6. 音视频开发成长之路与音视频知识点总结

    音视频涉及语音信号处理.数字图像处理.信息论.封装格式.编解码.流媒体协议.网络传输.渲染.算法等.在现实生活中,音视频发挥着越来越重要的作用,如视频会议.直播.短视频.播放器.语音聊天等.所以从事音 ...

  7. 从入门到卓越——大学生的软件开发成长之路

    前言: 许多有志于从事软件开发工作的学生经常会感到困惑,不是因为企业的要求过于苛刻,也不是因为认识不到自身的欠缺:而是,明明知道目标所在,却始终无法靠近它:有着无限的热情和毅力,却找不到合适的道路.众 ...

  8. 大数据开发成长之路——Linux基础

    Linux基础 这里主要介绍学习大数据过程中用到的Linux基础知识,现在主攻的方向是大数据开发,欢迎大家共同交流. 环境 推荐安装VMware虚拟机并安装CentOS操作系统,具体资源的下载和安装可 ...

  9. Python 测试开发从入门到高手成长之路

    > 文末领取测试开发进阶指南和福利! 在" **质量第一,效率为王** "的移动互联网和大数据时代,互联网 IT 技术团队为了应对产品快速迭代要求,就必须具备持续交付的能力. ...

  10. 测试/开发程序员的成长之路,未来是你们的......

    目录:导读 前言 一.Python编程入门到精通 二.接口自动化项目实战 三.Web自动化项目实战 四.App自动化项目实战 五.一线大厂简历 六.测试开发DevOps体系 七.常用自动化测试工具 八 ...

最新文章

  1. bash-shell高级编程--退出和退出状态码
  2. boost::phoenix::switch_相关的测试程序
  3. Qt字符串与整形转换
  4. 志愿者招募 | 2021 .NET Conf China
  5. WPF Slider设置整数
  6. linux新增动态库后可执行程序找不到的问题
  7. pthread异步_异步管道的实现
  8. 细说HTTP中POST与GET的区别与联系
  9. leetcode 85. Maximal Rectangle(最大矩形)
  10. CCIE一年后的心语
  11. 倪衡:大数据时代小微企业质量管理创新
  12. java switch枚举类,Java 枚举 switch的用法
  13. sqlserver批量(部分)导出一张表中的数据
  14. java毕业设计流浪猫狗救助网站源码+lw文档+mybatis+系统+mysql数据库+调试
  15. 安装prescan 8.6之后无sensor问题
  16. QuickMark: ElasticSearch curl command
  17. 通信中间件DDS介绍(一)
  18. 一篇文章带你看懂AWS re:Invent 2018大会,揭秘Amazon Aurora
  19. 针对个体的精准神经影像—当前的方法和未来方向
  20. css如何让不自动换行,css实现强制不换行/自动换行/强制换行

热门文章

  1. java设计模式在java中的应用
  2. python生成器的惰性计算
  3. dot watch+vs code提升asp.net core开发效率
  4. 安卓开发工程师应该这样快速使用机智云APP开源框架
  5. IDEA快捷键+使用小技巧
  6. XMPP聊天环境配置
  7. Java:单例模式的七种写法 (转)
  8. Jquery小菜鸟---防止按钮在短时间内被多次点击
  9. NMEA0183标准语句
  10. Python搭建简易HTTP服务(3.x版本和2.x版本的)