此类型的博客的写作初衷在于,整理自己平时所学的知识,随时欢迎各路大神指正
//绿色字的内容为注释
什么时候使用状态模式/状态模式有什么用?1.一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为。
2.一个操作中含有庞大的多分支结构,并且这些分支决定于对象的状态。(360百科)
当你希望用户(玩家)
使用相同的操作方式/*都是释放前冲攻击*/(调用相同的函数名,但实际会因当前的状态不同,使用的是不同的函数,或者说函数调用的方式不变),
游戏或者程序会产生不同的操作响应时就可以使用状态模式;
想写一个状态模式的基本框架很简单,我们只需要写三部分(三种类型的类)的内容
1、Context(状态的拥有者:战斗法师)
2、IState(抽象状态类/抽象状态模板,定义了前冲攻击这个技能,但并不会写出具体的实现方法/*通常是虚方法*/,通常会使用abstract抽象类去写,也可以使用接口Instance,或者普通类class)
3、继承IState的具体状态类(通常有多个 这个类override重写了前冲攻击这个技能的技能效果)
(1)State战斗法师(战斗法师使用手中的武器敲击敌方的头部;)
(2)State贝亚娜斗神(战斗法师使用手中矛形的武器突刺对方;)
这三部分拆分开来讲:
Context状态的拥有者只需要写3条内容:
1、存放IState类的字段//用来存放当前状态,和下面类似
2、SetState(IState)方法//用来设置当前状态,和下面类似/给上面的一条赋值
3、Requast()//可以同时写多个这种类型的方法,方法内部,放入对应的状态框架中的方法,像什么Update()方法,Enable()方法等专门给外界调用的方法,是子状态中的方法与外界交流的唯一出口
public class Context { /// <summary> /// 用来保存当前状态 /// </summary> protected State state; /// <summary> /// 给外界调用的设置状态方法 /// </summary> /// <param name="state"></param> public void SetState(State state) { this.state = state; } /// <summary> /// 使用状态模式的方法,通过这个可以间接的转换状态 /// </summary> /// <param name="var"></param> public void Request(int var) { state.Headle(var); } }IState状态的框架也同样有3样东西:
1、存放Context类的字段//用来方便子状态使用,和上面类似:如 切换状态
2、自身的构造函数//用来给Context赋值,和上面类似/给上面一条赋值
3、留给子状态继承并重写的所有抽象方法//和上面一样,也不限于一个方法
public abstract class State { /// <summary> /// 状态中保存有当前状态的拥有者 /// </summary> protected Context context; /// <summary> /// 想创建一个State 必须new一个此状态的拥有者,没有拥有者哪来的状态 /// </summary> /// <param name="context"></param> public State(Context context) { this.context = context; } /// <summary> /// 给其他扩展状态设置的此状态执行的操作 /// </summary> /// <param name="var"></param> public abstract void Headle(int var); }子状态只有2个主要任务:
1、重写父类方法,实现功能
2、切换状态
//使用默认构造函数
public class ConcreteStateA : State { public ConcreteStateA(Context context) : base(context) { } public override void Headle(int var) { if (var > 10) context.SetState(new ConcreteStateB(context)); Debug.Log("ConcreteStateA"); } } public class ConcreteStateB : State { public ConcreteStateB(Context context) : base(context) { } public override void Headle(int var) { if (var > 40) { context.SetState(new ConcreteStateA(context)); } Debug.Log("ConcreteStateB"); } } 写好了状态模式后,又该如何去使用状态模式呢?使用状态模式分3步
1、new一个状态的拥有者出来//连角色都没有,怎么可能让角色有状态
2、给刚刚new出来的拥有者SetState()设置一个初始状态//创建好了新角色以后,此角色总得有个状态吧,让她站着还是坐着随你便
3、使用拥有者中的公有方法来间接调用子状态中的方法
public class StateText : MonoBehaviour { void Start() { UnitTest(); } void UnitTest() { Context theContext = new Context();//new一个状态的拥有者 theContext.SetState(new ConcreteStateA(theContext));//设置一个初始状态,这里传入new出的拥有者的目地是,给IState中的Context赋值 theContext.Request(5);//使用拥有者中的公有方法来间接调用子状态中的方法 theContext.Request(15); theContext.Request(25); theContext.Request(35); theContext.Request(55); } }