游戏设计模式——状态模式(state)

状态模式

就是让一个对象的行为随着内部状态的改变而变化,而该对象也像是换了类一样。
用游戏的方式来解释
就像是魔兽世界里的德鲁伊,有两种形态,人形状态和兽形状态,任意切换一种状态,他的技能也会变化,或者像英雄联盟里边的豹女,就是这种形态,玩家此时感觉就像操作一个不同的角色,程序里边感觉像是换了类一样。
这种形态切换的能力,是德鲁伊的一种“内部状态的转换”,转换完成后,是德鲁伊这个角色的另外一种行为模式,不过,还是德鲁伊他本身,这种模式就是状态模式。

状态模式的优点

减少错误的发生并降低维护难度:不再使用switch(m_state)来判断当前的状态,这样可以减少新增游戏状态时,因未能检查到所有switch(m_state)程序代码而造成的错误。
状态执行环境单一化:每个状态相关的都在一个状态类中,对于程序猿来说,可以清楚地了解每个状态执行时所需要配合的对象和类
项目之间可以共享场景:这种做法对网络游戏特别有用,玩家的上线、登录、验证、数据等同步过程,实现上有一定的复杂度。把这些复杂的操作放在共享的场景中,这样使用和维护就能节省很多开发时间和成本。

状态模式的缺点

当有大量状态时,使用状态模式就会产生过多状态类的情况,造成类爆炸的问题,但是跟传统switch(state_code)的实现方式相比,状态模式更利于项目后期的维护,因为状态模式可以清楚地了解每个场景状态所需要配合的类对象,减少因为新增状态而需要大量修改现有程序代码的维护成本。

下边是例子

namespace Leon_State
{
    //状态持有者(持有目前的状态,并将有关的讯息传给状态)
    public class Context
    {
        State m_State = null;

        public void Request(int Value)
        {
            m_State.Handle(Value);
        }
        public void SetState(State theState)
        {
            Debug.Log("Context.SetState:" + theState);
            m_State = theState;
        }
    }

    //状态接口类(负责封装当Context处于特定状态时所该展现的行为)
    public abstract class State
    {
        protected Context m_Context = null;

        public State(Context theContext)
        {
            m_Context = theContext;
        }
        public abstract void Handle(int Value);
    }

    //状态A
    public class ConcreteStateA : State
    {
        public ConcreteStateA(Context theContext) : base(theContext) 
        { }
        public override void Handle(int Value)
        {
            Debug.Log("ConcreteStateA.Handel");
            if (Value > 10)
                m_Context.SetState(new ConcreteStateB(m_Context));
        }
    }

    //状态B
    public class ConcreteStateB : State
    {
        public ConcreteStateB(Context theContext) : base(theContext)
        { }
        public override void Handle(int Value)
        {
            Debug.Log("ConcreteStateB.Handel");
            if (Value > 20)
                m_Context.SetState(new ConcreteStateC(m_Context));
        }
    }

    //状态C
    public class ConcreteStateC : State
    {
        public ConcreteStateC(Context theContext) : base(theContext)
        { }
        public override void Handle(int Value)
        {
            Debug.Log("ConcreteStateC.Handel");
            if (Value > 30)
                m_Context.SetState(new ConcreteStateA(m_Context));
        }
    }
}

测试

public class Leon_StateTest : MonoBehaviour
{
    // Use this for initialization
    void Start()
    {
        UnitTest();
    }

    private void UnitTest()
    {
        Context theContext = new Context();
        theContext.SetState(new ConcreteStateA(theContext));
        theContext.Request(5);
        theContext.Request(15);
        theContext.Request(25);
        theContext.Request(35);
    }
}

打印
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值