低级怪物---一般是不能动的怪物,固定在原处,不断的发动攻击,然后根据英雄的方位,不断改变子弹的朝左还是朝向,如游戏中的炮台等。
中级怪物----初步有一些智商了,主要表现在当英雄在它的攻击范围内,能够知道英雄的位置,就以一定的比例判断是否进行攻击。如若不然,平时都是自己按照一定的路线进行行走,又或者是随机走动。然后攻击随机出动,只有当英雄在它的攻击范围内,它才会不再走动,原地以概率判断是否要进行攻击
高级怪物-----BOSS级怪物,它有自己的可视范围区,当英雄陷入它的可视范围区时,它就追着英雄跑。可视范围区内,还有个攻击范围区,当英雄陷入攻击范围区内时,怪物就按一定的概率出动攻击,这个概率一般比较大。然后,如果英雄不在怪物的可视范围区内时,怪物它有自己的巡逻路线,它按照这个路线不断的走,总会发现到英雄,英雄你再怎么跑,它都会跟着你。
主要是通过怪物与玩家的位置关系才去不同的策略,主要功能通过以下的方法实现:
//在可视范围内,怪物跟随英雄运动 void FollowRun(Node* m_hero,Node* m_map); //判断是否攻击 void JudegeAttack(); //怪物巡逻路线 void MonsterSeeRun(); //怪物启动监听英雄 void StartListen(Node* m_hero,Node* m_map); //监听函数,每隔3秒检测下,计算英雄与怪物的距离 void updateMonster(float delta); //更新函数,如果英雄在可视范围内,不断触发 void update(float delta);
Node* my_hero;//当前英雄 Node* my_map;//当前地图 float dis;//当前怪物和英雄的距离函数实现部分:
void Monster::FollowRun(Node* m_hero,Node* m_map) { //得到两点x的距离,记得怪物的坐标要加上地图的 float x = m_hero->getPositionX()-(this->getPositionX()+m_map->getPositionX()); //得到两点y的距离,记得怪物的坐标要加上地图的 float y = m_hero->getPositionY()-(this->getPositionY()+m_map->getPositionY()); //先计算怪物和英雄的距离 dis = sqrt(pow(x,2) + pow(y,2)); if(dis>=300)//当怪物与英雄距离超过300 return; if(dis<=100)//在怪物攻击范围内,怪物停止移动 { this->StopAnimation();//停止跑动 JudegeAttack();//以一定的概率判断是是否出动攻击 return; } if(x<-100)//判断怪物横坐标和英雄的距离 { MonsterDirecton=true; m_MonsterSprite->setFlippedX(MonsterDirecton);//设置方向 if(IsAttack) return; this->setPosition(this->getPositionX()-1,this->getPositionY());//怪物向英雄移动 this->SetAnimation("monster_run",6,MonsterDirecton);//播放动画 } else if(x>100) { MonsterDirecton=false; m_MonsterSprite->setFlippedX(MonsterDirecton);//设置方向 if(IsAttack) return; this->setPosition(this->getPositionX()+1,this->getPositionY()); this->SetAnimation("monster_run",MonsterDirecton);//播放动画 } else if(x<=100 || x >-100)//怪物橫坐標和英雄相差在100以内时,开始移动怪物纵坐标 { if(m_hero->getPositionY()>this->getPositionY()) { m_MonsterSprite->setFlippedX(MonsterDirecton);//设置方向 if(IsAttack) return; this->setPosition(this->getPositionX(),this->getPositionY()+1); this->SetAnimation("monster_run",MonsterDirecton);//播放动画 } else if(m_hero->getPositionY()<this->getPositionY()) { m_MonsterSprite->setFlippedX(MonsterDirecton);//设置方向 if(IsAttack) return; this->setPosition(this->getPositionX(),this->getPositionY()-1); this->SetAnimation("monster_run",MonsterDirecton);//播放动画 } } } void Monster::JudegeAttack() { //srand(time(NULL)); int x = random(0,100); log("-------%d",x); if(x>50) { this->AttackAnimation("monster_attack",5,MonsterDirecton); } } void Monster::MonsterSeeRun() { if(dis<300) return; this->SetAnimation("monster_run",MonsterDirecton);//播放动画 MoveBy *moveby1; if(MonsterDirecton==true) moveby1=MoveBy::create(1,Vec2(-70,0)); else moveby1=MoveBy::create(1,Vec2(70,0)); //创建回调动作,巡逻路线完后 // auto callFunc=CallFunc::create(this,callfunc_selector(Monster::StopAnimation)); auto callFunc = CallFunc::create( CC_CALLBACK_0(Monster::StopAnimation,this)); //创建连续动作 auto xunluo=Sequence::create(moveby1,callFunc,NULL); this->runAction(xunluo); } //启动监听 void Monster::StartListen(Node* m_hero,Node* m_map) { my_hero=m_hero; my_map=m_map; this->schedule(schedule_selector(Monster::updateMonster),3.0f);//每隔3秒计算距离 this->scheduleUpdate();//英雄一旦进入可视范围,怪物追着英雄打 } //监听函数,每隔3秒检测下 void Monster::updateMonster(float delta) { //得到两点x的距离,记得怪物的坐标要加上地图的 float x = my_hero->getPositionX()-(this->getPositionX()+my_map->getPositionX()); //得到两点y的距离,记得怪物的坐标要加上地图的 float y = my_hero->getPositionY()-(this->getPositionY()+my_map->getPositionY()); //先计算怪物和英雄的距离 dis = sqrt(pow(x,2)); if(dis>=300) { if(!IsRunning) MonsterSeeRun(); } } void Monster::update(float delta) { if(dis<300)///当英雄在它的可视范围内,不断追着英雄 FollowRun(my_hero,my_map); }对于这一块的讲解Evakaka已经讲的非常明白的了,只不过我第一次看见这句的时候也有点小小的疑惑
//得到两点x的距离,2));为什么要加上地图的坐标呢,我想表达式要是写成这样会更清晰一些:
//得到两点x的距离,记得怪物的坐标要加上地图的 float x = (m_hero->getPositionX()+m_map->getPositionX())-this->getPositionX(); //得到两点y的距离,记得怪物的坐标要加上地图的 float y = (m_hero->getPositionY()+m_map->getPositionY())-(this->getPositionY()); //先计算怪物和英雄的距离 dis = sqrt(pow(x,2));当hero移动的屏幕一般的时候,hero就只是做移动的动作,而真正移动的是map,所以如果仅仅比较hero和monster的
距离,肯定是要出错的。
工程下载...
PS:多写博客,帮助自己,方便他人!
原文链接:https://www.f2er.com/cocos2dx/344515.html