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上点击滑动,响应事件。


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

【cocos2d-x3.2】 模态对话框拦截所有事件的更多相关文章

  1. iOS推送通知优先级

    我已设置推送通知并正常工作,但是,有时我会遇到终端设备上的延迟交付.有没有办法我可以将推送的“优先级”键设置为10,以便立即发送推送?

  2. iOS将UIView转换为ScrollView而不破坏布局?

    是否有可能在不破坏所有约束和放置的情况下从UIView移动到UIScrollView.问题是我构建整个UI而不在iPhone4上测试它,现在我看到一些视图应该在ScrollView中工作.我尝试了一些技巧,但没有任何作用.约束被删除.以下是示例的示例图片:现在我希望test1UIView是ScrollView,我试图将ScrollView放在test1View中,然后在滚动视图中递归复制test1

  3. ios – 放大故事板中的任何视图时,Xcode 8.2和8.1崩溃

    当我单击视图框并拖动以放大视图时,视图不会放大.但相反,鼠标等待指示器将持续一秒钟,然后整个xcode将崩溃.这是在我的代码8.2更新后发生的.所以我尝试安装xcode8.1,问题仍然存在于一个特定项目中.所有其他项目都运作良好.故事板中没有警告或冲突.我不记得改变任何设置.附加崩溃日志:CRASH_LOG解决方法修正了问题:在我将ScrollView添加到ViewController并更改了Vi

  4. ios – UIButton在uiscrollView中不起作用

    我有一个将UIView作为子视图的scrollView.这有UIView子视图UIButton.只有scrollView连接到插座,其余全部都是代码.按钮不响应触摸,触摸时不变蓝.我能做些什么才能让它发挥作用?这是代码:解决方法您必须设置视图的内容大小.它必须大于或等于scrollView的内容大小.因为您的视图的默认大小是320*480和320*568.因此,增加视野的高度–self.view.frame=CGRectMake;然后将其添加为scrollView的子视图.将帮助您解决问题.

  5. ios – scrollViewDidEndDecelerating检测哪个集合视图在运行

    我使用这种方法来组织分页:当我滚动我的UICollectionView时,我在屏幕上更改了一些内容.但是我的屏幕上有很少的UICollectionView,我只需要一个.解决方法好吧,UICollectionView继承自UIScrollView,因此您可以检查哪个滚动视图最终从委托方法中减速.

  6. ios – 何时使用Semaphore而不是Dispatch Group?

    我会假设我知道如何使用DispatchGroup,为了解问题,我尝试过:结果–预期–是:为了使用信号量,我实现了:并在viewDidLoad方法中调用它.结果是:从概念上讲,dispachGroup和Semaphore都有同样的目的.老实说,我不熟悉:什么时候使用信号量,尤其是在与dispachGroup合作时–可能–处理问题.我错过了什么部分?

  7. 如何使用Xcode的自动布局调整视图大小

    解决方法在写这个问题时,我意识到了诀窍是什么:在NSPopUpButton的大小检查器中,我不得不降低内容拥抱优先级.显然,这可以控制视图“拥抱”其内容的紧密程度.因此,当拥抱优先级高于调整大小优先级时,视图将不希望增加其大小,因为这意味着其边界与其内容之间具有更多的空白空间.然后在我的特殊情况下,我也可以将两个NSPopUpButtons固定为具有相同的宽度和vo:popUpButtons将完美地调整大小,同时保持间距不变.

  8. ios – 默认的自动布局内容拥抱和内容压缩阻抗优先级值是什么?

    我正在尝试调试自动布局问题,并且知道内容拥抱和内容压缩阻力优先级的默认值将有所帮助.这些是什么?它们是否特定于特定组件?我可以使用常量来引用它们吗?

  9. ios – 链接点击监听器上的WKWebView?

    在WKWebView类中是否存在类似onLinkClickListener的东西?我试着谷歌搜索但没有发现任何东西,我也发现了一些关于simillar类型的stackoverflow的未解答的问题.我需要一个linkClickListener的原因是,当我点击链接并且页面尚未加载时,它不会加载网站.当页面加载了监听器时,我也可以创建一个花哨的加载屏幕.解决方法你可以这样做将WKNavigation

  10. 多个监听器用于委托iOS

    我有一个带有代理didSelectString的类搜索栏.我有一个实现委托的A类和一个实现委托的B类.但是只有来自A类的代理才被执行.代表可以有多个监听器吗?并且如何实现这一点解决方法该委托是单一消息传递协议.如果要发送更改的多个对象,则需要使用NSNotifications.您可以使用通知中心传递对象,如下所示:想要收听通知时并设置选择器

随机推荐

  1. 【cocos2d-x 3.x 学习笔记】对象内存管理

    Cocos2d-x的内存管理cocos2d-x中使用的是上面的引用计数来管理内存,但是又增加了一些自己的特色。cocos2d-x中通过Ref类来实现引用计数,所有需要实现内存自动回收的类都应该继承自Ref类。下面是Ref类的定义:在cocos2d-x中创建对象通常有两种方式:这两中方式的差异可以参见我另一篇博文“对象创建方式讨论”。在cocos2d-x中提倡使用第二种方式,为了避免误用第一种方式,一般将构造函数设为protected或private。参考资料:[1]cocos2d-x高级开发教程2.3节[

  2. 利用cocos2dx 3.2开发消灭星星六如何在cocos2dx中显示中文

    由于编码的不同,在cocos2dx中的Label控件中如果放入中文字,往往会出现乱码。为了方便使用,我把这个从文档中获取中文字的方法放在一个头文件里面Chinese.h这里的tex_vec是cocos2dx提供的一个保存文档内容的一个容器。这里给出ChineseWords,xml的格式再看看ChineseWord的实现Chinese.cpp就这样,以后在需要用到中文字的地方,就先include这个头文件然后调用ChineseWord函数,获取一串中文字符串。

  3. 利用cocos2dx 3.2开发消灭星星七关于星星的算法

    在前面,我们已经在GameLayer中利用随机数初始化了一个StarMatrix,如果还不知道怎么创建星星矩阵请回去看看而且我们也讲了整个游戏的触摸事件的派发了。

  4. cocos2dx3.x 新手打包APK注意事项!

    这个在编译的时候就可以发现了比较好弄这只是我遇到的,其他的以后遇到再补充吧。。。以前被这两个问题坑了好久

  5. 利用cocos2dx 3.2开发消灭星星八游戏的结束判断与数据控制

    如果你看完之前的,那么你基本已经拥有一个消灭星星游戏的雏形。开始把剩下的两两互不相连的星星消去。那么如何判断是GameOver还是进入下一关呢。。其实游戏数据贯穿整个游戏,包括星星消除的时候要加到获得分数上,消去剩下两两不相连的星星的时候的加分政策等,因此如果前面没有做这一块的,最好回去搞一搞。

  6. 利用cocos2dx 3.2开发消灭星星九为游戏添加一些特效

    needClear是一个flag,当游戏判断不能再继续后,这个flag变为true,开始消除剩下的星星clearSumTime是一个累加器ONE_CLEAR_TIME就是每颗星星消除的时间2.连击加分信息一般消除一次星星都会有连击信息和加多少分的信息。其实这些combo标签就是一张图片,也是通过控制其属性或者runAction来实现。源码ComboEffect.hComboEffect.cpp4.消除星星粒子效果消除星星时,为了实现星星爆裂散落的效果,使用了cocos2d提供的粒子特效引擎对于粒子特效不了

  7. 02 Cocos2D-x引擎win7环境搭建及创建项目

    官网有搭建的文章,直接转载记录。环境搭建:本文介绍如何搭建Cocos2d-x3.2版本的开发环境。项目创建:一、通过命令创建项目前面搭建好环境后,怎样创建自己的Cocos2d-x项目呢?先来看看Cocos2d-x3.2的目录吧这就是Cocos2d-x3.2的目录。输入cocosnew项目名–p包名–lcpp–d路径回车就创建成功了例如:成功后,找到这个项目打开proj.win32目录下的Hello.slnF5成功了。

  8. 利用cocos2dx 3.2开发消灭星星十为游戏添加音效项目源码分享

    一个游戏,声音也是非常的重要,其实cocos2dx里面的简单音效引擎的使用是非常简单的。我这里只不过是用一个类对所有的音效进行管理罢了。Audio.hAudio.cpp好了,本系列教程到此结束,第一次写教程如有不对请见谅或指教,谢谢大家。最后附上整个项目的源代码点击打开链接

  9. 03 Helloworld

    程序都有一个入口点,在C++就是main函数了,打开main.cpp,代码如下:123456789101112131415161718#include"main.h"#include"AppDelegate.h"#include"cocos2d.h"USING_NS_CC;intAPIENTRY_tWinMain{UNREFERENCED_ParaMETER;UNREFERENCED_ParaMETER;//createtheapplicationinstanceAppDelegateapp;return

  10. MenuItemImage*图标菜单创建注意事项

    学习cocos2dx,看的是cocos2d-x3.x手游开发实例详解,这本书错误一大把,本着探索求知勇于发现错误改正错误的精神,我跟着书上的例子一起调试,当学习到场景切换这个小节的时候,出了个错误,卡了我好几个小时。

返回
顶部