主人公能够放子弹了,虽然子弹看起来很美,但是怎么样来打到妖怪?

在这一章我们介绍一下最简单的碰撞检测方法去实现它。

首先第一个,我们有必要保存每个妖怪和子弹的指针,来够追踪他们的位置。

在这个游戏中我们增加两个tag标志去辨别CCNode对象是子弹还是妖怪。tag == 1表示他是一个妖怪,tag == 2 表示他是一个子弹。CCNode有一个m_nTag属性,我们可以使用getTag()/setTag()来访问它,CCSprite是CCNode的子类,我们可以利用这个。

先在HellowWorld类中添加两个成员变量来存储,在HelloWorldScene.h里声明一下。

  1. // cpp with cocos2d-x
  2. protected:
  3. cocos2d::CCArray *_targets;
  4. cocos2d::CCArray *_projectiles;

译注:原文中使用的CCMutableArray……但是在新版本中已经被直接废弃了,我们现在使用CCArray,他也是可变长数组,没有模板功能,使用时需要强制转换。

同时,在HelloWorldScene.h里声明HelloWorld的构造函数和析构函数,在HelloWorldScene.cpp里进行初始化:

  1. HelloWorld::~HelloWorld()
  2. {
  3. //cocos2d定义的宏,它等价于以下代码
  4. //if (_targets)
  5. //{
  6. // _targets->release();
  7. // _targets = NULL;
  8. //}
  9. CC_SAFE_RELEASE_NULL(_targets);
  10. CC_SAFE_RELEASE_NULL(_projectiles);
  11.  
  12. // 记得把析构函数声明为虚函数
  13. }
  14.  
  15. HelloWorld::HelloWorld():_targets(NULL)
  16. ,_projectiles(NULL)
  17. {
  18. _targets = new CCArray();
  19. _projectiles = new CCArray();
  20. }

然后修改一下addTarget方法,在方法的最后,设置妖怪的tag,并且加入到数组里:

  1. // cpp with cocos2d-x
  2. // Add to targets array
  3. target->setTag();
  4. _targets->addObject(target);

同理在 ccTouchesEnded 方法最后,设置子弹的tag并且加入到数组

  1. // cpp with cocos2d-x
  2. // 设置tag并且加入到数组
  3. projectile->setTag();
  4. _projectiles->addObject(projectile);

然后还要修改一下spriteMoveFinished方法,因为在他们被从父节点中移除的同时,也需要将他们从数组中移除。

  1. // cpp with cocos2d-x
  2. void HelloWorld::spriteMoveFinished(CCNode* sender)
  3. {
  4. CCSprite *sprite = (CCSprite *)sender;
  5. this->removeChild(sprite, true);
  6.  
  7. // 从 tag 判断类型从对应的数组中移除
  8. if (sprite->getTag() == )
  9. {
  10. _targets->removeObject(sprite);
  11. }
  12. else if (sprite->getTag() == )
  13. {
  14. _projectiles->removeObject(sprite);
  15. }
  16. }

下面的update方法将检查碰撞,并且移除碰撞的子弹和妖怪。

  1. // cpp with cocos2d-x
  2. void HelloWorld::update(float dt)
  3. {
  4. CCArray* projectilesToDelete = new CCArray();
  5. CCObject* pobject;
  6.  
  7. // cocos2d定义的宏,提供方便的只读遍历CCARRAY写法
  8. CCARRAY_FOREACH(_projectiles, pobject)
  9. {
  10. CCSprite* projectile = (CCSprite*)pobject;
  11. CCRect pRect = CCRect(projectile->getPosition().x - projectile->getContentSize().width/,
  12. projectile->getPosition().y - projectile->getContentSize().height/,
  13. projectile->getContentSize().width,
  14. projectile->getContentSize().height);
  15.  
  16. CCArray* targetsToDelete = new CCArray();
  17. CCObject* tobject;
  18. CCARRAY_FOREACH(_targets, tobject)
  19. {
  20. CCSprite* target = (CCSprite*)tobject;
  21. CCRect tRect = CCRect(target->getPosition().x - target->getContentSize().width/,
  22. target->getPosition().y - target->getContentSize().height/,
  23. target->getContentSize().width,
  24. target->getContentSize().height);
  25.  
  26. // 碰撞测试
  27. if( pRect.intersectsRect( tRect ) )
  28. {
  29. targetsToDelete->addObject( target );
  30. }
  31. }
  32.  
  33. // 移除被击中的目标
  34. CCARRAY_FOREACH(targetsToDelete, tobject)
  35. {
  36. CCSprite* target = (CCSprite*)tobject;
  37. _targets->removeObject(target);
  38. this->removeChild(target, true);
  39. }
  40.  
  41. // 记录击中目标的子弹
  42. if(targetsToDelete->count() > )
  43. {
  44. targetsToDelete->addObject(projectile);
  45. }
  46.  
  47. /* 由于我们是用的 new CCArray() 而非 CCArray::create()
  48. 获得的数组对象,所以需要手动调用release */
  49. targetsToDelete->release();
  50. }
  51.  
  52. // 移除击中目标的子弹
  53. CCARRAY_FOREACH(projectilesToDelete, pobject)
  54. {
  55. CCSprite* projectile = (CCSprite*)pobject;
  56. _projectiles->removeObject(projectile, true);
  57. this->removeChild(projectile, true);
  58. }
  59.  
  60. projectilesToDelete->release();
  61. }

