FSM-Golang

使用FSM(Finite State Machine)来制作怪物的AI,比较轻量级;

概念

状态机分为两大类:

名称说明
Moore machine输出只和状态有关而与输入无关
Mealy machine输出不仅和状态有关而且和输入有关系(使用这种状态机通常可以减少状态的数量。)

状态机可归纳为4个要素,即现态、条件、动作、次态。这样的归纳,主要是出于对状态机的内在因果关系的考虑。“现态”和“条件”是因,“动作”和“次态”是果。详解如下:

①现态:是指当前所处的状态。

②条件:又称为“事件”,当一个条件被满足,将会触发一个动作,或者执行一次状态的迁移。

③动作:条件满足后执行的动作。动作执行完毕后,可以迁移到新的状态,也可以仍旧保持原状态。动作不是必需的,当条件满足后,也可以不执行任何动作,直接迁移到新状态。

④次态:条件满足后要迁往的新状态。“次态”是相对于“现态”而言的,“次态”一旦被激活,就转变成新的“现态”了。

最首先状态机的概念是使用在电路,单片机相关的东西里面。

在刚才归纳的要素里面很重要的就是“状态”,“条件“,”动作“。

游戏中常用的状态机

DulcAU.png

要素元素
状态待机状态巡逻状态追击状态攻击状态
条件出现敌人主动怪判断遭到攻击攻击范围检测追击范围检测
动作朝某个位置移动施法

阅读 looplab/fsm 实现

DKZZLD.png

在创建状态机的时候需要指定状态之间切换的可能性;需要指定在状态切换的时候的调用。(状态是直接使用string来表示)

核心对象FMS,里面缓存了有限状态机的路由,并且能接受外部提供的Event的触发;

当Event区触发当前的有限状态机的时候,将会做状态的切换;

切换状态的时候,需要使用到 transitioner 对象;

参考实例代码:

package main

import (
    "fmt"
    "github.com/looplab/fsm"
)

// Door 门对象
type Door struct {
    To  string
    // FSM 有限状态机对象
    FSM *fsm.FSM
}

// NewDoor 新建门对象
// to 名称
func NewDoor(to string) *Door {
    d := &Door{
        To: to,
    }

    d.FSM = fsm.NewFSM(
        // 默认的状态名称
        "closed",
        fsm.Events{
            // 事件 open ,能将状态机从 closed 转换成 open 状态
            {Name: "open", Src: []string{"closed"}, Dst: "open"},
            // 事件 close ,能将状态机从 closed 转换成 open 状态
            {Name: "close", Src: []string{"open"}, Dst: "closed"},
        },
        fsm.Callbacks{
            // 给状态机注册 enter_state 回调函数
            "enter_state": func(e *fsm.Event) { d.enterState(e) },
        },
    )

    return d
}

// enterState 当进入新状态的回调
func (d *Door) enterState(e *fsm.Event) {
    fmt.Printf("The door to %s is %s\n", d.To, e.Dst)
}

func main() {
    door := NewDoor("heaven")

    // 发起 open 事件
    err := door.FSM.Event("open")
    if err != nil {
        fmt.Println(err)
    }

    // 发起 close 事件
    err = door.FSM.Event("close")
    if err != nil {
        fmt.Println(err)
    }
}

状态机本身只关心状态切换,他自己不关心这个事件生成;

参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值