JavaFX проверяет столкновение между анимированными фигурами на панели - множественные столкновения - PullRequest
0 голосов
/ 31 августа 2018

Я делаю простую игру с JavaFX, где мяч отскакивает от экрана после того, как его отпустили снизу (с помощью кнопки). Когда шар подпрыгивает вокруг панели, если он ударяется о Rectangle, он меняет свой цвет на синий.

Я пытаюсь добавить метод checkBounds, чтобы отслеживать, когда мяч (Circle) попадает в Rectangle. Как только мяч входит в контакт с прямоугольником, счет должен увеличиться на 10. Механизм подсчета очков работает, но он продолжает увеличиваться с каждым кадром, который проходит мяч через Rectangle, вместо того, чтобы увеличиваться только один раз, когда он входит , (Например, он должен увеличиваться только на 10 раз, а не продолжать подниматься на 10 все время, пока проходит мяч). Я вызываю checkBounds() 3 раза в цикле временной шкалы, чтобы проверить каждый прямоугольник на каждой итерации цикла.

checkBounds(ball, gameSquare); checkBounds(ball, gameSquare2); checkBounds(ball, gameSquare3);

Как бы я исправил эту логическую ошибку? Я пробовал несколько разных вариантов, но ни один из них не работает.

private void checkBounds(Shape block, Rectangle rect) {

    boolean collisionDetected = false;

    Shape intersect = Shape.intersect(block, rect);

    if (intersect.getBoundsInLocal().getWidth() != -1) {
        collisionDetected = true;
    }

    if (collisionDetected) {
        score.setText(Integer.toString(currentScore.getCurrentValue()));
        currentScore.incrementBy(10);
        rect.setFill(Color.BLUE);
    }
}

1 Ответ

0 голосов
/ 31 августа 2018

Я считаю, что вы хотите обнаружить изменение вашего collisionDetected с false на true. Один из способов сделать это - сохранить состояние предыдущего значения в качестве переменной-члена для каждого объекта столкновения. Для этого нам понадобится некоторый идентифицирующий идентификатор для прямоугольника, поэтому вы можете передать идентификатор в метод checkBounds:

private void checkBounds(Shape block, Rectangle rect, int id) {

нам также нужно создать переменную-член для хранения состояний:

private HashMap<Integer,Boolean> previousCollisionStateMap = new HashMap<>();

, а затем внутри кода checkBounds вы можете изменить условие, чтобы проверить наличие изменений

Boolean prevState = previousCollisionStateMap.get(id);
if (prevState == null) {  // this is just to initialize value
    prevState = false;
    previousCollisionStateMap.put(id,false);
}

if (!prevState && collisionDetected) {
    score.setText(Integer.toString(currentScore.getCurrentValue()));
    currentScore.incrementBy(10);
    rect.setFill(Color.BLUE);
}

и не забудьте обновить состояние в конце

previousCollisionStateMap.put(id,collisionDetected);
...