cf.TestScene = cc.Scene.extend({
    _listener1:null
});

cf.TestScene.create = function () {
    var res = new cf.TestScene();
    if(res && res.init()) {
        return res;
    }
    res = null;
    return null;
}

cf.TestScene.prototype.init = function () {
    if(cc.Scene.prototype.init.call(this)) {
        
        // 创建自定义监听器
        var that = this;
        if(!this.listener1) {
            this.listener1 = cc.EventListener.create({
                event: cc.EventListener.CUSTOM,eventName: "game_custom_event1",callback: function(event){
                    that.testCallback(event.getUserData());
                }
            });
            cc.eventManager.addListener(this.listener1,1);
        }
        // 定义了一个 EventCustom ,并且设置了其 UserData 数据,手动的通过 cc.eventManager.dispatchEvent(event); 将此事件分发出去,从而触发之前所实现的逻辑。

        var event = new cc.EventCustom("game_custom_event1");
        event.setUserData("message");
        cc.eventManager.dispatchEvent(event);

        return true;
    }
    return false;
}

cf.TestScene.prototype.onExit = function () {
    cc.Scene.prototype.onExit.call(this);
    if(this._listener1) {
        cc.eventManager.removeListener(this._listener1);
        this._listener1 = null;
    }
}

cf.TestScene.prototype.testCallback = function (data) {
    cc.log("it was in test Callback,data==>" + data);
}


参考:http://www.cocoachina.com/bbs/read.PHP?tid=225198

cocos2d-js v3.0 新功能-----事件分发机制

事件分发机制

简介
在使用时,首先创建一个事件监听器,事件监听器包含以下几种:

  • 触摸事件 (cc.EventListenerTouch)
  • 键盘响应事件 (cc.EventListenerKeyboard)
  • 加速记录事件 (cc.EventListeneracceleration)
  • 鼠标响应事件 (cc.EventListenerMouse)
  • 自定义事件 (cc.EventListenerCustom)
以上事件监听器统一由 cc.eventManager 来进行管理,它是一个单例对象。它的工作需要三部分组成:

  • 事件管理器 cc.eventManager
  • 事件类型 cc.EventTouch,cc.EventKeyboard 等
  • 事件监听器 cc.EventListenerTouch,cc.EventListenerKeyboard 等
监听器实现了各种触发后的逻辑,在适当时候由 事件管理器分发事件类型,然后调用相应类型的监听器。

使用方法
现在将要实现在一个界面中添加三个按钮,三个按钮将会互相遮挡,并且能够触发触摸事件,以下是具体实现

首先创建三个精灵,作为三个按钮的显示图片

复制代码
  1. var sprite1 = cc.Sprite.create("Images/CyanSquare.png");
  2. sprite1.x = size.width/2 - 80;
  3. sprite1.y = size.height/2 + 80;
  4. this.addChild(sprite1,10);

  5. var sprite2 = cc.Sprite.create("Images/magentaSquare.png");
  6. sprite2.x = size.width/2;
  7. sprite2.y = size.height/2;
  8. this.addChild(sprite2,20);

  9. var sprite3 = cc.Sprite.create("Images/YellowSquare.png");
  10. sprite3.x = 0;
  11. sprite3.y = 0;
  12. sprite2.addChild(sprite3,1);



创建一个单点触摸事件监听器,并完成逻辑处理内容

