2010-06-18 14 views
5

मैं निम्नलिखित विधि को लागू करने की कोशिश कर रहा हूं: शून्य बॉल :: DrawOn (ग्राफिक्स जी);डबल बफरिंग सी #

विधि को गेंद के सभी पिछले स्थानों (एक कतार में संग्रहीत) और आखिरकार वर्तमान स्थान को आकर्षित करना चाहिए। मुझे नहीं पता कि यह मायने रखता है, लेकिन मैं g.DrawEllipse (...) और g.FillEllipse (...) का उपयोग कर वर्तमान स्थान का उपयोग कर पिछले स्थानों को मुद्रित करता हूं।

सवाल यह है कि, जैसा कि आप कल्पना कर सकते हैं कि बहुत सारे ड्राइंग किए जा रहे हैं और इस तरह डिस्प्ले ज्यादा झिलमिलाहट शुरू हो जाता है। मैंने डबल बफर करने के लिए एक रास्ता खोजा था, लेकिन मुझे यह सब मिल सकता है:

1) System.Windows.Forms.Control.DoubleBuffered = true;

2) सेट स्टाइल (कंट्रोल स्टाइल। डबलबफर | कंट्रोलस्टाइल.उसरपेन्ट | कंट्रोलस्टाइल। ऑलपैंटिंगइन डब्लूएमपीेंट, सच);

पहले उपयोग करने का प्रयास करते समय, मुझे यह समझने में त्रुटि मिलती है कि इस विधि से संपत्ति डबलबफर्ड अपने सुरक्षा स्तर के कारण पहुंच योग्य नहीं है। जबकि मैं सेट स्टाइल विधि का उपयोग कैसे नहीं कर सकता।

यह जबकि सभी पहुँच मेरे पास करने के लिए ग्राफिक्स वस्तु मैं विधि में इनपुट के रूप में मिलता है संभव सब पर डबल बफर करने के लिए है?

अग्रिम धन्यवाद,

संपादित करें: मैं बनाया था निम्नलिखित वर्ग

namespace doubleBuffer 
{ 
    class BufferedBall : System.Windows.Forms.Form{ 
     private Ball ball; 
     public BufferedBall(Ball ball) 
     { 
      this.ball = ball; 
     } 

    public void DrawOn(Graphics g){ 
     this.DoubleBuffered = true; 
     int num = 0; 
     Rectangle drawArea1 = new Rectangle(5, 35, 30, 100); 
     LinearGradientBrush linearBrush1 = 
     new LinearGradientBrush(drawArea1, Color.Green, Color.Orange, LinearGradientMode.Horizontal); 
     Rectangle drawArea2 = new Rectangle(5, 35, 30, 100); 
     LinearGradientBrush linearBrush2 = 
      new LinearGradientBrush(drawArea2, Color.Black, Color.Red, LinearGradientMode.Vertical); 
     foreach (PointD point in ball.previousLocations) 
     { 
      Pen myPen1; 
      if (num % 3 == 0) 
       myPen1 = new Pen(Color.Yellow, 1F); 
      else if (num % 3 == 1) 
       myPen1 = new Pen(Color.Green, 2F); 
      else 
       myPen1 = new Pen(Color.Red, 3F); 
      num++; 
      myPen1.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid; 
      myPen1.StartCap = System.Drawing.Drawing2D.LineCap.RoundAnchor; 
      myPen1.EndCap = System.Drawing.Drawing2D.LineCap.AnchorMask; 
      g.DrawEllipse(myPen1, (float)(point.X - ball.radius), (float)(point.Y + ball.radius), (float)(2 * ball.radius), (float)(2 * ball.radius)); 
     } 
     if ((ball.Host.ElapsedTime * ball.Host.FPS * 10) % 2 == 0){ 
      g.FillEllipse(linearBrush1, (float)(ball.Location.X - ball.radius), (float)(ball.Location.Y + ball.radius), (float)(2 * ball.radius), (float)(2 * ball.radius)); 
     }else{ 
      g.FillEllipse(linearBrush2, (float)(ball.Location.X - ball.radius), (float)(ball.Location.Y + ball.radius), (float)(2 * ball.radius), (float)(2 * ball.radius)); 
     } 
    } 
} 

}

और गेंद drawOn इस तरह दिखता है:

new BufferedBall(this).DrawOn(g); 

कि है अपका क्या मतलब था? क्योंकि यह अभी भी झटकेदार है?

+0

ठीक है, SetStyle() तरीका सही है, और आप इसे सही कर रहे हैं। AFAIK, DoubleBuffered संपत्ति का उपयोग नहीं किया जाना चाहिए (SetStyle को प्राथमिकता दी जाती है), लेकिन आप हमेशा नियंत्रण/फॉर्म/जो कुछ भी इसका उपयोग कर सकते हैं और इसका उपयोग कर सकते हैं (यह संरक्षित है)। – sunside

उत्तर

3

