cocos2dx基础篇(25) 简单碰撞检测
【3.x】
将数学类 CCPoint、CCRect 改为v3.x版本的 Vec2、Rect 就好了。
【简单碰撞检测】
在一些游戏中经常会遇到碰撞检测的情况,如愤怒的小鸟飞出去后,是否与石头发生碰撞。
虽然说有一个Box2D物理碰撞引擎,但是在这里还是需要掌握一下简单的碰撞检测方法。
(1)矩形与矩形
(2)圆与圆
(3)矩形与圆
1、矩形与矩形
1.1、提出问题
问题:假设有两个矩形rect1,rect2,判断两矩是否碰撞相交(部分区域重叠)。
如下四幅图中,图1、2、4发生碰撞,图3未发生碰撞。


1.2、解决方案
由图可知,判断方法只要计算一下两个矩形相交部分是否能够成一个小矩形。
判断方法如下:(可用于计算相交部分的小矩形信息)
//
bool collision_RectWithRect(CCRect rect1, CCRect rect2)
{
//计算相交部分的矩形
//左下角坐标:( lx , ly )
//右上角坐标:( rx , ry )
float lx = max(rect1.getMinX() , rect2.getMinX() );
float ly = max(rect1.getMinY() , rect2.getMinY() );
float rx = min(rect1.getMaxX() , rect2.getMaxX() );
float ry = min(rect1.getMaxY() , rect2.getMaxY() );
//判断是否能构成小矩形
if( lx > rx || ly > ry ) return false; //矩形不相交
else return true; //发生碰撞
}
//
当然也可以使用cocos2dx引擎中的CCRect类已经存在的一个判断矩形碰撞的函数。
//
//返回bool。相交为true
rect1.intersectsRect(rect2);
//
//
//intersectsRect()函数的源码如下:
bool CCRect::intersectsRect(const CCRect& rect) const
{
return !( getMaxX() < rect.getMinX() ||
rect.getMaxX() < getMinX() ||
getMaxY() < rect.getMinY() ||
rect.getMaxY() < getMinY());
}
//
2、圆与圆
2.1、提出问题
问题:假设有两个圆circle1,circle2,判断两圆是否碰撞相交(部分区域重叠)。
如下三幅图中,图1、2发生碰撞,图3未发生碰撞。


2.2、解决方案
圆的碰撞检测比较简单,只要判断两圆心距离是否小于半径相加(r1+r2)即可。
判断方法如下:
//
bool collision_CircleWithCircle(CCPoint p1, float r1, CCPoint p2, float r2)
{
//计算圆心距离
float dist = p1.getDistance(p2);
//判断两圆是否相交
return dist < (r1+r2) ;
}
//
3、矩形与圆
3.1、提出问题
问题:假设有矩形rect、圆circle,判断矩形和圆是否碰撞相交(部分区域重叠)。
如下四幅图中,图1、2、4发生碰撞,图3未发生碰撞。


3.2、解决方案
矩形和圆的判断比较复杂,请看以下分析。
(1)首先,我们让圆在矩形外沿着矩形的边滚一圈,然后将圆心移动的轨迹连线,就可以得到一个圆角矩形。
(2)如下图红色区域为圆角矩形,显然我们只要判断圆心是否在圆角矩形区域内部即可。

(3)如果除去圆角矩形四个角上的4个四分之一圆的部分,仅仅让你判断圆心是否落在剩下的区域内,你应该能很快想出解决办法吧?
只要判断圆心是否在两个矩形的任意其中之一的内部即可。

