เพิ่มพื้นที่ตกแต่งรอบโหนดที่ทำงานเหมือนเอฟเฟกต์

สำหรับเกมไพ่ ฉันกำลังเขียนอยู่ ฉันสร้าง "การควบคุม" แบบกำหนดเองที่แสดงถึงการ์ด มันสามารถพลิก ลากไปรอบๆ เลือก และจะถูกปรับขนาด แปล และอื่นๆ ในระหว่างเกม

คุณลักษณะหลักอย่างหนึ่งของการ์ดคือสามารถ "เน้น" ได้หลายวิธี รูปแบบการไฮไลต์ขั้นพื้นฐานที่สุดคือการแสดงเส้นขอบเรืองแสง (เคลื่อนไหว) รอบๆ การ์ด

ฉันเริ่มต้นด้วยเอฟเฟกต์ 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 ได้อย่างไร? สามารถทำได้ถูกต้องหรือไม่?


person Roman Flückiger    schedule 25.07.2016    source แหล่งที่มา


คำตอบ (1)


setMouseTransparent(true) ทำงานอย่างถูกต้องสำหรับ effectView

อย่างไรก็ตาม ขอบเขตของพาเรนต์ (Pane) ยังคงรวม effectView และสร้างเหตุการณ์เมาส์ และเนื่องจาก pickOnBounds สำหรับ Regions ถูกตั้งค่าเป็น true ตามค่าเริ่มต้น (ซึ่งเป็นสิ่งที่ฉันพลาดไป เนื่องจากค่าเริ่มต้นทั่วไปตาม java doc คือ false) เราจึงต้องตั้งค่าเป็น false

แล้วมันได้ผล

person Roman Flückiger    schedule 25.07.2016