详解CocosCreator消息分发机制

概述

本篇开始介绍游戏业务架构相关的内容。在游戏业务层,所有需要隔离的系统和模块间通信都可以通过消息分发解耦。例如网络返回通知、数据更新同步到界面等。

消息分发基于观察者模式设计。需要处理消息的地方向消息中心注册监听回调,派发消息时,调用消息中心的派发接口遍历该消息的监听队列,调用对应的回调方法。

具体方案

先定义监听回调类型

/**
 * 消息监听回调方法
 */
export type NotifyListener = (src: any, data: any) => void;

通过key-value方式保存监听队列

private static msg2listDict: Dictionary< string, Array<NotifyListenerInfo> > = new Dictionary< string, Array<NotifyListenerInfo> >();

接口定义

/**
 * 添加多次监听者,需要手动移除
 * @param msg
 * @param listener
 * @param target
 */
public static addListener(msg: string, listener: NotifyListener, target?: any): void {}

/**
 * 添加单次监听者,事件触发后即移除
 * @param msg
 * @param listener
 * @param target
 */
public static addOnceListener(msg: string, listener: NotifyListener, target?: any): void {}

/**
 * 移除指定消息指定的监听者
 * @param msg
 * @param listener
 */
public static removeMsgListener(msg: string, listener: NotifyListener): void {}

/**
 * 移除指定消息所有监听者
 * @param msg
 */
public static removeMsgAllListeners(msg: string): void {}

/**
 * 移除指定目标对指定消息的监听
 * @param msg
 * @param target
 */
public static removeTargetMsgListen(msg: string, target: any): void {}

/**
 * 移除指定目标所有消息监听
 * @param target
 */
public static removeTargetAllMsgListen(target: any): void {}

/**
 * 派发消息
 * @param msg
 * @param src
 * @param data
 */
public static notify(msg: string, src: any, data: any): void {}

在添加移除实现中,需要注意某消息可能正在派发。

对于一个消息新添加的监听者,应该在当前队列消息派发完后再派发,因此,添加一个待添加队列

private static listener2add: Array<NotifyListenerInfo> = [];

在添加监听者时做以下判断

// 该消息正在派发,放入待添加队列
if (NotifyCenter.notifyMsgs.indexOf(msg) >= 0) {
    NotifyCenter.listener2add.push(info);
    return;
}

同样在移除监听者时,可能正在派发消息,避免对队列的修改导致for循环异常,添加一个待移除队列,派发消息时,如果该监听者在移除队列则不派发。在消息派发完后再将其移出队列

private static listener2remove: Array<NotifyListenerInfo> = [];

在移除监听者时做以下判断

// 该消息正在派发,放入待移除队列
if (NotifyCenter.notifyMsgs.indexOf(msg) >= 0) {
    NotifyCenter.listener2remove.push(list[i]);
} else {
    list.splice(i, 1);
}

派发消息时遍历指定消息下的队列

// 队列不存在,不需要处理
let list = NotifyCenter.msg2listDict.get(msg);
if (!list) {
    return;
}

// 标记消息正在派发,多个消息可能同时在派发,同一消息可能标记多次
NotifyCenter.notifyMsgs.push(msg);

// 处理消息派发
for (let i = 0, n = list.length; i < n; i++) {
    NotifyCenter._dispatch(list[i], src, data, false);
}

派发消息时先判断是否在移除队列

// 在移除队列,不派发
if (NotifyCenter.listener2remove.indexOf(info) >= 0) {
    return;
}

当前队列派发完后检查待添加队列

// 处理待添加队列派发
for (let i = 0, n = msg2add.length; i < n; i++) {
    if (listener2add[i].msg == msg) {
        NotifyCenter._dispatch(listener2add[i], src, data, true);
    }
}

引入消息分发中心,隔离的系统、模块间通过消息监听和派发通信,避免互相引用耦合。

以上就是详解CocosCreator消息分发机制的详细内容,更多关于CocosCreator消息分发的资料请关注我们其它相关文章!

(0)

