这两天在运用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 值来决议事宜响应的优先级,值越小优先级越高
总结一下:
经由过程点击位置举行点击局限推断,来肯定实行哪个sprite的事宜监听器
假如该位置存在堆叠的sprite绑定了雷同的事宜,则根据优先级(SceneGraphPriority显现优先级或FixedPriority牢固优先级)来递次实行函数回调
经由过程设置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);
});
上面的代码:
起首经由过程运用cc.EventListener.create建立了一个Touch事宜监听器touchListener
然后,经由过程cc.eventManager.addListener注册监听器到事宜管理器。cc.EventListener.create扩展出一个用户监听器。
event属性,定义这个监听器监听的范例。
swallowTouches属性设置是不是吃掉事宜,事宜被吃掉后不会递给下一层监听器。
onTouchBegan要领处置惩罚触摸点击按下事宜,我们在这里能够猎取到触摸点的坐标pos。event.getCurrentTarget()猎取当前事宜的接受者,并推断当前的是不是点击到了SushiSprite。
在touch事宜中,我们还能够增加onTouchMoved/onTouchEnded要领监听touch挪动和完毕的回调。假如onTouchBegan返回false后onTouchMoved/onTouchEnded不会实行。
tip: 在onTouchBegan要领中猎取点击点的坐标pos,然后经由过程cc.rectContainsPoint(target.getBoundingBox(),pos)推断点击的点是不是在SushiSprite上。
博客文章地点:http://joebon.cc/cocos2d-event-dispatcher