在上篇我们完成了子弹和地图碰撞的检测,在这篇我们将完成敌方坦克AI的编写。

具体思路是屏幕中保持有四个敌方坦克,然后坦克随机方向运动,并且子弹消失后1秒发射一次

1.我们新建一个敌方坦克的AI类来控制地方坦克AI行为:

static const char* enemyTankType[] =
{
"normalU.png", "speedU.png", "armor1U.png"
}; class EnemyAI
{
public:
EnemyAI();
~EnemyAI(); static EnemyAI* createEnemyAIWithTank(Tank* tank);
void initEnemyAIWithTank(Tank* tank);
void update(float delta); private:
void addTank(float delta);
void tankAction(float delta); private:
CCArray* mEnemyTanks;
Tank* mTank;
TileMapInfo* mTileMapInfo; //出现地点
CCPoint bornPoint[3];
};

上面目前只添加三种类型的敌方坦克,

在成员变量中,mEnemyTanks存放了所有的坦克,

mTank存放了玩家坦克,最后mTileMapInfo存放了地图信息。

bornPoint存放了敌方坦克出身的三个位置。

2.先实现void EnemyAI::initEnemyAIWithTank(Tank* tank)来初始化我们的EnemyAI类:

void EnemyAI::initEnemyAIWithTank(Tank* tank)
{
mTank = tank;
mTileMapInfo = tank->getTileMapInfo();
mEnemyTanks = CCArray::createWithCapacity(4);
mEnemyTanks->retain(); //初始化出现地点
CCSize mapSize = mTileMapInfo->getTileMap()->getContentSize();
CCSize tileSize = mTileMapInfo->getTileMap()->layerNamed("layer_0")->getMapTileSize();
bornPoint[0] = ccp(tileSize.width, mapSize.height - tileSize.height);
bornPoint[1] = ccp(mapSize.width / 2, mapSize.height - tileSize.height);
bornPoint[2] = ccp(mapSize.width - tileSize.width, mapSize.height - tileSize.height);
}

在上面我们初始化了敌方坦克出身的三个地点,然后创建了一个容量为4的数组mEnemyTanks来存放敌方坦克对象。

3.再实现静态方法返回EnmeyAI类指针:

EnemyAI* EnemyAI::createEnemyAIWithTank(Tank* tank)
{
EnemyAI* enemyTank = new EnemyAI();
enemyTank->initEnemyAIWithTank(tank); return enemyTank;
}

4.实现void EnemyAI::addTank(float delta):

其中delta是每一帧调用之间的事件间隔

void EnemyAI::addTank(float delta)
{
static float deltaTimes = 0.0f;
deltaTimes += delta;
if (deltaTimes >= 2.0f)
{
deltaTimes = 0.0f;
int count = mEnemyTanks->count();
if (count < 3) //先从固定位置添加三个坦克
{
Tank* enemyTank = Tank::createTankWithTankType(enemyTankType[count], mTileMapInfo);
enemyTank->setPosition(bornPoint[count]);
enemyTank->setRotation(180.0f);
mEnemyTanks->addObject(enemyTank);
}
else if (count == 3) //第四个坦克随机添加
{
int tankTypeIndex = (int)(CCRANDOM_0_1() * 4) % 3;
Tank* enemyTank = Tank::createTankWithTankType(enemyTankType[tankTypeIndex], mTileMapInfo);
enemyTank->setPosition(bornPoint[tankTypeIndex]);
enemyTank->setRotation(180.0f);
mEnemyTanks->addObject(enemyTank);
}
}
}

可以看到deltaTimes累加时间,超过2秒就开始添加坦克,初始三个坦克从固定位置添加,

然后第四个坦克随机位置添加。

5.实现void EnemyAI::tankAction(float delta),来控制坦克行为:

