lua 碰撞检测
来源:互联网 发布:天堂2源码服务端 编辑:程序博客网 时间:2024/05/17 21:56
不规则图形碰撞检测
对于矩形碰撞,很多人都知道。但面对多边形图形,大多数采用多矩形覆盖的方式。
但是我不是很喜欢这种方式,我所采用的是利用一个经典算法:
SAT 一种可以快速检测不规则的凸多边形是否碰撞的算法
给出两个凸多边形体,如果我们能找到一个轴线,使两物体在此轴线上的投影不重叠,则这两个物体之间没有发生碰撞,这个轴线叫做Separating Axis(红色轴线)。
对于2D来说,红色线就是垂直与多边形边的轴。
因此,如果我们要检查两多边形是否碰撞,就去检查两多边形在每个所有可能的轴上的投影是否重叠。
/// <summary>
/// 检测2个矩形是否发生碰撞
/// </summary>
/// <returns></returns>
public static bool IsIntersect (Vector2[] A, Vector2[] B)
{
Vector2 AX, AY, BX, BY;
AX = new Vector2();
AY = new Vector2();
BX = new Vector2();
BY = new Vector2();
AX.X = A[0].X - A[1].X;
AX.Y = A[0].Y - A[1].Y;
AY.X = A[0].X - A[3].X;
AY.Y = A[0].Y - A[3].Y;
BX.X = B[0].X - B[1].X;
BX.Y = B[0].Y - B[1].Y;
BY.X = B[0].X - B[3].X;
BY.Y = B[0].Y - B[3].Y;
//对于AX上:
if (Tmp(AX, A, B)) return false;
if (Tmp(AY, A, B)) return false;
if (Tmp(BX, A, B)) return false;
if (Tmp(BY, A, B)) return false;
return true;
}
private static bool Tmp(Vector2 IS,Vector2[] A,Vector2[] B)
{
float[] v = new float[4];
for (int i = 0; i < 4; i++)
{
float tmp = (IS.X * A[i].X + IS.Y * A[i].Y) / (IS.X * IS.X + IS.Y * IS.Y);
v[i] = tmp * IS.X * IS.X + tmp * IS.Y * IS.Y;
}
float[] vv = new float[4];
for (int i = 0; i < 4; i++)
{
float tmp = (IS.X * B[i].X + IS.Y * B[i].Y) / (IS.X * IS.X + IS.Y * IS.Y);
vv[i] = tmp * IS.X * IS.X + tmp * IS.Y * IS.Y;
}
if (Math.Max(Math.Max(v[0], v[1]),Math.Max(v[2],v[3])) >Math.Min(Math.Min(vv[0],vv[1]),Math.Min(vv[2],vv[3])) && Math.Min(Math.Min(v[0],v[1]),Math.Min(v[2],v[3])) < Math.Max(Math.Max(vv[0],vv[1]),Math.Max(vv[2],vv[3]))) {
return false;
}//表示暂时不知道是否碰撞
else return true;//表示知道未碰撞
}
/// </summary>
/// <returns></returns>
public static bool IsIntersect (Vector2[] A, Vector2[] B)
{
Vector2 AX, AY, BX, BY;
AX = new Vector2();
AY = new Vector2();
BX = new Vector2();
BY = new Vector2();
AX.X = A[0].X - A[1].X;
AX.Y = A[0].Y - A[1].Y;
AY.X = A[0].X - A[3].X;
AY.Y = A[0].Y - A[3].Y;
BX.X = B[0].X - B[1].X;
BX.Y = B[0].Y - B[1].Y;
BY.X = B[0].X - B[3].X;
BY.Y = B[0].Y - B[3].Y;
//对于AX上:
if (Tmp(AX, A, B)) return false;
if (Tmp(AY, A, B)) return false;
if (Tmp(BX, A, B)) return false;
if (Tmp(BY, A, B)) return false;
return true;
}
private static bool Tmp(Vector2 IS,Vector2[] A,Vector2[] B)
{
float[] v = new float[4];
for (int i = 0; i < 4; i++)
{
float tmp = (IS.X * A[i].X + IS.Y * A[i].Y) / (IS.X * IS.X + IS.Y * IS.Y);
v[i] = tmp * IS.X * IS.X + tmp * IS.Y * IS.Y;
}
float[] vv = new float[4];
for (int i = 0; i < 4; i++)
{
float tmp = (IS.X * B[i].X + IS.Y * B[i].Y) / (IS.X * IS.X + IS.Y * IS.Y);
vv[i] = tmp * IS.X * IS.X + tmp * IS.Y * IS.Y;
}
if (Math.Max(Math.Max(v[0], v[1]),Math.Max(v[2],v[3])) >Math.Min(Math.Min(vv[0],vv[1]),Math.Min(vv[2],vv[3])) && Math.Min(Math.Min(v[0],v[1]),Math.Min(v[2],v[3])) < Math.Max(Math.Max(vv[0],vv[1]),Math.Max(vv[2],vv[3]))) {
return false;
}//表示暂时不知道是否碰撞
else return true;//表示知道未碰撞
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//
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
;
//发生碰撞
}
//
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//
//返回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());
}
//
1
2
3
4
5
6
7
8
9
10
//
bool
collision_CircleWithCircle(CCPoint p1,
float
r1, CCPoint p2,
float
r2)
{
//计算圆心距离
float
dist = p1.getDistance(p2);
//判断两圆是否相交
return
dist < (r1+r2) ;
}
//
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//
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
;
}
//
0 0
- lua 碰撞检测
- lua实现cocos多边形碰撞检测
- cocos-Lua 捕鱼碰撞检测方法
- cocos3.10 lua 碰撞检测的使用
- quick-cocos2d-x lua中碰撞检测的实现
- 使用Cocos2d-lua开发植物大战僵尸12-碰撞检测
- 碰撞检测
- 碰撞检测
- 碰撞检测
- 碰撞检测
- 碰撞检测
- 碰撞检测
- 碰撞检测
- 碰撞检测
- 碰撞检测
- 碰撞检测
- 碰撞检测
- 碰撞检测
- makefile学习 (1)
- Android App的设计架构:MVC,MVP,MVVM与架构经验谈
- 机器学习公开课备忘录(一)回归问题
- 一种针对超声波测距的滤波处理算法
- Android编程权威指南(第二版)学习笔记(二)—— 第2章 Android 与 MVC 设计模式
- lua 碰撞检测
- Head first HTML&CSS学习笔记
- 关键字:static,const,volatile
- ***[Lintcode]House Robber II
- Android-动画基础合集
- Uva 11134 问题分解,贪心策略区间选点问题
- Java for Web学习笔记(三十):JSTL(6)FMT Tag(下)
- 杂花生树(八)
- Web前端面试指导(二十八):什么是闭包,为什么要用它?