Form कक्षा में DoubleBuffered संपत्ति को संरक्षित के रूप में उजागर किया गया है। http://msdn.microsoft.com/en-us/library/system.windows.forms.control.doublebuffered.aspx लेकिन चूंकि आप अपना फॉर्म Form से प्राप्त करते हैं, तो आप इसका उपयोग कर सकते हैं।

+0

नहीं, यह संरक्षित है। – LmSNe

+2

हां, लेकिन आप फॉर्म से प्राप्त कर रहे हैं। जब आप मूल Winforms ऐप बनाते हैं तो यह फॉर्म 1 से फ़ॉर्म फॉर्म बनाता है। आप वहां से इसका उपयोग कर सकते हैं। यदि नहीं - आप हमेशा इस संपत्ति को उजागर करने वाले आवरण बना सकते हैं। – Andrey

1

नियंत्रण-व्युत्पन्न कक्षाओं के डबल बफरिंग के लिए शैली सेट करने का एक आसान तरीका प्रतिबिंब का उपयोग करना है। यहां देखें: http://www.csharp-examples.net/set-doublebuffered/

इससे आपको संरक्षित संपत्ति सेट करने के लिए नियंत्रण को कम करने का चरण बचाएगा।

+0

लेकिन उस ऑब्जेक्ट से उस एक्सेस तक पहुंच की आवश्यकता होगी जिसे मैं चित्रित कर रहा हूं, है ना? मेरे पास सभी एक्सेस ग्राफिक्स ऑब्जेक्ट है जो फ़ंक्शन के पैरामीटर के रूप में प्रदान की जाती है। ऐसी स्थिति में प्रतिबिंब संभव है? – LmSNe

+0

हां। यह कोड की कुछ पंक्तियों के साथ प्रतिबिंब के माध्यम से किया जा सकता है: http://stackoverflow.com/questions/76993/how-to-double-buffer-net-controls-on-a-form –

2
this.DoubleBuffered = true; 

यह ठीक है, लेकिन आप निर्माता को यह बयान बढ़ना है । डबल-बफरिंग के लिए सेटअप की आवश्यकता होती है, विंडोज फॉर्म को बफर बनाना होता है, जिसे से पहले पेंट इवेंट चलाया जाना चाहिए। निर्माता आदर्श है।

1

आपको प्रत्येक बार जब आप दोबारा शुरू करने के लिए डबलबफर्ड को सेट करने की आवश्यकता नहीं है। ड्राइंग समाप्त होने पर यह अक्षम नहीं है। बस DrawOn से लाइन को हटाएं और इसे कन्स्ट्रक्टर या फॉर्म डिज़ाइनर में सेट करें और परिणामों की जांच करें। मूल्य को गलत पर सेट करते समय महत्वपूर्ण झिलमिलाहट पैदा करना महत्वपूर्ण नहीं है।

मैं एक फार्म जहां एक टाइमर एक redraw हर मिलीसेकंड बलों में अपने कोड की कोशिश की और कोई अस्थिर देखा जब DoubleBuffered सत्य है:

private int yDir = 1,xDir=1; 
int step = 1; 

private void timer1_Tick(object sender, EventArgs e) 
{ 
    if (ball.Location.Y >= this.Height-50) 
     yDir = -1 ; 
    if (ball.Location.X >= this.Width-50) 
     xDir= -1 ; 

    ball.MoveBy(xDir*step,yDir*step); 
    ball.Host.ElapsedTime++; 
    this.Invalidate(); 
} 

private void DoubleBufferedBall_Paint(object sender, PaintEventArgs e) 
{      
     DrawOn(e.Graphics); 
} 
0

एक अन्य विकल्प है कि मैं आप के लिए बाहर टॉस होगा, ऐसा करने के लिए है आपके सभी ड्राइंग को बिटमैप में, और फिर ऑनपेंट विधि में, आप बस उस बिटमैप को फॉर्म में खींचते हैं।

इसका मैनुअल, लेकिन यह आपको पूर्ण नियंत्रण देता है। मैंने इसे कुछ पालतू परियोजनाओं पर कुछ सफलता के साथ उपयोग किया है।

आप भी एक्सएनए में देखना चाहते हैं - यह आपके प्रोजेक्ट के लिए अधिक हो सकता है, लेकिन आप WinForms में XNA का उपयोग एक प्रतिपादन इंजन के रूप में कर सकते हैं।

+0

क्या आपका मतलब था? सार्वजनिक शून्य ड्राऑन (ग्राफिक्स जी) { बिटमैप बिटमैप = नया बिटमैप (800, 600, जी); ग्राफिक्स जी 1 = ग्राफिक्स। फ्रॉम इमेज (बिटमैप); // जी 1 के लिए ड्राइंग ... जी। ड्रॉइमेज (बिटमैप, नया प्वाइंट (0, 0)); } क्योंकि यह अभी भी झिलमिलाहट है। – LmSNe

+0

हां, यह है, लेकिन मुझे यकीन नहीं है कि यह अभी भी आपके लिए क्यों झिलमिलाहट करता है। – Nate

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