一、前言
人工智能,这是一个很深奥的话题。我们这里的怪物也要智能一点,至少会自动找英雄来打吧。
二、正文
现在我才开始看怪物的头文件
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 &x,const pair &y);
private:
std::map hateMap;
bool debugMode;
};
```
同样,Monster也有一个initWithMessage方法来用MonsterMessage来初始化属性。
下面我们讲一讲如何实现关于怪物对英雄的仇恨值
在头文件里面,我们只需要关注一个成员变量
std::map hateMap;
键值就是攻击者的二级指针,值就是仇恨值
还有这几个函数。
1.initHateMap 初始化仇恨值map
void Monster::initHateMap(){
std::list 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::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> 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& 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(m_target);
m->addHateValue(m_sender,m_HateValue);
}
this->removeFromParentAndCleanup(true);
}
}
```
新的子弹update函数,除了会触发目标的injured函数之外,如果目标是一个怪物的话,还会为调用其addHateValue()
现在真相大白了。
越攻击一个怪物,怪物对你的仇恨值就会越高,就会先攻击你。
好的,现在我们的怪物是不是有点智能了呢。
我的csdn地址:http://blog.csdn.net/hezijian22
邮箱地址:578690286@qq.com
如有问题或指教,欢迎与我交流,谢谢。