Почему я не могу заставить свой красный шар остановиться на синем ящике с помощью robot.getPixelColor?

Заголовок. Графический интерфейс выглядит следующим образом: Графический интерфейс головоломки с мячом

Приведенный ниже код предназначен для моей задачи таймера, отвечающей за управление движением мяча вниз, вызываемой:

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, и это не имеет значения.

Теперь, по счастливой случайности, я обнаружил, что если я добавлю 80 к Y и 25 к X, он остановится прямо на краю коробки.

Я также обнаружил, что если я добавлю 25 к Y и 25 к X для TimerTask, ответственного за перемещение мяча вверх (скорость отрицательна), мяч остановится на расстоянии 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();
    }

Кто-нибудь знает, что, черт возьми, происходит на самом деле? Я еще не смог определить направления вправо / влево, так как, похоже, нет шаблона.

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
46
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Робот не является надежным способом обнаружения ваших квадратов. Двойная буферизация может означать, что ваши пиксели на самом деле не отображаются.

Поскольку ваш собственный код рисует квадраты, сохраните координаты этих квадратов в частном поле и используйте их для проверки на столкновение вместо проверки цветов пикселей:

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 небезопасен для использования несколькими потоками. Вы должны использовать javax.swing.Таймер вместо java.util.Timer, так как он правильно выполняет свои задачи в потоке отправки событий AWT.

Другие вопросы по теме