【转】C#数据结构-有限状态机
?
有限狀態機FSM的要點是:
? ??
目前而言,游戲編程中狀態機的實現方式,有兩種可以選擇:
狀態模式的經典定義:允許對象在當內部狀態改變時改變其行為,就好像此對象改變了自己的類一樣
狀態模式的實現要點,主要有三點:
注:下面的代碼在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#数据结构-有限状态机的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【转】刨根究底CSS(1):开篇
- 下一篇: 京东iPhone 13抄底价:送1001