首页 > 代码库 > 怪物AI(复习)

怪物AI(复习)

怪物AI执行//-----------------------------------------------主动攻击------------------------------------------------------初始状态attack_style      Enum攻击方式              Enum主动攻击MonsterStat          EnumMonsterStat          EnumMonster游荡Monter被动Stat    EnumMonster被动Stat     EnumMonster被动NULL玩家移动或者进入地图,都会通知附近玩家以及在怪物的map_nearby_player容器中加入此玩家然后在action中_updateAttachObjsAndStat()中扫描扫描附近玩家,如果怪物是主动攻击类型就将其加入m_attach_objs容器中,并置curStat当前状态为EnumMonster追击然后根据相应的状态执行相应的动作追击过程:1.auto pl = get_attach_obj(m_attach_objs);//根据仇恨值获取攻击对象2.加载路线不在四周,加载路线,单步的,如果遇到障碍则会执行传奇的绕道算法,这种算法是单步比A*算法效率高,A*算法图相对是固定的,但游戏中怪物是移动的。3.怪物发现人物在四周,开始攻击:if(pl->second.distance <= 1)//如何玩家在怪物的四周{    if(!(rand() % 2))    {//攻击玩家        AttackPt att;        att.srcID = objId;        att.tgtID = pl->second.obj->objId;        att.skill_id =  普通攻击;//(nBodyID == 1003)? 9004 : 9005;        att.way = 1;//直接攻击        m_map->attach(att, this, pl->second.obj);        //找到目标,取消追踪路线        m_trace_line.clear();        is_move = false;            }    if(pl->second.obj->stat.cur_hp <= 0)    {        cancle_attached();//此时人被打死,    }    return false;}void MonsterObj::cancle_attached(){    m_is_attached = false;//玩家已死,取消攻击记录    m_attach_objs.clear();//取消攻击记录    m_trace_line.clear();    is_move = false;    MonsterStat = EnumMonsterStat::EnumMonster回家;}4.当把人打死了就把状态置为回家,回到怪物的出生地void MonsterObj::回家(){    if(rand() % 100 > 30)//30%的概率移动        return;    pos2d obj_t_mpos = _getTgtMapPos();    if(!is_move)    {        if(!m_finder->FindPath(obj_t_mpos.x, obj_t_mpos.y, base_mpos.x, base_mpos.y))            return;        m_finder->GetPath(m_trace_line);    }    //路线走完 或者 在出生点周围    if(m_trace_line.empty() /*|| isAround(当前位置,base_mpos)*/)    {        cancle_goback();        return;    }    pos2d next_mpos = m_trace_line.front();    //如果下一步不可以通过则(临时有怪物阻挡,所以要加判断)    if(isFreeMap(next_mpos.x, next_mpos.y))    {        auto old_bpos = _getBlockPos();        if(execute_trace_line())            _notify(old_bpos, _getBlockPos());    }}5.线路走完if(m_trace_line.empty() /*|| isAround(当前位置,base_mpos)*/){    cancle_goback();//取消回家    return;}6.又开始游荡void MonsterObj::cancle_goback()//取消回家计划{    //①取消回家路线    m_trace_line.clear();    is_move = false;    MonsterStat = EnumMonsterStat::EnumMonster游荡;}//---------------------------------------------胆小的--------------------------------------------------------胆小的刚开始时游荡和没有被动状态当收到攻击时就把状态为逃跑当逃跑线路走完时就取消攻击void MonsterObj::cancle_attached(){    m_is_attached = false;//玩家已死,取消攻击记录    m_attach_objs.clear();//取消攻击记录    m_trace_line.clear();    is_move = false;    MonsterStat = EnumMonsterStat::EnumMonster回家;}然后就回家回家之后开始游荡//----------------------------------------------被动的----------------------------------------------------------//被动的(类似的)被动的游荡->被打了(追击)->把人打死了->回家->游荡//-----------------------------------------------关于怪物被玩家打-----------------------------------------------//关于被动的被玩家打playchannel中attach,然后auto pl_old = m_attach_objs.find(attacher->objId);if(pl_old != m_attach_objs.end())    pl_old->second.hurt += hurt;//伤害积累,仇恨else//{    AttObject attobj = {hurt, -1, att_pl};    m_attach_objs[att_pl->objId] = attobj;//加入了攻击对象}m_is_attached = true;is_move = false;//优先追踪被攻击的玩家。if(Monster被动State != EnumMonster被冲撞) //因为被撞和被打回产生冲突    Monster被动State = EnumMonster被攻击; //停顿下死亡之后经过60秒,这样根据运行AI的速度,如果运行速度是1000ms那就是,60s置为重生状态重生之后使其游荡

今天看到那个定时器是100ms,然后运行60次怎么回事1分钟,找了半天原来现在怪物有了速度的概念

bool NPC::isRunAI(){    unsigned int now = GetTickCount();    if(now - cur_run_time < cur_run_speed//当时看这个正好是1000,所以本来是100ms的,强制成了1s,我找了半天才知道咋回事。    {        return false;    }    cur_run_time = now;    return true;}