假设看过sample中touch的代码,你会发现演示样例中有一个cc.NODE_TOUCH_CAPTURE_EVENT事件。它和cc.NODE_TOUCH_EVENT触摸事件一样,是引擎级别的事件,我们来看看它和触摸事件的差别。

首先触摸捕获事件默认是开启的,即setTouchCaptureEnabled(true)

触摸捕获事件的优先级要比触摸事件要高。换句话说。触摸捕获事件会比触摸事件先响应。而且有权不分发给触摸事件响应。

对于一个完整的捕获+触摸事件,有这么一个流程:

1.捕获阶段。一旦有触摸事件发生。那么首先会触发捕获事件。而且捕获顺序是从zOrder高到低,越在屏幕上方越优先捕获。从父节点传到子节点,父节点优先捕获。

2.目标阶段,该阶段就是各个节点响应自己的触摸事件。began。moved,ended等。

3传递阶段,仅仅要当前节点没有将触摸吞噬,那么触摸事件将会继续往下层的节点进行传送。

有了一些理论知识。我们来实际操作一下。写些代码。

function MyScene:ctor()	

    local layer = display.newLayer()
self:addChild(layer)
layer:setTouchEnabled(true)
layer:setTouchSwallowEnabled(false)
layer:setTouchMode(cc.TOUCH_MODE_ONE_BY_ONE)
layer:addNodeEventListener(cc.NODE_TOUCH_EVENT, function (event)
if event.name == "began" then
print("layer began")
elseif event.name == "moved" then
print("layer moved")
elseif event.name == "ended" then
print("layer ended")
end return true
end) layer:addNodeEventListener(cc.NODE_TOUCH_CAPTURE_EVENT, function (event)
if event.name == "began" then
print("layer capture began")
elseif event.name == "moved" then
print("layer capture moved")
elseif event.name == "ended" then
print("layer capture ended")
end return true
end) local sp = display.newSprite("HelloWorld.png", display.cx, display.cy)
layer:addChild(sp)
--self:addChild(sp)
sp:setTouchEnabled(true)
sp:setTouchSwallowEnabled(false)
sp:setTouchMode(cc.TOUCH_MODE_ONE_BY_ONE)
sp:addNodeEventListener(cc.NODE_TOUCH_EVENT, function (event)
if event.name == "began" then
print("sp began")
elseif event.name == "moved" then
print("sp moved")
elseif event.name == "ended" then
print("sp ended")
end return true
end) sp:addNodeEventListener(cc.NODE_TOUCH_CAPTURE_EVENT, function (event)
if event.name == "began" then
print("sp capture began")
elseif event.name == "moved" then
print("sp capture moved")
elseif event.name == "ended" then
print("sp capture ended")
end return true
end) end

代码中,加入了两个节点,一个是layer。一个sprite。sprite加入在layer上,他们都开启了触摸,没有吞噬触摸。而且加入了捕获事件和触摸事件,返回值为true。

简单点击一下窗体。看看print信息,

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdzMzNzE5ODMwMg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />

由于父节点会优先捕获事件,所以首先是layer捕获到了,其次子节点捕获到。接下来是处理触摸,由于子节点在父节点的上面,所以子节点先响应了触摸事件,处理过后由于没有吞噬触摸,所以会继续将触摸事件向下传递,此时它的以下就是它的父节点laier。所以layer又再一次捕获到了这个事件,最后layer開始响应触摸事件。

假设我们将子节点sprite设置吞噬触摸。

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdzMzNzE5ODMwMg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />

能够看到,当sprite响应了触摸事件之后就不再向下传递了,所以父节点就不能再捕获到上方传下来的触摸了。

我们再改动一下代码,把layer的捕获事件返回为false。sprite还是依旧保持吞噬触摸。也就是在之前的代码上做这种改动,

    layer:addNodeEventListener(cc.NODE_TOUCH_CAPTURE_EVENT, function (event)
if event.name == "began" then
print("layer capture began")
elseif event.name == "moved" then
print("layer capture moved")
elseif event.name == "ended" then
print("layer capture ended")
end return false
end) local sp = display.newSprite("HelloWorld.png", display.cx, display.cy)
layer:addChild(sp)
--self:addChild(sp)
sp:setTouchEnabled(true)
--sp:setTouchSwallowEnabled(false)
sp:setTouchMode(cc.TOUCH_MODE_ONE_BY_ONE)

