7

我只是想编写一个漂亮的物理游戏。

球碰撞看起来不错,但如果球碰撞太慢,它们会“粘”在一起。我不知道他们为什么这样做。

这是我的碰撞功能:

private void checkForCollision(ArrayList<Ball> balls) {
    for (int i = 0; i < balls.size(); i++) {
        Ball ball = balls.get(i);
        if (ball != this && ball.intersects(this)) {
            this.collide(ball, false);
        }
    }
}

public boolean intersects(Ball b) {
    double dx = Math.abs(b.posX - posX);
    double dy = Math.abs(b.posY - posY);
    double d = Math.sqrt(dx * dx + dy * dy);
    return d <= (radius + b.radius);
}

private void collide(Ball ball, boolean b) {
    double m1 = this.radius;
    double m2 = ball.radius;
    double v1 = this.motionX;
    double v2 = ball.motionX;

    double vx = (m1 - m2) * v1 / (m1 + m2) + 2 * m2 * v2 / (m1 + m2);

    v1 = this.motionY;
    v2 = ball.motionY;
    double vy = (m1 - m2) * v1 / (m1 + m2) + 2 * m2 * v2 / (m1 + m2);

    if (!b)
        ball.collide(this, true);
    System.out.println(vx + " " + vy);
    motionX = vx * BOUNCEOBJECT;
    motionY = vy * BOUNCEOBJECT;
}

但这就是它们以低速碰撞时发生的情况: 在此处输入图像描述

那么你有什么想法吗?

编辑:

Alnitak的更新效果非常好......但一个问题仍然存在......如果我像这样添加重力:

public void physic() {
    motionY += GRAVITY;                  // <= this part (GRAVITY is set to 0.3D)
    checkForCollision(screen.balls);
    keyMove();
    bounceWalls();

    posX += motionX;
    posY += motionY;
}

他们仍然相互移动。我认为这是增加重力的错误方法,不是吗?

而且我认为我对碰撞公式做错了,因为它们不正确:

落球

然后他们慢慢地沉入地下。

编辑: 发现了一个惊人的教程:http ://www.ntu.edu.sg/home/ehchua/programming/java/J8a_GameIntro-BouncingBalls.html

4

3 回答 3

8

这是一个常见的问题,因为有时弹跳球的 delta-v 不足以将其带出碰撞区域。

因此,碰撞程序再次反转方向,将其无限地带回另一个球内。

您应该为球的位置添加足够的偏移量(在碰撞力的方向上),以确保新计算的位置不再发生碰撞。

或者,检查添加新值后球是否会发生碰撞:motion

public boolean intersects(Ball b) {
    double dx = b.posX - (posX + motionX);  // no need for Math.abs()
    double dy = b.posY - (posY - motionY);
    double d = dx * dx + dy * dy;           // no need for Math.sqrt()
    return d < (radius + b.radius) * (radius + b.radius);
}

但您也应该更改ball.intersects(this)intersects(ball).

它们可能看起来有点过早地碰撞,但在快速移动的球上它可能不会被看到。

于 2012-08-29T18:20:19.223 回答
1
(m1 - m2) * v1 / (m1 + m2) + 2 * m2 * v2 / (m1 + m2);

这有一个整数值 2。请将其设为 2.0f 或 2.0d,然后检查一下。这一定是小速度的问题。因为整数常量自动转换成倍数。

如果这不起作用,那么Alnitak的回答会有所帮助。

如果你需要真正好的物理,你应该使用force然后将其转换为velocity然后将其转换为displacement。看看像龙格库塔欧拉积分这样的积分器技术

Force-->acceleration-->velocity-->displacement

如果发生碰撞,只需更新力,其余的就会流动。

----> http://codeflow.org/entries/2010/aug/28/integration-by-example-euler-vs-verlet-vs-runge-kutta/ <-----

http://www.forums.evilmana.com/game-programming-theory/euler-vs-verlet-vs-rk4-physics/

http://www.newagepublishers.com/samplechapter/001579.pdf

http://cwx.prenhall.com/bookbind/pubbooks/walker2/

Verlet 积分Runge-Kutta-4Euler 积分之间的一个点,最好用于分子动力学(如果省略电场和键,这是弹跳球的一个很好的例子)

于 2012-08-29T18:19:17.753 回答
0

刚刚找到了一个很棒的教程: http ://www.ntu.edu.sg/home/ehchua/programming/java/J8a_GameIntro-BouncingBalls.html

于 2012-09-20T20:12:33.260 回答