Cocos Creator(9)---事件

144 阅读4分钟

监听和发送事件

按钮事件

在iOS中,为按钮添加点击事件的方式为:

[button addTarget:self action: @selector(jk_blockActionTouched:) forControlEvents:UIControlEventTouchUpInside]

在Cocos Creator中,为按钮添加事件的方式 通过on方法

// 添加按钮点击事件 
buttonComponent.node.on(cc.Node.EventType.TOUCH_END, this.buttomActivity, this); 

buttomActivity(button) {
    console.log('按钮被点击了');
}

// 一下四种写法都是正确的
buttonComponent.node.on(cc.Node.EventType.TOUCH_END,this.buttomActivity);
buttonComponent.node.on(cc.Node.EventType.TOUCH_END,this.buttomActivity,this);
buttonComponent.node.on(cc.Node.EventType.TOUCH_END,function (event) {

}, this);
buttonComponent.node.on(cc.Node.EventType.TOUCH_END,function (event) {

});

添加事件,不管是按钮添加事件,还是系统事件监听,通过on的方式 第三个参数可以写,也可以省略。

添加监听(通知)

这个机制类似iOS中的消息通知

1、注册监听事件
2、发送事件
3、移除监听事件

1、注册监听事件 和按钮添加事件类似,都是通过on方法

事件处理是在节点(cc.Node)中完成的。对于组件,可以通过访问节点 this.node 来注册和监听事件。监听事件可以通过 this.node.on() 函数来注册,方法如下:

cc.Class({
  extends: cc.Component,

  properties: {
  },

  onLoad: function () {
    this.node.on('自定义事件名称', function ( event ) {
    // 这里的event 如果发送事件有给参数,event就有数据,否则的话 就是null的
      console.log('Hello!');
    });
  },
});

值得一提的是,事件监听函数 on 可以传第三个参数 target,用于绑定响应函数的调用者。以下两种调用方式,效果上是相同的:

// 使用函数绑定
this.node.on('mousedown', function ( event ) {
  this.enabled = false;
}.bind(this));

// 使用第三个参数
this.node.on('mousedown', function (event) {
  this.enabled = false;
}, this);

除了使用 on 监听,我们还可以使用 once 方法。once 监听在监听函数响应后就会关闭监听事件。

ononce的唯一区别是:
on注册的事件,只要有发送事件,这个就一直会执行,
once注册的事件,只要接收到一次事件,事件就被移除,后续发送的监听都不会被当前节点的监听执行。

关闭监听

添加了监听之后,就需要在合适的时机移除,

移除方法:就是off

this.node.off('自定义事件名称', this._sayHello, this);

添加/移除时机

一般来说,会在生命周期onEnableonDisable 进行添加、移除 比如:

_sayHello: function () { 
    console.log('Hello World'); 
}, 

onEnable: function () { 
    this.node.on('自定义事件名称', this._sayHello, this); 
}, 

onDisable: function () { 
    this.node.off('自定义事件名称', this._sayHello, this); 
},

发射事件

类似iOS的通知事件中的发送通知

发射事件有2种方式

1、发送事件emit

这是常用的一种。

this.node.emit('自定义事件名称', '发送时间的参数''可以有多个参数''最多5个参数');

2、派送事件dispatchEvent

这种用的比较少。 但是需要了解。

dispatchEvent采用冒泡派送的方式。冒泡派送会将事件从事件发起节点,不断地向上传递给它的父级节点,直到到达根节点或者在某个节点的响应函数中做了中断处理

举个例子:

节点结构如下:
ANode                            A节点
   BNode                         A的子节点B
       CNode                     B的子节点C

在C节点上派发事件

// A节点上注册事件
ANode.on('自定义事件名称', function (event) {
    console.log('A');
});

// B节点上注册事件
BNode.on('自定义事件名称', function (event) {
    console.log('B');
    event.stopPropagation();
});

// C节点上注册事件
CNode.on('自定义事件名称', function (event) {
    console.log('C');
});

// 在C节点上派发事件
CNode.dispatchEvent( new cc.Event.EventCustom('自定义事件名称', ture) );

此时的打印会打印:B、C。
A不会被打印,因为在B的节点上进行了阻断event.stopPropagation();

dispatchEvent代码实例

在上面的派发事件中,event的第二个参数为ture,这个表示的是:是否用冒泡的方法向上级节点继续派发。

用代码来实验这个参数

// 子节点属性
    @property({
        type: cc.Node,
    })
    labelNode: cc.Node = null;
    
    
    
    
// 创建节点及子节点
    let buttonNode = new cc.Node;                                   // 创建一个节点(Node)
        // 设置节点的位置和大小
        buttonNode.setPosition(cc.v2(100, 0));
        buttonNode.setContentSize(cc.size(100, 40));

        let buttonComponent = buttonNode.addComponent(cc.Button);       // 节点上加一个button的组件

        // 添加图片组件
        let imageNode = new cc.Node;
        let imageComponent = imageNode.addComponent(cc.Sprite);
        imageNode.parent = buttonNode;

        cc.resources.load("Image/icon2", cc.SpriteFrame, function (err, spriteFrame: cc.SpriteFrame) {
            if (err) {
                console.error('Failed to load image:', err);
                return;
            }
            imageComponent.spriteFrame = spriteFrame;
        });

        // 添加label组件
        let labelNode = new cc.Node('labelNode');
        let labelCompoment = labelNode.addComponent(cc.Label);
        labelCompoment.string = '按钮';
        labelNode.parent = buttonNode;

        // 将button节点加入到父节点
        // this.node.parent.addChild(buttonNode);
        buttonNode.parent = this.node.parent;

// 子节点赋值
        this.labelNode = labelNode;
        
        
        
        
// 向子节点和父节点注册事件
        buttonNode.on('custom', this.custom)
        buttonNode.getChildByName('labelNode').on('custom',this.custom);
    
    
// 延时执行派发事件
        this.scheduleOnce(this.dispatchEvent, 1)
        
        
        
// 派发事件
    dispatchEvent () {
        this.labelNode.dispatchEvent(new cc.Event.EventCustom('custom',ture));
    }

运行这段代码,custom方法执行了2次。
this.labelNode.dispatchEvent(new cc.Event.EventCustom('custom',false)); 参数改为false。custom只执行了一次

系统事件

在监听的事件中,可以是自定义事件,也可以是系统事件

比如:

BNode.on(cc.Node.EventType.MOUSE_DOWN, function (event) {
    console.log('MOUSE_DOWN'); 
});

键盘/重力事件

全局系统事件

键盘

cc.SystemEvent.EventType.KEY_DOWN
cc.SystemEvent.EventType.KEY_UP
cc.SystemEvent.EventType.DEVICEMOTION (设备重力传感)