我们执行一下,点击屏幕看下效果,

这里我是抬起了鼠标后截出来的日志信息,能够看到,layer的捕获開始打印了两次。

由于我们在父节点layer的捕获事件中,将其设置成返回false,所以其子节点是无法响应后面的触摸事件的,可是关键的是。即便父节点在捕获阶段阻止响应事件,但子对象仍然能够捕获到事件,仅仅是不会触发事件,说白了就是。父节点阻断了捕获,可是我子节点依旧能够捕获到,仅仅是子节点的捕获不响应各个事件,也不会再让后面的触摸事件响应。

所以我们回过来想一下,第一次触摸屏幕,父节点捕获到了。子节点也捕获到了,可是返回false,所以子节点的捕获事件不触发。所以看不到sprite打出捕获信息。而且sprite也不响应触摸事件。所以吞不吞噬也就没作用了。继续分发着走,那么layer就会再一次捕获到自己的事件,仅仅是这次返回的false,它把它自己的后面的触摸事件也停止了。

所以ended事件响应我们一个都看不到。

不知道大家有没有理清思路,这次我们不把sprite加入在layer上,sprite也加入在scene中。我们来看下结果,

function MyScene:ctor()	

    local layer = display.newLayer()
self:addChild(layer)
layer:setTouchEnabled(true)
layer:setTouchSwallowEnabled(false)
layer:setTouchMode(cc.TOUCH_MODE_ONE_BY_ONE)
layer:addNodeEventListener(cc.NODE_TOUCH_EVENT, function (event)
if event.name == "began" then
print("layer began")
elseif event.name == "moved" then
print("layer moved")
elseif event.name == "ended" then
print("layer ended")
end return true
end) layer:addNodeEventListener(cc.NODE_TOUCH_CAPTURE_EVENT, function (event)
if event.name == "began" then
print("layer capture began")
elseif event.name == "moved" then
print("layer capture moved")
elseif event.name == "ended" then
print("layer capture ended")
end return true
end) local sp = display.newSprite("HelloWorld.png", display.cx, display.cy)
--layer:addChild(sp)
self:addChild(sp)
sp:setTouchEnabled(true)
sp:setTouchSwallowEnabled(false)
sp:setTouchMode(cc.TOUCH_MODE_ONE_BY_ONE)
sp:addNodeEventListener(cc.NODE_TOUCH_EVENT, function (event)
if event.name == "began" then
print("sp began")
elseif event.name == "moved" then
print("sp moved")
elseif event.name == "ended" then
print("sp ended")
end return true
end) sp:addNodeEventListener(cc.NODE_TOUCH_CAPTURE_EVENT, function (event)
if event.name == "began" then
print("sp capture began")
elseif event.name == "moved" then
print("sp capture moved")
elseif event.name == "ended" then
print("sp capture ended")
end return true
end) end

触摸吞噬都关闭,各个事件返回值都是true,print的结果是。

由于sprite后加入。他们在同一个zOrder上所以sprite要靠前,先捕获到事件,然后到触摸事件,做完之后传递到以下的layer,layer開始捕获然后处理触摸事件。

这就是quick对于捕获事件的原理了。如有错误。欢迎指出。

