触摸事件

触摸事件
    local layer = cc.LayerColor:create(cc.c4b(255, 0, 0, 100))
    layer:setPosition(self["sceneSize"].width / 2, self["sceneSize"].height / 2)
    self:addChild(layer)
    
    local listener = cc.EventListenerTouchOneByOne:create()
    listener:setSwallowTouches(true)
    
    listener:registerScriptHandler(function (touch, event)
        print("began")
        return false
    end, cc.Handler.EVENT_TOUCH_BEGAN)
    listener:registerScriptHandler(function (touch, event)
        print("moved")
    end, cc.Handler.EVENT_TOUCH_MOVED)
    listener:registerScriptHandler(function (touch, event)
        print("ended")
    end, cc.Handler.EVENT_TOUCH_ENDED)
    
    layer:getEventDispatcher():addEventListenerWithSceneGraphPriority(listener, layer)
--------注意注册onTouchBegan事件的时候必须返回true或false
一步步分析这个listener如何能达到正常的工作状态。
首先调用addEventListenerWithSceneGraphPriority时我们传的参数有listener和要响应事件的对象(Node)
在这个方法里设置了三项listener的属性,重点来关注setAssociatedNode,setFixedPriority这两个
方法,setAssociatedNode将listener和相关的对象关联起来,以便访问的时候需要。而与
addEventListenerWithFixedPriority方法不同的是,我们这里的setFixedPriority为0,这里非常重要
因为之后会根据getFixedPriority这个值来判断是哪种事件监听的方式。
随着往下深入查找,会找到调用forceAddEventListener方法,如果getFixedPriority() == 0那么就要设置
listener的Flag为SCENE_GRAPH_PRIORITY, 调用associateNodeAndEventListener方法,在这个方法中
首先会根据传入的node在_nodeListenersMap中查找是否有这个node.如果没有就新创建一个listeners =
std::vector<EventListener*>容器,并以node为key将listeners存入_nodeListenersMap。
最后将listener添加到listeners中。


------在这里就产生了和自定义事件的代码上存储的却别。
首先,自定义和触摸事件都以LISTENER_ID位key的方式在CCEventDispatcher中的_listenersMap创建并关联一个列表
但是触摸事件还有继续关联node和listener这也就形成了上面所说的创建容器存入_nodeListenersMap
(注:自定义事件的LISTENER_ID事我们传入的事件名称,而触摸事件是引擎定义在CCEventLisenerTouch.cpp的
const std::string EventListenerTouchOneByOne::LISTENER_ID = "__cc_touch_one_by_one")
回到forceAddEventListener中,会标记node到_dirtyNodes中以便稍后调用事件的时候使用
---------查看dispachTouchEvent方法,以便了解为什么在onTouchBegan中要返回一个bool值,他的具体用途是什么。
在这个方法中有一个方法onTouchEvent方法,这是一会儿执行触摸事件的时候需要调用的。
往下看发现调用了一个dispatchEventToListeners方法,这个方法中才是真正调用所有注册的触摸事件,这个方法在
自定义事件中有叙述过,不做赘述。也就是说触摸事件的事件流停止条件包含自定义事件中的停止条件,另外
还有一个条件,看这个代码片段
                if (eventCode == EventTouch::EventCode::BEGAN)
                {
                    if (listener->onTouchBegan)
                    {
-- 这段代码就是onTouchEvent方法中的代码
-- 这里就是在调用所注册的onTouchBegan,接受到了isClaimed
                        isClaimed = listener->onTouchBegan(*touchesIter, event);
                        if (isClaimed && listener->_isRegistered)
                        {
                            listener->_claimedTouches.push_back(*touchesIter);
                        }
                    }
                }






--- 因为拿到isClaimed 这个值之后,如果为false才有可能是继续调用其他的
--- 触摸事件的条件之一,最后这个isClaimed会用在如下代码中
                if (isClaimed && listener->_isRegistered && listener->_needSwallow)
                {
                    if (isNeedsMutableSet)
                    {
                        mutableTouchesIter = mutableTouches.erase(mutableTouchesIter);
                        isSwallowed = true;
                    }
                    return true;
                }
                
                return false;





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值