2011-02-09 12 views
5

तो मेरे पास यह पैनल क्लास है। यह एक खिड़की की तरह थोड़ा है जहां आप आकार बदल सकते हैं, बंद कर सकते हैं, बटन जोड़ सकते हैं, स्लाइडर्स इत्यादि। यदि आप में से कोई भी याद रखें तो मॉरोइंड में स्टेटस स्क्रीन की तरह। मैं जो व्यवहार चाहता हूं वह यह है कि जब एक स्प्राइट पैनल की सीमाओं से बाहर होता है तो यह खींचा नहीं जाता है और यदि यह आंशिक रूप से बाहर है तो केवल भाग के अंदर ही खींचा जाता है। तो यह अभी क्या करता है एक पहले आयत प्राप्त करता है जो पैनल की सीमाओं का प्रतिनिधित्व करता है, और स्प्राइट के लिए आयत का प्रतिनिधित्व करता है, यह दोनों के बीच छेड़छाड़ का आयताकार पाता है, फिर स्प्राइट आयताकार और उपयोग के स्थानीय निर्देशांक के चौराहे का अनुवाद करता है स्रोत आयताकार के लिए । यह काम करता है और चालाक के रूप में मुझे लगता है कि कोड यह है कि मैं इस भावना को हिला नहीं सकता कि ऐसा करने का एक बेहतर तरीका है। इसके अलावा, इस सेट अप के साथ मैं अपने 2 डी कैमरे के लिए एक वैश्विक परिवर्तन मैट्रिक्स का उपयोग नहीं कर सकता, "दुनिया" में सब कुछ ड्रा करने के लिए कैमरा तर्क पारित किया जाना चाहिए। चौराहे के लिए
: वैसे भी, यहाँ कोड मैं हैमैं घूर्णन आयतों पर क्लिपिंग कैसे कर सकता हूं?

 public static Rectangle? Intersection(Rectangle rectangle1, Rectangle rectangle2) 
    { 
     if (rectangle1.Intersects(rectangle2)) 
     { 
      if (rectangle1.Contains(rectangle2)) 
      { 
       return rectangle2; 
      } 
      else if (rectangle2.Contains(rectangle1)) 
      { 
       return rectangle1; 
      } 
      else 
      { 
       int x = Math.Max(rectangle1.Left, rectangle2.Left); 
       int y = Math.Max(rectangle1.Top, rectangle2.Top); 
       int height = Math.Min(rectangle1.Bottom, rectangle2.Bottom) - Math.Max(rectangle1.Top, rectangle2.Top); 
       int width = Math.Min(rectangle1.Right, rectangle2.Right) - Math.Max(rectangle1.Left, rectangle2.Left); 
       return new Rectangle(x, y, width, height); 
      } 
     } 
     else 
     { 
      return null; 
     } 
    } 

और वास्तव में पैनल पर ड्राइंग के लिए:

public void DrawOnPanel(IDraw sprite, SpriteBatch spriteBatch) 
    { 
     Rectangle panelRectangle = new Rectangle(
      (int)_position.X, 
      (int)_position.Y, 
      _width, 
      _height); 
     Rectangle drawRectangle = new Rectangle(); 

     drawRectangle.X = (int)sprite.Position.X; 
     drawRectangle.Y = (int)sprite.Position.Y; 
     drawRectangle.Width = sprite.Width; 
     drawRectangle.Height = sprite.Height; 

     if (panelRectangle.Contains(drawRectangle)) 
     { 
      sprite.Draw(
       spriteBatch, 
       drawRectangle, 
       null); 
     } 
     else if (Intersection(panelRectangle, drawRectangle) == null) 
     { 
      return; 
     } 
     else if (Intersection(panelRectangle, drawRectangle).HasValue) 
     { 
      Rectangle intersection = Intersection(panelRectangle, drawRectangle).Value; 

      if (Intersection(panelRectangle, drawRectangle) == drawRectangle) 
      { 
       sprite.Draw(spriteBatch, intersection, intersection); 
      } 
      else 
      { 
       sprite.Draw(
        spriteBatch, 
        intersection, 
        new Rectangle(
         intersection.X - drawRectangle.X, 
         intersection.Y - drawRectangle.Y, 
         intersection.Width, 
         intersection.Height)); 
      } 
     } 
    } 