quick-cocos2d-x游戏开发【10】——触摸捕获事件 cc.NODE_TOUCH_CAPTURE_EVENT的更多相关文章

  1. iOS cocos2d 2游戏开发实战(第3版)书评

    2013是游戏爆发的一年,手游用户也是飞速暴增.虽然自己不做游戏,但也是时刻了解手机应用开发的新动向.看到CSDN的"写书评得技术图书赢下载分"活动,就申请了一本<iOS c ...

  2. [libgdx游戏开发教程]使用Libgdx进行游戏开发(10)-音乐和音效

    本章音效文件都来自于公共许可: http://files.cnblogs.com/mignet/sounds.zip 在游戏中,播放背景音乐和音效是基本的功能. Libgdx提供了跨平台的声音播放功能 ...

  3. cocos2d JS 监听键盘触摸响应事件(cc.EventListener.KEYBOARD)

    除了可以监听键盘按键,还可以是终端设备的各个菜单键,都能使用同一个监听器来进行处理. //给statusLabel绑定键盘事件 cc.eventManager.addListener({ event: ...

  4. (转载)如何学好iphone游戏开发

    转自:http://www.cnblogs.com/zilongshanren/archive/2011/09/19/2181558.html 自从发布<如何学习iphone游戏开发>到 ...

  5. [libGDX游戏开发教程]使用libGDX进行游戏开发(12)-Action动画

    前文章节列表:  使用libGDX进行游戏开发(11)-高级编程技巧   使用libGDX进行游戏开发(10)-音乐音效不求人,程序员也可以DIY   使用libGDX进行游戏开发(9)-场景过渡   ...

  6. [libGDX游戏开发教程]使用libGDX进行游戏开发(1)-游戏设计

    声明:<使用Libgdx进行游戏开发>是一个系列,文章的原文是<Learning Libgdx Game Development>,大家请周知.后续的文章连接在这里 使用Lib ...

  7. 【Cocos2D研究院之游戏开发】

    http://www.xuanyusong.com/archives/category/ios/cocos2d_game 分类目录归档:[Cocos2D研究院之游戏开发]   201211-19 Co ...

  8. cocos2d 游戏开发实战

    文章转自:http://uliweb.clkg.org/tutorial/read/40 6   cocos2d 游戏开发实战 6.1   创建cocos2d项目 6.2   cocos2d v3 & ...

  9. cocos2d-x ios游戏开发初认识(八) 触摸事件与碰撞检測

    玩过植物大战僵尸都知道,要在草坪里放一朵向日葵或者其他的植物仅仅需触摸那个植物将其拖入到想要摆放的位置,这事实上就是这节要写的触摸事件.还能够发现当我们的僵尸出来的时候,我们的小豌豆会发子弹攻击僵尸, ...

随机推荐

  1. Not get deviceToken yet. Maybe: your certificate not configured APNs? or current network is not so good so APNs registration failed? or there is no APNs register code? Please refer to JPush docs.”

    今天在项目中集成了极光推送,一切都配置完毕,把程序运行起来的时候,报了下面的错误: Not get deviceToken yet. Maybe: your certificate not confi ...

  2. ubuntu文件夹默认列表显示

    编辑-->首选项-->视图-->列表视图

  3. DMA2D 图形加速器简介

    在实际使用 LTDC 控制器控制液晶屏时,使 LTDC 正常工作后,往配置好的显存地址写入要显示的像素数据, LTDC 就会把这些数据从显存搬运到液晶面板进行显示,而显示数据的容量非常大,所以我们希望 ...

  4. [ubuntu]E: The package firmware-upgrade needs to be reinstalled, but I can't find an archive for it.

    解决办法把firmware-upgrade卸载 sudo dpkg --remove --force-all firmware-upgrade 然后 sudo apt-get update 即可

  5. u-boot中网口处理--硬件部分

    1.  网口硬件方案: AT91SAM9G10 + DM9000CEP: DM9000CEP为MAC+PHY解决方案,与MCU链接通过8位或16位数据总线. 内部SRAM为16Kbyte. 2. DM ...

  6. Window 2008 R2组策略之一——组策略管理控制台

    组策略管理在windows域管理中占有重要地位,本身也不是新的内容了.但微软在Windows2008中终于集成了一个非常好用的组策略管理工具——组策略管理控制台.并且为原有的组策略添加了新的元素.本文 ...

  7. 关于BETA、RC、ALPHA、Release、GA等版本号的意义

    关于BETA.RC.ALPHA.Release.GA等版本号的意义 转载 2016年06月19日 00:04:00 2049 0 1 . 最近由于工作需要经常要去SVN上拉开源项目的源码,对项目 ...

  8. Java打印整数的二进制表示(代码与解析)

    Java打印整数的二进制表示(代码与解析) int a=-99; for(int i=0;i<32;i++){ int t=(a & 0x80000000>>>i)&g ...

  9. Javascript 你不知道的事,好吧,是我不知道的事

    NaN表示一个不能产生正常结果的运算结果.它不等于任何值,包括它自己.可以用isNaN(number)来检测. 同Java中的字符串一样,JS中的字符串是不可变的.也就是说一旦字符串被创建,就无法改变 ...

  10. AOP称为面向切面编程,在程序开发中主要用来解决一些系统层面上的问题

    AOP称为面向切面编程,在程序开发中主要用来解决一些系统层面上的问题,比如日志,事务,权限等待,Struts2的拦截器设计就是基于AOP的思想,是个比较经典的例子. 一 AOP的基本概念 (1)Asp ...