游戏中的设计模式——状态者模式

大家好,今天要为大家介绍的是游戏中常用的设计模式之状态者模式,这个模式常用于我们Unity3D中的状态机切换,接下来就来看看这个模式的实现 (⊙_⊙)!

状态者模式

定义

每个对象都有其对应的状态,而每个状态又对应一些相应的行为,如果某个对象有多个状态时,那么就会对应很多的行为。那么对这些状态的判断和根据状态完成的行为,就会导致多重条件语句,并且如果添加一种新的状态时,需要更改之前现有的代码。这样的设计显然违背了开闭原则。状态模式正是用来解决这样的问题的。状态模式将每种状态对应的行为抽象出来成为单独新的对象,这样状态的变化不再依赖于对象内部的行为。

简而言之就是

把状态和逻辑分开,实现代码的解耦,有利与后期新状态的添加。

代码实现

public abstract class FSMState
{
    //状态id
    private   byte  stateId ;
    public virtual void OnEnterBefore()
    {

    }

    public virtual void CopyState(FSMState BeforeState) { }

    public abstract void OnEnter();

    public virtual void Update() { }

    public virtual void OnLeave() { }
}

作为各个子类状态的父类,每个子类状态都有进入状态、进入状态后、离开状态的方法

public   class  AtackFSM: FSMState
{
    ParticleEmitter  emmitor ;

    public override void OnEnter ()
    {   
    }

    float  timeCount =0 ;
    public  override void Update()
    {
        timeCount += Time.deltaTime;

        if (timeCount > 0.5f) {
            //......
        }
    }   
}

public   class  WalkFSM: FSMState
{
    public override void OnEnter ()
    {
        // animator.setint()
    }
}

生成 AttackFSM类和 WalkFSM类 ,继承于FSMState。

public  class   FSMManager
{
    private   FSMState[] fsmManager;

    // 增加了几个state
    private   byte  curAdd ;
    // 当前状态Id
    public  byte   curStateId ;

    public  FSMManager (byte  stateNumber)
    {
        curAdd = 0;

        curStateId = 0;
        fsmManager = new FSMState[stateNumber];
    }

    public  void AddState(FSMState  tmpState)
    {

        if (curAdd < fsmManager.Length) {
            fsmManager [curAdd] = tmpState;
            curAdd++;
        }

    }

    public  void ChangeState(byte  stateId)
    {
        fsmManager [curStateId].OnLeave ();

        fsmManager [stateId].CopyState (fsmManager [curStateId]);

        fsmManager [stateId].OnBeforEntor ();

        fsmManager [stateId].OnEnter ();

        curStateId = stateId;
    }

    public  void Update()
    {

        fsmManager[curStateId].Update ();
    }
}

建立一个FSMManager管理类,对外提供 AddState 和 ChangeState 接口

public class FSM : MonoBehaviour {

    public enum   FSMStateId
    {
        Idle,
        Attack,
        Walk,
        MaxValue
    }

    FSMManager   manager ;
    // Use this for initialization
    void Start () {

        WalkFSM tmpWalk = new WalkFSM ();
        AtackFSM tmpAttack = new AtackFSM ();

        manager = new FSMManager ((byte)FSMStateId.MaxValue);

        manager.AddState (tmpWalk);
        manager.AddState (tmpAttack);
    }


    public  void PlayAttack()
    {
        manager.ChangeState ((byte)FSMStateId.Attack);
    }

    // Update is called once per frame
    void Update () {
        manager.Update ();
    }
}

外界调用。


结束语

设计模式对于编程是非常重要的,但我对设计模式的理解还是不够深入的,还是要不停的学习,不停的码代码,才能揭开它的面纱。

©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页