【cocos2d-x3.2】 模态对话框拦截所有事件

前端之家收集整理的这篇文章主要介绍了【cocos2d-x3.2】 模态对话框拦截所有事件前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

From: http://www.jb51.cc/article/p-tgakmibj-xy.html


开发基础:Cocos2dx 3.2

开发目标:1.实现模态对话框,无论弹出多少层都可以拦截事件。 2.ScrollView上有按钮,可以点击按钮滑动,响应事件并且不影响模态对话框的事件拦截



实现方法:
1.Cocos2dx 2版本中,我们会设置DlgLayer事件的优先级为-128,这样会拦截底层的按钮事件(-128),但是问题是会拦截当前层的按钮事件(-128),需要将DlgLayer上的点击事件手动传入对话框上的按钮处理。
3.0版本中已经不再使用了,这种方法有很大的局限性,尤其在界面比较多,比较复杂的情况下,传递事件是一种比较挫的做法。直接排除。

2.Cocos2dx 3.X版本中,因为改变了事件的规则,几乎所有的控件的事件处理都按SceneGraPHPriority走的,甚至连Cocos2dx 2.X版本的Menu的-128也更改为0了。
做法: 直接弹出一个DlgLayer(CCColorLayer),封装一个事件吞噬(onTouchBegan,onTouchEnded...),事件优先级为addEventListenerWithSceneGraPHPriority,即0
因为所有层的拦截事件优先级为0,就会先处理最上方的事件,即弹出的对话框事件。


特殊情况:
弹出的对话框上有ScrollView,ScrollView上有按钮,最常见的问题就是
1.点击按钮能触发事件,但是点击按钮无法滑动ScrollView
解决办法:把按钮优先级设置为1(当前ScrollView的优先级为0),这样就能点着按钮滑动了。
但是产生新问题,按钮能滑动,却不能点击了,因为DlgLayer的优先级为0,会拦截掉按钮的事件。

2.有一个特殊的API,setSwallowTouches,在为一个控件封装点击事件的时候,可以将setSwallowTouches(false)。
这就意味着按钮能够响应点击事件,但是因为没有吞噬事件,就可以把按钮的事件传给ScrollView,ScrollView也可以滑动。
DlgLayer 优先级 0
ScrollView 优先级 0
Button 优先级 0
根据ZOrder的顺序,先触发Button,然后是ScrollView,最后是DlgLayer

3. 3.0版本不建议修改priority,因为你无法得知需要弹出多少层对话框,就无法确定每个对话框的priority

eventdispatcher事件分发规则
添加监听的方法addEventListenerWithSceneGraPHPriority和addEventListenerWithFixedPriority

1.SceneGraPHPriority
和Node节点绑定的所有事件的优先级为0,
添加监听器后,事件监听列表内部的排序为 "<0,scene graph (0 priority),>0"

2.FixedPriority
用来自己定制优先级,一般设置"<0 或 >0"

3. 响应事件的优先级,数值越小,越先响应,-1 0 1这个顺序
内部事件处理顺序:
1.优先级为负数的事件
2.优先级为0(scene graph)的事件,相同的优先级会根据Node的z顺序高的(绘制于顶部的)节点将优于z顺序低的节点。这将保证了诸如触碰事件的自顶向下传播。
3.优先级为整数的事件


最后附带一个lua版封装的TouchableSprite

