用23种设计模式打造一个cocos creator的游戏框架----(二十)解析器模式

1、模式标准

模式名称:解析器模式

模式分类:行为型

模式意图:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。

结构图:

适用于:
当有一个语言需要解释执行,并且可将该语言中的句子表示为一个抽象语法树时,以下情况效果最好:
1、该文法简单。对于复杂的发文,文法的类层次变得庞大而无法管理。此时语法分析程序生成器这样的工具是更好的选择。它们无须构建抽象语法树即可解释表达式,这样可以节省空间还可能节省时间。
2、效率不是一个关键问题。最高效的解释器通常不是通过直接解释语法分析树实现的,而是首先将它们转换成另一种形式。不过,即使在这种情况下,转换器仍然可用该模式实现。 

2、分析与设计

这里假设我们希望以文本的方式记录游戏命令过程比如:[[UnitItem]]{{attack}}[[UnitItem]] ,类似这种[[单位]]{{命令}}为格式,然后通过解析器解析成实际的命令

意图:给定一个语言(命令备忘录语言),定义它的文法的一种表示([[单位]]{{命令}}),并定义一个解释器,这个解释器使用该表示来解释语言中的句子。

3、开始打造

表达式接口 

export interface IExpression {interpret(context: UnitCommandUnitContext): void;
}

 单位表达式及解析方法

export class UnitItemExpression implements IExpression {private unitItemId: string;constructor(unitItemId: string) {this.unitItemId = unitItemId;}interpret(context: UnitCommandUnitContext): void {// 执行与终结符相关的解释操作let unitItem = context.getUnitItem(this.unitItemId)console.log("解析到单位项:", unitItem);context.setUnitItem(unitItem)}
}

 “命令”表达式及解析方法

export class CommandExpression implements IExpression {private commandId: string;constructor(commandId: string) {this.commandId = commandId;}interpret(context: UnitCommandUnitContext): void {// 执行与终结符相关的解释操作let command = context.getCommand(this.commandId)console.log("解析到命令:", command);context.setCommand(command);}
}

“遍历解析”表达式及解析方法

export class CommandSequenceExpression implements IExpression {private expressions: IExpression[];constructor(expressions: IExpression[]) {this.expressions = expressions;}interpret(context: UnitCommandUnitContext): void {for (const expression of this.expressions) {expression.interpret(context);}context.executeCommand()}
}

 单位 操作命令 另一个单位 的context

// 单位 操作命令 另一个单位 的context
export class UnitCommandUnitContext {command: ICommand = nullfromUnitItem: UnitItem<any> = nulltoUnitItem: UnitItem<any> = nullgetUnitItem(unitItemId: string) {return xhgame.game.battleEntity.model.unitItemMap.get(unitItemId)}getCommand(commandId: string) {// todo 其他补充return new AttackCommand(null, null)}setCommand(command: ICommand) {this.command = command}setUnitItem(unitItem: UnitItem<any>) {if (this.fromUnitItem == null) {this.fromUnitItem = unitItem}if (this.toUnitItem == null) {this.toUnitItem = unitItem}}executeCommand() {if (this.command instanceof AttackCommand) {this.command.setUnitItem(this.fromUnitItem)this.command.setTargetUnitItem(this.toUnitItem)this.command.execute()}}
}

 4、开始使用

// 创建一个 单位 操作命令 另一个单位的上下文
const unitCommandUnitContext = new UnitCommandUnitContext();
// 解析文本为 UnitItem.20 的单位对 UnitItem.21 的单位发动攻击
// 目前为了后期拓展下列以:[[单位]]{{命令}}为格式
const commandText = "[[UnitItem.20]]{{attack}}[[UnitItem.21]]";
// 构建抽象语法树
const expressions: IExpression[] = [];
const regex = /\[\[([^\]]+)\]\]|\{\{([^\}]+)\}\}|\[\{([^\}]+)\}\]|\[<([^\>]+)>\]/g;
let match;
while ((match = regex.exec(commandText)) !== null) {console.log(match)const token = match[0];const unitItemId = match[1]; // 捕获组1中的内容为单位项IDconst commandId = match[2]; // 捕获组2中的内容为命令IDif (unitItemId !== undefined) {expressions.push(new UnitItemExpression(unitItemId));} else if (commandId !== undefined) {expressions.push(new CommandExpression(commandId));}
}
console.log('expressions', expressions)
// “遍历解析”表达式
const commandSequence = new CommandSequenceExpression(expressions);
commandSequence.interpret(unitCommandUnitContext);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/285087.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

02-knative-serving部署

