【手游开发系列2】碰撞检测

在网易游戏研发笔试题中有一题就是这个碰撞检测,之前我看过一些文章,现在整理一个写个整理后的文章
之前大二写了一个简单的游戏【http://shouji.baidu.com/game/item?docid=6487395&from=as】,里面就是用很笨的枚举所有来相互检测是否碰撞 这样效率太慢了

1、前言:



下面这是我写的益智类小游戏 也要有碰撞检测和重力掉落 那时大二比较无知用了枚举去做碰撞检测 orz



飞机有很多子弹 还有敌机 相互之前要做碰撞检测


2、碰撞基础知识:
AABB包围盒:二维来说就是如图 三个矩形判断是否相交





OBB包围盒:就是AABB加一个方向 矩形可以旋转 在全民打飞机可以看到有的飞机会转弯



3、碰撞检测
AABB:
struct Point
{ int x,y;};
struct Rect
{
Point LeftBottom;
Point RightTop;
bool IsIntersect( const Rect & A )
{
return !(
RightTop.x< A .LeftBottom.x||
RightTop.y< A .LeftBottom.y||
LeftBottom.x> A .RightTop.x||
LeftBottom.y> A .RightTop.y);
}
};

OBB:
要用到sat分离轴定理
只针对凸多边形 凹多边形可以变成多个凸多边形 然后再运用sat
为:
(1)如果可以找到一条轴使得两个多边形在这条轴上的投影不相交,则这两个凸多边形就不相交
(2)以两个多边形的所有边的法线为轴 如果两个多边形在所有这些轴上的投影都相交,则这两个多边形就是相交的



4、OBB的实际代码
因为是矩形,所以法线也就是找长宽这两条线
代码有点挫 后期改进


struct Point
{ int x,y;};
struct Line
{
Point p1,p2;
};
struct Vector {
Vector( int x =0, int y =0)
{
this ->x= x ;
this ->y= y ;
}
int x,y;};
struct OBBRect
{
Line Line1;
Line Line2;
bool IsIntersect( const OBBRect & A )
{
//在Line1投影
Vector v(Line1.p2.x-Line1.p1.x,Line1.p2.y-Line1.p1.y);
//四个点在v上面的投影
Vector p1,p2,p3,p4;
float L1 = (v *[点乘] p1)/|p1|;
float L2 = (v *[点乘] p2)/|p2|;
float L3 = (v *[点乘] p3)/|p3|;
float L4 = (v *[点乘] p4)/|p4|;
float minL=min(L1,L2,l3,l4);
float maxL=max(L1,l4);

//所以矩形的投影是v上面长度minL 到 maxL的线段
//同理
Vector Ap1,Ap2,Ap3,Ap4;
float AL1 = (v *[点乘] Ap1)/|Ap1|;
float AL2 = (v *[点乘] Ap2)/|Ap2|;
float AL3 = (v *[点乘] Ap3)/|Ap3|;
float AL4 = (v *[点乘] Ap4)/|Ap4|;
float AminL=min(L1,l4);
float AmaxL=max(L1,l4);


//查看是否相交
//如果minL>AmaxL 或者 maxL<AmaxL 则不相交
//反之,相交

//同理
//在Line2投影

//同理
//在A.Line1投影

//同理
//在A.Line2投影
}
};

5、未完待续:
还有四叉树的优化 减少枚举全部的飞机或者说是子弹 orz



【关于博客】:每次都要上传图片 好麻烦 还是印象比较好

相关文章

    本文实践自 RayWenderlich、Ali Hafizji 的文章《...
Cocos-code-ide使用入门学习地点:杭州滨江邮箱:appdevzw@1...
第一次開始用手游引擎挺激动!!!进入正题。下载资源1:从C...
    Cocos2d-x是一款强大的基于OpenGLES的跨平台游戏开发...
1.  来源 QuickV3sample项目中的2048样例游戏,以及最近《...
   Cocos2d-x3.x已经支持使用CMake来进行构建了,这里尝试...