热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

quick-cocos2d-x游戏开发【10】——触摸捕获事件cc.NODE_TOUCH_CAPTURE_EVENT

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

如果看过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信息,


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


如果我们将子节点sprite设置吞噬触摸,


可以看到,当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对于捕获事件的原理了。如有错误,欢迎指出。



推荐阅读
  • PHP图片截取方法及应用实例
    本文介绍了使用PHP动态切割JPEG图片的方法,并提供了应用实例,包括截取视频图、提取文章内容中的图片地址、裁切图片等问题。详细介绍了相关的PHP函数和参数的使用,以及图片切割的具体步骤。同时,还提供了一些注意事项和优化建议。通过本文的学习,读者可以掌握PHP图片截取的技巧,实现自己的需求。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • Android JSON基础,音视频开发进阶指南目录
    Array里面的对象数据是有序的,json字符串最外层是方括号的,方括号:[]解析jsonArray代码try{json字符串最外层是 ... [详细]
  • 本文介绍了在Python3中如何使用选择文件对话框的格式打开和保存图片的方法。通过使用tkinter库中的filedialog模块的asksaveasfilename和askopenfilename函数,可以方便地选择要打开或保存的图片文件,并进行相关操作。具体的代码示例和操作步骤也被提供。 ... [详细]
  • SpringBoot uri统一权限管理的实现方法及步骤详解
    本文详细介绍了SpringBoot中实现uri统一权限管理的方法,包括表结构定义、自动统计URI并自动删除脏数据、程序启动加载等步骤。通过该方法可以提高系统的安全性,实现对系统任意接口的权限拦截验证。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 不同优化算法的比较分析及实验验证
    本文介绍了神经网络优化中常用的优化方法,包括学习率调整和梯度估计修正,并通过实验验证了不同优化算法的效果。实验结果表明,Adam算法在综合考虑学习率调整和梯度估计修正方面表现较好。该研究对于优化神经网络的训练过程具有指导意义。 ... [详细]
  • 从零学Java(10)之方法详解,喷打野你真的没我6!
    本文介绍了从零学Java系列中的第10篇文章,详解了Java中的方法。同时讨论了打野过程中喷打野的影响,以及金色打野刀对经济的增加和线上队友经济的影响。指出喷打野会导致线上经济的消减和影响队伍的团结。 ... [详细]
  • 成功安装Sabayon Linux在thinkpad X60上的经验分享
    本文分享了作者在国庆期间在thinkpad X60上成功安装Sabayon Linux的经验。通过修改CHOST和执行emerge命令,作者顺利完成了安装过程。Sabayon Linux是一个基于Gentoo Linux的发行版,可以将电脑快速转变为一个功能强大的系统。除了作为一个live DVD使用外,Sabayon Linux还可以被安装在硬盘上,方便用户使用。 ... [详细]
  • 闭包一直是Java社区中争论不断的话题,很多语言都支持闭包这个语言特性,闭包定义了一个依赖于外部环境的自由变量的函数,这个函数能够访问外部环境的变量。本文以JavaScript的一个闭包为例,介绍了闭包的定义和特性。 ... [详细]
  • C++中的三角函数计算及其应用
    本文介绍了C++中的三角函数的计算方法和应用,包括计算余弦、正弦、正切值以及反三角函数求对应的弧度制角度的示例代码。代码中使用了C++的数学库和命名空间,通过赋值和输出语句实现了三角函数的计算和结果显示。通过学习本文,读者可以了解到C++中三角函数的基本用法和应用场景。 ... [详细]
  • Html5-Canvas实现简易的抽奖转盘效果
    本文介绍了如何使用Html5和Canvas标签来实现简易的抽奖转盘效果,同时使用了jQueryRotate.js旋转插件。文章中给出了主要的html和css代码,并展示了实现的基本效果。 ... [详细]
  • Linux如何安装Mongodb的详细步骤和注意事项
    本文介绍了Linux如何安装Mongodb的详细步骤和注意事项,同时介绍了Mongodb的特点和优势。Mongodb是一个开源的数据库,适用于各种规模的企业和各类应用程序。它具有灵活的数据模式和高性能的数据读写操作,能够提高企业的敏捷性和可扩展性。文章还提供了Mongodb的下载安装包地址。 ... [详细]
  • 本文讨论了在iOS平台中的Metal框架中,对于if语句中的判断条件的限制和处理方式。作者提到了在Metal shader中,判断条件不能写得太长太复杂,否则可能导致程序停留或没有响应。作者还分享了自己的经验,建议在CPU端进行处理,以避免出现问题。 ... [详细]
author-avatar
手机用户2502939543
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有