Cocos2d-X 3.0 事宜分发机制

这两天在运用cocos2d-js做一个拔萝卜游戏,研讨了一番cocos2d的事宜分发机制,总结分享一下。

事宜

Cocos2d-JS v3.x中事宜分发机制举行了重写,事宜能够与恣意对象绑定,而不是只要Layer才猎取。对象建立本身的事宜监听器,然后加入到全局的事宜管理器统一管理。

事宜监听器有以下几种:

  • 触摸事宜

  • 键盘响应事宜

  • 鼠标响应事宜

  • 自定义事宜

  • 加快计事宜

事宜分发

在相识事宜分发机制之前,我们起首要明白什么是事宜分发。

关于事宜分发,cocos2d官方定义为:当事宜发作(比方,用户触摸屏幕,或许敲键盘),EventDispatcher 会宣布(Event objects)事宜对象到适宜的EventListeners,并挪用你的回调。各个Event object包括事宜的信息(比方,触摸点地点的坐标)。

我的明白是关于一个事宜(比方触摸事宜、键盘响应事宜等)能够与恣意对象绑定,那末当这个事宜被用户触发时,此时应当实行哪个对象的回调函数(比方此时我们在好几个sprite上同时绑定了touch事宜,用户此时点击屏幕,用户此时想点击的究竟是哪个sprite),我们就需要作出推断。EventDispatcher做的就是这个事变。

以touch事宜(触摸事宜)为例,推断用户点击的是哪个sprite的要领很简单,实在就是在onTouchBegan要领中猎取点击点的坐标pos,然后经由过程cc.rectContainsPoint(target.getBoundingBox(),pos)推断点击的点是不是在SushiSprite上。不过此时又会涌现别的一个题目,就是假如两个sprite有互相堆叠的部份,而此时用户点击的恰恰是堆叠部份,那末怎样推断究竟点击的是哪个sprite呢?这里是经由过程priority(分为两种:SceneGraphPriority和FixedPriority)来处置惩罚的,优先级高的sprite优先实行它所对应的事宜监听器的回调函数。如许就形成了一个根据优先级上下分列的sprite行列守候顺次实行用户触发的事宜,而这中心则经由过程swallowTouches(淹没事宜)属性来掌握是不是继承向优先级低的sprite通报事宜。这就形成了一个完全的事宜分发机制。

tip:

  • SceneGraphPriority(显现优先级):根据屏幕显现的“遮掩”实际情况,举行有序的函数回调。zOrder越大,优先级越大。

  • FixedPriority(牢固优先级):根据手动设定的 Priority 值来决议事宜响应的优先级,值越小优先级越高

总结一下:

  1. 经由过程点击位置举行点击局限推断,来肯定实行哪个sprite的事宜监听器

  2. 假如该位置存在堆叠的sprite绑定了雷同的事宜,则根据优先级(SceneGraphPriority显现优先级或FixedPriority牢固优先级)来递次实行函数回调

  3. 经由过程设置swallowTouches属性为true,并在onTouchBegan中返回true或许false来决议是不是阻挠事宜的递次通报。假如onTouchBegan返回true,且swallowTouches为true,则事宜被淹没,事宜的递次通报则被阻挠。

实例

新建一个sprite,并为其增加一个touch事宜:

var SushiSprite = cc.Sprite.extend({
    onEnter:function () {
        cc.log("onEnter");
        this._super();
    },
 
    onExit:function () {
        cc.log("onExit");
    }
});

addTouchEventListenser:function(){
    this.touchListener = cc.EventListener.create({
        event: cc.EventListener.TOUCH_ONE_BY_ONE,
        // When "swallow touches" is true, then returning 'true' from the onTouchBegan method will "swallow" the touch event, preventing other listeners from using it.
        swallowTouches: true,
        //onTouchBegan event callback function                      
        onTouchBegan: function (touch, event) { 
            var pos = touch.getLocation();
            var target = event.getCurrentTarget();  
            if ( cc.rectContainsPoint(target.getBoundingBox(),pos)) {
                cc.log("touched")
                return true;
            }
            return false;
        }
    cc.eventManager.addListener(this.touchListener,this);
});

上面的代码:

  1. 起首经由过程运用cc.EventListener.create建立了一个Touch事宜监听器touchListener

  2. 然后,经由过程cc.eventManager.addListener注册监听器到事宜管理器。cc.EventListener.create扩展出一个用户监听器。

  3. event属性,定义这个监听器监听的范例。

  4. swallowTouches属性设置是不是吃掉事宜,事宜被吃掉后不会递给下一层监听器。

  5. onTouchBegan要领处置惩罚触摸点击按下事宜,我们在这里能够猎取到触摸点的坐标pos。event.getCurrentTarget()猎取当前事宜的接受者,并推断当前的是不是点击到了SushiSprite。

  6. 在touch事宜中,我们还能够增加onTouchMoved/onTouchEnded要领监听touch挪动和完毕的回调。假如onTouchBegan返回false后onTouchMoved/onTouchEnded不会实行。

tip: 在onTouchBegan要领中猎取点击点的坐标pos,然后经由过程cc.rectContainsPoint(target.getBoundingBox(),pos)推断点击的点是不是在SushiSprite上。

博客文章地点:http://joebon.cc/cocos2d-event-dispatcher

参考文献

[1] http://cn.cocos2d-x.org/article/index?type=cocos2d-x&url=/doc/cocos-docs-master/manual/framework/cocos2d-js/3-jumping-into-cocos2d-js/3-6-creating-user-interaction-with-event-manager/zh.md

[2] http://cn.cocos2d-x.org/article/index?type=wiki&url=/doc/cocos-docs-master/manual/framework/native/wiki/eventdispatcher-mechanism/zh.md

    原文作者:Joebon
    原文地址: https://segmentfault.com/a/1190000005109807
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