34

设计模式之状态模式(State)-腾讯游戏学院

 5 years ago
source link: http://gad.qq.com/article/detail/288130
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
5bdef812c9e4a.png

状态模式主要用于状态机的设计,更加便利的控制切换对象状态,增强可扩展性和可维护性。状态机不仅适用于角色动作状态,同样适用于其他可以确切划分为相互独立的区间的功能模块。

一、 有限状态机:
又称FSM有限状态机,集合了对象所有的状态,通过外界输入和内部逻辑切换状态,保证同一时间只有一个状态,各状态相互独立,每个状态包含了切入、刷新、切出三部分,配合Unity的Animator使用效果更佳~~
    //状态基类
    public abstract class FSMState
    {
        public abstract void OnEnter();
        public abstract void Update();
        public abstract void OnExit();
    }
    //控制器
    public class FSMController
    {
        public FSMState curState { get; protected set; }
        public void ChangerState(FSMState state)
        {
            if (state != null)
            {
                if (curState != state)
                    curState.OnExit();
                curState = state;
                curState.OnEnter();
            }
        }
        public void Update()
        {
            curState.Update();
        }
    }
二、 并发状态机:
有限状态机只能保持单一状态,比如玩家有行走、跑动、跳跃、下蹲、攻击等状态,攻击又分为远程射击、投掷手雷、近身挥砍等,FSM不能同时移动并攻击。
这时候就需要两个独立的有限状态机,分别控制攻击状态和移动等其他状态,接收输入指令执行相应状态。(还可以设置让状态机销毁输入,对应的状态机接收输入指令后销毁输入,避免两个状态机重复响应。)有时候两个状态机需要交互,加入在跳跃的时候不能投掷手雷,这还需要在响应输入的时候对另一个状态进行判断。

三、分层状态机:
状态可以继承自父状态,收到输入指令进行判断,若不在判断范围,再交给父状态类判断处理。
public enum HeroState
{
    stand,
    walk,
    run,
}
public class OnGroundState
{
    public virtual void HandleInput(HeroState toState)
    {
        if(toState == HeroState.stand)
        {
        }
        else if (toState == HeroState.walk)
        {
        }
        else if(toState == HeroState.run)
        {
        }
        //······
    }
}
public class StandState : OnGroundState
{
    public override void HandleInput(HeroState toState)
    {
        if (toState == HeroState.stand)
        {
        }
        else if (toState == HeroState.walk)
        {
        }
        //······
        //不在处理范围,返回给父类
        base.HandleInput(toState);
    }
}
四、下推状态机:
举个栗子:玩家切换到射击状态,发射子弹,播放动画、特效、音效等等,在执行完射击动作后,需要再切换回到之前的状态,但之前状态可能是站立,也可能是行走、奔跑、跳跃···,在有限状态机中,使用一个状态指针来记录当前状态,那么下推状态机则是用一个状态指针队列来顺序记录状态。
比如用队列Queue来记录,新加入的状态会在最上面,状态执行完成,自动切换时弹出最上面的值,下一个值将成为新的状态。在前面的栗子中,射击结束后,就可以很容易的获取到之前的状态了。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK