cocos2dx3.2开发 RPG《Flighting》(十二)让怪物智能点——怪物仇恨值

前端之家收集整理的这篇文章主要介绍了cocos2dx3.2开发 RPG《Flighting》(十二)让怪物智能点——怪物仇恨值前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

一、前言

人工智能,这是一个很深奥的话题。我们这里的怪物也要智能一点,至少会自动找英雄来打吧。

二、正文

现在我才开始看怪物的头文件

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

如有问题或指教,欢迎与我交流,谢谢。

猜你在找的Cocos2d-x相关文章