示例环境 Kubernetes: v1.27.1Knative: v1.12networking layer: istio 可用的部署方式 基于YAML配置文档直接部署 Serving和Eventing需要分别进行部署 借助Knative Operator进行部署 首先部署Knative Operator通过Operator的KnativeServing部署Serving通过Operator的KnativeEv…

福德植保无人机工厂:创新科技与绿色农业的完美结合

亲爱的读者们&#xff0c;欢迎来到福德植保无人机工厂的世界。这里&#xff0c;科技与农业的完美结合为我们描绘出一幅未来农业的新篇章。福德植保无人机工厂作为行业的领军者&#xff0c;以其领先的无人机技术&#xff0c;创新的理念&#xff0c;为我们展示了一种全新的农业服…

在openSUSE-Leap-15.5-DVD-x86_64中使用deepin-wine-6.0.0.62再使用微信3.9.5

在openSUSE-Leap-15.5-DVD-x86_64中使用deepin-wine-6.0.0.62再使用微信3.9.5 参考文章&#xff1a; 《记录-下fedora 33安装deepin qq和微信 &#xff0c;不需要安装deepinwine》 https://tieba.baidu.com/p/7279470269 《opensuse使用virtualbox安装win10》 https://blog.c…

Linux---编辑器 vim

1. vim 的介绍 vim 是一款功能强大的文本编辑器&#xff0c;也是早年 Vi 编辑器的加强版&#xff0c;它的最大特色就是使用命令进行编辑&#xff0c;完全脱离了鼠标的操作。 2. vim 的工作模式 命令模式编辑模式末行模式 说明: vim 打开文件进入的是命令模式 工作模式效果…

Axure情形动作篇(ERP登录效验)

目录 一、ERP系统用户登录效验 1.1 完成步骤 1.2 最终效果 二、省市区联动 三、ERP菜单栏页面跳转 四、下拉加载效果实现 4.1 加载动画实现步骤 4.2 下划界面加载实现 4.3 最终效果 一、ERP系统用户登录效验 1.1 完成步骤 首先搭建ERP系统的登录界面&#xff08;输入…

Kafka 数据乱序

每个broker队列最多能缓存5个没有应答的请求&#xff1a; 发送数据1&#xff0c;2&#xff0c;3&#xff0c;4&#xff0c;5。发送到3的时候没有应答成功&#xff0c;要重发&#xff0c;结果4先过来了&#xff0c;就导致乱序。 解决&#xff1a;开启幂等性 max.in.flight.req…

lua语法

lua语法 1.lua数据类型 lua 脚本输出乱码&#xff0c;将lua脚本改为UTF-8编码&#xff0c;并且需要DOS下修改代码页&#xff1a;CHCP 65001 即可。 基本语法 注释 print("script lua win")-- 单行注释--[[多行注释]]--标识符 类似于&#xff1a;java当中 变量、…

05_Web框架之Django二

Web框架之Django二 学习目标和内容 1、能够使用类视图的写法 2、能够使用模板语言的相关语法 3、能够理解过滤器的作用 4、能够理解并使用模板继承 一、类视图 1、类视图介绍 视图是一个可调用的对象&#xff0c;它接收一个请求然后返回一个响应&#xff0c;这个可调用对象可…

jieba-fenci 结巴分词原理讲解 segment

拓展阅读 DFA 算法详解 为了便于大家学习&#xff0c;项目开源地址如下&#xff0c;欢迎 forkstar 鼓励一下老马~ 敏感词 sensitive-word 分词 segment 分词的必要性 我们平时做文本分析&#xff0c;或者我个人想做一个繁简体转换/同义词替换等工具&#xff0c;分词都是必须…

13.FTP

FTP FTP配置 添加一个本地用户 设置个密码 服务类型是FTP 工作路径授权给用户 设置用户角色为网络管理员 开启FTP服务 R2的路径下有这些文件 在R1进行测试&#xff0c;输入刚才创建的用户密码 get 获取文件 put上传文件 也可以在PC进行访问 可以升级路由器系…

超级计算机与天气预报:精准预测的科技革命

超级计算机与天气预报&#xff1a;精准预测的科技革命 一、引言 随着科技的飞速发展&#xff0c;超级计算机已经成为现代社会不可或缺的一部分。它们在科研、工业、军事等领域发挥着重要作用&#xff0c;其中天气预报是一个颇具代表性的应用领域。本文将探讨超级计算机在天气…

MongoDB中的关系

本文主要介绍MongoDB中的关系。 目录 MongoDB的关系嵌入关系引用关系 MongoDB的关系 MongoDB是一个非关系型数据库&#xff0c;它使用了键值对的方式来存储数据。因此&#xff0c;MongoDB没有像传统关系型数据库中那样的表、行和列的概念。相反&#xff0c;MongoDB中的关系是通…