物理圈碰撞弹出并滑向界限

Gre*_*ell 5 java physics collision

在Java中,我正在为Android编写一个移动应用程序,以便与我自己编写的某些类进行交互.重力取决于手机的倾斜度.

我注意到当我在一个角落里蜷缩成一堆球时,其中一些会开始抖动,或者有时会在与其他球碰撞时滑动.这可能是因为我正在以错误的顺序执行步骤吗?

现在我有一个循环通过每个球到:

  • 模拟迭代
  • 检查与其他球的碰撞
  • 检查与场景边界的碰撞

我应该补充一点,我与边界有摩擦,当发生球与球的碰撞时,只是为了失去能量.

以下是处理冲突的部分代码:

    // Sim an iteration
    for (Ball ball : balls) {
        ball.gravity.set(gravity.x, gravity.y);

        if (ball.active) {
            ball.sim();

            // Collide against other balls
            for (Ball otherBall : balls) {
                if (ball != otherBall) {
                    double dist = ball.pos.distance(otherBall.pos);
                    boolean isColliding = dist < ball.radius + otherBall.radius;
                    if (isColliding) {
                        // Offset so they aren't touching anymore
                        MVector dif = otherBall.pos.copy();
                        dif.sub(ball.pos);
                        dif.normalize();
                        double difValue = dist - (ball.radius + otherBall.radius);
                        dif.mult(difValue);
                        ball.pos.add(dif);

                    // Change this velocity
                    double mag = ball.vel.mag();
                    MVector newVel = ball.pos.copy();
                    newVel.sub(otherBall.pos);
                    newVel.normalize();
                    newVel.mult(mag * 0.9);
                    ball.vel = newVel;

                    // Change other velocity
                    double otherMag = otherBall.vel.mag();
                    MVector newOtherVel = otherBall.pos.copy();
                    newOtherVel.sub(ball.pos);
                    newOtherVel.normalize();
                    newOtherVel.mult(otherMag * 0.9);
                    otherBall.vel = newOtherVel;
                    }
                }
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

小智 2

如果这是检查球之间相互作用的唯一代码,那么问题似乎很清楚。一个球不可能静止在另一个球上以保持平衡。

假设您有一个球直接位于另一个球之上。当您计算顶部球由于重力而产生的加速度时,您还应该像您发布的那样进行碰撞检查,除了这次检查dist <= ball.radius + otherBall.radius. 如果是这种情况,那么您应该假设球之间的法向力等于重力,并消除与连接两个球中心的矢量一致的重力分量。如果你不这样做,那么顶部的球将加速进入底部的球,触发你发布的碰撞代码,你会感到紧张。

当球与场景边界接触时,必须使用类似的逻辑。