当前位置:   article > 正文

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

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

1、模式标准

模式名称:解析器模式

模式分类:行为型

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

结构图:

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

2、分析与设计

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

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

3、开始打造

表达式接口 

  1. export interface IExpression {
  2. interpret(context: UnitCommandUnitContext): void;
  3. }

 单位表达式及解析方法

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

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

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

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

  1. export class CommandSequenceExpression implements IExpression {
  2. private expressions: IExpression[];
  3. constructor(expressions: IExpression[]) {
  4. this.expressions = expressions;
  5. }
  6. interpret(context: UnitCommandUnitContext): void {
  7. for (const expression of this.expressions) {
  8. expression.interpret(context);
  9. }
  10. context.executeCommand()
  11. }
  12. }

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

  1. // 单位 操作命令 另一个单位 的context
  2. export class UnitCommandUnitContext {
  3. command: ICommand = null
  4. fromUnitItem: UnitItem<any> = null
  5. toUnitItem: UnitItem<any> = null
  6. getUnitItem(unitItemId: string) {
  7. return xhgame.game.battleEntity.model.unitItemMap.get(unitItemId)
  8. }
  9. getCommand(commandId: string) {
  10. // todo 其他补充
  11. return new AttackCommand(null, null)
  12. }
  13. setCommand(command: ICommand) {
  14. this.command = command
  15. }
  16. setUnitItem(unitItem: UnitItem<any>) {
  17. if (this.fromUnitItem == null) {
  18. this.fromUnitItem = unitItem
  19. }
  20. if (this.toUnitItem == null) {
  21. this.toUnitItem = unitItem
  22. }
  23. }
  24. executeCommand() {
  25. if (this.command instanceof AttackCommand) {
  26. this.command.setUnitItem(this.fromUnitItem)
  27. this.command.setTargetUnitItem(this.toUnitItem)
  28. this.command.execute()
  29. }
  30. }
  31. }

 4、开始使用

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/152456
推荐阅读
相关标签
  

闽ICP备14008679号