Для карточной игры, которую я сейчас пишу, я создал пользовательский элемент управления, представляющий собой карту. Его можно переворачивать, перетаскивать, выбирать, масштабировать, переводить и так далее в ходе игры.
Одной из основных особенностей карты является то, что ее можно «подсветить» по-разному. Самая простая форма выделения — это отображение светящейся рамки (анимированной) вокруг карты.
Я начал с эффектов JavaFX здесь (DropShadow с анимированным распространением/радиусом), но быстро отказался от этого, потому что производительность оказалась очень плохой.
Итак, я заменил эффект анимированным ImageView «за» картой (базовая анимация спрайта из листа спрайтов с предварительно обработанной анимацией свечения). Это решает проблему с производительностью, но создает множество других проблем, которые я сейчас пытаюсь решить...
Поскольку я не хочу, чтобы «точка привязки» была в верхнем левом углу свечения вокруг карты, а в верхнем левом углу самой карты, я попытался сместить ImageView в узле карты на -X/ -Ю.
(Различные блики могут «расширять» узел на разную величину, это не должно влиять на расположение узла, и при установке местоположения узла вам вообще не нужно заботиться о потенциально отличающихся смещениях бликов или бликах.)
Сначала это выглядело хорошо, но это все еще влияет на границы всего узла. Например, если я добавляю к узлу прослушиватель событий мыши, он срабатывает при щелчке в области «свечения», даже если я установил для ImageView прозрачность мыши. Мне пришлось бы создать «прокси» методы для всех методов событий на пользовательском узле и перенаправить их на «внутренний» узел карты. Что, конечно, возможно, но, честно говоря, это не то решение, которое я надеюсь найти.
Текущий узел карты имеет в основном следующую структуру:
public class Card extends Pane {
// the view that will contain the border glow (blue area in image below)
private ImageView effectView;
// stand-in for the rest of the card stuff (image etc)
private Rectangle placeholderForCardContent;
public Card() {
effectView = new ImageView();
effectView.setMouseTransparent(true);
placeholderForCardContent = new Rectangle();
getChildren().addAll(effectView, placeholderForCardContent);
}
@Override
protected void layoutChildren() {
// offsets are defined by the current highlight
effectView.setLayoutX(-50);
effectView.setLayoutY(-50);
effectView.setFitWidth(getWidth() + 100);
effectView.setFitHeight(getHeight() + 100);
placeholderForCardContent.setLayoutX(0);
placeholderForCardContent.setLayoutY(0);
placeholderForCardContent.setWidth(getWidth());
placeholderForCardContent.setHeight(getHeight());
}
}
Пример: new Card().setOnMouseClick() и т.п. должны воздействовать только на область, в настоящее время равную placeHolderForCardContent, но не распространяться на effectView. Просто он должен вести себя как эффект узла...
На следующем изображении показано, как я пытаюсь построить:
Как правильно сделать что-то подобное в JavaFX? Можно ли это сделать правильно?