Untuk permainan kartu, yang sedang saya tulis, saya membuat "kontrol" khusus yang mewakili sebuah kartu. Itu dapat dibalik, diseret, dipilih, dan akan diskalakan, diterjemahkan, dan sebagainya selama permainan berlangsung.
Salah satu fitur inti kartu adalah dapat "disorot" dengan berbagai cara. Bentuk penyorotan paling dasar adalah menampilkan batas bercahaya (animasi) di sekeliling kartu.
Saya mulai dengan efek JavaFX di sini (DropShadow dengan penyebaran/radius animasi) tetapi dengan cepat meninggalkannya, karena kinerjanya ternyata sangat buruk.
Jadi, saya mengganti efeknya dengan animasi ImageView "di belakang" kartu (animasi sprite dasar dari sprite sheet dengan animasi cahaya yang telah dirender sebelumnya). Ini memecahkan masalah kinerja, tetapi menimbulkan banyak masalah lain yang saat ini saya coba atasi...
Karena, saya tidak ingin "titik jangkar" menjadi sudut kiri atas cahaya di sekitar kartu tetapi sudut kiri atas kartu itu sendiri, saya mencoba mengimbangi ImageView di dalam simpul kartu dengan -X/ -Y.
(Sorotan yang berbeda dapat "memperluas" simpul dengan jumlah yang berbeda, hal ini tidak akan mempengaruhi lokasi simpul, dan ketika mengatur lokasi simpul, Anda tidak perlu peduli dengan potensi offset atau sorotan sorotan yang berbeda sama sekali.)
Pada awalnya ini tampak bagus, tapi ini masih mempengaruhi batas-batas seluruh node. Misalnya, jika saya menambahkan pendengar peristiwa mouse ke node, ia akan aktif ketika mengklik di area "bersinar", meskipun saya menyetel ImageView ke mouse transparan. Saya harus membuat metode "proksi" untuk semua metode acara pada node khusus dan meneruskannya ke node kartu "dalam". Yang tentu saja mungkin - tapi sejujurnya bukan solusi yang saya harapkan.
Node kartu saat ini pada dasarnya memiliki struktur berikut:
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());
}
}
Contoh: new Card().setOnMouseClick() dan sejenisnya seharusnya hanya memengaruhi area yang saat ini sama dengan placeHolderForCardContent, namun tidak meluas ke effectView. Sederhananya, itu harus berperilaku seperti Efek dari node...
Gambar berikut menunjukkan apa yang saya coba buat:
Bagaimana hal seperti ini dilakukan dengan benar di JavaFX? Bisakah itu dilakukan dengan benar?