1、概述

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

2、三种点击

1、函数回调

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

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

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

2、TouchEvent响应

    这是新加入的响应方式。它主要是使用在Widget上的。可以将其看做是函数回调的一个扩展,为更多的响应处理提供可能。使用方法大致是:

//声明
void touchButton(Object* object,TouchEventType type); //挂接到控件上
uiButton->addTouchEventListener(this,toucheventselector(HelloWorld::touchButton)); //实现
void HelloWorld::touchButton(Object* object,TouchEventType type)
{
LabelTTF* label;
switch (type)
{
case TouchEventType::TOUCH_EVENT_BEGAN:
label = static_cast<LabelTTF*>(getChildByTag());
label->setString("按下按钮");
break;
case TouchEventType::TOUCH_EVENT_MOVED:
label = static_cast<LabelTTF*>(getChildByTag());
label->setString("按下按钮移动");
break;
case TouchEventType::TOUCH_EVENT_ENDED:
label = static_cast<LabelTTF*>(getChildByTag());
label->setString("放开按钮");
break;
case TouchEventType::TOUCH_EVENT_CANCELED:
label = static_cast<LabelTTF*>(getChildByTag());
label->setString("取消点击");
break;
default:
break;
}
}

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

3、Listener消息响应方式

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

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

auto dispatcher = Director::getInstance()->getEventDispatcher();
auto myListener = EventListenerTouchOneByOne::create(); //如果不加入此句消息依旧会向下传递
myListener->setSwallowTouches(true); myListener->onTouchBegan = [=](Touch* touch,Event* event)
{
//some check
if (pass)
{
return true;
}
return false;
}; myListener->onTouchMoved = [=](Touch* touch,Event* event)
{
//do something
}; myListener->onTouchEnded = [=](Touch* touch,Event* event)
{
//do something
}; dispatcher->addEventListenerWithSceneGraphPriority(myListener,mySprite1);
dispatcher->addEventListenerWithSceneGraphPriority(myListener,mySprite2);

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

最新文章

  1. UIRefreshControl
  2. sql编写将时间转换年月日 时分格式
  3. Java Bean Validation 最佳实践
  4. Linux压缩与解压常用命令
  5. 深入理解计算机系统(2.2)---布尔代数以及C语言上的位运算
  6. Code笔记之:CSS块级元素、内联元素概念
  7. mac下php开发环境搭建+CI框架使用
  8. 关闭linux下的使用的端口
  9. &quot;/Date(1405056837780)/&quot; 时间转换
  10. CEF3 怎样禁止右键菜单
  11. hdu 3415 Max Sum of Max-K-sub-sequence(单调队列)
  12. jpush 延迟推送的栗子
  13. git reset、git checkout和git revert的区别
  14. 自学Zabbix1.3-zabbix进程
  15. Android文件(File)操作
  16. Spring事务事件监控
  17. Exp5 MSF基础应用 20164313 杜桂鑫
  18. 【2016.3.18】作业 VS2015安装&amp;单元测试(2)
  19. Winform 各种属性、方法、控件
  20. React Native指南汇集了各类react-native学习资源、开源App和组件

热门文章

  1. [转]Extundelete--数据恢复软件
  2. Object C学习笔记22-#define 用法
  3. jQuery基础之(五)jQuery自定义添加&quot;$&quot;与解决&quot;$&quot;的冲突
  4. AJAX(二)AJAX框架
  5. Moqui学习Day1
  6. oracle练习题
  7. css中的默认margin
  8. mysql-分页查询方案
  9. Lucene 4.7 --创建索引
  10. MyEclipse10中导入的jquery文件报错(出现红叉叉,提示语法错误)