Изменение цвета холста во время выполнения JavaFX - PullRequest
0 голосов
/ 06 октября 2019

Так что я немного экспериментировал с javaFX, так как он является частью одного из моих предметов. У меня есть катапульта, которая стреляет мячом в определенном направлении. Мне было интересно, не могли бы вы как-нибудь изменить цвет фона холста во время выполнения по определенному случаю - например, когда мяч ударяется о стену. Я уже понял, как заставить мяч отскочить от стены, но не могу понять, как изменить цвет bg во время выполнения.

Я использую import javafx.scene.canvas.GraphicsContext;поскольку это то, с чем мы «должны» работать.

Я думал, что-то вроде этого будет работать, я нашел некоторые темы о сне, поэтому я попробовал.

public void flashCanvas() {

try
{
    gc.setFill(Color.WHITESMOKE);
    Thread.sleep(100);
    gc.setFill(Color.BLACK);
    Thread.sleep(100);
}
catch(InterruptedException ex)
{
    Thread.currentThread().interrupt();
    }

}

Я думал, что это просто изменит цвет, затем подождите и сноваочередной раз.

Спасибо за помощь!

Ответы [ 2 ]

0 голосов
/ 07 октября 2019

Вы блокируете поток приложения JavaFX с помощью Thread.sleep, который предотвращает изменение отрисовки. (В вашем коде на самом деле нет изменений, поскольку вы просто заменяете цвет, используемый для рисования, при условии, что этот цвет больше нигде не используется, но это то, что произойдет, если вы нарисовали что-то в дополнение к изменению fill property.)

Я рекомендую использовать один из классов из javafx.animation пакета , чтобы изменить это.

В этом случае PauseTransition кажется самым простым способомчтобы пойти, но если вы хотите включить цикл обновления, я рекомендую вместо этого использовать AnimationTimer или Timeline и интегрировать этот тип логики в «цикл» обновления. Используя одну из последних возможностей, вы можете просто сохранить последний раз, когда мяч ударился о стену, и на основе этой информации решить, какой цвет использовать для рисования фона.

Пример использования PauseTransition:

gc.setFill(Color.WHITESMOKE);
gc.fillRect(x, y, w, h);

// schedule update without blocking
PauseTransition pause = new PauseTransition(Duration.millis(100));
pause.setOnFinished(evt -> {
    gc.setFill(Color.BLACK);
    gc.fillRect(x, y, w, h);
});
pause.play();

Обратите внимание, что вам, вероятно, потребуется перерисовать не только фон, так как использование fillRect заменяет все содержимое, находящееся в данный момент в прямоугольнике.

0 голосов
/ 07 октября 2019

Короткий ответ
Вы можете настроить желаемое поведение, используя эту часть кода

   Runnable collide = new Runnable() {
        @Override
        public void run() {
            Platform.runLater(() ->
                damageEffect()
            );
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Platform.runLater(() ->
                resetEffect()
            );
        }
    };
    new Thread(collide).start();


Объяснение вы не можете использовать Thread.Sleep() в главном потоке, что приведет к зависанию вашего пользовательского интерфейса, поэтому вам нужно сделать это в другом потоке и для большей безопасности при изменении чего-либо в потоке пользовательского интерфейса / основного потока, который следует использоватьPlatform.runLater()

вы можете написать любой эффект в этих функциях boomEffect() и resetEffect(), если вы хотите изменить цвет заливки холста, вы можете использовать код, предоставленный @Barudar в комментарии, подобный этому

private void resetEffect() {
    canvas.getGraphicsContext2D().setFill(Color.RED);
    canvas.getGraphicsContext2D().fillRect(0,0,canvas.getWidth(),canvas.getHeight());
}

, где fillRect() принимают начальные X, начальные Y, конечные X, конечные Y в качестве параметров

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...