तो मुझे लगता है कि मेरे सवाल है, वहाँ ऐसा करने के लिए एक बेहतर तरीका है इस?

अद्यतन: बस ScissorRectangle संपत्ति के बारे में पता चला। ऐसा करने के लिए यह एक सभ्य तरीका लगता है; इसे एक RasterizerState ऑब्जेक्ट की आवश्यकता होती है जिसे spritebatch में बनाया और पारित किया जाता है। बेगिन ओवरलोड जो इसे स्वीकार करता है। ऐसा लगता है कि यह सबसे अच्छा शर्त हो सकता है हालांकि। व्यूपोर्ट भी है जिसे मैं स्पष्ट रूप से बदल सकता हूं। विचार? :)

+0

मेरा सुझाव है कि आप अपने प्रश्न में एक अधिक स्पष्ट फॉर्मूलेशन का उपयोग करें, "घुमावदार आयताकारों पर क्लिपिंग कैसे करें?" के आधार पर कुछ। – Joh

+0

ओह, वाह मैंने घूर्णन के बारे में भी सोचा नहीं था। धन्यवाद –

उत्तर

1

स्क्रीन के एक हिस्से में ड्राइंग को सीमित करने के कई तरीके हैं। यदि क्षेत्र आयताकार है (जो यहां मामला प्रतीत होता है), तो आप पैनल की सतह पर व्यूपोर्ट (ग्राफिक्सडिवाइस देखें) सेट कर सकते हैं।

गैर-आयताकार क्षेत्रों के लिए, आप स्टैंसिल बफर का उपयोग कर सकते हैं या गहराई बफर के साथ कुछ चाल का उपयोग कर सकते हैं। स्टैंसिल बफर या गहराई बफर में सतह के आकार को खीचें, अपने रेंडर स्टेटस को केवल उस पेंसल को आकर्षित करने के लिए सेट करें जिसे आपने केवल स्टैंसिल/गहराई बफर में प्रस्तुत किया है, अंत में अपने स्प्राइट्स को प्रस्तुत करें।

1

ऐसा करने का एक तरीका सरल प्रति-पिक्सेल टक्कर है। हालांकि यह एक बुरा विचार है कि अगर sprites बड़े या असंख्य हैं, यह छोटे sprites के साथ काम करने के लिए एक बहुत ही आसान और तेज़ तरीका हो सकता है। सबसे पहले, यह देखने के लिए पैनल के खिलाफ एक बाउंडिंग सर्कल या बाउंडिंग स्क्वायर टकराव जांच करें कि आपको प्रति-पिक्सेल पहचान करने की भी आवश्यकता है या नहीं।

फिर, एक ऐसी विधि बनाएं जो जांचती है कि स्प्राइट की स्थिति, स्केल और रोटेशन पैनल के अंदर अब तक रखता है कि इसे पैनल द्वारा पूरी तरह से संलग्न किया जाना चाहिए, इसलिए आपको प्रति-पिक्सेल टकराव की आवश्यकता नहीं है उस स्तिथि में। यह केवल एक बाउंडिंग वर्ग बनाकर बहुत आसानी से किया जा सकता है जिसमें स्प्राइट के विकर्ण की लंबाई की चौड़ाई और ऊंचाई होती है, और उसके साथ टकराव की जांच होती है।

अंत में, यदि इनमें से दोनों विफल हो जाते हैं, तो हमें प्रति-पिक्सेल टकराव करना होगा। यह देखने के लिए कि क्या यह पैनल की सीमाओं के भीतर है, स्प्राइट में प्रत्येक पिक्सेल के माध्यम से जाएं और जांचें। यदि यह पिक्सेल के अल्फा मान को 0

पर सेट नहीं किया गया है।

संबंधित मुद्दे

 संबंधित मुद्दे