为什么我不能使用robot.getPixelColor使红球停在蓝框上?

时间:2019-05-29 02:27:21

标签: java timertask awtrobot

标题。 GUI如下所示:Ball Puzzle GUI

下面的代码用于我的计时器任务,该任务负责控制球的向下运动,称为:

timer.scheduleAtFixedRate(moveDown,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,并且没有区别。

现在,通过运气,我发现如果在Y上加上80,在X上加上25,它将立即停在框的边缘。

我还发现,如果我为负责将球向上移动(速度为负)的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();
    }

有人知道到底发生了什么吗?我还没有弄清楚左右方向,因为似乎没有规律。

1 个答案:

答案 0 :(得分:0)

机器人不是检测正方形的可靠方法。双缓冲可能意味着您的像素实际上没有显示。

由于您自己的代码正在绘制正方形,因此请将这些正方形的坐标保留在专用字段中,并使用它们检查碰撞而不是检查像素颜色:

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。您应该使用javax.swing.Timer而不是java.util.Timer,因为它可以在AWT事件分配线程中正确执行其任务。