如何建立2D物理引擎?[关闭]


20

我制作的最高级的游戏是使用物理引擎Box2dFlashAS3制作的8球台球游戏,以及带有关卡的平台游戏。

当我做平台游戏时,我一直希望知道如何制作引擎,以便我可以重复使用它。当我看到具有坡度,弯曲坡度,完美重力和真实物理学的游戏时,我一直希望我知道如何对引擎进行编码。

请为需要的任何相关知识库建议技术和文章。


Answers:


16

虽然我建议不要将自己的物理引擎滚动到除了执行它的经验之外的任何事情上(只是意识到您可能应该在完成后将其丢弃-很难弄清所有边缘情况和数值极限/稳定性问题,而为现有的引擎做贡献可能会更好地利用您的时间),以下是一些资源:

台球馆课程:快速准确地检测圆或球之间的碰撞,讨论了圆/圆和球/球碰撞。

Ñ教程是精彩用于基于定理分离轴检测和响应的基本理解。


9

Erin Catto 在GDC上提供了有关Box2D在线实施的所有GDC讲座。根据我的经验,Box2D还具有简单易读的代码。


pdf的确是坚硬的材料。但是,正如您所说,当我通读cpp和h文件时,它们是“可以理解的”。谢谢。
Vishnu

+1。Box2D也非常注意稳定性,这是您自己滚动时非常困难的事情之一。
利安德2010年

5

这是您可能的操作方式:

近似运动

每个物理对象都需要这些向量:

  • 位置:对象所在的位置。
  • 速度:其位置如何变化。
  • 加速:其速度如何变化。

因此,直观地讲,您需要在每个物理对象的每一帧中执行以下操作a

a.speed    += a.acceleration
a.position += a.speed

陷阱:这被称为欧拉积分法。对于较小的速度和加速度以及较小的时间步长,此近似值更好。在游戏中,通常是这样。但是,如果一个对象确实非常快地朝着薄壁移动或直接向另一个移动的对象移动,则当其位置增加足够大的数量以完全穿过该对象时,它可能会跳过与该对象的碰撞。如果您有快速移动的物体,则可能需要连续碰撞检测来避免这种情况。

碰撞

可以用以下序列来近似碰撞:

  1. 检测:检测到两个物体相交。
  2. 解决方案:更改每个身体的位置,使其不再相交。
  3. 物理:改变每个身体的速度以考虑动量,摩擦和复原(弹跳)。

这称为离散冲突检测,因为它发生在离散的时间点。每个步骤都应引起注意:

第1步:碰撞检测(东西在碰撞吗?)

对于两个圆:只需检查其中心是否大于其半径之和即可。

对于两个矩形:检查其任何角坐标是否在另一个矩形内。

对于涉及更复杂多边形的任何事物,您将需要Separating-Axis-Theorem,这是另一个问题的主题。

陷阱:您可能确实要考虑许多其他碰撞类型。有些真的很复杂:凸多边形可能相交多次

第2步:解决冲突(将它们分开。)

解决冲突的一种简单方法是使用从碰撞检测获得的值通过最小穿透平移。这实质上涉及以最小可能的移动距离将物体分开。

例如,考虑圆-圆碰撞,其中一个圆固定在适当位置。最小位移向量的方向与其中点向量之间的差相同。它的长度是半径之和与中心之间的距离之差。

这个想法很容易推广到其他形状。

陷阱:如果两个碰撞对象都是可移动的,则可能必须将它们两个都移动整个距离的一小部分,才能获得它们移动的近似值。他们显然必须朝不同的方向移动。

步骤3:碰撞物理学(其他更改。)

趋于发生的最明显的事情是一个或两个对象改变方向,即旋转其速度矢量。这很容易实现。

陷阱:对象可能是弹性的,但可能不是弹性的,在这种情况下,系统中的总能量减少了。由于空气阻力,您可能需要拖动。摩擦(特别是静摩擦)的实施非常复杂

一些结论

如果要模拟现实,则模拟难度就成倍增加。您正步入无数边缘案例,令人难以置信的困难公式以及不断增长的研究论文堆栈的雷区。

如果您的需求很简单或渴望学习,请尝试一下。

如果您的需求很复杂或者您不喜欢数学,请使用物理引擎为您掩盖细节。Box2DBullet在游戏中非常受欢迎。




By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.