设计模式之命令模式(Command)

xiaoxiao2025-10-24  5

首先感谢《Game.Programming.Patterns(游戏编程模式)》一书,让我对设计模式有了更加全面的理解。

因为书中都是C语言的示例,无奈对C又知之甚少,在此就个人的理解,对书中命令模式章节的示例,尝试用C#写一下,如果有不恰当的地方还希望大家指出~~

先看一下菜鸟教程对命令模式的描述:

实现:键盘输入触发角色行为

--> 键盘输入 --> 发出命令 --> 具体命令执行


定义角色行为命令:

//执行函数“Execute”参数:执行该行为的对象(角色)

//游戏行为基类, 根据需求是否继承MonoBehaviour public abstract class Command { public abstract void Execute(Actor actor); } //具体行为子类 public class FireCommand : Command { public override void Execute(Actor actor) { if (actor == null) return; actor.Fire(); } } //具体行为子类 public class JumpCommand : Command { public override void Execute(Actor actor) { if (actor == null) return; actor.Jump(); } }

//撤销。将每一次单独保存,撤销时还原到上一个行为即可。

//多步撤销,用Stack或List依次保存每次行为,撤销时还原到上一个行为,同时删除当前及以后的行为。

//(另,关于数据结构,Move行为只是为了演示利用命令模式实现撤销操作,使用时还是要考虑实际情况。比如只是撤销角色位置移动,可以把位置信息Vector3用一个Stack或List记录下来,撤销时取上一个位置信息给角色赋值,如果撤销的操作比较多,既有角色位置信息,还有HP、MP等等,这时候就需要用类来记录完整的角色信息了)

public class MoveCommand : Command { Vector3 targetPos; Vector3 beforePos; public MoveCommand(Vector3 moveToPos) { targetPos = moveToPos; beforePos = Vector3.zero; } public override void Execute(Actor actor) { if (actor == null) return; //保存移动之前的位置 beforePos = actor.position; actor.MoveTo(targetPos); } public void MoveBack(Actor actor) { actor.MoveTo(beforePos); } }

定义角色及具体行为表现:

//通过行为命令调用角色函数,再执行具体对象的具体行为

public class Actor { public Vector3 position { get; protected set; } public virtual void Jump() { Debug.Log(GetType().Name + " Jump"); } public virtual void Fire() { Debug.Log(GetType().Name + " Fire"); } public virtual void MoveTo(Vector3 targetPos) { position = targetPos; Debug.Log(GetType().Name + " Move To " + targetPos); } } public class Player01 : Actor { } public class Player02 : Actor { }

按键输入,触发行为:

//自定义按键事件:定义按键(指针),在"InputConfig"函数中,给按键绑定行为(方法),这样在按键输入以后,会自动调用自定义绑定的行为。

//控制多角色,可以随时切换角色,触发当前选择角色的行为

public class InputHandler : MonoBehaviour { //可控制角色 Actor actor01 = new Player01(); Actor actor02 = new Player02(); //当前控制角色 Actor currentActor; //输入按键定义调用函数(命令) Command inputF; Command inputJ; void Start() { //默认角色 currentActor = actor01; //配置输入按键 InputConfig(); } //玩家自定义按键功能: 输入按键 与 执行命令 分开, void InputConfig() { //自定义绑定命令函数 inputF = new FireCommand(); inputJ = new JumpCommand(); } void Update() { //输入处理 if (Input.GetKeyDown(KeyCode.F)) inputF.Execute(currentActor); else if(Input.GetKeyDown(KeyCode.J)) inputJ.Execute(currentActor); //移动 if (Input.GetKeyDown(KeyCode.UpArrow)) new MoveCommand(Vector3.up).Execute(currentActor); else if (Input.GetKeyDown(KeyCode.DownArrow)) new MoveCommand(Vector3.down).Execute(currentActor); //······ //切换控制角色 if (Input.GetKeyDown(KeyCode.Alpha1)) currentActor = actor01; else if (Input.GetKeyDown(KeyCode.Alpha2)) currentActor = actor02; } }

 

转载请注明原文地址: https://www.6miu.com/read-5038436.html

最新回复(0)