打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
【   】【游戏中有限状态机FSM的三种实现方法】
         有限状态机,英文Finite state machine,简称FSM。至今在游戏中应用广泛,今天总结性地说说其三种实现方法(注意其中的代码系伪代码,主要为说明思想,并不一定能运行。)
(一)基本概念
         首先看看比较严格的定义:有限状态机(Finite State Machine)是具有离散输入和输出系统的一种数学模型。表示有限个状态以及在条件输入下状态之间的转移行为。具有有限个内部状态,随着信号(条件)的输入,内部状态不断地转移。
通常我们用状态迁移图或状态迁移表来表示:(请看以下示例)


图b就是与图a等价的状态迁移表。
系统中可取得的状态=S1,S2,S3,事件=t1,t2,t3,t4。事件t1将引起系统状态S1向状态S3迁移,事件t2将引起系统状
       态S3向状态S2迁移,等等
另外,状态迁移图指明了作为特定事件的结果(状态)。在状态中包含可能执行的行为。


(二)实现方法


下面看看其三种实现方法:
1)switch case/if else设计方法
2)基于表结构的状态机设计方法
3)状态设计模式
下面分别说说其思想(主要基于C/C++伪码):
1)switch case/if else设计方法
enum StateType{state_RunAway,state_Patrol,state_attack};
void Agent::UpdateState(StateType CurrentState){
switch(CurrentState) {
  case state_RunAway:
           EvadeEnemy();
           if (Safe())    {  ChangeState(state_ Patrol);   }
           break;
  case state_Patrol:
           FollowPatrolPath();
           if (Threatened())
           if (StrongerThanEnemy()) { ChangeState(state_Attack); }
           else  {   ChangeState(state_ RunAway); }
           break;
  case state_Attack:
           if  (WeakerThanEnemy())  {  ChangeState(state RunAway); }
           else  {  BashEnemyOverHead(); }
           break;
  }//end switch
}
这个比较简单,不说鸟
2)基于表结构的状态机设计方法


/*状态1的动作表*/
ACT_TABLE_T state1ActTable[] = {
    {EVENT1,state1Event1Fun},
    {EVENT3,state1Event3Fun},
};
/*状态2的动作表*/
ACT_TABLE_T state2ActTable[] = {
    {EVENT2,state2Event2Fun},
};
/*状态表*/
STATE_TABLE_T FsmTable[] = {
    {STATE1,state1ActTable},
    {STATE2,state2ActTable},
};
/*客户端提供的状态处理函数*/
void state1Event1Fun(void* pFsm)
{
   FSM_MoveState((FSM_T*)pFsm,STATE2);
   return;
}
void state1Event3Fun(void* pFsm)
{
   FSM_MoveState((FSM_T*)pFsm,STATE3);
   return;
}
void state2Event2Fun(void* pFsm)
{
   FSM_MoveState((FSM_T*)pFsm,STATE3);
   return;
}

FSM_Regist(&fsm,FsmTable);
    ...

可以看出此种方式,可以实现状态机的热更新,因为这些表格是存在数组里面的。用c#的代理是可以较容易实现的,用cc++的话需要用函数指针即可。
3)状态设计模式
UML图如下所示


用一下图示为示例:


1.环境(Context): Gun.java
public  class  Gun{
       State  state;
       public  void  Gun(){
          state = new BulletStateThree(this); }
       public void setState(State  state){  
          this.state=state; }
       public State getState( ){
          return state;}
       public void fire(){
          state.fire();}
       public void  LoadBullet(){
          state.LoadBullet();}
}
2.抽象状态(State): State.java
public  interface  State{
      public void fire();
        public void LoadBullet();
        public String showStateMess();  
}
3.具体状态(Concrete State)_1:BulletStateThree.java
public class BulletStateThree implements State{
        Gun gun;
        BulletStateThree(Gun gun){this.gun=gun;}
        public void fire(){
        System.out.print(“打出一个子弹”);//do a reflect act
        gun.setState(new BulletStateTwo(this));//transfer to another sate
        }
        public void loadBullet(){System.out.println(“无法装弹”);}
        public String showStateMess(){return “2个子弹状态”;}
}
   具体状态(Concrete State)_2:BulletStateTwo.java
public class BulletStateTwo implements State{
        Gun gun;
        BulletStateTwo(Gun gun){this.gun=gun;}
        public void fire(){
        System.out.print(“打出1个子弹”);
        gun.setState(new BulletStateOne(this));
        }
        public void loadBullet(){System.out.println(“无法装弹”);}
        public String showStateMess(){return “1个子弹状态”;}
}
   具体状态(Concrete State)_1:BulletStateOne.java
public class BulletStateOne implements State{
        Gun gun;
        BulletStateOne(Gun gun){this.gun=gun;}
        public void fire(){
        System.out.print(“打出1个子弹”);
        gun.setState(new BulletStateNull(this));
        }
        public void loadBullet(){System.out.println(“无法装弹”);}
        public String showStateMess(){return “无子弹状态”;}
}
   具体状态(Concrete State)_1:BulletStateNull.java
public class BulletStateNull implements State{
        Gun gun;
        BulletStateNull(Gun gun){this.gun=gun;}
        public void fire(){
        System.out.print(“不能打出子弹”);
        }
        public void loadBullet(){
        System.out.println(“装弹”);
        gun.setState(new BulletStateThree(this));}
        public String showStateMess(){ return “无子弹状态”;}
}
4.Application: Application.java
            public class Application {
        public static void main(String args[]){
        Gun gun=new Gun();
        gun.fire(); gun.fire(); gun.fire(); gun.fire();
        gun.LoadBullet();
        }
}
That's all,3KS






本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
有限状态机(FSM)的设计与实现(二)
教你一招搞定,单片机开发常用的状态机
【原创】技术系列之 状态机(一)
基于事件驱动的有限状态机实现工作流引擎的核心调度算法 | 中国开放流程社区
【实现简易而强大的游戏AI
U3D 简单的FSM状态机
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服