void EnemyAI::tankAction(float delta)
{
CCObject* pObj;
CCARRAY_FOREACH(mEnemyTanks, pObj)
{
Tank* tank = (Tank*)pObj; //坦克自动移动,碰到墙壁自动换方向
int Rotation = tank->getRotation();
if (!tank->command((enumOrder)(Rotation / 90 + 1)))
{
int n = (int)(CCRANDOM_0_1() * 5) % 5;
if (n != 0)
tank->command((enumOrder)n);
} //每隔一秒开一次火
tank->setBulletDelta(tank->getBulletDelta() + delta);
if (tank->getBulletDelta() > 0.5)
{
//开火后,如果子弹在飞行中,归零计时
if (tank->command(cmdFire))
{
tank->setBulletDelta(0.0);
}
}
}
}

从mEnemyTanks中遍历坦克对象,然后向固定方向移动,遇到墙壁则随机换方向移动。

在下面,子弹消失后,隔0.5秒再次发射子弹。

6.最后实现我们的void EnemyAI::update(float delta),它会在每一帧切换的时候被调用。

void EnemyAI::update(float delta)
{
//坦克不足4个,补充坦克
addTank(delta); //坦克行为控制
tankAction(delta);
}

可以看到,简单的调用添加坦克函数和控制坦克行为函数。

7.下面我们把敌人的AI类整合到CityScene场景中:

bool  CityScene::init()
{
CCLayer::init(); //初始化地图信息
char szRound[260];
sprintf(szRound, "Round%d.tmx", mRound);
TileMapInfo* tileMapInfo = TileMapInfo::createMapInfoWithFile(szRound);
CCTMXTiledMap* tmxTileMap = tileMapInfo->getTileMap();
this->addChild(tmxTileMap); //在已有的地图上,创建玩家坦克
mPlayerTank[0] = Tank::createTankWithTankType("player2U.png", tileMapInfo); //放到地图中初始化位置
CCSize tileSize = tmxTileMap->getTileSize();
CCSize mapSize = tmxTileMap->getContentSize();
mPlayerTank[0]->setPosition(ccp(mapSize.width / 2 - tileSize.width * 3, tileSize.height)); //添加虚拟手柄的显示
mLayerPanel = Panel::create();
addChild(mLayerPanel, 3); //创建敌人坦克的AI
mEnemyAI = EnemyAI::createEnemyAIWithTank(mPlayerTank[0]); return true;
}

//创建敌人坦克的AI
mEnemyAI = EnemyAI::createEnemyAIWithTank(mPlayerTank[0]);

可以看到最后面创建了我们的AI。

8.我们在场景的update中调用AI的update函数

void CityScene::update(float delta)
{
CCLayer::update(delta);
//将控制面板中的mLayerPanel获取的命令传给坦克
if (mPlayerTank[0] != NULL)
mPlayerTank[0]->command(mLayerPanel->getOrder()); //调用敌人AI的update
mEnemyAI->update(delta);
}

到这里基本的坦克AI构建完成,我们运行下看看效果:

完整代码下载地址:

http://download.csdn.net/detail/yincheng01/6764095