复制代码
  1. // 创建一个事件监听器 OneByOne 为单点触摸
  2. var listener1 = cc.EventListener.create({
  3. event: cc.EventListener.TOUCH_ONE_BY_ONE,
  4. swallowtouches: true,// 设置是否吞没事件,在 onTouchBegan 方法返回 true 时吞没
  5. onTouchBegan: function (touch,event) { //实现 onTouchBegan 事件回调函数
  6. var target = event.getCurrentTarget();// 获取事件所绑定的 target

  7. // 获取当前点击点所在相对按钮的位置坐标
  8. var locationInNode = target.convertToNodeSpace(touch.getLocation());
  9. var s = target.getContentSize();
  10. var rect = cc.rect(0,s.width,s.height);

  11. if (cc.rectContainsPoint(rect,locationInNode)) { // 点击范围判断检测
  12. cc.log("sprite began... x = " + locationInNode.x + ",y = " + locationInNode.y);
  13. target.opacity = 180;
  14. return true;
  15. }
  16. return false;
  17. },
  18. onTouchMoved: function (touch,event) { // 触摸移动时触发
  19. // 移动当前按钮精灵的坐标位置
  20. var target = event.getCurrentTarget();
  21. var delta = touch.getDelta();
  22. target.x += delta.x;
  23. target.y += delta.y;
  24. },
  25. onTouchEnded: function (touch,event) { // 点击事件结束处理
  26. var target = event.getCurrentTarget();
  27. cc.log("sprite ontouchesEnded.. ");
  28. target.setopacity(255);
  29. if (target == sprite2) {// 重新设置 ZOrder,显示的前后顺序将会改变
  30. sprite1.setLocalZOrder(100);
  31. } else if (target == sprite1) {
  32. sprite1.setLocalZOrder(0);
  33. }
  34. }
  35. });


cc.EventListener.create 是一个创建事件监听器的总接口,你可以使用 event 来设置创建的监听器类型,
如上例中的cc.EventListener.TOUCH_ONE_BY_ONE 为单次触摸事件监听器。

Event类型列表:

  1. cc.EventListener.TOUCH_ONE_BY_ONE
  2. cc.EventListener.TOUCH_ALL_AT_ONCE
  3. cc.EventListener.KEYBOARD
  4. cc.EventListener.MOUSE
  5. cc.EventListener.acceleration
  6. cc.EventListener.CUSTOM
添加事件监听器到事件管理器

复制代码
  1. // 添加监听器到管理器
  2. cc.eventManager.addListener(listener1,sprite1);
  3. cc.eventManager.addListener(listener1.clone(),sprite2);
  4. cc.eventManager.addListener(listener1.clone(),sprite3);


cc.eventManager 是单例对象,可直接拿来使用,通过它管理所有事件分发情况。通过 addListener 函数可以将listener加入到管理器中,需要注意的是第二个参数,如果传入的是一个Node对象,则加入的是SceneGraPHPriority(精灵以显示优先级) 类型的listener,如果是一个数值类型的参数,则入到的是FixedPriority 类型的listener。

注意: 这里当我们再次使用 listener1 的时候,需要使用 clone() 方法创建一个新的克隆,因为在使用 addListener 方法时,会对当前使用的事件监听器添加一个已注册的标记,这使得它不能够被添加多次。另外,有一点非常重要,FixedPriority 类型的 listener添加完之后需要手动remove,而SceneGraPHPriority 类型的 listener是跟node绑定的,在node调用cleanup时会被移除。具体的示例用法可以参考引擎自带的tests。

更快速的添加事件监听器到管理器的方式

复制代码
  1. cc.eventManager.addListener({
  2. event: cc.EventListener.TOUCH_ALL_AT_ONCE,
  3. ontouchesMoved: function (touches,event) {
  4. var touch = touches[0];
  5. var delta = touch.getDelta();

  6. var node = event.getCurrentTarget().getChildByTag(TAG_TILE_MAP);
  7. var diff = cc.pAdd(delta,node.getPosition());
  8. node.setPosition(diff);
  9. }
  10. },this);


cc.eventManager的 addListener 的第一个参数也支持两种参数, cc.EventListener 类型和json格式的对象,如果是json格式对象,方法会根据event来创建相关的监听器。

新的触摸机制

