为什么我不能使用 robot.getPixelColor 让我的红球停在蓝框上?
Why can't I get my Red Ball to Stop on the Blue Box using robot.getPixelColor?
标题。 GUI 如下所示:Ball Puzzle GUI
下面的代码是我的定时器任务,负责控制球的向下运动,调用者:
timer.scheduleAtFixedRate(下移, 0, 20);
每当按下箭头键时,球应该会继续朝那个方向移动,直到遇到一个正方形。我知道我现在正在使用 .cancel() 但我打算通过临时暂停 TimerTask 来解决这个问题。
虽然没有向 X 或 Y 值添加任何内容,但球永远不会停止。 (我应该提到当它到达底部时它会回到顶部)
当不更改 X 或 Y 值时,输出的颜色似乎会发生变化。例如,第一次在 (0,360) 时,输出颜色为 (208,208,208),而下一次在 (0,360) 时,输出颜色为 (240,240,240)。
当添加我认为会在框的边缘停止时,Y + 51,它仍然没有停止。检测到的唯一颜色是 (208,208,208),这是一种灰色。
如果我把Y+51和X+25都加了,球还是不停,只输出灰色。请注意,我已将速度更改为 1,但没有任何区别。
现在,幸运的是,我发现如果我将 80 加到 Y 上,将 25 加到 X 上,它就会停在盒子的边缘。
我还发现,如果我将负责向上移动球(速度为负)的 TimerTask 的 Y 增加 25,将 X 增加 25,球将在距框边缘 1 个像素处停止。
public void run() {
try {
Robot robot = new Robot();
int y = ball.positionY + 80;
int x = ball.positionX + 25;
System.out.println(ball.positionX);
System.out.println(ball.positionY);
color = robot.getPixelColor(x, y);
System.out.println("Red = " + color.getRed());
System.out.println("Green = " + color.getGreen());
System.out.println("Blue = " + color.getBlue());
} catch (AWTException e) {
e.printStackTrace();
}
if((color.getRed() == 0) && (color.getGreen() == 0) && (color.getBlue() == 255)){
moveDown.cancel();
moving = false;
}
else{
ball.positionY += 5;
if (ball.positionY > 670) {
ball.positionY = 0;
}
}
ball.repaint();
}
有人知道到底发生了什么吗?我还没有弄清楚 right/left 方向,因为似乎没有规律。
机器人不是检测方块的可靠方法。双缓冲可能意味着您的像素实际上并未显示。
由于您自己的代码正在绘制正方形,请将这些正方形的坐标保存在私有字段中,并使用它们来检查碰撞而不是检查像素颜色:
private final Collection<Rectangle> squares = new ArrayList<>();
// ...
if (squares.stream().anyMatch(sq -> sq.contains(x, y))) {
moveDown.cancel();
moving = false;
} else {
ball.positionY += 5;
if (ball.positionY > 670) {
ball.positionY = 0;
}
}
另请注意 Swing is not safe for use by multiple threads. You should be using javax.swing.Timer 而不是 java.util.Timer,因为它在 AWT 事件调度线程中正确执行其任务。
标题。 GUI 如下所示:Ball Puzzle GUI
下面的代码是我的定时器任务,负责控制球的向下运动,调用者:
timer.scheduleAtFixedRate(下移, 0, 20);
每当按下箭头键时,球应该会继续朝那个方向移动,直到遇到一个正方形。我知道我现在正在使用 .cancel() 但我打算通过临时暂停 TimerTask 来解决这个问题。
虽然没有向 X 或 Y 值添加任何内容,但球永远不会停止。 (我应该提到当它到达底部时它会回到顶部) 当不更改 X 或 Y 值时,输出的颜色似乎会发生变化。例如,第一次在 (0,360) 时,输出颜色为 (208,208,208),而下一次在 (0,360) 时,输出颜色为 (240,240,240)。
当添加我认为会在框的边缘停止时,Y + 51,它仍然没有停止。检测到的唯一颜色是 (208,208,208),这是一种灰色。
如果我把Y+51和X+25都加了,球还是不停,只输出灰色。请注意,我已将速度更改为 1,但没有任何区别。
现在,幸运的是,我发现如果我将 80 加到 Y 上,将 25 加到 X 上,它就会停在盒子的边缘。
我还发现,如果我将负责向上移动球(速度为负)的 TimerTask 的 Y 增加 25,将 X 增加 25,球将在距框边缘 1 个像素处停止。
public void run() {
try {
Robot robot = new Robot();
int y = ball.positionY + 80;
int x = ball.positionX + 25;
System.out.println(ball.positionX);
System.out.println(ball.positionY);
color = robot.getPixelColor(x, y);
System.out.println("Red = " + color.getRed());
System.out.println("Green = " + color.getGreen());
System.out.println("Blue = " + color.getBlue());
} catch (AWTException e) {
e.printStackTrace();
}
if((color.getRed() == 0) && (color.getGreen() == 0) && (color.getBlue() == 255)){
moveDown.cancel();
moving = false;
}
else{
ball.positionY += 5;
if (ball.positionY > 670) {
ball.positionY = 0;
}
}
ball.repaint();
}
有人知道到底发生了什么吗?我还没有弄清楚 right/left 方向,因为似乎没有规律。
机器人不是检测方块的可靠方法。双缓冲可能意味着您的像素实际上并未显示。
由于您自己的代码正在绘制正方形,请将这些正方形的坐标保存在私有字段中,并使用它们来检查碰撞而不是检查像素颜色:
private final Collection<Rectangle> squares = new ArrayList<>();
// ...
if (squares.stream().anyMatch(sq -> sq.contains(x, y))) {
moveDown.cancel();
moving = false;
} else {
ball.positionY += 5;
if (ball.positionY > 670) {
ball.positionY = 0;
}
}
另请注意 Swing is not safe for use by multiple threads. You should be using javax.swing.Timer 而不是 java.util.Timer,因为它在 AWT 事件调度线程中正确执行其任务。