首先感谢《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;
}
}
本文来自博客园,作者:萧然CS,转载请注明原文链接:https://www.cnblogs.com/z-c-s/p/15112985.html
浙公网安备 33010602011771号