(4)然后再判断圆心是否在四个角上的四分之一圆的区域部分即可。
显然,只要判断圆心与矩形的四个顶点的距离是否小于圆的半径即可。
(5)综合上诉:(3)(4)的判断,即可得出圆是否矩形相交。
判断方法如下:
//
bool collision_RectWithCircle(CCRect rect, CCPoint p, float r)
{
//获取矩形信息
//左下角坐标:( lx , ly )
//右上角坐标:( rx , ry )
float lx = rect.getMinX();
float ly = rect.getMinY();
float rx = rect.getMaxX();
float ry = rect.getMaxY();
//计算圆心到四个顶点的距离
float d1 = p.getDistance( ccp(lx, ly) );
float d2 = p.getDistance( ccp(lx, ry) );
float d3 = p.getDistance( ccp(rx, ly) );
float d4 = p.getDistance( ccp(rx, ry) );
//判断是否碰撞
//判断距离是否小于半径
if( d1<r || d2<r || d3<r || d4<r ) return true;
//是否在圆角矩形的,横向矩形内
if( p.x > (lx-r) && p.x < (rx+r) && p.y > ly && p.y < ry ) return true;
//是否在圆角矩形的,纵向矩形内
if( p.x > lx && p.x < rx && p.y > (ly-r) && p.y < (ry+r) ) return true;
//不发生碰撞
return false;
}
//
cocos2dx基础篇(25) 简单碰撞检测的更多相关文章
- cocos2dx基础篇(3) 常用重要类
---------------------------------------- 入口类main.cpp 主要控制类AppDelegate.cpp -------------------------- ...
- 自动化测试基础篇--Selenium简单的163邮箱登录实例
摘自https://www.cnblogs.com/sanzangTst/p/7472556.html 前面几篇内容一直讲解Selenium Python的基本使用方法.学习了什么是selenium: ...
- cocos2dx基础篇(23) 粒子系统CCParticleSystem
[3.x] (1)去掉"CC" (2)粒子位置模式 tPositionType 改为强枚举类型 ParticleSystem::PositionType:: // ...
- cocos2dx基础篇(16) 基本绘图DrawPrimitives
[3.x] (1)去掉前缀 "cc" (2)将 ccDraw***() 封装到了 DrawPrimitives 命名空间中. (3)重写绘图函数: draw(Ren ...
- 【Cocos2d入门教程二】Cocos2d-x基础篇
上一章已经学习了环境的搭建.这一章对基础概念进行掌握.内容大概有: 1.导演 2.场景 3.节点 4.层 4.精灵 1.导演(Director) 导演存在的主要作用: a.环境设定(帧率 初始化ope ...
- cocos2dx基础篇(22) 基本动画CCAnimation/CCAnimate
[小知识] CCSpriteFrame :精灵帧. 它是相对动画而产生的,其实就是一张纹理图片. CCAnimationFrame :动画帧. 由精灵帧与间隔帧数组成,是动画CC ...
- cocos2dx基础篇(4) 标签CCLabel
[本节内容] cocos2dx三种文字字体的显示:CCLabelTTF(一般字体).CCLabelAtlas(自定义字体).CCLabelBMFont(自定义字体) CCLabelTTF CCLabe ...
- cocos2dx基础篇(18) 数据存储CCUserDefault
在cocos2dx中提供了一个数据存储类CCUserDefault,可以作为一个轻量级的数据库来使用.它支持五种数据bool.int.float.double.string的存储. [3.x] ...
- cocos2dx基础篇(15) 列表视图CCTableView
[3.x] (1)去掉 "CC" (2)TableViewCell 中: > unsigned int getIdx() 返回类型改为 ssize_t(类型为 long) ( ...
随机推荐
- ArcMap常用操作
1.矢量数据融合 数据管理->制图综合->融合 Data Management Tools -> Generalization -> Dissolve
- wx小程序知识点(五)
五.双向绑定和 vue 的区别 ① vue 中实现双向绑定只需要修改 this.data var vm = new Vue({ el: '#example', data: { message: 'He ...
- Travis CI Could not find or load main class org.gradle.wrapper.GradleWrapperMain 错误
问题 在 Travis CI 编译的时候出现 Error: Could not find or load main class org.gradle.wrapper.GradleWrapperMain ...
- Presto部署指南
1.Presto简介说明 Presto是一个开源的分布式SQL查询引擎,适用于交互式分析查询,数据量支持GB到PB字节. Presto的设计和编写完全是为了解决像Facebook这样规模的商业数据仓库 ...
- postman如何绕过登录账户和密码验证,进行接口测试的方法
实测于:2019.01.08 参考原文:https://yq.aliyun.com/ziliao/403942 一.获取登录后的cookie数据 1.打开浏览器: 2.启用开发者模式(F12键): 3 ...
- python学习之路(21)
偏函数 Python的functools模块提供了很多有用的功能,其中一个就是偏函数(Partial function).要注意,这里的偏函数和数学意义上的偏函数不一样. 在介绍函数参数的时候,我们讲 ...
- java正则表达式详细总结
Java 提供了功能强大的正则表达式API,在java.util.regex 包下.本教程介绍如何使用正则表达式API. 正则表达式 一个正则表达式是一个用于文本搜索的文本模式.换句话说,在文本中搜索 ...
- Dijk入门(杭电2544题)
#include<iostream> #include<cstring> using namespace std; #define INF 0x3f3f3f3f int n,m ...
- 详讲KMP算法
两个字符串: 模式串:ababcaba 文本串:ababcabcbababcabacaba KMP算法作用:快速在文本串中匹配到模式串 如果是穷举法的方式: 大家有发现,这样比效率很低的. 所以就需要 ...
- “fatal error: hdf5.h: 没有那个文件或目录”解决方法
問題一: Installing Caffe without CUDA: fatal error: cublas_v2.h No such file: 在Makefile.config中修改,將CPU_ ...