日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

【转】C#数据结构-有限状态机

發布時間:2023/12/10 C# 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【转】C#数据结构-有限状态机 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

有限狀態機FSM的要點是:

  • ? ? 擁有一組狀態,并且可以在這組狀態之間進行切換。
  • ? ? 狀態機同時只能在一個狀態。
  • ? ? 一連串的輸入或事件被發送給機器。
  • ? ? 每個狀態都有一系列的轉換,轉換與輸入和另一狀態相關。當輸入進來,如果它與當前狀態的某個轉換匹配,機器轉為轉換所指的狀態。
  • ? ??
    目前而言,游戲編程中狀態機的實現方式,有兩種可以選擇:

  • ? ? 用枚舉配合switch case語句。
  • ? ? 實現多態(也就是狀態模式)。
  • 狀態模式的經典定義:允許對象在當內部狀態改變時改變其行為,就好像此對象改變了自己的類一樣
    狀態模式的實現要點,主要有三點:

  • ? ? 為狀態定義一個接口。
  • ? ? 為每個狀態定義一個類。
  • ? ? 恰當地進行狀態委托。
  • 注:下面的代碼在unity中用C#實現,不過只是借用了unity的輸入操作,對于理解有限狀態機,沒有阻礙。

    ?

    • ? ? ? 初始化是站立狀態;
    • ? ? ? 按下向上的方向鍵,可以跳躍;在跳躍的狀態,按向下的方向鍵,可以下斬,按向上的方向鍵,不做處理;
    • ? ? ? 按下向下的方向鍵,可以下蹲;在下蹲的狀態,按向下的方向鍵,不做處理,按向上的方向鍵,恢復站立狀態;

    代碼來自于這里超鏈接

    狀態接口實現:

    ?
  • public interface HeroineBaseState

  • {

  • void HandleInput();

  • }

  • 站立狀態實現:

    ?
  • using UnityEngine;

  • ?
  • public class StandingState : HeroineBaseState

  • {

  • private Heroine _heroine;

  • public StandingState(Heroine heroine)

  • {

  • _heroine = heroine;

  • Debug.Log("進入站立狀態!");

  • }

  • ?
  • public void HandleInput()

  • {

  • if (Input.GetKeyDown(KeyCode.UpArrow))

  • {

  • Debug.Log("get KeyCode.UpArrow!");

  • _heroine.SetHeroineState(new JumpingState(_heroine));

  • }

  • if (Input.GetKeyDown(KeyCode.DownArrow))

  • {

  • Debug.Log("get KeyCode.DownArrow!");

  • _heroine.SetHeroineState(new DuckingState(_heroine));

  • }

  • }

  • }

  • 跳躍狀態實現:

    ?
  • using UnityEngine;

  • ?
  • public class JumpingState : HeroineBaseState

  • {

  • ?
  • private Heroine _heroine;

  • public JumpingState(Heroine heroine)

  • {

  • _heroine = heroine;

  • Debug.Log("進入跳躍狀態!");

  • }

  • ?
  • public void HandleInput()

  • {

  • if (Input.GetKeyDown(KeyCode.UpArrow))

  • {

  • Debug.Log("已經在跳躍狀態中!");

  • return;

  • }

  • if (Input.GetKeyDown(KeyCode.DownArrow))

  • {

  • Debug.Log("get KeyCode.DownArrow!");

  • _heroine.SetHeroineState(new DrivingState(_heroine));

  • }

  • }

  • }

  • 下蹲狀態實現:

    ?
  • using UnityEngine;

  • ?
  • public class DuckingState : HeroineBaseState

  • {

  • private Heroine _heroine;

  • public DuckingState(Heroine heroine)

  • {

  • _heroine = heroine;

  • Debug.Log("進入下蹲躲避狀態!");

  • }

  • ?
  • public void HandleInput()

  • {

  • if (Input.GetKeyDown(KeyCode.DownArrow))

  • {

  • Debug.Log("已經在下蹲躲避狀態中!");

  • return;

  • }

  • if (Input.GetKeyUp(KeyCode.UpArrow))

  • {

  • Debug.Log("get GetKeyUp.UpArrow!");

  • _heroine.SetHeroineState(new StandingState(_heroine));

  • }

  • }

  • }

  • 下斬狀態實現:

    ?
  • using UnityEngine;

  • ?
  • public class DrivingState : HeroineBaseState

  • {

  • private Heroine _heroine;

  • public DrivingState(Heroine heroine)

  • {

  • _heroine = heroine;

  • Debug.Log("進入下斬狀態!");

  • }

  • ?
  • public void HandleInput()

  • {

  • if (Input.GetKeyDown(KeyCode.UpArrow))

  • {

  • Debug.Log("get KeyCode.UpArrow!");

  • _heroine.SetHeroineState(new StandingState(_heroine));

  • }

  • }

  • }

  • 女主角實現:

    ?
  • public class Heroine

  • {

  • HeroineBaseState _state;

  • ?
  • public Heroine()

  • {

  • _state = new StandingState(this);

  • }

  • ?
  • public void SetHeroineState(HeroineBaseState newState)

  • {

  • _state = newState;

  • }

  • ?
  • public void Update()

  • {

  • _state.HandleInput();

  • }

  • ?
  • }

  • 測試代碼,在Unity里要掛在一個GameObject上執行。

    ?
  • using UnityEngine;

  • ?
  • public class TestHeroine : MonoBehaviour

  • {

  • private Heroine _heroine;

  • ?
  • // 初始化調用,先執行

  • void Start()

  • {

  • _heroine = new Heroine();

  • }

  • ?
  • // 每幀調用一次

  • void Update()

  • {

  • _heroine.Update();

  • }

  • }

  • 上面用的接口,還可以用虛函數或者抽象函數來實現多態。下面模擬了銀行存款取款,賬戶的狀態的變化。

    C#代碼實現:

    ?
  • using System;

  • ?
  • namespace StructScript

  • {

  • ?
  • public class StateScript

  • {

  • static void Main(string[] args)

  • {

  • Account account = new Account();

  • account.Add(500);

  • account.Add(3000);

  • account.Remove(1000);

  • account.Remove(10000);

  • ?
  • Console.ReadLine();

  • }

  • }

  • ?
  • public class Account

  • {

  • private State state;

  • ?
  • public Account()

  • {

  • state = new RedState(0.0, this);

  • }

  • ?
  • public State State

  • {

  • get { return state; }

  • set { state = value; }

  • }

  • ?
  • public void Add(int amount)

  • {

  • Console.WriteLine("Add " + amount);

  • state.Add(amount);

  • Console.WriteLine("Balance: " + state.Balance);

  • Console.WriteLine("State: " + state.GetType().Name);

  • }

  • ?
  • public void Remove(int amount)

  • {

  • Console.WriteLine("Remove " + amount);

  • state.Remove(amount);

  • Console.WriteLine("Balance: " + state.Balance);

  • Console.WriteLine("State: " + state.GetType().Name);

  • }

  • }

  • ?
  • /// <summary>

  • /// 狀態基類

  • /// </summary>

  • public abstract class State

  • {

  • protected Account account;

  • protected double balance;

  • protected double lowerLimit;

  • protected double upperLimit;

  • ?
  • public Account Account

  • {

  • get { return account; }

  • set { account = value; }

  • }

  • ?
  • public double Balance

  • {

  • get { return balance; }

  • set { balance = value; }

  • }

  • ?
  • public abstract void Add(int amount);

  • public abstract void Remove(int amount);

  • }

  • ?
  • /// <summary>

  • /// 紅色賬戶狀態

  • /// </summary>

  • public class RedState : State

  • {

  • public RedState(State state) : this(state.Balance, state.Account) { }

  • ?
  • public RedState(double balance, Account account)

  • {

  • this.balance = balance;

  • this.account = account;

  • lowerLimit = -100.0;

  • upperLimit = 0.0;

  • }

  • ?
  • public override void Add(int amount)

  • {

  • balance += amount;

  • StateChangeCheck();

  • }

  • ?
  • public override void Remove(int amount)

  • {

  • Console.WriteLine("余額不足");

  • }

  • ?
  • private void StateChangeCheck()

  • {

  • if (balance > upperLimit)

  • {

  • account.State = new SilverState(this);

  • }

  • }

  • }

  • ?
  • /// <summary>

  • /// 銀色賬戶狀態

  • /// </summary>

  • public class SilverState : State

  • {

  • public SilverState(State state) : this(state.Balance, state.Account) { }

  • ?
  • public SilverState(double balance, Account account)

  • {

  • this.balance = balance;

  • this.account = account;

  • lowerLimit = 0.0;

  • upperLimit = 1000.0;

  • }

  • ?
  • public override void Add(int amount)

  • {

  • balance += amount;

  • StateChangeCheck();

  • }

  • ?
  • public override void Remove(int amount)

  • {

  • double remain = balance - amount;

  • if (remain < -100)

  • {

  • Console.WriteLine("余額不足");

  • }

  • else

  • {

  • balance = remain;

  • StateChangeCheck();

  • }

  • }

  • ?
  • private void StateChangeCheck()

  • {

  • if (balance < lowerLimit)

  • {

  • account.State = new RedState(this);

  • }

  • else if (balance > upperLimit)

  • {

  • account.State = new GoldState(this);

  • }

  • }

  • }

  • ?
  • /// <summary>

  • /// 金色賬戶狀態

  • /// </summary>

  • public class GoldState : State

  • {

  • public GoldState(State state) : this(state.Balance, state.Account) { }

  • ?
  • public GoldState(double balance, Account account)

  • {

  • this.balance = balance;

  • this.account = account;

  • lowerLimit = 1000.0;

  • upperLimit = 10000000.0;

  • }

  • ?
  • public override void Add(int amount)

  • {

  • balance += amount;

  • StateChangeCheck();

  • }

  • ?
  • public override void Remove(int amount)

  • {

  • double remain = balance - amount;

  • if (remain < -100)

  • {

  • Console.WriteLine("余額不足");

  • }

  • else

  • {

  • balance = remain;

  • StateChangeCheck();

  • }

  • }

  • ?
  • private void StateChangeCheck()

  • {

  • if (balance < 0.0)

  • {

  • account.State = new RedState(this);

  • }

  • else if (balance < lowerLimit)

  • {

  • account.State = new SilverState(this);

  • }

  • }

  • }

  • }

  • 總結

    以上是生活随笔為你收集整理的【转】C#数据结构-有限状态机的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。