前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[Cocos Creator] 事件监听与发射机制的实现

[Cocos Creator] 事件监听与发射机制的实现

作者头像
陈皮皮
发布2020-07-10 16:42:36
1.1K0
发布2020-07-10 16:42:36
举报
文章被收录于专栏:菜鸟小栈菜鸟小栈

前言

在程序开发中,经常会用到事件监听发射机制,方便在不同的脚本之间传递信息,按需监听,避免了脚本之间过多的关联,提高效率,无形中达到了解耦的效果。

本文将带着大家从 0 实现一个事件监听发射系统,让我们开始吧。

正文

整体思路

  • 事件容器:首先我们需要一个容器来装各种不同的事件且每种事件都可以有多个 订阅 ,所谓 订阅 是我们自定义的一种数据结构(实质为对象),包含一个回调(即要做的事情)和一个对象(即做事情的人)。
  • 监听逻辑:给指定的事件添加一个 订阅
  • 发射逻辑:遍历指定事件的所有订阅并且执行他们的回调。
  • 取消监听逻辑:遍历指定事件的所有订阅,将对应的订阅移除。
  • 移除事件逻辑:移除指定事件和其订阅 。

代码实现

提示:点击文章底部 阅读原文 即可获取完整文件

1. 定义 订阅 ISubscription 的结构:

interface ISubscription {
    callback: Function;
    object: any;
}

2. 定义 事件容器 IEvents 的结构(key 为字符串类型的事件名,value 则为 订阅 类型的数组):

interface IEvents {
    [event: string]: ISubscription[];
}

3. 定义 GameEvent 类和 事件容器 类型的变量:

export class GameEvent {
    private static events: IEvents = {};
}

4. 实现监听函数 on ,需要传入的参数为事件名回调调用对象(可选,当回调为箭头函数时可以不传入此参数);当容器中不存在目标事件时,需先创建事件,这里我没有进行重复检测,有需要可以自行加入:

/**
 * 监听事件
 * @param event 事件名
 * @param callback 回调
 * @param object 监听对象
 */
public static on(event: string, callback: Function, object?: any) {
    if (!this.events[event]) this.events[event] = [];
    this.events[event].push({ callback, object });
}

5. 实现发射函数 emit ,需要传入的参数为事件名以及若干参数;没有目标事件直接返回,否则遍历所有订阅并调用:

/**
 * 发射事件
 * @param event 事件名
 * @param args 参数
 */
public static emit(event: string, ...args: any[]) {
    if (!this.events[event]) return;
    for (let i = 0; i < this.events[event].length; i++) {
        this.events[event][i].callback.apply(this.events[event][i].object, args);
    }
}

6. 实现取消监听函数 off ,需传入与函数 on 同样的参数;存在目标事件时遍历所有订阅,除去相应订阅:

/**
 * 取消监听事件
 * @param event 事件名
 * @param callback 回调
 * @param object 监听对象
 */
public static off(event: string, callback: Function, object?: any) {
    if (!this.events[event]) return;
    for (let i = 0; i < this.events[event].length; i++) {
        if (this.events[event][i].callback === callback && (!object || this.events[event][i].object === object)) {
            this.events[event].splice(i, 1);
            i--;
        }
    }
}

7. 实现清除事件函数 remove :

/**
 * 移除事件
 * @param event 事件名
 */
public static remove(event: string) {
    if (this.events[event]) delete this.events[event];
}

8. 另外还可以实现一次性的监听事件 once ,只需在调用一次后移除即可,具体逻辑本文不再赘述。

使用示例

import { GameEvent } from "../../eazax-ccc/core/GameEvent";

const { ccclass, property } = cc._decorator;

@ccclass
export default class Test extends cc.Component {

    onLoad() {
        // 监听事件
        GameEvent.on('init', this.init, this);
        GameEvent.on('init', (param: any) => { this.init(param) });
        // 发射事件
        GameEvent.emit('init', 666);
    }

    private init(param: any) {
        cc.log(param);
    }

    onDestroy() {
        // 取消监听
        GameEvent.off('init', this.init, this);
        GameEvent.off('init', (param: any) => { this.init(param) });
        // 清除事件
        GameEvent.remove('init');
    }
}

结束语

以上皆为本菜鸡的个人观点,文采实在不太好,如果写得不好还请各位见谅。如果有哪些地方说的不对,还请各位指出,大家共同进步。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-04-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 菜鸟小栈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档