以上的步骤看似相对 2.x 版本触摸机制实现时,复杂了点,在老的版本中继承一个 delegate ,里面定义了 onTouchBegan 等方法,然后在里面判断点击的元素,进行逻辑处理。而这里将事件处理逻辑独立出来,封装到一个 Listener 中,而以上的逻辑实现了以下功能:

通过添加事件监听器,将精灵以显示优先级 (SceneGraPHPriority) 添加到事件分发器。这就是说,当我们点击精灵按钮时,根据屏幕显示的“遮盖”实际情况,进行有序的函数回调(即:如图中黄色按钮首先进入 onTouchBegan 逻辑处理)。
在事件逻辑处理时,根据各种条件处理触摸后的逻辑,如点击范围判断,设置被点击元素为不同的透明度,达到点击效果。
因为设置了 swallowtouches: true 并且在 onTouchBegan 中做相应的判断,以决定其返回值是 false 还是 true,用来处理触摸事件是否依据显示的顺序关系向后传递。
注意:与 SceneGraPHPriority 所不同的是 FixedPriority 将会依据手动设定的 Priority 值来决定事件相应的优先级,值越小优先级越高。

其它事件派发处理模块
除了触摸事件响应之外,还有以下模块使用了相同的处理方式。

键盘响应事件

除了键盘,还可以是终端设备的各个菜单,他们使用同一个监听器来进行处理。

//给statusLabel绑定键盘事件
cc.eventManager.addListener({
event: cc.EventListener.KEYBOARD,
onKeypressed:function(keyCode,event){
var label = event.getCurrentTarget();
label.setString("Key " + keyCode.toString() + " was pressed!");
},
onkeyreleased: function(keyCode,event){
var label = event.getCurrentTarget();
label.setString("Key " + keyCode.toString() + " was released!");
}
},statusLabel);

加速计事件

在使用加速计事件监听器之前,需要先启用此硬件设备:

cc.inputManager.setAccelerometerEnabled(true);

然后将相应的事件处理监听器与sprite进行绑定就可以了,如下:

复制代码
  1. cc.eventManager.addListener({
  2. event: cc.EventListener.acceleration,
  3. callback: function(acc,event){
  4. //这里处理逻辑
  5. }
  6. },sprite);


鼠标响应事件

在 3.0 中多了鼠标捕获事件派发,这可以在不同的平台上,丰富我们游戏的用户体验。

