【cocos2d-x3.2游戏开发】 3.2 模态对话框

开发基础: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 = TouchableSprite
TouchableSprite.listener_ = nil
TouchableSprite.swallowTouch_ = true
TouchableSprite.fixedPriority_ = 0
TouchableSprite.useNodePriority_ = false
TouchableSprite.removeListenerOnTouchEnded_ = false
TouchableSprite.touch_began_listener_ = nil
TouchableSprite.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)
end

function TouchableSprite:setTouchBeganListener(touch_began_listener)
    self.touch_began_listener_ = touch_began_listener
end

function TouchableSprite:setTouchEndedListener(touch_ended_listener)
    self.touch_ended_listener_ = touch_ended_listener
end

function 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_)
    end
end

function TouchableSprite:setSwalllowTouch(swallow)
    self.swallowTouch_ = swallow
end

function TouchableSprite:onExit()
    local eventDispatcher = self:getEventDispatcher()
    eventDispatcher:removeEventListener(self.listener_)
end

function TouchableSprite:setPriority(fixedPriority)
    self.fixedPriority_ = fixedPriority
    self.useNodePriority_ = false
end

function TouchableSprite:removeListenerOnTouchEnded(toRemove)
    self.removeListenerOnTouchEnded_ = toRemove
end

function TouchableSprite:setPriorityWithNode(useNodePriority)
    self.fixedPriority_ = 0
    self.useNodePriority_ = useNodePriority
end

return TouchableSprite

老版本的模态对话框:【COCOS2DX-游戏开发之二】 模态对话框

时间: 2024-10-26 23:29:36

【cocos2d-x3.2游戏开发】 3.2 模态对话框的相关文章

【Cocos2D研究院之游戏开发】

http://www.xuanyusong.com/archives/category/ios/cocos2d_game 分类目录归档:[Cocos2D研究院之游戏开发] 201211-19 Cocos2D研究院之打开全新ViewController与返回(八) 雨松MOMO [Cocos2D研究院之游戏开发] 围观5745次 17条评论          之前cocos2d的文章都是由魏凯同学维护,从今天开始我也会抽时间写点cocos2d的文章.最近在研究如何将IOS游戏与软件结合起来.通常游

6、Cocos2dx 3.0游戏开发找小三之游戏的基本概念

重开发者的劳动成果,转载的时候请务必注明出处:http://blog.csdn.net/haomengzhu/article/details/27689713 郝萌主友情提示: 人是习惯的产物,当你习惯快乐时,记忆里的不愉快就消失了. 游戏开始之前 经过之前的学习,我们已经可以开发一个最基本的 Cocos2d-x 游戏了,这个游戏包括一张背景图片和一个退出游戏的按 钮,但是这距离完成一个完整.实用的游戏还很遥远.在这一章节中,我们将首先抛开 Cocos2d,介绍游戏开发的基本概念,然后结合 Co

6、Cocos2dx 3.0游戏开发的基本概念找个小三场比赛

重开发人员的劳动成果,转载的时候请务必注明出处:http://blog.csdn.net/haomengzhu/article/details/27689713 郝萌主友情提示: 人是习惯的产物,当你习惯快乐时.记忆里的不愉快就消失了. 游戏開始之前 经过之前的学习,我们已经能够开发一个最主要的 Cocos2d-x 游戏了,这个游戏包含一张背景图片和一个退出游戏的按 钮,可是这距离完毕一个完整.有用的游戏还非常遥远.在这一章节中,我们将首先抛开 Cocos2d,介绍游戏开发的基本概念.然后结合

【2048小游戏】——CSS/原生js爬坑之纯CSS模态对话框&amp;游戏结束

引言:2048小游戏的结束界面,使用纯CSS制作模态对话框,一般做模态对话框都会使用BootStrap自带的模态对话框组件方便使用,但在制作要运行在移动端的小项目时,就不能使用BootStrap,因为文件太大,下载耗时,耗费流量. 一.模态对话框的组成 2个Div,一个铺满整屛,一个显示内容 坑:如何让Div铺满整屛?解决:2个办法 宽  高 100%    →    position:absolute:  →   top=0;left=0; 四个方向  margin-top/left/righ

cocos2d 游戏开发实战

文章转自:http://uliweb.clkg.org/tutorial/read/40 6   cocos2d 游戏开发实战 6.1   创建cocos2d项目 6.2   cocos2d v3 "hello world" 6.2.1   显示一个飞船 6.3   精灵 6.4   開始 space viking 之旅 6.4.1   添加 sneakyinput 6.5   精灵的移动效果,旋转效果 6.6   定时器效果 6.7   启动 cocos2d,默认竖屏 6.8   检

[ios5 cocos2d游戏开发实战] 笔记3-FileUtils, notificationCenter

FileUtils //文件管理工具 FileUtils::getInstance() std::string getStringFromFile(const std::string& filename);//读取文件中的字符串 Data getDataFromFile(const std::string& filename);//获取文件数据 void setSearchPaths(const std::vector<std::string>& searchPaths

使用 Cocos2d 3.1.1 创建 Windows Phone 8 游戏开发环境

cocos2d-x 是目前流行的游戏游戏开发框架,目前最新的版本是 3.1.1, 网上有些教程已经比较老了,本文将会介绍如何使用最新的 3.1.1 创建 Windows Phone 8 开发环境. 本文假设你已经安装了 VS2012 或者 VS2013,并且已经安装了 Windows Phone8 的 SDK. 一.下载和安装 Cocos2d-x 官网地址:http://www.cocos2d-x.org/ 点击菜单栏中的 Download, 进入下载页面. 我们下载最新的 V3.1.1,新版功

cocos2d 游戏开发:Cocos2d v3 &quot;hello world&quot;+显示飞船

V3 RC4 版本图片 显示一个飞船 将Chapter1中 SpaceCargoShip.png 文件 添加到项目里面. 代码在 init : CCSprite *spaceCargoShip = [CCSprite spriteWithImageNamed:@"SpaceCargoShip.png"]; [spaceCargoShip setPosition:ccp(200.0f,150.9f)]; [self addChild:spaceCargoShip]; 在上面的代码下增加如

Cocos2d-x 自定义血条及其美化----之游戏开发《赵云要格斗》(4)

本章要讲解给怎么在界面上加一个血条,老规矩,还是在Cocos2d-x地图随精灵无限滚动与边缘检测----之游戏开发<赵云要格斗>   的基础上进行增加功能的. cocos2d-x版本:2.2.5 工程环境:windows7+VS2010 先来看看效果吧:由于还没有引入怪物,所以我弄成攻击一次,血条少1或10两种来看看效果 目录: 一.自定义血条类 二.使用自定义血条类并进行美化 三.改变英雄血量 一.自定义血条类 本着后头血条要给怪物来用,所以设计了一个血条类.原理其实就是两个ccsprite