Как создать случайные местоположения круга при нажатии кнопки в JavaFX?

Я пытаюсь выучить Java по курсу Udemy, и меня попросили создать задание, прежде чем переходить к следующим разделам.

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

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

public class CircleJumper extends Application {

    // Declare Variables
    private int count;
    private Circle initCircle;
    private Button initButton;
    private Text countText;

    /*
    *
    * Write function here
    *
    */
    @Override
    public void start(Stage primaryStage){

        // Initiate Variables
        count = 0;
        initCircle = new Circle(30, -50, 30);
        initButton = new Button("Click Me!");
        countText = new Text("Clicks: 0");
        // Here its where I built the click counter
        initButton.setOnAction((event) -> {
            count++;
            countText.setText("Pushes: " + count);
        });        
        ;
        Group baseDemo = new Group(initButton, countText);

        FlowPane pane = new FlowPane(baseDemo, initCircle);
        pane.setAlignment(Pos.CENTER);
        pane.setHgap(20);
        pane.setStyle("-fx-background-color: cyan");

        Scene scene = new Scene(pane, 600, 300);

        primaryStage.setTitle("Draw a Circle when Button is Pressed");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        launch(args);
    }

}

ОБНОВЛЕНИЕ: я решил объявить свою переменную count = Math.random(); и создал круг. После этого нажатие кнопки должно получить сгенерированный Math.random и поместить его в setTranslate, я прав?

    public void start(Stage primaryStage){

        // Initiate Variables
        count = Math.random();
        initCircle = new Circle(30, 50, 30);
        initButton = new Button("Click Me!");

        Group circlePos = new Group(initCircle);
        circlePos.setTranslateX(10);
        circlePos.setTranslateY(10);

        initButton.setOnAction((event) -> {
            count++;
            circlePos.setTranslateY(count);
            circlePos.setTranslateX(count);
        });

        Group baseDemo = new Group(initButton);

        FlowPane pane = new FlowPane(baseDemo, initCircle);
        pane.setAlignment(Pos.CENTER);
        pane.setHgap(20);
        pane.setStyle("-fx-background-color: cyan");

        Scene scene = new Scene(pane, 600, 300);

        primaryStage.setTitle("Draw a Circle when Button is Pressed");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

person Rose    schedule 18.09.2019    source источник
comment
См. Math#random() или java.util.Random. Первый возвращает значения в диапазоне [0.0,1.0), которые вы можете умножить на ширину/высоту родительского круга, чтобы получить новый центр x/y. У последнего есть метод, который может возвращать ограниченные ints (в диапазоне [0,bound)).   -  person Slaw    schedule 19.09.2019
comment
Не могли бы вы проверить мой обновленный вопрос, я сделал, как вы предложили, и передал возвращаемое значение из случайного в setTranslateX/Y ...... все еще не движется :/ .   -  person Rose    schedule 19.09.2019


Ответы (1)


Сначала попробуйте сами, но я опубликую решение, чтобы вы могли увидеть, как это делается, на случай, если вы застрянете.

  1. Создайте random в вашем методе инициализации приложения
  2. Если вы увеличиваете количество кликов, получить пару целых чисел, используя random.nextInt(bound) из рандома.
  3. Установить круг centerX и centerY к вашим случайным значениям.
  4. Сделанный.

Хорошо, не совсем готово, проблема, которую вы обнаружите, когда попробуете (что вы должны сделать), заключается в том, что это не сработает, круг не будет центрироваться на установленных вами значениях x и y. Это связано с тем, что Circle находится на панели макета (FlowPane), которая игнорирует ваши ручные настройки макета (хотя и не переводит значения). Решение - поставить кружок в Группу (первым пунктом, чтобы он был под всем), потом в группу поставить Flow Pane, а в FlowPane у вас будет ваша кнопка и счетчик кликов.

Возможно, вы захотите зарезервировать translateX/Y для анимации, а не для макета, хотя его можно использовать для перемещения фигур, и его также можно использовать по этой причине.

import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.control.Button;
import javafx.scene.layout.FlowPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.text.Text;
import javafx.stage.Stage;

import java.util.Random;

public class CircleJumper extends Application {
    private static final double MAX_X = 600;
    private static final double MAX_Y = 300;

    private int clickCount = 0;
    private Random random;

    @Override
    public void init() {
        random = new Random();
    }

    @Override
    public void start(Stage stage){
        Circle circle = new Circle(MAX_X / 2, MAX_Y / 2, 30);
        Button button = new Button("Click Me!");
        Text clickCountText = new Text("Clicks: " + clickCount);

        button.setOnAction((event) -> {
            clickCount++;
            clickCountText.setText("Clicks: " + clickCount);

            circle.setCenterX(random.nextInt((int) MAX_X));
            circle.setCenterY(random.nextInt((int) MAX_Y));
        });        

        Group layout = new Group(
                circle,
                new FlowPane(button, clickCountText)
        );

        stage.setScene(new Scene(layout, MAX_X, MAX_Y, Color.CYAN));
        stage.setResizable(false);
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}
person jewelsea    schedule 19.09.2019
comment
OMG, я работал над этим, направляя меня в ваши комментарии, и не знал, что у вас есть новый ответ. Да, это то, что я искал, спасибо, чувак. Сейчас я поиграю с ним, чтобы увидеть, как он работает. - person Rose; 19.09.2019