一个可点击的图片,可以在ScrollView上点击滑动,响应事件。


    @H_502_85@--[[
  1. 可点击的图片,可以设置响应的优先级。
  2. @H_502_85@比如ScrollView上的按钮,可以用TouchableSprite实现。将TouchableSprite设置为不吞噬消息即可。
  3. @H_502_85@~~~lua
  4. @H_502_85@--点击点击事件
  5. localfunctionequip_touch_began_listener(sender,touch,event)
  6. @H_502_85@end
  7. @H_502_85@--点击结束事件
  8. localfunctionequip_touch_ended_listener(sender,event)
  9. @H_502_85@ifscroll_view:isTouchMoved()then
  10. return
  11. @H_502_85@end
  12. @H_502_85@--可以添加容错点击,如5个像素内。
  13. localstart_pt=touch:getStartLocation()
  14. @H_502_85@localend_pt=touch:getLocation()
  15. ifcheckint(start_pt.x)==checkint(end_pt.x)andcheckint(start_pt.y)==checkint(end_pt.y)then
  16. @H_502_85@print(sender.id_)
  17. print("Readytoequip......")
  18. @H_502_85@end
  19. end
  20. @H_502_85@
  21. --添加到ScrollView上可点击的图片
  22. @H_502_85@localsp=TouchableSprite.new("data/equip.png",
  23. equip_touch_began_listener,
  24. @H_502_85@equip_touch_ended_listener,
  25. false)
  26. @H_502_85@
  27. sp.id_=9999
  28. @H_502_85@scroll_view:addChild(sp)
  29. @H_502_85@~~~lua
  30. @H_502_85@]]
  31. localTouchableSprite=class("TouchableSprite",function(pic_path)
  32. @H_502_85@returndisplay.newSprite(pic_path)
  33. end)
  34. @H_502_85@
  35. TouchableSprite.__index=TouchableSprite
  36. @H_502_85@TouchableSprite.listener_=nil
  37. TouchableSprite.swallowTouch_=true
  38. @H_502_85@TouchableSprite.fixedPriority_=0
  39. TouchableSprite.useNodePriority_=false
  40. @H_502_85@TouchableSprite.removeListenerOnTouchEnded_=false
  41. TouchableSprite.touch_began_listener_=nil
  42. @H_502_85@TouchableSprite.touch_ended_listener_=nil
  43. @H_502_85@--[[
  44. 构造一个可响应点击事件的TouchableSprite。
  45. @H_502_85@
  46. ~~~lua
  47. @H_502_85@
  48. --监听器有三个参数,第一个参数是自己
  49. @H_502_85@localfunctiontouch_began_listener(sender,event)
  50. end
  51. @H_502_85@
  52. localfunctiontouch_ended_listener(sender,event)
  53. @H_502_85@localstart_pt=touch:getStartLocation()
  54. localend_pt=touch:getLocation()
  55. @H_502_85@ifcheckint(start_pt.x)==checkint(end_pt.x)andcheckint(start_pt.y)==checkint(end_pt.y)then
  56. print(sender.id_)
  57. @H_502_85@print("Readytoequip......")
  58. end
  59. @H_502_85@end
  60. @H_502_85@localsp=TouchableSprite.new("data/equip.png", @H_502_85@equip_touch_ended_listener)
  61. @H_502_85@sp:setTexture("data/equip1.png")
  62. sp:setPriority(1)
  63. @H_502_85@parent:addChild(sp)
  64. @H_502_85@~~~lua
  65. @H_502_85@@paramstringpic_path传入图片路径.可为空,后通过:setTexture("pic_path")重新设置
  66. @paramtouch_began_listener点击开始事件的监听器。为空时不响应。监听器有三个参数,第一个参数是可点击图片自己
  67. @H_502_85@@paramtouch_ended_listener点击结束时事件监听器。为空时不响应。监听器有三个参数,第一个参数是可点击图片自己
  68. @paramswallow_touch是否吞噬事件true事件不再向下传递false响应完事件后,继续向下传递
  69. @H_502_85@]]
  70. functionTouchableSprite:ctor(pic_path,touch_began_listener,touch_ended_listener,swallow_touch)
  71. @H_502_85@self.touch_began_listener_=touch_began_listener
  72. self.touch_ended_listener_=touch_ended_listener
  73. @H_502_85@self.swallowTouch_=swallow_touch
  74. @H_502_85@localfunctiononNodeEvent(event)
  75. ifevent=="enter"then
  76. @H_502_85@self:onEnter()
  77. elseifevent=="exit"then
  78. @H_502_85@self:onExit()
  79. end
  80. @H_502_85@end
  81. @H_502_85@self:registerScriptHandler(onNodeEvent)
  82. end
  83. @H_502_85@
  84. functionTouchableSprite:setTouchBeganListener(touch_began_listener)
  85. @H_502_85@self.touch_began_listener_=touch_began_listener
  86. end
  87. @H_502_85@
  88. functionTouchableSprite:setTouchEndedListener(touch_ended_listener)
  89. @H_502_85@self.touch_ended_listener_=touch_ended_listener
  90. end
  91. @H_502_85@
  92. functionTouchableSprite:onEnter()
  93. @H_502_85@localeventDispatcher=self:getEventDispatcher()
  94. @H_502_85@localfunctiononTouchBegan(touch,event)
  95. locallocationInNode=self:convertToNodeSpace(touch:getLocation())
  96. @H_502_85@locals=self:getContentSize()
  97. localrect=cc.rect(0,s.width,s.height)
  98. @H_502_85@
  99. ifcc.rectContainsPoint(rect,locationInNode)then
  100. @H_502_85@
  101. ifself.touch_began_listener_then
  102. @H_502_85@self:touch_began_listener_(self,event)
  103. end
  104. @H_502_85@returntrue
  105. end
  106. @H_502_85@
  107. returnfalse
  108. @H_502_85@end
  109. @H_502_85@localfunctiononTouchMoved(touch,event)
  110. @H_502_85@end
  111. @H_502_85@localfunctiononTouchEnded(touch,event)
  112. print("onTouchEnded.......")
  113. @H_502_85@ifself.touch_ended_listener_then
  114. self:touch_ended_listener_(self,event)
  115. @H_502_85@end
  116. @H_502_85@ifself.removeListenerOnTouchEnded_then
  117. eventDispatcher:removeEventListener(self.listener_)
  118. @H_502_85@end
  119. end
  120. @H_502_85@
  121. locallistener=cc.EventListenerTouchOneByOne:create()
  122. @H_502_85@self.listener_=listener
  123. listener:setSwallowTouches(self.swallowTouch_)
  124. @H_502_85@
  125. listener:registerScriptHandler(onTouchBegan,cc.Handler.EVENT_TOUCH_BEGAN)
  126. @H_502_85@listener:registerScriptHandler(onTouchMoved,cc.Handler.EVENT_TOUCH_MOVED)
  127. listener:registerScriptHandler(onTouchEnded,cc.Handler.EVENT_TOUCH_ENDED)
  128. @H_502_85@
  129. if0==self.fixedPriority_then
  130. @H_502_85@eventDispatcher:addEventListenerWithSceneGraPHPriority(listener,self)
  131. else
  132. @H_502_85@eventDispatcher:addEventListenerWithFixedPriority(listener,self.fixedPriority_)
  133. end
  134. @H_502_85@end
  135. @H_502_85@functionTouchableSprite:setSwalllowTouch(swallow)
  136. self.swallowTouch_=swallow
  137. @H_502_85@end
  138. @H_502_85@functionTouchableSprite:onExit()
  139. localeventDispatcher=self:getEventDispatcher()
  140. @H_502_85@eventDispatcher:removeEventListener(self.listener_)
  141. end
  142. @H_502_85@
  143. functionTouchableSprite:setPriority(fixedPriority)
  144. @H_502_85@self.fixedPriority_=fixedPriority
  145. self.useNodePriority_=false
  146. @H_502_85@end
  147. @H_502_85@functionTouchableSprite:removeListenerOnTouchEnded(toRemove)
  148. self.removeListenerOnTouchEnded_=toRemove
  149. @H_502_85@end
  150. @H_502_85@functionTouchableSprite:setPriorityWithNode(useNodePriority)
  151. self.fixedPriority_=0
  152. @H_502_85@self.useNodePriority_=useNodePriority
  153. end
  154. @H_502_85@
  155. returnTouchableSprite
原文链接:https://www.f2er.com/cocos2dx/346204.html

猜你在找的Cocos2d-x相关文章