【cocos2d-x3.2游戏开发】 模态对话框拦截所有事件
来源:互联网 发布:js 范围选择滑块插件 编辑:程序博客网 时间:2024/05/21 14:52
开发基础: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上点击滑动,响应事件。
--[[ 可点击的图片,可以设置响应的优先级。 比如ScrollView上的按钮,可以用TouchableSprite实现。将TouchableSprite设置为不吞噬消息即可。 ~~~lua -- 点击点击事件 local function equip_touch_began_listener(sender, touch, event) end -- 点击结束事件 local function equip_touch_ended_listener(sender, touch, event) if scroll_view:isTouchMoved() then return end -- 可以添加容错点击,如5个像素内。 local start_pt = touch:getStartLocation() local end_pt = touch:getLocation() if checkint(start_pt.x) == checkint(end_pt.x) and checkint(start_pt.y) == checkint(end_pt.y) then print(sender.id_) print("Ready to equip......") end end -- 添加到ScrollView上可点击的图片 local sp = TouchableSprite.new("data/equip.png", equip_touch_began_listener, equip_touch_ended_listener, false) sp.id_ = 9999 scroll_view:addChild(sp) ~~~lua]]local TouchableSprite = class("TouchableSprite", function(pic_path) return display.newSprite(pic_path) end)TouchableSprite.__index = TouchableSpriteTouchableSprite.listener_ = nilTouchableSprite.swallowTouch_ = trueTouchableSprite.fixedPriority_ = 0TouchableSprite.useNodePriority_ = falseTouchableSprite.removeListenerOnTouchEnded_ = falseTouchableSprite.touch_began_listener_ = nilTouchableSprite.touch_ended_listener_ = nil--[[构造一个可响应点击事件的TouchableSprite。~~~lua -- 监听器有三个参数,第一个参数是自己 local function touch_began_listener(sender, touch, event) end local function touch_ended_listener(sender, touch, event) local start_pt = touch:getStartLocation() local end_pt = touch:getLocation() if checkint(start_pt.x) == checkint(end_pt.x) and checkint(start_pt.y) == checkint(end_pt.y) then print(sender.id_) print("Ready to equip......") end end local sp = TouchableSprite.new("data/equip.png", equip_touch_began_listener, equip_touch_ended_listener) sp:setTexture("data/equip1.png") sp:setPriority(1) parent:addChild(sp) ~~~lua@param string pic_path 传入图片路径.可为空,后通过:setTexture("pic_path")重新设置@param touch_began_listener 点击开始事件的监听器。为空时不响应。 监听器有三个参数,第一个参数是可点击图片自己@param touch_ended_listener 点击结束时事件监听器。为空时不响应。 监听器有三个参数,第一个参数是可点击图片自己@param swallow_touch 是否吞噬事件 true 事件不再向下传递 false 响应完事件后,继续向下传递]]function TouchableSprite:ctor(pic_path, touch_began_listener, touch_ended_listener, swallow_touch) self.touch_began_listener_ = touch_began_listener self.touch_ended_listener_ = touch_ended_listener self.swallowTouch_ = swallow_touch local function onNodeEvent(event) if event == "enter" then self:onEnter() elseif event == "exit" then self:onExit() end end self:registerScriptHandler(onNodeEvent)endfunction TouchableSprite:setTouchBeganListener(touch_began_listener) self.touch_began_listener_ = touch_began_listenerendfunction TouchableSprite:setTouchEndedListener(touch_ended_listener) self.touch_ended_listener_ = touch_ended_listenerendfunction TouchableSprite:onEnter() local eventDispatcher = self:getEventDispatcher() local function onTouchBegan(touch, event) local locationInNode = self:convertToNodeSpace(touch:getLocation()) local s = self:getContentSize() local rect = cc.rect(0, 0, s.width, s.height) if cc.rectContainsPoint(rect, locationInNode) then if self.touch_began_listener_ then self:touch_began_listener_(self,touch, event) end return true end return false end local function onTouchMoved(touch, event) end local function onTouchEnded(touch, event) print("onTouchEnded.......") if self.touch_ended_listener_ then self:touch_ended_listener_(self, touch, event) end if self.removeListenerOnTouchEnded_ then eventDispatcher:removeEventListener(self.listener_) end end local listener = cc.EventListenerTouchOneByOne:create() self.listener_ = listener listener:setSwallowTouches(self.swallowTouch_) listener:registerScriptHandler(onTouchBegan,cc.Handler.EVENT_TOUCH_BEGAN ) listener:registerScriptHandler(onTouchMoved,cc.Handler.EVENT_TOUCH_MOVED ) listener:registerScriptHandler(onTouchEnded,cc.Handler.EVENT_TOUCH_ENDED ) if 0 == self.fixedPriority_ then eventDispatcher:addEventListenerWithSceneGraphPriority(listener, self) else eventDispatcher:addEventListenerWithFixedPriority(listener,self.fixedPriority_) endendfunction TouchableSprite:setSwalllowTouch(swallow) self.swallowTouch_ = swallowendfunction TouchableSprite:onExit() local eventDispatcher = self:getEventDispatcher() eventDispatcher:removeEventListener(self.listener_)endfunction TouchableSprite:setPriority(fixedPriority) self.fixedPriority_ = fixedPriority self.useNodePriority_ = falseendfunction TouchableSprite:removeListenerOnTouchEnded(toRemove) self.removeListenerOnTouchEnded_ = toRemoveendfunction TouchableSprite:setPriorityWithNode(useNodePriority) self.fixedPriority_ = 0 self.useNodePriority_ = useNodePriorityendreturn TouchableSprite
Cocos2dx 2.x版本的模态对话框:【COCOS2DX-游戏开发之二】 模态对话框
- 【cocos2d-x3.2游戏开发】 模态对话框拦截所有事件
- 【cocos2d-x3.2游戏开发】 模态对话框拦截所有事件
- 【cocos2d-x3.2】 模态对话框拦截所有事件
- 【cocos2d-x3.2游戏开发】 lua 类, 继承, 面向对象
- 【cocos2d-x3.2游戏开发】 lua 类, 继承, 面向对象
- Cocos2d-x3.2 双击事件
- Cocos2d-x3.2 双击事件
- Cocos2d-x3.2 双击事件
- Cocos2d-x3.2 双击事件
- 游戏2048--基于cocos2d-x3.2
- 《游戏觉醒之Cocos2d-x3.10游戏开发》- 生命周期
- 《游戏觉醒之Cocos2d-x3.10游戏开发》- 导演(Director)
- 《游戏觉醒之Cocos2d-x3.10游戏开发》- 场景(Scene)
- cocos2d-x3.2游戏开发在mac os下配置android环境
- cocos2d-x3.x 游戏手柄
- Cocos2d-x3.0 触摸事件
- Cocos2d-x3.1事件实例
- cocos2d-x3.2入门
- 解决python3使用cx_Freeze打包成exe后不能运行
- 黑马程序员_java的反射机制
- linux netlink
- [Unity 笔记] 关于 Unity Forward Rendering
- android.content.ActivityNotFoundException: Unable to find explicit activity class 【安卓报错】
- 【cocos2d-x3.2游戏开发】 模态对话框拦截所有事件
- ubuntu 卸载程序
- Linux wext和nl80211接口简介
- javascript HTML函数
- ONVIF客户端搜索设备获取rtsp地址开发笔记(精华篇)
- HDU 2563 统计问题
- hdu 1280 前m大的数 (水题)
- 斐波那契数c++实现
- IOS8 新增UIAlertController类