接上一节内容:cocos2dx - tmx地图分层移动处理

本节怪物及简单AI实现

一、怪物

  cocos2dx - v2.3.3编辑器骨骼动画 里创建的CPlalyer一样,新建一个CMonster类,也可以提出一个公共基类IEntity,为了以后扩展其他类型的实体做准备。

这里怪物还要有一个AI的实体类CAIModule类。

相对玩家主要添加以下:

//init方法中添加如下

        m_pAIModule = CAIModule::create();
this->addChild(m_pAIModule);

同时对移动和攻击进行修改

void CMonster::Move(float delta)
{
if (isFloatZero(delta))
{
PlayAction(enAction::ACT_DEFAULT);
if (m_pAIModule)
{
// 移动结束回调
m_pAIModule->OnActionCallback();
}
}
else
{
float fspeed = ; // px/fps
float dx = delta;
if (isFartherThan(dx, fspeed))
{
dx = dx > ? fspeed : -fspeed;
}
setPositionX(getPositionX() + dx);
m_deltaX = delta - dx;
PlayAction(ACT_RUN);
// 设置当前的方向
setScaleX(delta >? - : );
}
}
// 攻击结束动作处理
      m_pAction->play("attack", false);
std::function<void()> func = [this](){
    m_pAction->play("default", true);
      m_nActType = ACT_DEFAULT;
      if (m_pAIModule)
      {
          // 攻击结束回调
           m_pAIModule->OnActionCallback();
       }
      };
       m_pAction->setLastFrameCallFunc(func);  

以上主要在移动和攻击结束的时候调用了AI模块的动作回调。

二、AI模块

本节只是实现最简单的AI机制,直接将策略写在了update中,在间隔一个THINKTIME时间后判断当前最优行动,并执行动作。

如下:

void CAIModule::update(float dt)
{
m_nThinkTime += int(dt*);
if (m_nThinkTime>THINKTIME)
{
if (CMonster* pMonster = dynamic_cast<CMonster*>(getParent()))
{
m_stepFunc = nullptr;
if (CPlayer* pPlayer = CBattleMgr::getInstance()->GetPlayer())
{
if (m_pTarget)
{
m_pTarget->release();
m_pTarget = nullptr;
}
m_pTarget = pPlayer;
m_pTarget->retain(); m_nStep = ;
m_nThinkTime = ;
float dis = pMonster->getPosition().distance(pPlayer->getPosition());
if (dis <)
{
m_stepFunc = std::bind(&CAIModule::Attack, this, std::placeholders::_1, std::placeholders::_2);
Attack(pPlayer, m_nStep);
//attack
}
else
{
m_stepFunc = std::bind(&CAIModule::Move2Node, this, std::placeholders::_1, std::placeholders::_2);
Move2Node(pPlayer, m_nStep);
//move to pos ;
}
}
}
}
}

以上直接设定AI执行对象为玩家,在距离小于200执行攻击,否则向玩家节点靠近移动。同时清楚当前 m_nThinkTime时间,在下一个决策时间到来之前怪物会根据动作步骤持续执行当前动作。

所以这里也需要设置一下动作的当前m_nStep为0,同时设置一下执行的函数m_stepFunc。

为了能够在怪物攻击或者移动结束后m_nStep执行到下一步,实现了一个OnActionCallback函数。如下:

void CAIModule::OnActionCallback()
{
if (m_stepFunc)
{
++m_nStep;
m_stepFunc(m_pTarget, m_nStep);
}
}

这样即可实现简单的AI移动效果,让拥有该AI对象的怪物,不断靠近玩家并且攻击玩家。
CAIModule全代码如下:

