上篇我们完成了简单的AI编写,但是各个坦克移动时之间是可以重合的,

这节课我们来完成坦克之间的碰撞检测,还是在上篇的EnemyAI中完成。

1.我先现在坦克类Tank中添加两个成员变量:

	CC_SYNTHESIZE(CCRect, mMovedRect, MovedRect);
CC_SYNTHESIZE(bool, IsBlock, Block);

mMovedRect是移动后的位置,目的是保存移动后的位置来检测碰撞,

如果发现与其他坦克碰撞了,则不执行移动动作;

IsBlock是用来标记坦克是否被碰撞的。

2.然后我们还得在Tank类中添加一个移动函数,根据是否阻塞来控制坦克移动:

	void move();

具体实现很简单,如下:

void Tank::move()
{
if (!IsBlock)
{
setPosition(ccp(mMovedRect.getMidX(), mMovedRect.getMidY()));
}
}

3.既然是碰撞检测,当然得有简单的碰撞函数先是检测两个矩形区域是否相交:

bool EnemyAI::IsRectIntersect(CCRect rectA, CCRect rectB)
{
float left = max(rectA.getMinX(), rectB.getMinX());
float right = min(rectA.getMaxX(), rectB.getMaxX());
if (left > right)
return false; float top = min(rectA.getMaxY(), rectB.getMaxY());
float bottom = max(rectA.getMinY(), rectB.getMinY());
if (top < bottom)
return false; return true;
}

如上,检测原理很简单,

假设A矩形在B矩形左边,那么A矩形的右边的X坐标小于B矩形左边的X坐标,

那么两个矩形不相交,反之A矩形在B矩形右边亦然。

在假设A矩形在B矩形上方或下方,检测原理和上面相同。

如果检测到矩形相交,则返回true。

4.我们再到EnemyAI中添加一个函数,来检测所有坦克之间的碰撞:

void EnemyAI::collisionTest()
{
//坦克和敌方坦克之间的碰撞检测
CCObject* pObj;
CCARRAY_FOREACH(mEnemyTanks, pObj)
{
Tank* enemyTank = (Tank*)pObj;
if (IsRectIntersect(mTank->getMovedRect(), enemyTank->getMovedRect()))
{
enemyTank->setBlock(true);
mTank->setBlock(true);
}
} //敌方坦克之间的碰撞
CCArray* ccTmpArray = CCArray::create();
ccTmpArray->addObjectsFromArray(mEnemyTanks);
while (ccTmpArray->count())
{
CCObject* pObj;
Tank* tmpTank = (Tank*)ccTmpArray->lastObject();
ccTmpArray->removeLastObject();
CCARRAY_FOREACH(ccTmpArray, pObj)
{
if (IsRectIntersect(tmpTank->getMovedRect(), ((Tank*)pObj)->getMovedRect()))
{
tmpTank->setBlock(true);
((Tank*)pObj)->setBlock(true);
ccTmpArray->removeObject(pObj);
}
}
}
}

如上,我们先单个检测玩家坦克和地方坦克的碰撞,然后检测敌方坦克之间的碰撞:

我们先从敌方坦克数组中取出一辆坦克,然后将他从数组中移除,

再跟其他所有坦克进行碰撞检测,如果发现有碰撞的坦克,设置他的IsBlock阻塞标记为true,

然后将它从数组中移除,如此循环,直到数组中所有坦克检测完成。

5.最后我们需要在EnemyAI中的void EnemyAI::tankAction(float delta)

中检测碰撞以及控制坦克行为:

void EnemyAI::tankAction(float delta)
{
CCObject* pObj;
CCARRAY_FOREACH(mEnemyTanks, pObj)
{
Tank* tank = (Tank*)pObj; //坦克按照上次的方向一直往前走
int Rotation = tank->getRotation();
tank->command((enumOrder)(Rotation / 90 + 1)); //坦克每隔一秒开一次火
tank->setBulletDelta(tank->getBulletDelta() + delta);
if (tank->getBulletDelta() > 1)
{
//开火后,如果子弹在飞行中,归零计时
if (tank->command(cmdFire))
{
tank->setBulletDelta(0.0);
}
} //检测坦克之间的碰撞
collisionTest(); //如果坦克阻塞,换个方向
if (tank->getBlock())
tank->setRotation((int)(CCRANDOM_0_1() * 3.2) * 90);
//如果上面的判断完成后,坦克根据自己的阻塞状态移动
tank->move();
}
mTank->move();
}

可以看到在检测了碰撞后,用move来控制坦克的移动。

下面我们编译运行程序看看效果:

完整代码下载地址:

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

cocos2d-x游戏开发系列教程-坦克大战游戏之所有坦克之间的碰撞检测的更多相关文章

  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 ...

随机推荐

  1. Mac 终端命令运行java

    链接地址:http://www.cnblogs.com/wangrui-techbolg/archive/2012/12/29/2839047.html 由于mac已经装好java环境,所以直接课运行 ...

  2. The Power of Reading——英语学习小技巧之七

    This method is "The Power of Reading" and it comes from an article by Dr.Stephen Krashen. ...

  3. HTML5 音频视频

    HTML5 视频和音频的 DOM 参考手册 HTML5 DOM 为 <audio> 和 <video> 元素提供了方法.属性和事件. 这些方法.属性和事件允许您使用 JavaS ...

  4. JQuery 实现返回顶部效果

    首先要里了解一下几个知识 $(window).scrollTop() ---滚动条距顶部距离 fadeIn() 方法使用淡入效果来显示被选元素,假如该元素是隐藏的. fadeOut() 方法使用淡出效 ...

  5. asp.net从客户端检测到有潜在危险的Request.Form 值

    asp.net开发中,经常遇到“从客户端检测到有潜在危险的Request.Form 值”错误提示,很多人给出的解决方案是: 1.web.config文档<system.web>后面加入这一 ...

  6. hdu 4679 (树形DP)

    题意:给一棵树,边的权值都是1,摧毁每条边是有代价的,选择摧毁一条边,把一棵树分成两部分,求出两部分中距离最大的两点的距离,求出距离*代价最小的边,多条的话输出序号最小的. 刚开始理解错题意了,wro ...

  7. 免费的HTML5连载来了《HTML5网页开发实例具体解释》连载(六)媒体查询

    响应式设计的还有一个重要技术手段是媒体查询.假设仅仅是简单的设计一个流式布局系统,那么能够保证每一个网格按比例的放大和缩小,但有可能会使得在小屏幕下(如手机设备)网格太小而严重影响阅读,这种设计称不上 ...

  8. ShareSDK for Android 只有新浪微博分享

    本文代码例子:http://pan.baidu.com/share/link?shareid=3710053477&uk=3189484501 ShareSDK 官方的例子非常好,但代码太多看 ...

  9. windows 下一个mysql password忘记改变

    到场mysql简介 my.ini 于[mysqld]以下被加入 skip-grant-tables win+R 热键 进cmd 然后输入命令net stop mysql  最后一点,使文件夹mysql ...

  10. iOS 最新UIAlertController

    iOS 8的新特性之一就是让接口更有适应性.更灵活,因此许多视图控制器的实现方式发生了巨大的变化.全新的UIPresentationController 在实现视图控制器间的过渡动画效果和自适应设备尺 ...