OK~最后我们在HelloWorld::init方法最后添加一行代码,让游戏在每秒钟60次的刷新画面时调用HelloWorld::update方法

  1. this->scheduleUpdate();

大功告成!生成运行一下,看看是不是一打一个准!

Chapter5 – 碰撞检测的更多相关文章

  1. javascript动画系列第三篇——碰撞检测

    前面的话 前面分别介绍了拖拽模拟和磁性吸附,当可视区域内存在多个可拖拽元素,就出现碰撞检测的问题,这也是javascript动画的一个经典问题.本篇将详细介绍碰撞检测 原理介绍 碰撞检测的方法有很多, ...

  2. 使用 JavaScript 和 canvas 做精确的像素碰撞检测

    原文地址:Pixel accurate collision detection with Javascript and Canvas 译者:nzbin 我正在开发一个需要再次使用碰撞检测的游戏.我通常 ...

  3. JavaScript动画-碰撞检测

    ▓▓▓▓▓▓ 大致介绍 碰撞检测是指在页面中有多个元素时,拖拽一个元素会出现碰撞问题,碰撞检测是以模拟拖拽和磁性吸附中的范围限定为基础的 效果:碰撞检测 ▓▓▓▓▓▓ 碰撞检测 先来看看碰撞检测的原理 ...

  4. Unity3d刚体Rigidbody与碰撞检测Collider

    做了一个碰撞的小Demo,用一个球去撞击一堵墙,结果在球和墙都设置了刚体和碰撞体的情况下,球穿过了墙.移动球的位置,球有时能穿过墙,有时会被墙阻挡. 对于球穿过了墙,这个问题,在网上找了一下答案,基本 ...

  5. UIDynamic(重力行为+碰撞检测)

    一.重力行为 说明:给定重力方向.加速度,让物体朝着重力方向掉落 1.方法 (1)UIGravityBehavior的初始化 - (instancetype)initWithItems:(NSArra ...

  6. [Unity3D插件]2dToolKit系列三 碰撞检测功能的实现以及障碍物的随机摆放

    貌似有一段时间没更新2dtoolkit系列了,这段时间一直在忙着其他事情,今天开始继续这个插件系列的教程,网上搜索,貌似关于这个插件的教程无非还是跟官方的教程很类似,有的甚至都没有自己照着亲手实践一遍 ...

  7. javascript中矩形的碰撞检测---- 计算碰撞部分的面积

    今天在做一个拖拽改变元素排序的东西的时候,在做被拖动元素同时碰撞到两个元素时,究竟应该与哪个元素交换位置的问题上,纠结到崩溃,实在是想不到别的办法去做了,只能去想办法计算碰撞的面积. 这应该不是最合适 ...

  8. 写一些封装part1 (事件绑定移除,圆形矩形碰撞检测)

    var EventHandle = { addEvent:function(ele,type,handle){ if (ele.addEventListener) { ele.addEventList ...

  9. windows编程:画线,简单的碰撞检测,简单的帧率锁定

    #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <windowsx.h> #include <mmsy ...

随机推荐

  1. excel转化为Json

    Sheet sheet;        Workbook book;        Cell cell1,cell2,cell3,cell4;        JSONArray jsonArray = ...

  2. HDU - 1702 ACboy needs your help again!(栈和队列)

    Description ACboy was kidnapped!! he miss his mother very much and is very scare now.You can't image ...

  3. HDU 3265 Posters ——(线段树+扫描线)

    第一次做扫描线,然后使我对线段树的理解发生了动摇= =..这个pushup写的有点神奇.代码如下: #include <stdio.h> #include <algorithm> ...

  4. struts体系结构

    问题:   为什么 invoke()方法,一旦执行,表示action方法执行完毕,jsp页面已经处理完毕: 其返回值再修改无意义,不影响结果?? 解释: 着重看如下颜色的字: ■ ■ 官方文档有明确的 ...

  5. ONES 安装、配置以及初始化配置

    环境依赖 bower composer php 5.5.9+ mysql 5.6.5+ PHP和MySQL版本均为最低要求版本,安装前请先确认. 通过CLI安装 $ git clone http:// ...

  6. maven 教程一 入门

    摘要: (1)maven是项目管理工具,类似makefile.主要的生命阶段有 validate:验证工程是否正确,所有需要的资源是否可用.  compile:编译项目的源代码.    test:使用 ...

  7. UI和UE有什么区别呢?

    UCD(以用户为中心的设计)UE(用户体验)UI(用户界面)HCI(人机交互)usability(易用性)

  8. HDU 2846 Repository(字典树)

    字典树较为复杂的应用,我们在建立字典树的过程中需要把所有的前缀都加进去,还需要加一个id,判断它原先是属于哪个串的.有人说是AC自动机的简化,但是AC自动机我还没有做过. #include<io ...

  9. Hadoop集群搭建的密钥配置SSH实现机制

  10. Struts2利用注解实现action跳转

    使用注解来配置Action的最大好处就是可以实现零配置,但是事务都是有利有弊的,使用方便,维护起来就没那么方便了. 要使用注解方式,我们必须添加一个额外包:struts2-convention-plu ...