编写简单的 2D 物理引擎的时候遇到了点问题

2015-06-26 19:31:36 +08:00
 abcdabcd987

我最近在写一个非常简单的2D物理引擎,大概就是支持球和球、球和墙壁的弹性碰撞,但是目前遇到了几个问题。先说下我的实现方法吧。每个球记录下 (pos, vel, acc) 三个向量,然后每一帧 vel += acc; pos += vel;。碰撞的话,发现两个物体重叠,就用弹性碰撞的公式重新计算物体的速度向量。目前加速度还取的是0。

现在遇到了三个问题:

两个球相撞的时候,有可能会纠缠在一起。这个原因我还是知道的,万一下一帧的时候球依然重叠,那么就会再一次重新计算速度向量,于是乎就纠缠在一起了。我试过打一个标记,表示这个球刚刚撞完,然后等这个球不和别的物体重叠了之后,再把这个标记清除掉。然而这样做的话,在几个球相撞的时候就会出问题。

还有,有的球撞着撞着速度变快了之后,直接从墙壁穿出去了……

另外,我对加上一个重力场表示很疑惑,不知道怎么实现。我尝试设置每个球的加速度向量,然后出现了两个严重的问题。一是球跳起来的高度越来越低,最后就贴在下边界上了。二是球贴在下边界上之后,速度依然会增加,于是当速度足够大的时候就飞出下边界了。我在想是不是应该引入力的表示??

我实在是没有游戏编程的经验,求各位前辈指点一下,说说这些情况怎么解决,或者是应该看看什么资料?谢谢!

btw 目前的失败演示: http://lab.abcdabcd987.com/playground/bouncing_air2/

4181 次点击
所在节点    游戏开发
9 条回复
dd99iii
2015-06-26 19:44:51 +08:00
无聊的看了一会,并没有看到楼主描述的情况。。。。。。需要看多久?
arbipher
2015-06-26 19:54:52 +08:00
你看看box2d(的源码)怎么解决的吧

我只读过文档,文档里这么说的
# solver #
The physics world has a solver that is used to advance time and to resolve contact and joint constraints.
The Box2D solver is a high performance iterative solver that operates in order N time, where N is the
number of constraints.

# continuous collision #
The solver advances bodies in time using discrete time steps. Without intervention this can lead to
tunneling.

tunneling就是你说的“穿出去”的情况
abcdabcd987
2015-06-26 20:04:23 +08:00
@dd99iii 哈哈 感谢捧场 把浏览器窗口拉到最小 然后刷新一下
endrollex
2015-06-26 20:09:47 +08:00
写过3D物理,第一个情况计算一下穿透深度,然后立即修正它们的位置,
速度变快穿过,这个要用辅助包围体,不过我还没去实现
第三个,重力不是让球越跳越低?
文章推荐这篇
http://gamedevelopment.tutsplus.com/tutorials/how-to-create-a-custom-2d-physics-engine-the-basics-and-impulse-resolution--gamedev-6331
(虽然有点问题,看评论)
abcdabcd987
2015-06-26 20:31:22 +08:00
@endrollex 😂你说得对
abcdabcd987
2015-06-26 20:32:23 +08:00
@arbipher 感谢
secondwtq
2015-06-27 12:47:12 +08:00
只会用别人的物理引擎然后每次都被坑惨的渣渣路过...
c742435
2015-06-27 13:14:30 +08:00
较为精确的计算方式:
将一个球的数据记录为(出发时间,出发位置,出发速度)。
上一帧时间T0,当前帧时间T1,发现两个球重叠了。则这两个AB球碰撞的时间Tab必然是T0 < Tab < T2,则球的数据应该被记录为(Tab,碰撞时位置,碰撞后速度)。

最精确的计算方式:沿当前所有球的方向上画一条射线(或者抛物线,如果有重力的话。当重力不高,高,单帧时间足够短,也可以画直线段),射线和射线之间、射线和墙壁之间会有交点。检查每一个交点,确定是否会发生碰撞以及发生的时间。按照时间排序,最先发生碰撞的时刻,更新所有球的位置以及碰撞的两个球的速度,然后循环这个计算。
abcdabcd987
2015-06-28 19:37:55 +08:00
@c742435 事实上,这正是我原来的方法……
http://lab.abcdabcd987.com/playground/bouncing_air/
然而如果加上加速度的话,碰撞时间的计算就变成四次方程了
而且如果加上一个重力,并且容器有底的话,那么当一堆小球叠在底下的时候,碰撞量估计会非常大,然后算力就不足了囧 =,=

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/201433

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX