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

设计模式学习-简单的命令模式例子

上一章节介绍过了命令模式,这一篇文章就简单的做一个小案例来巩固学习

搭建场景

简单的搭建一个场景就行 ,随便准备一个物体放在场景中位置Reset一下即可。
在这里插入图片描述

代码编写
  1. 定义接口(或者抽象类)ICommand 用来规范Command的行为。注意在命令模式中命令是桥接作用负责接受者和执行者之间的联调。所以一般会有很多的命令,每个命令都会有ICommand规范的方法同时也可以添加其他的方法。
public interface ICommand{void Execute();void UnExecute();
}
  1. 实现定义的接口(或者抽象类) 同时为了具有这种桥接的作用,MyCommand 需要持有Receiver
public enum Direction{Left,Down,Right,Up
}
public class MyCommand : ICommand{private Receiver _receiver;private Direction _direction;private GameObject _moveObj;private float _distance;public MyCommand(Direction direction,Receiver receiver,GameObject moveObj,float distance){this._receiver = receiver;this._direction = direction;this._moveObj = moveObj;this._distance = distance;}public void Execute(){_receiver.OperationDirection(_moveObj,_direction,_distance );}public void UnExecute(){_receiver.OperationDirection(_moveObj,InverseDirection(_direction),_distance );}private Direction InverseDirection(Direction direction){switch(direction){case Direction.Left:return Direction.Right;case Direction.Right:return Direction.Left;case Direction.Up:return Direction.Down;case Direction.Down:return Direction.Up;}}public override void ToString(){return $"{_moveObj.name}:{DirectionStr(_direction)}:{_distance.ToString()}";}private string DirectionStr(Direction dircteion) {switch (dircteion) { case Direction.Left:return "Left";case Direction.Right:return "Right";case Direction.Up:return "Up";case Direction.Down:return "Down";default:return default;}
}
}

3.接受者,接受者的意思是接受命令执行自身的函数

public class Receiver{public void OperationDirection(GameObject moveObj,Direction direction,float distance){switch(direction){case Direction.Left:MoveX(moveObj,-distance);break;case Direction.Right:MoveX(moveObj,distance);break;case Direction.Up:MoveY(moveObj,distance);break;case Direction.Up:MoveY(moveObj,-distance);break;}}private void MoveX(GameObject moveObj,float distance){var tempPos = moveObj.transform.position;tempPos .x+=distance;moveObj.transform.position = tempPos;}private void MoveY(GameObject moveObj,float distance){var tempPos = moveObj.transform.position;tempPos.y+=distance;moveObj.transform.position = tempPos;}
}

4.执行者,挂载在场景中的任意物体上(建议放空物体上)负责代码的执行 调度

public class InputHandler : MonoBehaviour{private Receiver _receiver;[SerializeField][Tooltip("移动距离")]private float distance = 1f;private List<ICommand> commands = new List<ICommand>(); // 存储命令方便回溯private int currentCommandNum = 0;  // 当前执行的命令public GameObject moveObj;  //控制的物体上面的那个Move直接拖到这里进行绑定 private void Start(){_receiver= new Receiver();// 空处理 可写可不写}private void Move(Direction direction){var command = new MyCommand(direction,_receiver,moveObj,distance);command.Execute();commands.Add(command);currentCommandNum++;}private void Undo(){if(currentCommandNum > 0 ){currentCommandNum--;MyCommand command= (MyCommand )commands[currentCommandNum];command.UnExecute();}}private void Redo(){if (currentCommandNum < commands.Count) { MyCommand command= (MyCommand )commands[currentCommandNum];currentCommandNum++;command.Execute();}}void OnGUI(){string label = "   start";if (currentCommandNum == 0){label = ">" + label;}label += "\n";for (int i = 0; i < commands.Count; i++){if (i == currentCommandNum - 1)label += "> " + commands[i].ToString() + "\n";elselabel += "   " + commands[i].ToString() + "\n";}GUI.Label(new Rect(0, 0, 400, 800), label);}private void Update(){if (Input.GetKeyDown(KeyCode.UpArrow)|| Input.GetKeyDown(KeyCode.W)) { moveUp(); }if (Input.GetKeyDown(KeyCode.DownArrow) || Input.GetKeyDown(KeyCode.S)) { moveDown(); }if (Input.GetKeyDown(KeyCode.LeftArrow) || Input.GetKeyDown(KeyCode.A)){ moveLeft(); }if (Input.GetKeyDown(KeyCode.RightArrow) || Input.GetKeyDown(KeyCode.D)) { moveRight(); }if (Input.GetKeyDown(KeyCode.R)){ Redo(); }if (Input.GetKeyDown(KeyCode.U)){ Undo(); }}void moveUp() { Move(Direction.Up); }void moveDown() { Move(Direction.Down); }void moveLeft() {  Move(Direction.Left); }void moveRight() { Move(Direction.Right); }
}