#ifndef __CAIModule_H__
#define __CAIModule_H__
#include "IGameDef.h"
#include "cocos2d.h"
USING_NS_CC;
class CAIModule : public Node
{
public:
// implement the "static create()" method manually
CREATE_FUNC(CAIModule); virtual bool init(); void update(float dt); void OnActionCallback();
private: void Attack(Node* pEnemy, int step); void Move2Node(Node* pNode,int step); CAIModule();
~CAIModule(); int m_nStep; // 当前操作的步骤数
float m_nThinkTime; // 操作的间隔事件 Node* m_pTarget; std::function<void(Node* node, int step)> m_stepFunc;
}; #endif __CAIModule_H__ #include "AIModule.h"
#include "Monster.h"
#include "BattleMgr.h"
#define THINKTIME (1000) // 决策时间
CAIModule::CAIModule() :m_nThinkTime(THINKTIME), m_pTarget(nullptr), m_stepFunc(nullptr), m_nStep()
{
} CAIModule::~CAIModule()
{
if (m_pTarget)
{
m_pTarget->release();
m_pTarget = nullptr;
}
} bool CAIModule::init()
{
scheduleUpdate();
return true;
} void CAIModule::update(float dt)
{
m_nThinkTime += int(dt*);
if (m_nThinkTime>THINKTIME)
{
if (CMonster* pMonster = dynamic_cast<CMonster*>(getParent()))
{
m_stepFunc = nullptr;
if (CPlayer* pPlayer = CBattleMgr::getInstance()->GetPlayer())
{
if (m_pTarget)
{
m_pTarget->release();
m_pTarget = nullptr;
}
m_pTarget = pPlayer;
m_pTarget->retain(); m_nStep = ;
m_nThinkTime = ;
float dis = pMonster->getPosition().distance(pPlayer->getPosition());
if (dis <)
{
m_stepFunc = std::bind(&CAIModule::Attack, this, std::placeholders::_1, std::placeholders::_2);
Attack(pPlayer, m_nStep);
//attack
}
else
{
m_stepFunc = std::bind(&CAIModule::Move2Node, this, std::placeholders::_1, std::placeholders::_2);
Move2Node(pPlayer, m_nStep);
//move to pos ;
}
}
}
}
} void CAIModule::Attack(Node* pEnemy, int step)
{
CMonster* pMonster = dynamic_cast<CMonster*>(getParent());
if (!pMonster)
{
return;
} switch (step)
{
case :
{
if (!pEnemy)
{
return;
}
// 立即攻击
if (isFartherThan(pMonster->getPositionX() < pEnemy->getPositionX(), ))
{
Attack(pEnemy,);
}
else
{
// 太近,移动远一点
m_nStep =;
Move2Node(pEnemy,);
}
}
break;
case :
{
if (!pEnemy)
{
return;
}
// 调整方向准备攻击
pMonster->setScaleX(pMonster->getPositionX() < pEnemy->getPositionX() ? - : );
++m_nStep;
std::function<void()> func = [this]()
{
Attack(nullptr,);
};
this->runAction(Sequence::create(DelayTime::create(0.3), CallFunc::create(func), NULL));
}
break;
case :
{
// 直接攻击
pMonster->Attack();
}
break;
default:
// m_nThinkTime = THINKTIME;
break;
}
} void CAIModule::Move2Node(Node* pNode, int step)
{
if (!pNode)
{
return;
}
CMonster* pMonster = dynamic_cast<CMonster*>(getParent());
if (!pMonster)
{
return;
} switch (step)
{
case :
{
if (pMonster->getPositionX() < pNode->getPositionX())
{
pMonster->Move(pNode->getPositionX() - - pMonster->getPositionX());
}
else
{
pMonster->Move(pNode->getPositionX() + - pMonster->getPositionX());
}
}
break;
default:
// m_nThinkTime = THINKTIME;
break;
}
} void CAIModule::OnActionCallback()
{
if (m_stepFunc)
{
++m_nStep;
m_stepFunc(m_pTarget, m_nStep);
}
}

附上实现后的效果图:

1、这是自动朝着玩家走

  

2、这是在靠近玩家后进行攻击

  

