人物FSM

人物有限状态机
之前看这个状态机没看懂,今天又翻出来,看的略懂
FSM在游戏中应用的地方还是挺多的 怪物AI,玩家行为管理
        条件(包含若干事件)       条件(包含若干事件)
状态1<-------------------->状态2<------------------->状态3
状态之间跃迁通过条件,条件包含若干事件
1.初始化条件
// 从读表器中查找编号为i的记录
const PlayerFSMConditionInfo* pInfo = (const PlayerFSMConditionInfo*)kConditionLoader.Find(i);
if (pInfo)
{
    // 新建条件
    FSMCondition* pCondition = new FSMCondition(eFsmEvent_Amount);
    // 为条件添加事件
    for (int j = 0; j < eFsmEvent_Amount; j++)
    {
        // 因为0也代表了一个事件,所以,这里用-1来判定对应字段是否有有效数据
        if (pInfo->nEvtArray[j] != -1)
        {
            // 加入该事件包含的条件
            pCondition->AttachEvent(pInfo->nEvtArray[j]);
        }
    }
    // 将条件存入条件集合中
    m_vecConditions[i] = pCondition;
}
else
{
    m_vecConditions[i] = NULL;
}

// 不同于条件的加载过程,这里需要首先将所有状态构造出来
// 以备稍后对所有状态进行跃迁条件的设置
for (int i = 0; i < eFsmState_Amount; i++)
{
    //创建所有的状态
    m_vecStates[i] = new FSMState(i);
}

3.注册每个状态的目标状态和相应的条件
// 表格中的记录总数由读表器给出
nCount = kStateLoader.GetRecordCount();
for (unsigned int i = 0; i < nCount; i++)
{
    // 取得第i条记录
    const PlayerFSMStateInfo* pInfo = (const PlayerFSMStateInfo*)kStateLoader.Find(i);
    // 使用表格数据,注册状态跃迁信息
    // 即:nSrcStateID状态通过条件nConditionID,可跃迁至nDstStateID
    RegistTransition(pInfo->nSrcStateID, pInfo->nDstStateID, pInfo->nConditionID);
}

4.发送事件,跃迁动作
FSMCondition kCondition(eFsmEvent_Amount);
{
    OutputLog(">>>>>>>> 用户按下鼠标\n");
    kCondition.Reset();
    kCondition.AttachEvent(eFsmEvent_Click);
    m_kFSM.Transition(&kCondition);
    ShowFSMState();
}

void FSM::Transition(FSMCondition* pCondition)
{
    //根据条件将当前状态尝试进行状态跃迁
    FSMState* pState = m_pCurrentState->Transition(pCondition);
    if (pState != m_pCurrentState)
    {
        // 保存之前的状态
        m_pLastState = m_pCurrentState;

        // 设置当前状态为新的状态
        m_pCurrentState = pState;

        // 通知观察者
        Notify();
    }
}

FSMState* FSMState::Transition(FSMCondition* pCondition)
{
    for (unsigned int i = 0; i < m_vecTargetCondition.size(); i++)
    {
        //查找是否是目标条件的子集
        if (m_vecTargetCondition[i]->IsSubSetOfCondition(pCondition))
        {
            //返回对应的目标状态
            return m_vecTargetState[i];
        }
    }
    return this;
}

基本过程这样的
通过配置将条件及其所包含的事件,状态跃迁的条件配置好,程序加载读取配置文件
当动作(事件)发生时,通过该事件构造一个条件,将这个条件和当前状态的目标条件进行匹配,如果匹配上了,就返回对应的目标状态,如果发现状态不同就通知观察者就相应变化,在根据状态决定其行为

 

posted @ 2015-04-10 11:45  zzyoucan  阅读(228)  评论(0编辑  收藏  举报