`

基于2D多边形的碰撞检测和响应(一)

阅读更多
简介
本文是阐述如何在2D动作游戏中进行精确而高效的碰撞检测。这里的碰撞是基于多边形而不是基于精灵的。这两者之间在设计上会有不同。
基于精灵的碰撞检测是通过精灵之间的重叠的像素来完成的。而多边形使用向量数学来精确计算交点,时间和碰撞方向。虽然多边形仅仅是精灵的一个近似,但是它比精灵系统要高级。
  • 可以精确模拟逼真的简单物理学,例如反弹,摩擦,斜面的滑行
  • 碰撞检测可以更精确的用于高速精灵系统。在基于精灵的系统中,如果物体移动过快就会在跳过另一个物体。
  • 基于向量数学因此可以扩展到3D,然而精灵碰撞系统被严格限制在2D的情况下。

特性
本文使用的算法只适用于凸多边形,例如三角形,四边形,六边形,圆形。对于非凸多边形,你可以将其分解为多个凸多边形,例如三角形。
算法可以用于快速移动或慢速移动的多边形。不管物体移动多快,碰撞都不会丢失。它也可以处理重叠的问题,并促使交叠物体分离。
演示也支持分割多边形交叉。这可以用于子弹的建模。
同时提供了简单的物体系统,弹力,一些基本的摩擦和静摩擦力。用于确保物体不会从斜面上滑落。

有一个刚体系统的例子,使用了Chrsi Hecker的物理教程。


限制
有序碰撞。就是说并不是有序的进行碰撞。这对于快速移动的物体会出现一定的问题。一旦碰撞被检测到,它就被直接处理了。理想状态下你可能需要找到一个碰撞点并处理它,然后寻找更多的碰撞。但是对于2D动作游戏,这通常是不必要的。
一、分离坐标轴方法
这个方法是碰撞检测的核心。它的规则非常简单并且非常易于实现。这个方法也非常快并且非常可靠,因为计算中没有使用除法操作,下面给出一个简单的基于两个BOX的碰撞检测的例子。

算法试图在两个物体之间找到一个合适平面,如果这个平面存在,那么物体就没有相交。
为了测试物体是否是分开的,简单的方法是投影这个物体到平面的法线上,并比较两者之间的间距看二者是否重叠。

显然有无数的平面可以用来分割两个物体。但是已经经过证明的是:你只需要使用一部分平面来进行测试,对于BOX从上图中可以看出平面的法线为BOX B的长轴。

对于BOX来说需要测试的分割平面是那些法线等于两个BOX的轴向的平面。因此对于两个BOX来说,你只需要测试4个分割平面即可。在这四个平面里,一旦发现一个分割平面可以分割BOX那么你就可以断定这两个BOX是不相交的。
如果四个平面都不能分割BOX,那么这两个BOX一定是相交的,也就是出现了碰撞。
可以扩展这个算法到普通的多边形,算法是相同的,只用需要测试的平面的数量改变了。并且分割平面在每个多边形边的垂直方向上又有一个法线。在下 图中,你可以看到两个分割平面用于测试。在红色的平面上你可以看到两个间隔是重叠的。然而,在蓝色的平面上间隔是不重叠的,因此,蓝色的平面的是分割平 面,因此物体是不相交的。

现在,我们有一个算法来检测两个多边形是否是相交的。代码可以分为三个部分:

a)         生成需要测试的分离轴

b)        计算每一个多边形在分离轴法线上的投影

c)        检测这些投影是否相交

bool Intersect(Polygon A, Polygon B)
{
for(I = 0; I < A.num_edges; I ++)
{
Vector N = Vector(-A.EdgeDir[I].y, A.EdgeDir[I].x);
if (AxisSeparatePolygons(N, A, B))
return false;
}
for(I = 0; I < B.num_edges; I ++)
{
Vector N = Vector(-B.EdgeDir[i].y, B.EdgeDir[I].x);
if (AxisSeparatePolygons (N, A, B))
return false;
}
return true;
}

void CalculateInterval(Vector Axis, Polygon P, float& min, float& max)
{
float d = Axis dot P.vertex[0]; //
从坐标原点开始计算向量
min = max = d;
for(I = 0; I < P.num_vertices; I ++)
{
float d = P.vertex[I] dot Axis;
if (d < min)
min = d;
else
if(d > max)
max = d;
}
}

算法检测2D多边形之间的碰撞,这个算法非常的快速和适用。边的方向不需要单位化,因此你可以避免存贮边的方向,并通过多边形的顶点直接得到边的方向。

for(J = A.num_vertices-1, I = 0; I < A.num_vertices; J = I, I ++)
{
Vector E = A.vertex[I] – A.vertex[J];
Vector N = Vector(-E.y, E.x);

if (AxisSeparatePolygons(N, A, B))
return false;
}


 

分享到:
评论

相关推荐

    2D多边形碰撞算法及示例

    通过实践和理解这些概念,我们可以构建出高效且准确的2D多边形碰撞检测系统。"Polygon collision"压缩包中的资源可能包含了详细教程、源代码示例以及用OpenGL实现的动画展示,帮助读者更直观地理解和应用这些理论...

    基于OpenGL的碰撞检测源程序

    在这个基于OpenGL的碰撞检测源程序中,我们关注的核心是游戏开发和模拟中的一个重要概念:如何确定两个或多个对象是否在空间中相遇或相交,即碰撞检测。 碰撞检测在许多应用中至关重要,例如视频游戏、物理模拟和...

    基于QT的C++的碰撞检测

    总的来说,这个项目展示了如何结合QT框架和C++来实现一个交互式的碰撞检测系统,允许用户通过鼠标滚轮动态调整视角,从而观察和分析碰撞情况。这涉及到图形用户界面的设计、事件处理、几何形状的碰撞检测算法以及2D...

    二维多边形碰撞检测

    二维多边形碰撞检测是计算机图形学中的一个重要概念,尤其在游戏...总之,二维多边形碰撞检测是一个涉及几何、算法和编程技术的综合问题。通过学习和实践,开发者可以创建出更加真实的2D游戏环境,提高玩家的游戏体验。

    Cocos2d-x碰撞检测原理与英雄要打死怪物--之游戏开发《赵云要格斗》

    Box2D提供了一个强大的多边形碰撞检测系统,可以创建具有不同形状(如圆形、多边形)的物理体,并通过模拟真实世界的物理规则来检测碰撞。在Cocos2d-x中,你可以通过集成Box2D并创建`CCPhysicsWorld`,然后为每个...

    cocos2d-x游戏碰撞检测(中文翻译)毕设也肯定用的上

    在游戏开发中,碰撞检测是不可或缺的一个重要环节,特别是在2D游戏领域,cocos2d-x作为一款广泛使用的开源游戏引擎,提供了丰富的功能来支持这一过程。本文将深入探讨cocos2d-x游戏碰撞检测的相关知识点,以帮助...

    2D碰撞实现-Demo

    在游戏开发中,2D碰撞检测是至关重要的一个环节,它确保了游戏对象在虚拟世界中的交互行为符合物理规律,增强了玩家的沉浸感。本文将深入探讨如何在2D环境中实现室内碰撞,以及如何利用自研2D游戏引擎来完成这一功能...

    碰撞检测 有关C++

    5. **碰撞检测库**:在C++中,有许多现成的碰撞检测库,如Bullet、Box2D和Ogre3D等,它们提供了丰富的接口和功能,能快速实现各种碰撞检测需求。 6. **优化技巧**:为了提升性能,可以使用启发式方法,如动态优先...

    物理碰撞检测实例

    cocos2d-x 3.0的物理引擎提供了两种主要的碰撞检测方法:基于距离的检测和基于固定时间步长的检测。基于距离的检测会在每次更新时检查所有可能的碰撞,这种方法精度高但效率较低。而基于固定时间步长的检测则是在每...

    2D-Polygon-Collision-Detection

    接着,我们可以采用分离轴定理(Separating Axis Theorem, SAT),这是一种广泛应用于2D多边形碰撞检测的算法。该定理基于一个核心思想:如果两个多边形不相交,那么存在一个轴使得两个多边形的投影在该轴上没有重叠...

    Tiled Map中使用碰撞检测

    本篇文章将深入探讨如何在基于Tiled Map的游戏中实现碰撞检测,特别是使用cocos2d框架。cocos2d是一个强大的开源游戏引擎,广泛应用于iOS和Android平台,对于iPhone游戏开发尤其适用。 首先,我们需要理解Tiled Map...

    cocos2d-x游戏开发系列教程-坦克大战游戏之所有坦克之间的碰撞检测

    cocos2d-x提供了一些内置的几何形状类,如`CCRect`(矩形)和`CCPolygon`(多边形),用于表示游戏对象的边界,并提供了相应的碰撞检测方法。对于坦克这类基本为矩形的物体,我们可以使用`CGRectIntersectsRect()`...

    xna中的碰撞检测

    本资源重点讲解如何在2D环境中实现碰撞检测,这对于创建像《超级玛丽》这样的平台跳跃游戏或者简单的弹球游戏至关重要。 首先,我们需要理解碰撞检测的基本概念。碰撞检测是指在游戏世界中,判断两个或多个物体是否...

    人物移动和碰撞检测

    在游戏开发中,人物移动和碰撞检测是两个至关重要的技术环节。它们决定了游戏中的角色如何在虚拟世界中行动,以及如何与环境互动。本资源包含了人物移动算法和碰撞检测技术的相关资料,帮助开发者深入理解并实现这些...

    ActionScript碰撞检测封装类

    在游戏开发中,碰撞检测是不可或缺的一个重要环节,特别是在使用ActionScript进行开发时。ActionScript是一种基于ECMAScript的脚本语言,常用于Adobe Flash和Adobe AIR应用,尤其是在早期的网页游戏开发中广泛使用。...

    Collisions是一个JavaScript库用于快速准确地检测多边形圆形和点之间的碰撞

    1. **多边形与多边形碰撞**:利用了分离轴定理(Separating Axis Theorem,简称SAT),这是一种广泛应用于2D碰撞检测的高级技术。通过寻找两个多边形的投影,如果在所有可能的轴上都没有重叠,就可以确定它们没有...

    cocos2d-x游戏开发系列教程-坦克大战游戏之子弹的碰撞检测处理

    在cocos2d-x中,可以为每个游戏对象创建一个物理身体,设置其形状(如圆形、多边形等),并开启物理引擎进行实时碰撞检测。当发生碰撞时,会触发相应的物理碰撞事件。 在处理子弹与坦克的碰撞时,我们需要创建一个...

    碰撞检测源代码,欢迎下载,学习物理引擎的比较有用

    在IT领域,尤其是在游戏开发和实时模拟中,碰撞检测是一个至关重要的部分。它涉及到计算机图形学、物理学以及算法设计等多个方面。"碰撞检测源代码"是实现这一功能的基础,对于那些想要深入理解或构建自己的物理引擎...

    opengl 碰撞检测

    OpenGL碰撞检测是计算机图形...总的来说,OpenGL碰撞检测是一个涉及几何、变换、算法和响应处理的综合过程。理解和掌握这个技术,不仅可以提升你的编程技能,还能帮助你在创建交互式3D应用时做出更加真实和动态的效果。

    OpenGL碰撞检测

    总的来说,OpenGL碰撞检测是一个结合了图形学、几何学和物理学的综合性问题。通过理解并掌握相关的理论和算法,开发者可以创建出具有真实感的交互式3D应用程序。在MFC框架下,这一过程需要对Windows编程和C++有深入...

Global site tag (gtag.js) - Google Analytics