cocos2dx - 生成怪物及AI的更多相关文章

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

    原创文章,转载请注明出处:http://www.cnblogs.com/zisou/p/cocos2d-xARPG4.html 谈到怪物AI,我觉得就比较话多了,首先理解一下(Artificial I ...

  2. Demo_塔防(自动生成怪物,导航,炮塔攻击,怪物掉血死忙)

    using UnityEngine; using System.Collections; public struct WaveMsg { //该波次生成的怪物 public GameObject mo ...

  3. Cocos2d-x 生成真正的随机数

    关于随机数 cocos2d-x 定义了一个宏 CCRANDOM_0_1 生成的是 [0, 1] 之间的值 因此,要生成  [0-100] 之间的数    CCRANDOM_0_1 * 100 生成 [ ...

  4. cocos2d-x生成随机数

            //获取系统时间         //time_t是long类型,精确到秒,通过time()函数可以获得当前时间和1970年1月1日零点时间的差         time_t tt; ...

  5. 随机生成文章的AI(C++)

    #include <iostream> #include <cstdlib> #include <ctime> #include <fstream> u ...

  6. cocos2dx - 伤害实现

    接上一节内容:cocos2dx - 生成怪物及AI 本节主要讲如何通过创建简单的矩形区域来造成伤害 在小游戏中简单的碰撞需求应用box2d等引擎会显得过于臃肿复杂,且功能不是根据需求定制,还要封装,为 ...

  7. 《MFC游戏开发》笔记九 游戏中的碰撞判定初步&怪物运动简单AI

    本系列文章由七十一雾央编写,转载请注明出处. http://blog.csdn.net/u011371356/article/details/9374935 作者:七十一雾央 新浪微博:http:// ...

  8. 七夕节来啦!AI一键生成情诗,去发给你的女朋友吧!

    [摘要] Hello大家好,今天就是七夕节了,为了增进和女朋友之间的情感,我写了一个自动生成情诗的AI: 大家可以在ModelArts尝试复现模型,然后快去发给你们的女朋友吧- 大家好,我是b站up主 ...

  9. 【cocos2d-x 手游研发----地图活起来了】

    谈到地图不少人都说要做地图编辑器了,但是我暂时绕过这一步,如果不用寻路地图就不能移动?寻路就是会绕过障碍物的算法. 我做了一个简单的地图的思想,就是地图分层3层:背景层.可行区域层.遮罩层,但是地图就 ...

随机推荐

  1. 个人作业3——个人总结(Alpha阶段)

    Deadline: 2017-5-15 22:00PM,以博客发表日期为准 评分基准: 按时交 - 有分,检查的项目个人总结内容 晚交 - 0分 迟交一周以上 - 倒扣本次作业分数 抄袭 - 倒扣本次 ...

  2. 201521123091 《Java程序设计》第5周学习总结

    Java 第五周总结 第五周的作业. 目录 1.本章学习总结 2.Java Q&A 3.使用码云管理Java代码 4.PTA实验 1.本章学习总结 1.1 尝试使用思维导图总结有关多态与接口的 ...

  3. 201521123014 《Java程序设计》第6周学习总结

    1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图,对面向对象思想进行一个总结. 1.2 可选:使用常规方法总结其他上课内容. GUI与Sw ...

  4. 201521123105 《Java程序设计》第1周学习总结

    1.学习总结      简单学习jave 了解并区分JVM JRE JDK 了解JAVA语言的发展史 2.书面作业        Q:为什么java程序可以跨平台运行?执行java程序的步骤是什么?( ...

  5. 201521123004《Java程序设计》第9周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容. 答:思维导图如下: Java中使用try-catch语法处理异常: try { 可能产生异常的代码段 }catch ...

  6. 201521123078 《Java程序设计》第14周学习总结

    1. 本周学习总结 2. 书面作业 1. MySQL数据库基本操作 建立数据库,将自己的姓名.学号作为一条记录插入.(截图,需出现自己的学号.姓名) 在自己建立的数据库上执行常见SQL语句(截图) 2 ...

  7. javascript面向对象编程笔记

    对象:一切事物皆是对象.对象是一个整体,对外提供一些操作.比如说一个收音机是一个对象,我们不需要知道它的内部结构是什么,只需要会使用外部的按钮就可以使用收音机. 面向对象:面向对象语言的标志是他们都有 ...

  8. JavaEE error整理(不断更新)

    该文章用于整理开发中遇到的一些错误,及解决方法,不断整理更新. 1. 缺包异常 异常1:java.lang.NoClassDefFoundError: org/apache/commons/loggi ...

  9. mount挂载和交换分区swap

    目录 mount挂载 挂载方法 选项 查看设备 卸载命令 文件挂载配置文件fstab 交换文件与分区 swap优先级 三个工具free,df,du 扩展 移动介质 使用光盘 挂载USB设备 mount ...

  10. 接口测试入门(3)--使用httpClient进行登录用例操作/set-cookies验证/ List<NameValuePair>设置post参数/json解析

    (最近学的都是很基础的接口测试,都是基于UI界面可见的接口,就是发请求,接收响应,分析返回的结果,校验,对共通模块进行封装,仅此而已,其实做自动化的思路基本都是如此,UI也是.) 现在开始用httpC ...