Java 使用 ACM 图形进行故障碰撞检测

Java Glitchy Collision Detection with ACM Graphics

我是 Java 的新手,我正在使用 ACM 库处理图形。我试图用这段代码做的是:

  1. 介绍两个球,一个在左边,一个在中间。他们都在中间,y坐标。
  2. 让第一个球移动直到遇到第二个球。然后停下来给第二个球一个与其大小成正比的速度(类似于动量守恒)。
  3. 让第二个球弹到墙上,然后移动直到遇到第一个球。然后停止并再次给第一个球一个与其大小成正比的速度。
  4. 使这个动作无限。

我的代码是这样的:

import java.awt.Color;

import acm.graphics.*;
import acm.program.*;
import acm.util.RandomGenerator;

public class Collision extends GraphicsProgram {

    private static final double RADIUS_ONE = 35;
    private static final double RADIUS_TWO = 65; 

    public void run() {

        GOval ballOne = new GOval(0, (getHeight() - RADIUS_ONE)/2, RADIUS_ONE, RADIUS_ONE);
        ballOne.setFilled(true);
        ballOne.setColor(Color.GREEN);
        add(ballOne);

        GOval ballTwo = new GOval((getWidth() - RADIUS_TWO)/2, (getHeight() - RADIUS_TWO)/2, RADIUS_TWO, RADIUS_TWO);
        ballTwo.setFilled(true);
        ballTwo.setColor(Color.ORANGE);
        add(ballTwo);

        double velocityOne = 3;
        double velocityTwo = 0;

        while (true) {  

            ballOne.move(velocityOne, 0);
            ballTwo.move(velocityTwo, 0);

            if (ballOne.getX() >= getWidth() - RADIUS_ONE || ballOne.getX() <= 0) {
                velocityOne = -velocityOne;
            }
            if (ballTwo.getX() >= getWidth() - RADIUS_TWO || ballTwo.getX() <= 0) {
                velocityTwo = -velocityTwo;
            }

            if (ballOne.getX() + RADIUS_ONE >= ballTwo.getX()) {

                if (velocityTwo == 0) {
                    velocityTwo = (velocityOne * RADIUS_ONE * RADIUS_ONE)/(RADIUS_TWO * RADIUS_TWO);
                    velocityOne = 0;
                } else if (velocityOne == 0) {
                    velocityOne = (velocityTwo * RADIUS_TWO * RADIUS_TWO)/(RADIUS_ONE * RADIUS_ONE);
                    velocityTwo = 0;
                }

            }

            pause(10);
        }
    }
}

如果您 运行 此代码,您会发现它有故障。在遇到第二个球时,第一个球不会停止移动并与第二个球一起移动。但是,如果将 velocityOne 更改为 2 而不是 3,则一切正常。或者,如果您将 RADIUS_TWO 改为 45 而不是 65,则代码会针对 velocityOne.

的每个值正常运行

任何人都可以解释为什么这段代码在大多数值下都出现故障,而它却能以如此少的值正常工作吗?非常感谢。

在检测碰撞时,您会 运行 遇到很多错误!这是很常见的事情。

您收到这些错误的原因是因为当您尝试检测碰撞时,您的代码会在每个时间间隔刷新(您通常可以选择时间间隔之间的时间)并检查两件事是否相交. 在这种情况下,我假设您的球正从另一个球身边飞过,速度太快以至于您的 "collision checker" 无法捡起它。

您可以做的几件事:

-让球慢下来

-减少"checks for collision"

之间的时间

-增加碰撞区域(这意味着即使检查器没有看到边缘碰撞,如果两个区域重叠,它就知道它们已经碰撞了)