cocos2d-x游戏开发系列教程-坦克大战游戏之敌方坦克AI的编写的更多相关文章

  1. HTML5游戏开发系列教程6(译)

    原文地址:http://www.script-tutorials.com/html5-game-development-lesson-6/ 这是我们最新一篇HTML5游戏开发系列文章.我们将继续使用c ...

  2. HTML5游戏开发系列教程7(译)

    原文地址:http://www.script-tutorials.com/html5-game-development-lesson-7/ 今天我们将完成我们第一个完整的游戏--打砖块.这次教程中,将 ...

  3. HTML5游戏开发系列教程5(译)

    原文地址:http://www.script-tutorials.com/html5-game-development-lesson-5/ 最终我决定准备下一篇游戏开发系列的文章,我们将继续使用can ...

  4. HTML5游戏开发系列教程4(译)

    原文地址:http://www.script-tutorials.com/html5-game-development-lesson-4/ 这篇文章是我们继续使用canvas来进行HTML5游戏开发系 ...

  5. cocos2d-x游戏开发系列教程-坦克大战游戏启动界面的编写

    用前面介绍的方法,创建一个cocos2d-x项目,可以看到新项目内容如下图:

  6. HTML5游戏开发系列教程8(译)

    原文地址:http://www.script-tutorials.com/html5-game-development-lesson-8/ 这是我们最新一篇HTML5游戏开发系列文章.我们将继续使用c ...

  7. HTML5游戏开发系列教程10(译)

    原文地址:http://www.script-tutorials.com/html5-game-development-lesson-10/ 最后我们将继续使用canvas来进行HTML5游戏开发系列 ...

  8. HTML5游戏开发系列教程9(译)

    原文地址:http://www.script-tutorials.com/html5-game-development-lesson-9/ 今天我们将继续使用canvas来进行HTML5游戏开发系列的 ...

  9. cocos2d-x游戏开发系列教程-坦克大战游戏之子弹的碰撞检测处理

    在上篇我们加上了简单的坦克之间的碰撞检测,这篇我们继续加上子弹之间, 子弹与坦克之间的碰撞检测,对于上一篇碰撞处理不太完美的地方我们继续改进. 1.子弹之间的碰撞 //玩家子弹和敌方子弹之间的碰撞 C ...

  10. cocos2d-x游戏开发系列教程-坦克大战游戏之所有坦克之间的碰撞检测

    上篇我们完成了简单的AI编写,但是各个坦克移动时之间是可以重合的, 这节课我们来完成坦克之间的碰撞检测,还是在上篇的EnemyAI中完成. 1.我先现在坦克类Tank中添加两个成员变量: CC_SYN ...

随机推荐

  1. C - N皇后问题(搜索)

    Description 在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上. 你的任务是,对于给定的N,求出有多少种合 ...

  2. Android目录结构介绍&Android学习之hello world

    分类: 嵌入式 一个android项目有如下目录: src:这里放的是我们编写的源代码 gen:这里的是eclipse自动生成的文件,不用管它 asssts:放置文件 res:也是放置文件,不同的是r ...

  3. _int64、long long 的区别

    C++的64位整数[原]by 赤兔 http://baike.baidu.com/view/1235293.htm 在做ACM题时,经常都会遇到一些比较大的整数.而常用的内置整数类型常常显得太小了:其 ...

  4. Web性能优化方案

    第一章 打开网站慢现状分析 在公司访问部署在IDC机房的VIP网站时会感觉很慢.是什么原因造成的?为了缩短页面的响应时间,改进我们的用户体验,我们需要知道用户的时间花在等待什么东西上. 可以跟踪一下我 ...

  5. VC++非MFC项目中如何使用TRACE宏

    记得原来尝试学MFC的时候觉得有一个TRACE可以在Debug时向VS的调试输出窗口输出字串符,用来调试时跟踪变量很方便. 然则如果不是MFC项目或者ATL的项目的话是不能使用这个宏的.这时有一个没有 ...

  6. Tomcat7 + JRebel6.3.0 + IntelliJ idea 热部署配置过程+错误分析

    以前使用Tomcat的时候直接就可以热部署,现在换了一个使用Spring框架的项目突然就不能热部署了. 网上说在tomcat里conf/context.xml中加入 <Context antiJ ...

  7. [置顶] JAVA概述(6)常量,关键字,进制转换

    21.关键字.... 变量: 就是将不确定的数据进行存储.也就是需要在内粗恩中开辟一个空间. 整数类型   1个字节 byte                    占 8位 -128~~~127 2 ...

  8. source code of MES Data

    <HTML> <HEAD> <TITLE>TELOGS</TITLE> </HEAD> <BODY> <?php /* c ...

  9. MDK常见错误详解集合

    错误代码及错误信息 错误释义 error 1: Out of memory 内存溢出 error 2: Identifier expected 缺标识符 error 3: Unknown identi ...

  10. CMarkUp接口说明

    CMarkup是一个小型XML的分析器,实现语言是C++,英文版的接口说明地址为:http://www.firstobject.com/dn_markupmethods.htm 有厉害的网友已经翻译出 ...