当前位置: 首页 > news >正文

用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);

相关文章:

  • 【LeetCode刷题笔记】155.最小栈
  • 减速机振动相关标准 - 笔记
  • 鸿蒙HarmonyOS开发用什么语言
  • Python之PyCharm开发工具的安装与设置
  • for命令语句
  • 持久化存储 StorageClass
  • Python爬虫全解析
  • ACT、NAT、NATPT和EASY-IP
  • KafKa基本原理
  • LibreNMS:从docker出发
  • Arduino中以太网Udp通信
  • HarmonyOS NEXT:技术革新与生态挑战的交汇点
  • pytorch——豆瓣读书评价分析
  • 菜鸟学习日记(python)——匿名函数
  • 9. DashBoard
  • 【MySQL经典案例分析】 Waiting for table metadata lock
  • codis proxy处理流程
  • conda常用的命令
  • CSS盒模型深入
  • express如何解决request entity too large问题
  • Javascript基础之Array数组API
  • MQ框架的比较
  • MySQL主从复制读写分离及奇怪的问题
  • SegmentFault 社区上线小程序开发频道,助力小程序开发者生态
  • SQL 难点解决:记录的引用
  • SQLServer之创建数据库快照
  • SQLServer之创建显式事务
  • TypeScript实现数据结构(一)栈,队列,链表
  • vuex 笔记整理
  • webgl (原生)基础入门指南【一】
  • 程序员最讨厌的9句话,你可有补充?
  • 第十八天-企业应用架构模式-基本模式
  • 动态魔术使用DBMS_SQL
  • 关于Java中分层中遇到的一些问题
  • 好的网址,关于.net 4.0 ,vs 2010
  • 将回调地狱按在地上摩擦的Promise
  • 类orAPI - 收藏集 - 掘金
  • 每天一个设计模式之命令模式
  • 移动互联网+智能运营体系搭建=你家有金矿啊!
  • 运行时添加log4j2的appender
  • 策略 : 一文教你成为人工智能(AI)领域专家
  • #我与Java虚拟机的故事#连载10: 如何在阿里、腾讯、百度、及字节跳动等公司面试中脱颖而出...
  • #我与Java虚拟机的故事#连载17:我的Java技术水平有了一个本质的提升
  • $(selector).each()和$.each()的区别
  • $HTTP_POST_VARS['']和$_POST['']的区别
  • (12)Linux 常见的三种进程状态
  • (2)MFC+openGL单文档框架glFrame
  • (Redis使用系列) SpringBoot中Redis的RedisConfig 二
  • (顶刊)一个基于分类代理模型的超多目标优化算法
  • (附源码)springboot教学评价 毕业设计 641310
  • (附源码)ssm跨平台教学系统 毕业设计 280843
  • (三)c52学习之旅-点亮LED灯
  • (三)模仿学习-Action数据的模仿
  • (一)插入排序
  • .bat批处理出现中文乱码的情况