Chapter5 – 碰撞检测
主人公能够放子弹了,虽然子弹看起来很美,但是怎么样来打到妖怪?
在这一章我们介绍一下最简单的碰撞检测方法去实现它。
首先第一个,我们有必要保存每个妖怪和子弹的指针,来够追踪他们的位置。
在这个游戏中我们增加两个tag标志去辨别CCNode对象是子弹还是妖怪。tag == 1表示他是一个妖怪,tag == 2 表示他是一个子弹。CCNode有一个m_nTag属性,我们可以使用getTag()/setTag()来访问它,CCSprite是CCNode的子类,我们可以利用这个。
先在HellowWorld类中添加两个成员变量来存储,在HelloWorldScene.h里声明一下。
// cpp with cocos2d-x
protected:
cocos2d::CCArray *_targets;
cocos2d::CCArray *_projectiles;
译注:原文中使用的CCMutableArray……但是在新版本中已经被直接废弃了,我们现在使用CCArray,他也是可变长数组,没有模板功能,使用时需要强制转换。
同时,在HelloWorldScene.h里声明HelloWorld的构造函数和析构函数,在HelloWorldScene.cpp里进行初始化:
HelloWorld::~HelloWorld()
{
//cocos2d定义的宏,它等价于以下代码
//if (_targets)
//{
// _targets->release();
// _targets = NULL;
//}
CC_SAFE_RELEASE_NULL(_targets);
CC_SAFE_RELEASE_NULL(_projectiles); // 记得把析构函数声明为虚函数
} HelloWorld::HelloWorld():_targets(NULL)
,_projectiles(NULL)
{
_targets = new CCArray();
_projectiles = new CCArray();
}
然后修改一下addTarget方法,在方法的最后,设置妖怪的tag,并且加入到数组里:
// cpp with cocos2d-x
// Add to targets array
target->setTag();
_targets->addObject(target);
同理在 ccTouchesEnded 方法最后,设置子弹的tag并且加入到数组
// cpp with cocos2d-x
// 设置tag并且加入到数组
projectile->setTag();
_projectiles->addObject(projectile);
然后还要修改一下spriteMoveFinished方法,因为在他们被从父节点中移除的同时,也需要将他们从数组中移除。
// cpp with cocos2d-x
void HelloWorld::spriteMoveFinished(CCNode* sender)
{
CCSprite *sprite = (CCSprite *)sender;
this->removeChild(sprite, true); // 从 tag 判断类型从对应的数组中移除
if (sprite->getTag() == )
{
_targets->removeObject(sprite);
}
else if (sprite->getTag() == )
{
_projectiles->removeObject(sprite);
}
}
下面的update方法将检查碰撞,并且移除碰撞的子弹和妖怪。
// cpp with cocos2d-x
void HelloWorld::update(float dt)
{
CCArray* projectilesToDelete = new CCArray();
CCObject* pobject; // cocos2d定义的宏,提供方便的只读遍历CCARRAY写法
CCARRAY_FOREACH(_projectiles, pobject)
{
CCSprite* projectile = (CCSprite*)pobject;
CCRect pRect = CCRect(projectile->getPosition().x - projectile->getContentSize().width/,
projectile->getPosition().y - projectile->getContentSize().height/,
projectile->getContentSize().width,
projectile->getContentSize().height); CCArray* targetsToDelete = new CCArray();
CCObject* tobject;
CCARRAY_FOREACH(_targets, tobject)
{
CCSprite* target = (CCSprite*)tobject;
CCRect tRect = CCRect(target->getPosition().x - target->getContentSize().width/,
target->getPosition().y - target->getContentSize().height/,
target->getContentSize().width,
target->getContentSize().height); // 碰撞测试
if( pRect.intersectsRect( tRect ) )
{
targetsToDelete->addObject( target );
}
} // 移除被击中的目标
CCARRAY_FOREACH(targetsToDelete, tobject)
{
CCSprite* target = (CCSprite*)tobject;
_targets->removeObject(target);
this->removeChild(target, true);
} // 记录击中目标的子弹
if(targetsToDelete->count() > )
{
targetsToDelete->addObject(projectile);
} /* 由于我们是用的 new CCArray() 而非 CCArray::create()
获得的数组对象,所以需要手动调用release */
targetsToDelete->release();
} // 移除击中目标的子弹
CCARRAY_FOREACH(projectilesToDelete, pobject)
{
CCSprite* projectile = (CCSprite*)pobject;
_projectiles->removeObject(projectile, true);
this->removeChild(projectile, true);
} projectilesToDelete->release();
}
OK~最后我们在HelloWorld::init方法最后添加一行代码,让游戏在每秒钟60次的刷新画面时调用HelloWorld::update方法
this->scheduleUpdate();
大功告成!生成运行一下,看看是不是一打一个准!
Chapter5 – 碰撞检测的更多相关文章
- javascript动画系列第三篇——碰撞检测
前面的话 前面分别介绍了拖拽模拟和磁性吸附,当可视区域内存在多个可拖拽元素,就出现碰撞检测的问题,这也是javascript动画的一个经典问题.本篇将详细介绍碰撞检测 原理介绍 碰撞检测的方法有很多, ...
- 使用 JavaScript 和 canvas 做精确的像素碰撞检测
原文地址:Pixel accurate collision detection with Javascript and Canvas 译者:nzbin 我正在开发一个需要再次使用碰撞检测的游戏.我通常 ...
- JavaScript动画-碰撞检测
▓▓▓▓▓▓ 大致介绍 碰撞检测是指在页面中有多个元素时,拖拽一个元素会出现碰撞问题,碰撞检测是以模拟拖拽和磁性吸附中的范围限定为基础的 效果:碰撞检测 ▓▓▓▓▓▓ 碰撞检测 先来看看碰撞检测的原理 ...
- Unity3d刚体Rigidbody与碰撞检测Collider
做了一个碰撞的小Demo,用一个球去撞击一堵墙,结果在球和墙都设置了刚体和碰撞体的情况下,球穿过了墙.移动球的位置,球有时能穿过墙,有时会被墙阻挡. 对于球穿过了墙,这个问题,在网上找了一下答案,基本 ...
- UIDynamic(重力行为+碰撞检测)
一.重力行为 说明:给定重力方向.加速度,让物体朝着重力方向掉落 1.方法 (1)UIGravityBehavior的初始化 - (instancetype)initWithItems:(NSArra ...
- [Unity3D插件]2dToolKit系列三 碰撞检测功能的实现以及障碍物的随机摆放
貌似有一段时间没更新2dtoolkit系列了,这段时间一直在忙着其他事情,今天开始继续这个插件系列的教程,网上搜索,貌似关于这个插件的教程无非还是跟官方的教程很类似,有的甚至都没有自己照着亲手实践一遍 ...
- javascript中矩形的碰撞检测---- 计算碰撞部分的面积
今天在做一个拖拽改变元素排序的东西的时候,在做被拖动元素同时碰撞到两个元素时,究竟应该与哪个元素交换位置的问题上,纠结到崩溃,实在是想不到别的办法去做了,只能去想办法计算碰撞的面积. 这应该不是最合适 ...
- 写一些封装part1 (事件绑定移除,圆形矩形碰撞检测)
var EventHandle = { addEvent:function(ele,type,handle){ if (ele.addEventListener) { ele.addEventList ...
- windows编程:画线,简单的碰撞检测,简单的帧率锁定
#define WIN32_LEAN_AND_MEAN #include <windows.h> #include <windowsx.h> #include <mmsy ...
随机推荐
- http协议--笔记
HTTP协议的缺点:1.通信使用明文(不加密),内容可能会被窃听2.不验证通信方的身份,因此有可能遭遇伪装3.无法证明报文的完整性,所以有可能已遭篡改 防止窃听保护信息的几种对策:加密技术通信的加密H ...
- Android----->多线程的实现Thread、IntentService的运用
首先建立一个Intent.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout x ...
- Nape 获取碰撞点加特效
package { import nape.phys.Body; import nape.shape.Shape; import nape.shape.Circle; import flash.dis ...
- linux自动化构建工具-scons指南
1.scons是linux下的自动构建工具 scons是用Python编写的,使用scons之前需确认是否已经安装了Python.(在系统的命令行中运行python -V或python --versi ...
- MFC 窗体背景图片设置
很多人在做MFC 界面的时候想要给对话框加入背景图片,很多人都会想到在OnPaint()里面来加一段代码来实现,其实这样做并不怎么科学,因为它会导致窗口不断重绘,在很多项目中窗口会闪烁(比如带播放视频 ...
- 修改document.domain的注意事项(转)
有时候,需要修改document.domain. 典型的情形:http://a.xxx.com/A.htm 的主页面有一个<iframe src="http://b.xxx.com/B ...
- 转: 两个 Shell 网站: explainshell 和 shellcheck
今天向大家介绍两个有意思的 Shell 网站,一个是 explainshell.com,另一个是 shellcheck.net. explainshell 先说 explainshell.explai ...
- UIView 面面观
原创:转载请注明出处 1.UIView: 一个视图对象控制该区域的渲染,同时也控制内容的交互. 2.UIView的功能就是:展示.渲染.交互 3.UIView 和很多其他视图控件的默认tag值是0,所 ...
- python之lambda、filter、map、reduce的用法说明
python中有一些非常有趣的函数,面试的时候可能会遇到.今天也来总结一下,不过该类的网上资料也相当多,也没多少干货,只是习惯性将一些容易遗忘的功能进行整理. lambda 为关键字.filter,m ...
- 修改Python文件日志输出位置
Python logging模块介绍:http://blog.chinaunix.net/uid-26000296-id-4372063.html [root@fuel ~]# vi /var/lib ...