相关推荐

  • 剖析CocosCreator新资源管理系统

    1.资源与构建 1.1 creator资源文件基础 在了解引擎如何解析.加载资源之前,我们先来了解一下这些资源文件(图片.Prefab.动画等)的规则,在creator项目目录下有几个与资源相关的目录: assets 所有资源的总目录,对应creator编辑器的资源管理器 library 本地资源库,预览项目时使用的目录 build 构建后的项目默认目录 在assets目录下,creator会为每个资源文件和目录生成一个同名的.meta文件,meta文件是一个json文件,记录了资源的版本.uu

  • CocosCreator通用框架设计之资源管理

    如果你想使用Cocos Creator制作一些规模稍大的游戏,那么资源管理是必须解决的问题,随着游戏的进行,你可能会发现游戏的内存占用只升不降,哪怕你当前只用到了极少的资源,并且有使用cc.loader.release来释放之前加载的资源,但之前使用过的大部分资源都会留在内存中!为什么会这样呢? cocos creator 资源管理存在的问题 资源管理主要解决3个问题,资源加载,资源查找(使用),资源释放.这里要讨论的主要是资源释放的问题,这个问题看上去非常简单,在Cocos2d-x中确实也很简

  • 在vue.js中使用JSZip实现在前端解压文件的方法

    1. 在vue文件的html中引入element的上传控件,代码如下: <div> <el-upload action="//jsonplaceholder.typicode.com/posts/" :before-upload="handleBefore"> <el-button size="small" type="primary">点击上传</el-button> <

  • 解读CocosCreator源码之引擎启动与主循环

    前言 预备 不知道你有没有想过,假如把游戏世界比作一辆汽车,那么这辆"汽车"是如何启动,又是如何持续运转的呢? 如题,本文的内容主要为 Cocos Creator 引擎的启动流程和主循环. 而在主循环的内容中还会涉及到:组件的生命周期和计时器.缓动系统.动画系统和物理系统等... 本文会在宏观上为大家解读主循环与各个模块之间的关系,对于各个模块也会简单介绍,但不会深入到模块的具体实现. 因为如果把每个模块都"摸"一遍,那这篇文章怕是写不完了. Go! 希望大家看完这

  • 如何在CocosCreator中使用JSZip压缩

    CocosCreator版本:2.4.2 jszip的实际项目应用 游戏中有大量配置的情况下,文件会变得非常大,所以有些游戏会采用zip包压缩解压 例如如下游戏,将游戏配置config.json压缩成zip包,加载后进行解压使用 拿到他的配置压缩包 将.bin改成.zip,进行解压,得到游戏的所有json配置文件 未压缩之前6M+ 压缩后文件 500KB+,压缩后小了10倍左右. 在cocos中使用jszip 首先,在github上下载jszip库  https://github.com/Stu

  • CocosCreator骨骼动画之龙骨DragonBones

    CocosCreator版本2.3.4 龙骨动画 将龙骨动画放到cocos的assets下.我这里龙骨动画是Dragonbones导出的二进制动画. 直接拖拽龙骨动画(骨头图标)到舞台 设置骨骼动画的属性,DragonAltasAsset图片,Animation动作,PlayTime循环播放等 代码生成龙骨动画 龙骨资源路径是assets/resources/dragonbones,loadResDir只需要填dragonbones就行了. //根据路径加载资源 cc.loader.loadRe

  • 详解CocosCreator MVC架构

    概述 这一篇将介绍在游戏客户端常用的架构MVC架构.一个游戏的MVC如下划分: M:1)单例全局的数据中心World,所有游戏模块的数据在World中有入口,2)各个模块自己的数据结构. V:1)通过creator预制体制作的UI界面.场景,2)各个界面显示逻辑的ViewCtrl C:1)全局的MainCtrl,2)各个模块的业务逻辑类ModuleCtrl 具体模块 先介绍M部分.由于一个模块的数据,在其他模块也有访问的需求,例如好友模块,在聊天的时候也需要访问,在排行榜里需要访问.数据应该有一

  • 如何在CocosCreator中做一个List

    CocosCreator版本:2.3.4 cocos没有List组件,所以要自己写.从cocos的example项目中找到assets/case/02_ui/05_listView的demo来改造. 自写一个虚拟列表,有垂直布局,水平布局,网格布局和Padding的List Demo地址:https://files-cdn.cnblogs.com/files/gamedaybyday/cocos2.3.4_ListViewDemo_Grid.7z cocos原来的LayOut做列表,有100个数

  • 如何在CocosCreator里画个炫酷的雷达图

    前言 雷达图(Radar Chart) 也称为网络图.星图或蜘蛛网图. 是以从同一点开始的轴上表示的三个或更多个定量变量的二维图表的形式显示多元数据的图形方法. 适用于显示三个或更多的维度的变量. 雷达图常用于

  • 详解CocosCreator消息分发机制

    概述 本篇开始介绍游戏业务架构相关的内容.在游戏业务层,所有需要隔离的系统和模块间通信都可以通过消息分发解耦.例如网络返回通知.数据更新同步到界面等. 消息分发基于观察者模式设计.需要处理消息的地方向消息中心注册监听回调,派发消息时,调用消息中心的派发接口遍历该消息的监听队列,调用对应的回调方法. 具体方案 先定义监听回调类型 /** * 消息监听回调方法 */ export type NotifyListener = (src: any, data: any) => void; 通过key-v

  • 详解CocosCreator项目结构机制

     一.项目文件夹结构 初次创建并打开一个 Cocos Creator 项目后,开发者的项目文件夹将会包括以下结构: 下面我们将会介绍每个文件夹的功能. 1.资源文件夹(assets) assets 将会用来放置游戏中所有的本地资源.脚本和第三方库文件.只有在 assets 目录下的内容才能显示在 资源管理器 中.assets 中的每个文件在导入项目后都会生成一个相同名字的 .meta 文件,用于存储对应的资源配置和索引信息..meta 文件需要一并提交到版本控制系统,详见 资源管理注意事项 --

  • 详解JavaScript 的执行机制

    一.关于javascript javascript是一门单线程语言,在最新的HTML5中提出了Web Worker,但javascript是单线程这一核心仍未改变. 为什么js是单线程的语言?因为最初的js是用来在浏览器验证表单操纵DOM元素的.如果js是多线程的话,两个线程同时对一个DOM进行了相互冲突的操作,那么浏览器的解析是无法执行的. Web Worker 的作用,就是为 JavaScript 创造多线程环境,允许主线程创建 Worker 线程,将一些任务分配给后者运行.在主线程运行的同

  • 详解CocosCreator系统事件是怎么产生及触发的

    环境 Cocos Creator 2.4 Chrome 88 概要 模块作用 事件监听机制应该是所有游戏都必不可少的内容.不管是按钮的点击还是物体的拖动,都少不了事件的监听与分发. 主要的功能还是通过节点的on/once函数,对系统事件(如触摸.点击)进行监听,随后触发对应的游戏逻辑.同时,也支持用户发射/监听自定义的事件,这方面可以看一下官方文档监听和发射事件. 涉及文件 其中,CCGame和CCInputManager都有涉及注册事件,但他们负责的是不同的部分. 源码解析 事件是怎么(从浏览

  • 详解CocosCreator制作射击游戏

    场景布置 游戏资源 炮塔旋转 机制与之前手柄实例的小车相同,使用touchmove监听触摸事件, 获取触摸位置 通过位置用signAngle方法将该位置与cc.v2(1,0)位置的角度差求出(记得要加负号,比较所得逆时针为负,赋值angle逆指针为正). 所求的的角度即为最终角度. onLoad(){ //初始化为90度 this.node.angle=90; this.node.on('touchstart',this.onTouchStart,this); this.node.on('tou

  • 详解进程同步与互斥机制

    目录 一.什么是进程同步 二.什么是进程互斥 三.常见的进程同步与互斥机制 一.什么是进程同步 在多道批处理系统中,多个进程是可以并发执行的,但由于系统的资源有限,进程的执行不是一贯到底的, 而是走走停停,以不可预知的速度向前推进,这就是进程的异步性. 那么,进程的异步性会带来什么问题呢?举个例子,如果有 A.B 两个进程分别负责读和写数据的操作,这两个线程是相互合作.相互依赖的.那么写数据应该发生在读数据之前.而实际上,由于异步性的存在,可能会发生先读后写的情况,而此时由于缓冲区还没有被写入数

  • Java 详解异常的处理机制

    目录 1.异常概述与异常体系结构 1.1异常概述 1.2运行时异常与编译时异常 1.3异常体系结构 2.常见异常 1. ArrayIndexOutOfBoundsException 2.NullPointerException 3.ArithmeticException 4.ClassCastException 3.异常处理机制 3.1异常的抛出与捕获 3.2异常处理机制:try-catch-finally 5.用户自定义异常类 6.异常处理5个关键字 1.异常概述与异常体系结构 1.1异常概述

  • 详解Spring的核心机制依赖注入

    详解Spring的核心机制依赖注入 对于一般的Java项目,他们都或多或少有一种依赖型的关系,也就是由一些互相协作的对象构成的.Spring把这种互相协作的关系称为依赖关系.如A组件调用B组件的方法,可称A组件依赖于B组件,依赖注入让Spring的Bean以配置文件组织在一起,而不是以硬编码的方式耦合在一起 一.理解依赖注入 依赖注入(Dependency Injection) = 控制反转(Inversion ofControl,IoC):当某个Java实例(调用者)需另一个Java实例(被调

  • 详解struts2的token机制和cookie来防止表单重复提交

    详解struts2的token机制和cookie来防止表单重复提交 今天在做一个投票系统时要实现防止表单重复提交! 当时就想到了用struts2提供的token机制 struts2的token机制防止表单重复提交: 首先需要在提交的jsp页面(要使用token机制,必须使用struts2提供的标签库)加上 <s:token></s:token> 这段代码,然后在struts.xml里面需要进行如下配置: <action name="token" class

随机推荐