cocos2d-x封神榜(4) -- 【怪物智能AI】

转载 2013年12月05日 14:46:50

      谈到怪物AI,我觉得就比较话多了,首先理解一下(Artificial Intelligence人工智能),人工智能是计算机科学的一个分支,人工智能是计算机科学技术的前沿科技领域。人工智能与计算机软件有密切的关系。各种人工智能应用系统都要用计算机软件去实现,许多聪明的计算机软件也应用了人工智能的理论方法和技术。

      总而言之,言而总之,我理解的AI就是:用人类自己的思考模式去赋予游戏中角色判断的能力,来进行某些特定的行为!

      下面具体图文介绍一下,我在游戏中一些实用的AI制作思路;

 

 

      这是这个思路就可以让怪物捕获玩家,并且追踪玩家攻击的一个图示!这个思路是基本,最终决策怪物是否去执行这个行为的操作算法又是一个AI智能,所以咱们又可以分为:

决策AI:可以根据怪物等级,怪物的类型(BOSS),怪物技能类型等很多决策和根本属性相连所起作用的操作,都可以做成决策AI;

行为AI:追踪玩家,攻击玩家,给玩家加血(如同伴),逃跑等这些行为动作操作;

      OK,下面大家应该了解AI的基本思路了,那我们直接贴代码了;

      我直接把AI写在了地图层里面了,因为之前我框架的设计,是有一个地图base,而所有的怪物,主角色,NPC都属于地图层,因为要做很多遍历操作,所以在地图base中写上智能AI算法,然后再继承拓展下来。

      首先先制造一群怪物!并且让怪物在设置的Rect内随机移动!

/********************************************
注释:
makenum 最大怪物数量
monsteridtags 怪物起始标签
randomrange 配置怪圈大小(只能填正整数)
monster_model 怪物数据
yinzihigth 影子的距离
fristpoint 怪物初始设定的怪圈点
*********************************************/
void Maps_Diyu::makemonster(int makenum,int monsteridtags,CCPoint randomrange,MainRoledata monster_model,int yinzihigth,CCPoint fristpoint)
{
    for (int i = 0; i < makenum; i++)
    {
        int add_x = (int)(CCRANDOM_MINUS1_1()*randomrange.x);
        int add_y =(int)(CCRANDOM_MINUS1_1()*randomrange.y);
        monster_model.tags=monsteridtags+i;
        monster_model.nowpoint= CCPointMake(nowmap->getContentSize().width/2+fristpoint.x+add_x,nowmap->getContentSize().height/2+fristpoint.y+add_y);
        SpiritsMonster* newmonster = new SpiritsMonster(monster_model,1,yinzihigth);
        nowmap->addChild(newmonster->monster, 1,monsteridtags+i);
    }
}
      然后处理怪物的行为AI:

