一、前言
人工智能,这是一个很深奥的话题。我们这里的怪物也要智能一点,至少会自动找英雄来打吧。
二、正文
现在我才开始看怪物的头文件
class Monster : public Role{ public: Monster(); static Monster* create(const std::string& name,FlightLayer* layer); void initMonster(); virtual Point getHpSliderPos(); void addHateValue(Role* sender,int HateValue); void initWithMessage(const MonsterMessage& msg); private: virtual void update(float dt); void updateMonsterAttackTarget(); void initHateMap(); void refreshHateMap(); virtual void injured(int damage); Role** getHatest(); bool cmpHate(const pair<Role_Ptr,int> &x,const pair<Role_Ptr,int> &y); private: std::map<Role_Ptr,int> hateMap; bool debugMode; };
同样,Monster也有一个initWithMessage方法来用MonsterMessage来初始化属性。
在头文件里面,我们只需要关注一个成员变量
std::map<Role_Ptr,int> hateMap;
键值就是攻击者的二级指针,值就是仇恨值
还有这几个函数。
1.initHateMap 初始化仇恨值map
void Monster::initHateMap(){ std::list<Role_Ptr> temp = m_layer->getRolesArray(); for(auto it = temp.begin();it!=temp.end();++it){ if((**it)->getRoleType() == Role::ROLE_TYPE_HERO || (**it)->getRoleType() == Role::ROLE_TYPE_NULL){ hateMap.insert(make_pair((*it),0)); } } }也是通过m_layer获取全部的role,并且将是英雄的放进来
2.updateMonsterAttackTarget 在update函数中被调用
void Monster::updateMonsterAttackTarget(){ initHateMap(); refreshHateMap(); if(hateMap.size()==0){ return; } if(getHatest()){ this->setAttackTarget(getHatest()); } if(m_attackTarget == nullptr){ int size = hateMap.size(); int randnum = rand()%size; CCLOG("SIZE = %d,RAND = %d",size,randnum); int i = 1; map<Role_Ptr,int>::iterator it; for(it=hateMap.begin();it!=hateMap.end() && i < randnum;++it){ ++i; } this->setAttackTarget(it->first); return; } }大概就是获取仇恨值最高的(getHatest),设置为攻击目标,如果没有最高的,就随机找一个英雄
3.refreshHateMap
void Monster::refreshHateMap(){ for(auto HMit = hateMap.begin();HMit!= hateMap.end();){ if(*(*HMit).first == nullptr){ HMit = hateMap.erase(HMit); }else{ ++HMit; } }将死了的英雄的仇恨值记录清理掉
4.getHateset
Role** Monster::getHatest(){ vector<pair<Role_Ptr,int>> tempVec; for(auto it = hateMap.begin();it!=hateMap.end();it++){ tempVec.push_back(*it); } sort(tempVec.begin(),tempVec.end(),std::bind(&Monster::cmpHate,this,std::placeholders::_1,std::placeholders::_2)); if((*tempVec.begin()).second == 0){ return nullptr; } Role** ret = (*tempVec.begin()).first; return ret; }获取仇恨值最高的
5.addHateValue
void Monster::addHateValue(Role* sender,int HateValue){ auto tempIt = find_if(hateMap.begin(),hateMap.end(),[=](const pair<Role_Ptr,int>& x)->bool{ if(*x.first == sender){ return true; }else{ return false; }}); if(tempIt!=hateMap.end()){ (*tempIt).second += HateValue; } }
有没有发现一个问题?哪里来的仇恨值呢?哪里有调用过addHateValue?
这里我把仇恨值的添加放到子弹里面了,可以说,是一颗颗带着仇恨的子弹
void Bullet::update(float dt){ m_target = *m_targetPtr; if(!m_target){ this->removeFromParentAndCleanup(true); return; } if(!m_target->getBoundingBox().containsPoint(this->getPosition())){ float distance = ccpDistance(getPosition(),m_target->getPosition()+Vec2(0,m_target->getContentSize().height)); float t = distance / m_speed; float speed_x = (m_target->getPositionX() - getPositionX()) / t; float speed_y = (m_target->getPositionY()+ m_target->getContentSize().height/2 - getPositionY()) / t; setPositionX(getPositionX() + speed_x); setPositionY(getPositionY() + speed_y); }else{ m_target->injured(m_effect,m_damage); if(m_target->getRoleType()==Role::ROLE_TYPE_MONSTER){ Monster* m = dynamic_cast<Monster*>(m_target); m->addHateValue(m_sender,m_HateValue); } this->removeFromParentAndCleanup(true); } }新的子弹update函数,除了会触发目标的injured函数之外,如果目标是一个怪物的话,还会为调用其addHateValue()
现在真相大白了。
越攻击一个怪物,怪物对你的仇恨值就会越高,就会先攻击你。
好的,现在我们的怪物是不是有点智能了呢。
我的csdn地址:http://blog.csdn.net/hezijian22
邮箱地址:578690286@qq.com
如有问题或指教,欢迎与我交流,谢谢。