编写简单的 2D 物理引擎的时候遇到了点问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Game Engines
Unreal Engine
MyCryENGINE
abcdabcd987
V2EX    游戏开发

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

  •  
  •   abcdabcd987 2015-06-26 19:31:36 +08:00 4602 次点击
    这是一个创建于 3825 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    现在遇到了三个问题:

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

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

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

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

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

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

    最精确的计算方式:沿当前所有球的方向上画一条射线(或者抛物线,如果有重力的话。当重力不高,高,单帧时间足够短,也可以画直线段),射线和射线之间、射线和墙壁之间会有交点。检查每一个交点,确定是否会发生碰撞以及发生的时间。按照时间排序,最先发生碰撞的时刻,更新所有球的位置以及碰撞的两个球的速度,然后循环这个计算。
    abcdabcd987
        9
    abcdabcd987  
    OP
       2015-06-28 19:37:55 +08:00
    @c742435 事实上,这正是我原来的方法……
    http://lab.abcdabcd987.com/playground/bouncing_air/
    然而如果加上加速度的话,碰撞时间的计算就变成四次方程了
    而且如果加上一个重力,并且容器有底的话,那么当一堆小球叠在底下的时候,碰撞量估计会非常大,然后算力就不足了 =,=
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5167 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 30ms UTC 07:36 PVG 15:36 LAX 23:36 JFK 02:36
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86