2D弹性碰撞不能正常工作

时间:2015-01-03 16:58:05

标签: java game-physics

我已经有了这个代码并且球会反弹,但是当我施加一些重力时,我希望它们保持在彼此之上。但相反,它们会慢慢消失。

Screenshot

这是我的代码。

    for (int i = 0; i < balls.size(); i++) {
        Ball curr = balls.get(i);


        if (curr.getPos().getX() - curr.radius <= 0) {
            curr.getVel().mul(-0.9, 1);
            curr.getPos().set(curr.radius, curr.getPos().getY());
        } else if (curr.getPos().getX() + curr.radius >= WIDTH) {
            curr.getVel().mul(-0.9, 1);
            curr.getPos().set(WIDTH - curr.radius, curr.getPos().getY());
        }

        if (curr.getPos().getY() - curr.radius <= 0) {
            curr.getVel().mul(1, -0.9);
            curr.getPos().set(curr.getPos().getX(), curr.radius);
        } else if (curr.getPos().getY() + curr.radius >= HEIGHT) {
            curr.getVel().mul(1, -0.9);
            curr.getPos().set(curr.getPos().getX(), HEIGHT - curr.radius);
        }

        for (int j = 0; j < balls.size(); j++) {
            if (j == i) continue;
            Ball other = balls.get(j);
            double xDist = curr.getPos().getX() - other.getPos().getX();
            double yDist = curr.getPos().getY() - other.getPos().getY();
            double distance = xDist * xDist + yDist * yDist;
            if (distance <= (curr.radius + other.radius) * (curr.radius + other.radius)) {
                double xVel = other.getVel().getX() - curr.getVel().getX();
                double yVel = other.getVel().getY() - curr.getVel().getY();
                double dot = xDist * xVel + yDist * yVel;
                if (dot > 0) {
                    double colScale = dot / distance;
                    double xCol = xDist * colScale;
                    double yCol = yDist * colScale;
                    double mass = curr.mass + other.mass;
                    double weightCurr = 2 * other.mass / mass;
                    double weightOther = 2 * curr.mass / mass;
                    curr.getVel().add(weightCurr * xCol, weightCurr * yCol);
                    other.getVel().sub(weightOther * xCol, weightOther * yCol);
                    curr.getPos().add(curr.getVel().mul(DMP));
                    other.getPos().sub(other.getVel().mul(DMP));
                }
            }
        }
    }

谢谢!

1 个答案:

答案 0 :(得分:0)

应在此之后插入一行:

    for (int j = 0; j < balls.size(); j++) {
       if( j == i ) continue;

否则每个球都会自行投球。

另一个潜在的错误来源是球在四个墙壁和另一个墙壁上反弹的方式:第一个球被墙壁检查然后反弹到所有其他球,然后只有其他墙壁被检查。

for (int i = 0; i < balls.size(); i++) {
    Ball curr = balls.get(i);
    // wall checks
}  // wall-check done!

 for (int i = 0; i < balls.size(); i++) {
     Ball curr = balls.get(i);
     for (int j = 0; j < balls.size(); j++) {
         if( j == i ) continue;
         // ball - ball check ...
     }
 }
另外,如果球1通过球2的检查,但是球2然后被球3推离到球1的半径中,则可能发生重叠。不知道如何处理这个:重复球 - 直到不需要更正?