• 人物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(">>>>>>>> 用户按下鼠标
    ");
        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;
    }
    
    基本过程这样的
    通过配置将条件及其所包含的事件,状态跃迁的条件配置好,程序加载读取配置文件
    当动作(事件)发生时,通过该事件构造一个条件,将这个条件和当前状态的目标条件进行匹配,如果匹配上了,就返回对应的目标状态,如果发现状态不同就通知观察者就相应变化,在根据状态决定其行为
  • 相关阅读:
    IP地址分类整理
    PHP
    [转载]数组的全排列问题
    使用 Homebrew 安装 Git
    Homebrew简介及安装
    iOS开发~CocoaPods使用详细说明
    关于目前自己iOS项目使用的第三方开源库
    IOS 时间格式 时间转换 大总结
    Xcode磁盘空间大清理
    Swift百万线程攻破单例(Singleton)模式
  • 原文地址:https://www.cnblogs.com/zzyoucan/p/4414129.html
Copyright © 2020-2023  润新知