Java 相互弹起球(LibGDX)

Java 相互弹起球(LibGDX),java,android,libgdx,Java,Android,Libgdx,我正在用游戏开发框架libgdx开发一款Android游戏。 我想相互弹起多个球。我的方法是循环聚合,效果很好。但是当我尝试这个代码时,球有时会出现在一个随机的地方。它们不会设置为最小平移距离 public void moveBalls(float t) { // loop through all balls for(int i = 0; i < balls.size(); i++) { Ball ballA = balls

我正在用游戏开发框架libgdx开发一款Android游戏。 我想相互弹起多个球。我的方法是循环聚合,效果很好。但是当我尝试这个代码时,球有时会出现在一个随机的地方。它们不会设置为最小平移距离

    public void moveBalls(float t) {
        // loop through all balls
        for(int i = 0; i < balls.size(); i++) {
             Ball ballA = balls.get(i);
             float vx = ballA.getVx(); // velocity x
             float vy = ballA.getVy(); // velocity y
             float x  = ballA.getX();  // position x
             float y  = ballA.getY();  // position y

             // check if ball collide with other ball
             for (int j = i + 1; j < balls.size(); j++) {
                   Ball ballB = balls.get(j);
                   float radius = BALL_SIZE / 2;
                   float pointXA = x + radius;
                   float pointYA = y + radius;
                   float pointXB = ballB.getX() + radius;
                   float pointYB = ballB.getY() + radius;
                   if(Collision.isCircleCollsion(pointXA, pointYA, pointXB, pointYB, radius, radius)) {
                       // vector between pointA and pointB
                       Vector2 delta = ballA.getPosition().sub(ballB.getPosition());
                       float distance = delta.len();

                       // calculate minimum translation distance vector
                       Vector2 mtd = delta.scl(((radius + radius) - distance) / distance);

                       // add mtd
                       x += mtd.x * 0.5f;
                       y += mtd.y * 0.5f;
                       ballB.setX(ballB.getX() - mtd.x * 0.5f);
                       ballB.setY(ballB.getY() - mtd.y * 0.5f);
                 }
             }

             vx = vx + Gdx.input.getAccelerometerX() * ACCEL_X_FACTOR;
             x -= t * vx;
             y -= t * vy;

             ballA.setVx(vx);
             ballA.setVy(vy);
             ballA.setX(x);
             ballA.setY(y);
        }
    }
这似乎有效,但有时球会出现在屏幕上的任意位置


出了什么问题?

Vector2 mtd=delta.scl(((半径+半径)-距离)/距离)之后的断言是什么?假设距离变得很小,那么向量2 mtd=delta.scl(((半径+半径)-距离)/距离)会导致mtd变为长矢量2。(我还有其他保留意见,但这应该首先澄清。)我使用mtd向量来避免球与球之间的相交如果距离
半径<2*radius
,此缩放操作的结果应该是什么?如果距离=半径,则系数为1.0。如果
距离==0.5*半径
,则系数为3.0,并且随着距离的减小,它将增加到无穷大。我编辑了我的问题。有两个建议:(1)检查缩放系数的最大值
(半径+半径)-距离)/距离
。显著大于1的值可能会使球远离碰撞点。(2) 一个球可以反弹不止一次,因为与一些
ballA
碰撞后,
ballB
的位置会立即更新。应制作列表的副本,并且应使用旧列表计算时间t的所有碰撞。
ballAPoint = (2;2)
ballBPoint = (5;4)
radius     = 2
distance   = sqrt((5-2)^2 + (4-2)^2) = 3,61

delta = (3;2)

// delta * ((radius + radius) - distance) / distance

mtd = delta * ((2 + 2) - 3,61) / 3,61 = (0,324, 216)

mtd.x / 2 -> x intersection
mtd.y / 2 -> y intersection