V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Game Engines
Unreal Engine
MyCryENGINE
abcdabcd987
V2EX  ›  游戏开发

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

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

    我最近在写一个非常简单的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   ·   实用小工具   ·   1600 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 16:57 · PVG 00:57 · LAX 08:57 · JFK 11:57
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.