/********************************************
注释:
monsternum 最大怪物数量
monsteridtags 怪物起始标签
monster_model 怪物数据
reatR 怪物仇恨视角的范围值(通常200左右)
attck_reatR 怪物可攻击范围值(远程怪和物理怪物)
playerpoint 主角坐标
randomrange 怪物默认随机移动范围
fristpoint 怪物初始设定的怪圈点
*********************************************/
void Maps_Diyu::attact_todo(int monsternum,int monsteridtags ,MainRoledata monster_model,int reatR,int attck_reatR,CCPoint playerpoint,CCPoint randomrange,CCPoint fristpoint)
{
    for (int i = 0; i < monsternum; i++)
    {
        CCRect* attck_rect = new CCRectMake(this->getChildByTag(monsteridtags+i)->getPosition().x-attck_reatR/2,this->getChildByTag(monsteridtags+i)->getPosition().y-attck_reatR/2,attck_reatR,attck_reatR);
        if(attck_rect->containsPoint(playerpoint)==true)
        {
            //执行怪物攻击主角
            CCLog(FontChina::G2U("进入怪物可攻击范围"));
            //攻击时改变方向
            SpiritsMonster::attackTomainRole_dir(ccp((int)playerpoint.x,(int)playerpoint.y),(CCSprite*)(this->getChildByTag(monsteridtags+i)),monster_model);
            //释放技能动画
            int add_x = (int)(CCRANDOM_MINUS1_1()*8);
            int add_y =(int)(CCRANDOM_MINUS1_1()*8);
            SkillEffects* skill = new SkillEffects(ccp((int)playerpoint.x+add_x,(int)playerpoint.y+add_y),monster_model,(0.2f+CCRANDOM_0_1()),8,3,1000);
            this->addChild(skill->effects_main,1000,50);
        }
        else
        {
            CCRect* track_rect = new CCRectMake(this->getChildByTag(monsteridtags+i)->getPosition().x-reatR/2,this->getChildByTag(monsteridtags+i)->getPosition().y-reatR/2,reatR,reatR);
            if(track_rect->containsPoint(playerpoint)==true)
            {
                //执行移动,不停追杀主角
                CCLog(FontChina::G2U("进入怪物仇恨视野区域"));
                //防止靠近主角,保持一定距离!主要为了好看和处理被攻击效果。
                int add_x = (int)(CCRANDOM_MINUS1_1()*25);
                int add_y =(int)(CCRANDOM_MINUS1_1()*25);
                //移动时改变方向
                SpiritsMonster::moveTomap_dir(ccp((int)playerpoint.x,(int)playerpoint.y),(CCSprite*)(this->getChildByTag(monsteridtags+i)),monster_model);
                CCArray* callbackArray = CCArray::create();
                int nowtags = monsteridtags+i;
                char strs[64];
                sprintf(strs,"%d",nowtags);
                CCString* ccnowtags = CCString::create(strs);
                callbackArray->addObject(ccnowtags);
                callbackArray->addObject(monster_model.spiritname);
                char dir_x[64];
                sprintf(dir_x,"%d",(int)this->getChildByTag(nowtags)->getPositionX());
                char dir_y[64];
                sprintf(dir_y,"%d",(int)this->getChildByTag(nowtags)->getPositionY());
                CCString* d_x = CCString::create(dir_x);
                CCString* d_y = CCString::create(dir_y);
                callbackArray->addObject(d_x);
                callbackArray->addObject(d_y);
                CCFiniteTimeAction *actbackfun = CCCallFuncO::create(this, callfuncO_selector(Maps_Diyu::moveoverCallBack),callbackArray);
                CCActionInterval* act_movexixue = CCMoveTo::create(3+CCRANDOM_MINUS1_1(),ccp((int)playerpoint.x+add_x,(int)playerpoint.y+add_y));
                this->getChildByTag(nowtags)->runAction(CCSequence::create(act_movexixue,actbackfun,NULL));
            }
            else
            {
                //脱离仇恨时,随机定点周围移动
                int stopandrun = (int)(CCRANDOM_MINUS1_1()*10);
                if(stopandrun>=1)
                {
                    //脱离仇恨
                    int add_x = (int)(CCRANDOM_MINUS1_1()*randomrange.x);
                    int add_y =(int)(CCRANDOM_MINUS1_1()*randomrange.y);
                    CCPoint move_dir = ccp(this->getContentSize().width/2+fristpoint.x+add_x,this->getContentSize().height/2+fristpoint.y+add_y);

                    SpiritsMonster::moveTomap_dir(ccp((int)move_dir.x,(int)move_dir.y),(CCSprite*)(this->getChildByTag(monsteridtags+i)),monster_model);
                    CCArray* callbackArray = CCArray::create();
                    int nowtags = monsteridtags+i;
                    char strs[64];
                    sprintf(strs,"%d",nowtags);
                    CCString* ccnowtags = CCString::create(strs);
                    callbackArray->addObject(ccnowtags);
                    callbackArray->addObject(monster_model.spiritname);
                    char dir_x[64];
                    sprintf(dir_x,"%d",(int)this->getChildByTag(nowtags)->getPositionX());
                    char dir_y[64];
                    sprintf(dir_y,"%d",(int)this->getChildByTag(nowtags)->getPositionY());
                    CCString* d_x = CCString::create(dir_x);
                    CCString* d_y = CCString::create(dir_y);
                    callbackArray->addObject(d_x);
                    callbackArray->addObject(d_y);
                    CCFiniteTimeAction *actbackfun = CCCallFuncO::create(this, callfuncO_selector(Maps_Diyu::moveoverCallBack),callbackArray);
                    CCActionInterval* act_movexixue = CCMoveTo::create(3+CCRANDOM_MINUS1_1(),ccp(move_dir.x,move_dir.y));
                    this->getChildByTag(nowtags)->runAction(CCSequence::create(act_movexixue,actbackfun,NULL));

                }
            }
        }
    }
}

      这段逻辑包括了,如果玩家进入怪物的仇恨区域,那么怪物会先移动到玩家附近的点(此时玩家移动开,怪物会根据定时器去判断下一步如何操作:如1,玩家移动后还在仇恨区域,那么继续追踪玩家;2,如果玩家脱离仇恨,那么怪物执行回到初始坐标点的操作,然后继续原地巡逻!),如果此时玩家已经在怪物的攻击范围内了,那么怪物会直接选择攻击!这样怪物就会变得貌似有了思想一样,他会去考虑判断各种行为,那个区域我该做什么?不该做什么?

      有了这个逻辑,我们还要赋予怪物循环思考的能力!

//启动所有怪物智能AI监听器
    nowmap->schedule(schedule_selector(Maps_Diyu::makemonsterAttack), (3.0f)); 

      我们根据定时器去每隔3秒内去监控行为AI!

      整个行为AI已经完毕!就可以实现比较智能的怪物追杀主角了!这也就牵扯到了游戏难度怪物难度的问题了,往往好玩的游戏智能AI都占用了程序一半以上时间去处理;怪物并不是血多,防御高他就是一个BOSS,如果BOSS他会满地图追着玩家打,会自己加血,逃跑,那这样的BOSS我们作为玩家来说,打起来也比较刺激有意思,有挑战!

这篇就写这么多了,下回分解一下游戏界面UI交互的一些东西,充分运用定时器去管理一些玩家对屏幕基本操作的逻辑;

[Unity3D]Unity3D游戏开发之怪物AI

在上一篇文章中,我们基本上实现了一个小地图的功能,今天呢,我们来实现怪物AI,所谓怪物AI就是指我们为怪物编写一定的算法,使其可以具备一定程度的智能化,以增强游戏的可玩性。在一般的RPG游戏中,怪物通...
  • qinyuanpei
  • qinyuanpei
  • 2014年04月01日 18:52
  • 15090

怪物AI之发现玩家(视觉范围发现系列)

怪物AI之发现玩家(视觉范围发现系列)在网上找到一些资料参考,然后写写自己的想法。 这里感谢MOMO等大神。我们用玩家检测怪物的方法来测,这样比较试用与弱联网游戏,每次在同步玩家的时候来判断玩家与怪...
  • yangshbb
  • yangshbb
  • 2016年05月13日 21:16
  • 555

ARPG游戏中怪物AI实现

目前项目组正在做的是一款ARPG于MMO结合的游戏,下面游戏中AI实现的方式。一 AI配置1 配置说明AI配置使用python脚本,实现方式上使用伪行为树的结构,实现约定好关键字的意思,结构如下:ai...
  • xufeng0991
  • xufeng0991
  • 2016年05月11日 21:59
  • 2661

< Unity 3D专栏 >游戏中 - 怪物AI基础篇

AI代码,值得收藏 using UnityEngine; using System.Collections; public class BoosAI : MonoBehaviour { /...
  • ycguhang
  • ycguhang
  • 2013年08月22日 23:28
  • 7902

【Unity3D自学记录】游戏开发之怪物AI

using UnityEngine; using System.Collections; public class BoosAI : MonoBehaviour { //敌人状态 ...
  • hackdjh
  • hackdjh
  • 2014年06月19日 16:44
  • 1531

打造动作游戏的怪物

下图为怪物战斗的组成部分。从怪物团队到怪物个体进行划分。时间不多的同学,可以先看看下图。     前言     横版动作格斗游戏中,我所接触最早的应该就属《双截龙I》了。单打的...
  • jamesliulyc
  • jamesliulyc
  • 2015年06月04日 12:17
  • 962

【cocos2d-x 手游研发----怪物智能AI】

原创文章,转载请注明出处:http://www.cnblogs.com/zisou/p/cocos2d-xARPG4.html   谈到怪物AI,我觉得就比较话多了,首先理解一下(Arti...
  • sun___shine
  • sun___shine
  • 2016年05月24日 19:29
  • 309

实现敌人(怪物)的简单AI(自动巡逻、看到玩家攻击玩家、玩家离开恢复自动巡逻)

 using UnityEngine; using UnityEngine.AI; /// /// 敌人自动巡逻 /// public class EnemyMove : Mono...
  • Libiao_Li
  • Libiao_Li
  • 2017年06月23日 09:41
  • 305

怪物如何追随玩家_怪物AI

1.png (130.6 KB, 下载次数: 0) 下载附件  保存到相册 5 天前 上传 1.将下面的脚本挂在怪物身上 2.设置玩家Tag为Player 3...
  • cl110cl
  • cl110cl
  • 2014年08月12日 09:51
  • 1584

教你如何制作怪物智能AI(转)

转自:http://cocos2d.9tech.cn/news/2013/1112/38577.html 谈到怪物AI,我觉得就比较话多了,首先理解一下(Artificial Intelligenc...
  • hhy018
  • hhy018
  • 2013年11月22日 14:57
  • 1056
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:cocos2d-x封神榜(4) -- 【怪物智能AI】
举报原因:
原因补充:

(最多只允许输入30个字)