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

9 篇文章 0 订阅
8 篇文章 0 订阅
在网易游戏研发笔试题中有一题就是这个碰撞检测,之前我看过一些文章,现在整理一个写个整理后的文章
之前大二写了一个简单的游戏【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,L2,l3,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,L2,l3,l4);
              float  AmaxL=max(L1,L2,l3,l4);


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

              //同理
              //在Line2投影

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

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

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



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


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值