现在就基本上已经做完了,是一个很简单的案例用来巩固学习命令模式

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • AI科学家:自动化科研的未来之路
  • S3C2440开发板:时钟,PWM定时器控制蜂鸣器发声
  • 小白遇上字符串解析问题,正则和原生字符串函数谁来救场?
  • 双绞线如何抑制传导干扰
  • DigitalOcean Kubernetes引入NVIDIA H100 GPU,助力 AI/ML 创新
  • 第R2周:LSTM-火灾温度预测
  • Java使用POI创建带样式和公式的Excel文件
  • 区块链Hyperledger Fabric2.2 环境搭建
  • OpenCV 旋转矩形边界
  • 2.ChatGPT的发展历程:从GPT-1到GPT-4(2/10)
  • 【FFMPEG】Install FFmpeg CUDA gltransition in Ubuntu
  • linux颜色
  • hadoop的sbin
  • 2.第二阶段x86游戏实战2-认识进制、理解数据宽度和位的概念
  • 智能提醒助理系列-小程序静默登录
  • ES6指北【2】—— 箭头函数
  • 《用数据讲故事》作者Cole N. Knaflic:消除一切无效的图表
  • Angular2开发踩坑系列-生产环境编译
  • Angular数据绑定机制
  • django开发-定时任务的使用
  • ES2017异步函数现已正式可用
  • es6(二):字符串的扩展
  • express.js的介绍及使用
  • golang中接口赋值与方法集
  • iOS 颜色设置看我就够了
  • javascript 哈希表
  • Java多态
  • Java-详解HashMap
  • Js基础知识(一) - 变量
  • Python进阶细节
  • 构建二叉树进行数值数组的去重及优化
  • 函数式编程与面向对象编程[4]:Scala的类型关联Type Alias
  • 基于Volley网络库实现加载多种网络图片(包括GIF动态图片、圆形图片、普通图片)...
  • 将回调地狱按在地上摩擦的Promise
  • 开年巨制!千人千面回放技术让你“看到”Flutter用户侧问题
  • 前端每日实战:70# 视频演示如何用纯 CSS 创作一只徘徊的果冻怪兽
  • 前端学习笔记之观察者模式
  • 人脸识别最新开发经验demo
  • 设计模式(12)迭代器模式(讲解+应用)
  • 责任链模式的两种实现
  • 分布式关系型数据库服务 DRDS 支持显示的 Prepare 及逻辑库锁功能等多项能力 ...
  • #[Composer学习笔记]Part1:安装composer并通过composer创建一个项目
  • #调用传感器数据_Flink使用函数之监控传感器温度上升提醒
  • %3cli%3e连接html页面,html+canvas实现屏幕截取
  • (翻译)Quartz官方教程——第一课:Quartz入门
  • (附源码)python旅游推荐系统 毕业设计 250623
  • (附源码)springboot美食分享系统 毕业设计 612231
  • (附源码)ssm考生评分系统 毕业设计 071114
  • (南京观海微电子)——示波器使用介绍
  • (生成器)yield与(迭代器)generator
  • (十二)Flink Table API
  • (转)3D模板阴影原理
  • (转)Android学习笔记 --- android任务栈和启动模式
  • .NET Core MongoDB数据仓储和工作单元模式封装
  • .Net Core 生成管理员权限的应用程序