【转载】Quick 中的触摸事件
2015-05-15 13:10
134 查看
原文地址 http://cn.cocos2d-x.org/article/index?type=quick_doc&url=/doc/cocos-docs-master/manual/framework/quick/V3/touch-events/zh.md
一个游戏画面就是许多显示节点构成的一棵树:
在这棵树里,Node 所处的垂直位置就是它们的
例如有一个需求是在玩家触摸屏幕上的方块时,人物角色做一个动作。那么使用 Layer 接受到触摸事件后,开发者需要自行判断触摸位置是否在方块之内。当屏幕上有很多东西需要响应玩家交互时,程序结构就开始变得复杂了。
所以 Quick-Cocos2d-x 允许开发者将任何一个 Node 设置为接受触摸事件。并且触摸事件一开始只会出现在这个 Node 的
所谓
![](http://cn.cocos2d-x.org/doc/cocos-docs-master/manual/framework/quick/V3/touch-events/res/boundingbox.png)
为了简化实现,
触摸事件的
began: 手指开始触摸屏幕。在
moved: 手指在屏幕上移动。
ended: 手指离开屏幕。
cancelled: 因为其他原因取消触摸操作。
在多点触摸时,事件状态的含义有所区别:
began: 手指开始触摸屏幕。用户可能同时用多个手指接触屏幕,但因为硬件响应速度极快的原因,
added: 开始触摸后,如果有更多触摸点出现,则出现
removed: 如果触摸结束前有触摸点消失(接触屏幕的部分手指离开了屏幕),则出现
ended: 如果所有触摸点都消失(所有手指都离开了屏幕),则出现
moved: 由于多点触摸时,可能只有部分触摸点移动。所以此时
如果要改变这个行为,可以用:
setTouchSwallowEnabled() 是否允许 Node 吞噬触摸,默认为
isTouchSwallowEnabled() 检查 Node 是否允许吞噬触摸。
setTouchEnabled() 是否允许 Node 响应触摸,默认为
isTouchEnabled() 检查 Node 是否允许触摸。
但即便禁用了 Node 的触摸事件,也只能阻止这个 Node 响应触摸,而不能阻止这个 Node 的子 Node 响应触摸。
假设有一个对话框(Node),我们需要禁止对话框中的所有 Node 响应触摸。那么需要禁止对话框 Node 捕获事件:
setTouchCaptureEnabled() 是否允许 Node 捕获触摸,默认为
isTouchCaptureEnabled() 检查 Node 是否允许捕获触摸。
总结而言,
当用户的一根手指触摸到屏幕时,将产生一个触摸事件:
遍历所有响应触摸的 Node,找出
检查 TargetNode 的
从 TargetNode 的根 Node(通常是 Scene)开始,检查
这个阶段被称为
在 TargetNode 上触发事件。这个阶段被称为
如果事件返回结果为
在 TargetNode 完成事件的响应后,检查
从 TargetNode 开始往其所有父 Node 触发事件,直到某个 Node 返回
利用事件的三个阶段,我们可以注册
关于触摸机制的灵活运用,可以参考
removeNodeEventListener() 从 Node 上移除指定类型的事件处理函数,需要提供
setTouchEnabled() 是否允许 Node 响应触摸,默认为
isTouchEnabled() 检查 Node 是否允许触摸。
setTouchMode() 设置触摸模式,默认为
getTouchMode() 返回 Node 当前的触摸模式。
setTouchCaptureEnabled() 是否允许 Node 捕获触摸,默认为
isTouchCaptureEnabled() 检查 Node 是否允许捕获触摸。
setTouchSwallowEnabled() 是否允许 Node 吞噬触摸,默认为
isTouchSwallowEnabled() 检查 Node 是否允许吞噬触摸。
Quick 中的触摸事件
Cocos2d-x 原本的触摸机制存在一些限制,在使用中需要开发者做不少额外的处理。所以 Quick-Cocos2d-x 提出了自己的一套触摸机制。本文详细介绍了这套新机制的用法。显示层级
在 Cocos2d-x 里,整个游戏的画面是由一系列的 Scene, Node, Sprite, Layer 等对象构成的。而所有这些对象都是从 Node 这个类继承而来。我们可以将 Node 称为显示节点。
一个游戏画面就是许多显示节点构成的一棵树:
显示层级。越往上的 Node,其显示层级就越高。从画面表现上来说,下面的 Node 是背景,上面的 Node 是建筑,那么建筑就会挡住一部分背景。
触摸区域
在 Cocos2d-x 里,只有 Layer 对象才能接受触摸事件。而 Layer 总是响应整个屏幕范围内的触摸,这就要求开发者在拿到触摸事件后,再做进一步的处理。例如有一个需求是在玩家触摸屏幕上的方块时,人物角色做一个动作。那么使用 Layer 接受到触摸事件后,开发者需要自行判断触摸位置是否在方块之内。当屏幕上有很多东西需要响应玩家交互时,程序结构就开始变得复杂了。
所以 Quick-Cocos2d-x 允许开发者将任何一个 Node 设置为接受触摸事件。并且触摸事件一开始只会出现在这个 Node 的
触摸区域内。
所谓
触摸区域,就是一个 Node 及其所有子 Node 显示内容占据的屏幕空间。要注意的是这个屏幕空间包含了图片的透明部分。下图中,节点 A 是一个 Sprite 对象,它的触摸区域就是图片大小;而节点 B 是一个 Node 对象,其中包含了三个 Sprite 对象,那么节点 B 的触摸区域就是三个 Sprite 对象触摸区域的合集。
![](http://cn.cocos2d-x.org/doc/cocos-docs-master/manual/framework/quick/V3/touch-events/res/boundingbox.png)
为了简化实现,
触摸区域都是一个矩形,所以节点 B 的
触摸区域实际上是一个“包含三个 Sprite 对象触摸区域合集的矩形”,可以参考上图中的红色边框线。
用法示例
下面列出触摸事件的用法示例,更详细的示例请参考samples/touch示例。
单点触摸事件
event.name指示了事件的状态:
began: 手指开始触摸屏幕。在
began状态时,如果要继续接收该触摸事件的状态变化,事件处理函数必须返回
true。
moved: 手指在屏幕上移动。
ended: 手指离开屏幕。
cancelled: 因为其他原因取消触摸操作。
多点触摸
began: 手指开始触摸屏幕。用户可能同时用多个手指接触屏幕,但因为硬件响应速度极快的原因,
began状态时,
event.points中可能仍然只有一个触摸点的数据,其他触摸点数据会通过
added状态提供。
added: 开始触摸后,如果有更多触摸点出现,则出现
added状态。此时
event.points中包含新加入的触摸点数据。
removed: 如果触摸结束前有触摸点消失(接触屏幕的部分手指离开了屏幕),则出现
removed状态。此时
event.points中包含删除的触摸点数据。
ended: 如果所有触摸点都消失(所有手指都离开了屏幕),则出现
ended状态。此时
event.points中包含删除的触摸点数据。
moved: 由于多点触摸时,可能只有部分触摸点移动。所以此时
event.points中只包含有变化的触摸点数据。
触摸事件吞噬
默认情况下,Node 在响应触摸后(在began状态返回
true表示要响应触摸),就会阻止事件继续传递给 Node 的父对象(更下层的 Node),这称为
触摸事件吞噬。
如果要改变这个行为,可以用:
setTouchSwallowEnabled() 是否允许 Node 吞噬触摸,默认为
true。如果设置为
false,则 Node 响应触摸事件后,仍然会将事件继续传递给父对象。
isTouchSwallowEnabled() 检查 Node 是否允许吞噬触摸。
禁用触摸
对于一个 Node,随时可以启用或禁用其触摸事件:setTouchEnabled() 是否允许 Node 响应触摸,默认为
false。
isTouchEnabled() 检查 Node 是否允许触摸。
但即便禁用了 Node 的触摸事件,也只能阻止这个 Node 响应触摸,而不能阻止这个 Node 的子 Node 响应触摸。
假设有一个对话框(Node),我们需要禁止对话框中的所有 Node 响应触摸。那么需要禁止对话框 Node 捕获事件:
true。当设置为
false时,该 Node 及其所有子 Node 都无法得到触摸事件。
isTouchCaptureEnabled() 检查 Node 是否允许捕获触摸。
总结而言,
setTouchEnabled()只针对当前 Node,而
setTouchCaptureEnabled()同时影响当前 Node 及其所有子 Node。
触摸事件的三个阶段
quick 中触摸事件分为三个阶段:capturing(捕获)、targeting(触发)、bubbling(冒泡)。当用户的一根手指触摸到屏幕时,将产生一个触摸事件:
遍历所有响应触摸的 Node,找出
显示层级最高,并且其
触摸区域包含触摸位置的那个 Node。这个 Node 被称为 TargetNode(目标 Node)。
检查 TargetNode 的
isTouchCaptureEnabled()结果,如果返回
false,则重复 1
从 TargetNode 的根 Node(通常是 Scene)开始,检查
cc.NODE_TOUCH_CAPTURE_EVENT事件的返回结果。任何一个 Node 返回
false都会阻止事件在 TargetNode 上触发。并从步骤 1 开始查找其他符合条件的 Node。
这个阶段被称为
capturing。
在 TargetNode 上触发事件。这个阶段被称为
targeting。
如果事件返回结果为
false,表示 TargetNode 不响应该事件,并从步骤 1 开始查找其他符合条件的 Node。
在 TargetNode 完成事件的响应后,检查
TargetNode:isTouchSwallowEnabled()的返回值。如果是
true,则取消
bubbling阶段。
从 TargetNode 开始往其所有父 Node 触发事件,直到某个 Node 返回
false或者事件被吞噬。这个阶段称为
bubbling。
利用事件的三个阶段,我们可以注册
capturing阶段的触摸事件处理函数:
cc.ui中的各个 UI 控件,以及
samples/touch示例。
API 参考
addNodeEventListener() 为 Node 的特定事件设置处理函数,返回一个 id 表示注册成功。removeNodeEventListener() 从 Node 上移除指定类型的事件处理函数,需要提供
addNodeEventListener()返回的注册 id。
setTouchEnabled() 是否允许 Node 响应触摸,默认为
false。
isTouchEnabled() 检查 Node 是否允许触摸。
setTouchMode() 设置触摸模式,默认为
cc.TOUCH_MODE_ONE_BY_ONE。
getTouchMode() 返回 Node 当前的触摸模式。
setTouchCaptureEnabled() 是否允许 Node 捕获触摸,默认为
true。
isTouchCaptureEnabled() 检查 Node 是否允许捕获触摸。
setTouchSwallowEnabled() 是否允许 Node 吞噬触摸,默认为
true。
isTouchSwallowEnabled() 检查 Node 是否允许吞噬触摸。
相关文章推荐
- Quick-cocos2d-x事件触摸机制
- quick 中的触摸事件
- quick-lua touch 触摸事件
- quick 中的触摸事件
- quick-cocos2d-x游戏开发【10】——触摸捕获事件 cc.NODE_TOUCH_CAPTURE_EVENT
- quick中的触摸事件
- 转载大神IOS开发系列【9】--触摸事件、手势识别、摇晃事件、耳机线控
- Quick_触摸事件
- quick-cocos2d-x游戏开发【10】——触摸捕获事件 cc.NODE_TOUCH_CAPTURE_EVENT
- 【quick-lua 002】 触摸捕获事件 cc.NODE_TOUCH_CAPTURE_EVENT
- [cocos2dx_Lua]quick中的触摸事件
- quick中触摸事件响应机制
- 【quick-cocos2d-x】单点触摸与touch事件
- Quick-Cocos2d-x游戏开发触摸捕获事件 cc.NODE_TOUCH_CAPTURE_EVENT
- 关于quick-2dx多层Layer堆叠触摸事件穿透
- 事件触摸-Quick-Cocos2dx
- Quick-Cocos2d-x初学者游戏教程(十二) ------------ 触摸事件
- quick-cocos2dx lua语言讲解 (动作,定时器,触摸事件,工程的类的讲解)
- QUICK 中的触摸事件
- quick-cocos2d-x lua 触摸事件、操作文件的实例