Java 使用 ACM 图形进行故障碰撞检测
Java Glitchy Collision Detection with ACM Graphics
我是 Java 的新手,我正在使用 ACM 库处理图形。我试图用这段代码做的是:
- 介绍两个球,一个在左边,一个在中间。他们都在中间,y坐标。
- 让第一个球移动直到遇到第二个球。然后停下来给第二个球一个与其大小成正比的速度(类似于动量守恒)。
- 让第二个球弹到墙上,然后移动直到遇到第一个球。然后停止并再次给第一个球一个与其大小成正比的速度。
- 使这个动作无限。
我的代码是这样的:
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"
之间的时间
-增加碰撞区域(这意味着即使检查器没有看到边缘碰撞,如果两个区域重叠,它就知道它们已经碰撞了)
我是 Java 的新手,我正在使用 ACM 库处理图形。我试图用这段代码做的是:
- 介绍两个球,一个在左边,一个在中间。他们都在中间,y坐标。
- 让第一个球移动直到遇到第二个球。然后停下来给第二个球一个与其大小成正比的速度(类似于动量守恒)。
- 让第二个球弹到墙上,然后移动直到遇到第一个球。然后停止并再次给第一个球一个与其大小成正比的速度。
- 使这个动作无限。
我的代码是这样的:
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"
之间的时间-增加碰撞区域(这意味着即使检查器没有看到边缘碰撞,如果两个区域重叠,它就知道它们已经碰撞了)