复制代码
  1. cc.eventManager.addListener({
  2. event: cc.EventListener.MOUSE,
  3. onMouseMove: function(event){
  4. var str = "MousePosition X: " + event.getLocationX() + "Y:" + event.getLocationY();
  5. // do something...
  6. },
  7. onmouseup: function(event){
  8. var str = "Mouse Up detected,Key: " + event.getButton();
  9. // do something...
  10. },
  11. onMouseDown: function(event){
  12. var str = "Mouse Down detected,
  13. onMouseScroll: function(event){
  14. var str = "Mouse Scroll detected,X: " + event.getLocationX() + "Y:" + event.getLocationY();
  15. // do something...
  16. }
  17. },this);


自定义事件

以上是系统自带的事件类型,这些事件由系统内部自动触发,如 触摸屏幕,键盘响应等,除此之外,还提供了一种 自定义事件,简而言之,它不是由系统自动触发,而是人为的干涉,如下:

复制代码
  1. var _listener1 = cc.EventListener.create({
  2. event: cc.EventListener.CUSTOM,
  3. eventName: "game_custom_event1",
  4. callback: function(event){
  5. statusLabel.setString("Custom event 1 received," + event.getUserData() + " times");
  6. }
  7. });
  8. cc.eventManager.addListener(this._listener1,1);


以上定义了一个 “自定义事件监听器”,实现了一些逻辑,并且添加到事件分发器。那么以上逻辑是在什么情况下响应呢?请看如下:

复制代码
  1. ++selfPointer._item1Count;
  2. var event = new cc.EventCustom("game_custom_event1");
  3. event.setUserData(selfPointer._item1Count.toString());
  4. cc.eventManager.dispatchEvent(event);


定义了一个 EventCustom ,并且设置了其 UserData 数据,手动的通过 cc.eventManager.dispatchEvent(event); 将此事件分发出去,从而触发之前所实现的逻辑。

移除事件监听器

我们可以通过以下方法移除一个已经被添加了的监听器。

复制代码
  1. cc.eventManager.removeListener(listener); //移除一个已添加的监听器


也可以使用如下方法,移除注册到cc.eventManager中以一种类型注册的所有监听器,也可以用这个方法移除注册到cc.eventManager以同一node对象注册的所有监听器。

复制代码
  1. cc.eventManager.removeListeners(cc.EventListener.TOUCH_ONE_BY_ONE); //移除所有TOUCH_ONE_BY_ONE类型的监听器
  2. cc.eventManager.removeListeners(aSprite); //移除所有与aSprite相关的监听器


还可以使用如下方法,移除cc.eventManager中所有监听器。

复制代码
  1. cc.eventManager.removeAllListeners();

当使用 removeAll 的时候,此节点的所有的监听将被移除,推荐使用 指定删除的方式。

_注意:_removeAll 之后 菜单 也不能响应。因为它也需要接受触摸事件。

暂停/恢复 cc.Node(SceneGraph类型)的监听器

开发过程中,我们经常会遇到这样的情况:想要让一个Layer中所有的Node对象的事件都停止响应。 在响应用户事件后,又要恢复该Layer的所有事件响应。如: 用户想要显示一个模式对话框,显示对话框后,禁止对话框后所有对象的事件响应。 在用户关闭对话框后,又恢复这些对象的事件响应。

我们只需要暂停根node的事件,就可以让根节点以及其子节点暂停事件响应。 代码如下:

复制代码
  1. cc.eventManager.pauseTarget(aLayer,true);//让aLayer对象暂停响应事件


而恢复对象的事件响应也非常简单:

复制代码
  1. cc.eventManager.resuMetarget(aLayer,true); //让aLayer对象恢复响应事件


注意: 第二个参数为可选参数,默认值为false,表示是否递归调用子节点的暂停/恢复操作.

属性与方法列表
cc.Event (事件类)



cc.EventCustom (自定义事件)


cc.EventCustom 继承自 cc.Event





cc.EventMouse (鼠标事件)

cc.EventMouse 继承自 cc.Event



cc.EventTouch ()

cc.EventTouch 继承自 cc.Event



cc.EventListener (事件监听器)




cc.EventListener.create 函数参数列表:

创建EventListenerTouchOneByOne对象:

event: cc.EventListener.TOUCH_ONE_BY_ONE

可选参数:

  1. swallowtouches,boolean,是否吞下该touch点
  2. onTouchBegan,function,TouchBegan 事件回调
  3. onTouchMoved,TouchMoved 事件回调
  4. onTouchEnded,TouchEnded 事件回调
  5. onTouchCancelled,TouchCancelled 事件回调


创建EventListenerTouchAllAtOnce对象:

event: cc.EventListener.TOUCH_ALL_AT_ONCE

可选参数:

  1. ontouchesBegan,touchesBegan 事件回调
  2. ontouchesMoved,touchesMoved 事件回调
  3. ontouchesEnded,touchesEnded 事件回调
  4. ontouchesCancelled,touchesCancelled 事件回调


创建EventListenerKeyboard对象:

event: cc.EventListener.KEYBOARD

可选参数:

  1. onKeypressed,Keypressed (键按下) 事件回调
  2. onkeyreleased,keyrelease (键放开) 事件回调


创建EventListenerMouse对象:

event: cc.EventListener.MOUSE

可选参数:

  1. onMouseDown,MouseDown 事件回调
  2. onmouseup,MouseUp 事件回调
  3. onMouseMove,MouseMove 事件回调
  4. onMouseScroll,MouseScroll 事件回调


创建EventListeneracceleration对象:

event: cc.EventListener.acceleration

可选参数:

  1. callback,Acclerometer 事件回调


创建EventListenerCustom对象:

event: cc.EventListener.CUSTOM

可选参数:

  1. callback,自定义事件回调




cc.eventManager


cocos2d-js 自定义监听 EventCustom的更多相关文章

  1. 详解使用postMessage解决iframe跨域通信问题

    这篇文章主要介绍了详解使用postMessage解决iframe跨域通信问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  2. HTML5数字输入仅接受整数的实现代码

    这篇文章主要介绍了HTML5数字输入仅接受整数的实现代码,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  3. 深入了解canvas在移动端绘制模糊的问题解决

    这篇文章主要介绍了深入了解canvas在移动端绘制模糊的问题解决,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  4. HTML5手指下滑弹出负一屏阻止移动端浏览器内置下拉刷新功能的实现代码

    这篇文章主要介绍了HTML5手指下滑弹出负一屏阻止移动端浏览器内置下拉刷新功能的实现代码,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

  5. 浅谈html5之sse服务器发送事件EventSource介绍

    本篇文章主要介绍了浅谈html5之sse服务器发送事件EventSource介绍,具有一定的参考价值,有兴趣的可以了解一下

  6. HTML5 拖放(Drag 和 Drop)详解与实例代码

    本篇文章主要介绍了HTML5 拖放(Drag 和 Drop)详解与实例代码,具有一定的参考价值,有兴趣的可以了解一下

  7. ios – Swift中的非响应流委托

    所以我在Swift中使用套接字并试图将应用程序与我的服务器连接起来.我让应用程序连接到服务器的IP地址,并在服务器上使用netcat进行测试.在执行期间,应用程序的控制台输出显示它已成功连接到服务器.但是,流委托似乎没有响应.当我输入netcat时,app控制台没有打印任何内容.我已经搜索了很长一段时间,发现我的实现与其他实现非常相似.也许我在这里遗漏了一些我看不到的东西.任何想到这个问题的人都将不胜感激!

  8. ios – UIScrollView内容不允许用户交互

    我有一个启用了分页的UIScrollView,如下所示:在UIScrollView中,我添加了几个UIWebViews,并将其启用的交互设置为是这样的.它打破了UIScrollView上的分页和所有触摸.如果我将用户交互设置为NO,则页面有效,但我无法在UIWebView中突出显示文本.我试着像下面那样对UIScrollView进行子类化,但是会出现同样的情况.任何的想法?

  9. ios – 如何知道用户在iPhone中的播放控件上单击快进和快退按钮

    还是有其他方法吗?

  10. ios – 如何在使用隐式动画为CALayer设置动画时继承动画属性

    我试图使用隐式动画在CALayer上设置自定义属性的动画:在-actionForKey:方法我需要返回动画,负责插值.当然,我必须以某种方式告诉动画如何检索动画的其他参数.有关如何实现这一点的任何想法?

随机推荐

  1. 【cocos2d-x 3.x 学习笔记】对象内存管理

    Cocos2d-x的内存管理cocos2d-x中使用的是上面的引用计数来管理内存,但是又增加了一些自己的特色。cocos2d-x中通过Ref类来实现引用计数,所有需要实现内存自动回收的类都应该继承自Ref类。下面是Ref类的定义:在cocos2d-x中创建对象通常有两种方式:这两中方式的差异可以参见我另一篇博文“对象创建方式讨论”。在cocos2d-x中提倡使用第二种方式,为了避免误用第一种方式,一般将构造函数设为protected或private。参考资料:[1]cocos2d-x高级开发教程2.3节[

  2. 利用cocos2dx 3.2开发消灭星星六如何在cocos2dx中显示中文

    由于编码的不同,在cocos2dx中的Label控件中如果放入中文字,往往会出现乱码。为了方便使用,我把这个从文档中获取中文字的方法放在一个头文件里面Chinese.h这里的tex_vec是cocos2dx提供的一个保存文档内容的一个容器。这里给出ChineseWords,xml的格式再看看ChineseWord的实现Chinese.cpp就这样,以后在需要用到中文字的地方,就先include这个头文件然后调用ChineseWord函数,获取一串中文字符串。

  3. 利用cocos2dx 3.2开发消灭星星七关于星星的算法

    在前面,我们已经在GameLayer中利用随机数初始化了一个StarMatrix,如果还不知道怎么创建星星矩阵请回去看看而且我们也讲了整个游戏的触摸事件的派发了。

  4. cocos2dx3.x 新手打包APK注意事项!

    这个在编译的时候就可以发现了比较好弄这只是我遇到的,其他的以后遇到再补充吧。。。以前被这两个问题坑了好久

  5. 利用cocos2dx 3.2开发消灭星星八游戏的结束判断与数据控制

    如果你看完之前的,那么你基本已经拥有一个消灭星星游戏的雏形。开始把剩下的两两互不相连的星星消去。那么如何判断是GameOver还是进入下一关呢。。其实游戏数据贯穿整个游戏,包括星星消除的时候要加到获得分数上,消去剩下两两不相连的星星的时候的加分政策等,因此如果前面没有做这一块的,最好回去搞一搞。

  6. 利用cocos2dx 3.2开发消灭星星九为游戏添加一些特效

    needClear是一个flag,当游戏判断不能再继续后,这个flag变为true,开始消除剩下的星星clearSumTime是一个累加器ONE_CLEAR_TIME就是每颗星星消除的时间2.连击加分信息一般消除一次星星都会有连击信息和加多少分的信息。其实这些combo标签就是一张图片,也是通过控制其属性或者runAction来实现。源码ComboEffect.hComboEffect.cpp4.消除星星粒子效果消除星星时,为了实现星星爆裂散落的效果,使用了cocos2d提供的粒子特效引擎对于粒子特效不了

  7. 02 Cocos2D-x引擎win7环境搭建及创建项目

    官网有搭建的文章,直接转载记录。环境搭建:本文介绍如何搭建Cocos2d-x3.2版本的开发环境。项目创建:一、通过命令创建项目前面搭建好环境后,怎样创建自己的Cocos2d-x项目呢?先来看看Cocos2d-x3.2的目录吧这就是Cocos2d-x3.2的目录。输入cocosnew项目名–p包名–lcpp–d路径回车就创建成功了例如:成功后,找到这个项目打开proj.win32目录下的Hello.slnF5成功了。

  8. 利用cocos2dx 3.2开发消灭星星十为游戏添加音效项目源码分享

    一个游戏,声音也是非常的重要,其实cocos2dx里面的简单音效引擎的使用是非常简单的。我这里只不过是用一个类对所有的音效进行管理罢了。Audio.hAudio.cpp好了,本系列教程到此结束,第一次写教程如有不对请见谅或指教,谢谢大家。最后附上整个项目的源代码点击打开链接

  9. 03 Helloworld

    程序都有一个入口点,在C++就是main函数了,打开main.cpp,代码如下:123456789101112131415161718#include"main.h"#include"AppDelegate.h"#include"cocos2d.h"USING_NS_CC;intAPIENTRY_tWinMain{UNREFERENCED_ParaMETER;UNREFERENCED_ParaMETER;//createtheapplicationinstanceAppDelegateapp;return

  10. MenuItemImage*图标菜单创建注意事项

    学习cocos2dx,看的是cocos2d-x3.x手游开发实例详解,这本书错误一大把,本着探索求知勇于发现错误改正错误的精神,我跟着书上的例子一起调试,当学习到场景切换这个小节的时候,出了个错误,卡了我好几个小时。

返回
顶部