【quick-cocos2d-x】单点触摸与touch事件

【quick-cocos2d-x】单点触摸与touch事件,第1张

概述http://www.voidcn.com/article/p-zaumxusj-ns.html http://www.voidcn.com/article/p-qtzgdntn-ns.html   quick的触摸机制,我想廖大已经在这篇文章里说的很清楚了,我们这些小辈们就是在他的基础上完备一下,说说用法就可以了,嘿嘿。 在2.2.3之前的版本(不包括2.2.3),触摸机制和廖大在那篇文章里面的

http://www.jb51.cc/article/p-zaumxusj-ns.html

http://www.jb51.cc/article/p-qtzgdntn-ns.html

quick的触摸机制,我想廖大已经在这篇文章里说的很清楚了,我们这些小辈们就是在他的基础上完备一下,说说用法就可以了,嘿嘿。


在2.2.3之前的版本(不包括2.2.3),触摸机制和廖大在那篇文章里面的说的一样,添加触摸响应采用addtouchEventListener来完成,不过在此之后,对触摸机制就进行了完全的改写,和cocos2dx 3.0的版本一样,采用更加灵活的CCNode事件分发机制。


如果你对cocos 3.0中触摸机制很了解,那么quick的触摸使用起来也很方便。直接来看怎么用。

在前面已经说了,我们添加的节点元素都是在scene中的,但是触摸响应不能直接给scene添加事件监听,所以我们可以用一个层来完成。并且,如果能够接受触摸响应,还需要开启触摸功能。

[HTML] view plaincopyprint?

650) this.width=650;" width="12" height="12" alt="在CODE上查看代码片" src="http://img.jb51.cc/vcimg/static/loading.png" src="https://code.csdn.net/assets/CODE_ico.png">

650) this.width=650;" width="12" height="12" alt="派生到我的代码片" src="http://img.jb51.cc/vcimg/static/loading.png" src="https://code.csdn.net/assets/ico_fork.svg">

locallayer=display.newLayer()

self:addChild(layer)

layer:settouchEnabled(true)

layer:settouchMode(cc.touch_MODE_ONE_BY_ONE)

layer:addNodeEventListener(cc.NODE_touch_EVENT,function(event)

localx,y,prevX,prevY=event.x,event.y,event.prevX,event.prevY

ifevent.name=="began"then

print("layerbegan")

elseifevent.name=="moved"then

print("layermoved")

elseifevent.name=="ended"then

print("layerended")

end

returntrue

end)

  local layer = display.newLayer()  self:addChild(layer)  layer:settouchEnabled(true)  layer:settouchMode(cc.touch_MODE_ONE_BY_ONE)  layer:addNodeEventListener(cc.NODE_touch_EVENT,function (event)    local x,prevY = event.x,event.prevY    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)


从上面的代码可以看到,可以设置触摸的模式,

cc.touch_MODE_ONE_BY_ONE 是单点触摸

cc.touch_MODE_ALL_AT_ONCE 是多点触摸


在添加节点事件监听addNodeEventListener中,我们设置监听事件的类型是cc.NODE_touch_EVENT

这个监听事件类型,其定义了几个引擎级事件,分别是,

-- cocos2dx 引擎级事件
c.NODE_EVENT = 0
c.NODE_ENTER_FRAME_EVENT = 1
c.NODE_touch_EVENT = 2
c.NODE_touch_CAPTURE_EVENT = 3
c.MENU_ITEM_CliCKED_EVENT = 4
c.ACCELERATE_EVENT = 5
c.KEYPAD_EVENT = 6


其次是event参数,在event参数里,里面有name,x,y,prevX,prevY 这五个变量,分别代表着

-- event.name 是触摸事件的状态:began,moved,ended,cancelled,added(仅限多点触摸),removed(仅限多点触摸)
-- event.x,event.y 是触摸点当前位置
-- event.prevX,event.prevY 是触摸点之前的位置


所以添加上面的代码,简单触摸屏幕,就可以看到log中的print的结果。


在触摸的回调函数function(event)中,记得考虑是否需要添加返回值,返回值的作用不用多说,true则后面的moved,ended等状态会接收到,否则接收不到,默认如果不添加则代表false。


在新版触摸机制中,还需要主要的一个就是触摸吞噬,

settouchSwallowEnabled(true)

它的作用就是是否继续传递触摸消息,在绘制节点的时候,越是在屏幕上方,就是zOrder越大,越优先接收到触摸事件,如果设置吞噬,那么在它下方的节点都不会接收到触摸消息了。默认如果不设置则quick自动设置为true。


当然,不仅仅可以给layer添加触摸事件,你也可以给精灵添加,这就看你游戏的需要了。

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


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


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

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

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

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

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


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

?

650) this.width=650;" width="12" height="12" alt="在CODE上查看代码片" src="http://img.jb51.cc/vcimg/static/loading.png" src="https://code.csdn.net/assets/CODE_ico.png">

650) this.width=650;" width="12" height="12" alt="派生到我的代码片" src="http://img.jb51.cc/vcimg/static/loading.png" src="https://code.csdn.net/assets/ico_fork.svg">

functionMyScene:ctor()

layer:settouchSwallowEnabled(false)

end)

layer:addNodeEventListener(cc.NODE_touch_CAPTURE_EVENT,'Microsoft YaHei';Font-size:14px;">print("layercapturebegan")

print("layercapturemoved")

print("layercaptureended")

localsp=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,'Microsoft YaHei';Font-size:14px;">print("spbegan")

print("spmoved")

print("spended")

sp:addNodeEventListener(cc.NODE_touch_CAPTURE_EVENT,'Microsoft YaHei';Font-size:14px;">print("spcapturebegan")

print("spcapturemoved")

print("spcaptureended")

end

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.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信息,

650) this.wIDth=650;" alt="" src="http://img.jb51.cc/vcimg/static/loading.png" src="http://img.blog.csdn.net/20140829104703040">


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


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

650) this.wIDth=650;" alt="" src="http://img.jb51.cc/vcimg/static/loading.png" src="http://img.blog.csdn.net/20140829112643953">


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


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

returnfalse

--sp:settouchSwallowEnabled(false)

sp:settouchMode(cc.touch_MODE_ONE_BY_ONE)

  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.cy)  layer:addChild(sp)  --self:addChild(sp)  sp:settouchEnabled(true)  --sp:settouchSwallowEnabled(false)  sp:settouchMode(cc.touch_MODE_ONE_BY_ONE)


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

650) this.wIDth=650;" alt="" src="http://img.jb51.cc/vcimg/static/loading.png" src="http://img.blog.csdn.net/20140829114220578">


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

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


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


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

--layer:addChild(sp)

self:addChild(sp)

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

650) this.wIDth=650;" alt="" src="http://img.jb51.cc/vcimg/static/loading.png" src="http://img.blog.csdn.net/20140829115802627">


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


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

总结

以上是内存溢出为你收集整理的【quick-cocos2d-x】单点触摸与touch事件全部内容,希望文章能够帮你解决【quick-cocos2d-x】单点触摸与touch事件所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1017833.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-23
下一篇 2022-05-23

发表评论

登录后才能评论

评论列表(0条)

保存