2010-03-02 9 views
15

Ich zeichne ständig Rahmen, und ich brauche die Form nicht zu flackern. Wie erreiche ich das?Wie Flicker in einem WinForms-Formular zu beheben?

public partial class Form1 : Form 
{ 
    Image[] dude = new Image[3]; 
    static int renderpoint = 0; 
    int lastimage = 0; 

    public Form1() 
    { 
     dude[1] = new Bitmap(@"snipe1.bmp"); 
     dude[0] = new Bitmap(@"snipe0.bmp"); 

     InitializeComponent(); 
    } 

    private void Form1_Shown(object sender, EventArgs e) 
    { 
     MainLoop(); 
    } 

    private void MainLoop() 
    { 
     double FPS = 10; 

     long ticks1 = 0; 
     long ticks2 = 0; 
     double interval = (double)Stopwatch.Frequency/FPS; 

     while (true) 
     { 
      ticks2 = Stopwatch.GetTimestamp(); 
      if (ticks2 >= ticks1 + interval) 
      { 
       ticks1 = Stopwatch.GetTimestamp(); 

       MoveGraphics(); 
       this.Refresh(); 
      } 

      Thread.Sleep(1); 
     } 
    } 

    private void Form1_Paint(object sender, PaintEventArgs e) 
    { 
     Graphics g = e.Graphics; 
     Rectangle rect = new Rectangle(renderpoint, 0, 100, 100); 
     Color lowcolor = Color.FromArgb(0, 128, 64); 
     Color highcolor = Color.FromArgb(0, 128, 64); 

     ImageAttributes imageAttr = new ImageAttributes(); 
     imageAttr.SetColorKey(lowcolor, highcolor); 

     if (lastimage == 1) 
     { 
      lastimage = 0; 
      g.DrawImage(dude[1], rect, 0, 0, 100, 100, GraphicsUnit.Pixel, imageAttr); 
     } 
     else 
     { 
      lastimage = 1; 
      g.DrawImage(dude[0], rect, 0, 0, 100, 100, GraphicsUnit.Pixel, imageAttr); 
     } 
    } 

    void MoveGraphics() 
    { 
     if (renderpoint > 950) 
     { 
      renderpoint = 0; 
     } 
     else 
     { 
      renderpoint += 10; 
     } 
    } 
} 

Es gibt den aktuellen Code. Vorschläge?

+0

C# haben keine Formulare. –

Antwort

12

Fügen Sie diese in Ihrem Form1 Konstruktor:

this.DoubleBuffered = true; 
+0

Das scheint gut zu funktionieren ... Aber die Jury auszuhalten, bis ich es mit mehr und simultanen Grafiken testen kann. – Bloodyaugust

12
  1. Sie Ihren Rendering in der Paint Ereignishandler
  2. deaktivieren automatische Löschen des Hintergrunds.
  3. Aktivieren Sie die doppelte Pufferung entweder über die Stile oder manuell.
  4. Wenn Sie neu streichen wollen, rufen Invalidate

Wenn Sie versuchen, von glatten Animation zu ziehen, ich kann dann Schiff zu WPF, OpenGL empfehlen Springen oder XNA. GDI + wurde nicht für die Animation entwickelt (die Windows-Nachrichtenschleife ist kein Echtzeitsystem, Sie werden also immer zittern).

+2

Verwenden Sie auch einen Timer anstelle von 'Thread.Sleep'. – SLaks

+0

# 1 ... Ich denke, Sie wollten sagen, machen Sie Ihr Rendering zu einem Offscreen-Puffer, wenn nötig, und einfach BitBlt zu Ihrem Formular in der Paint Event-Handler. – overslacked

+0

@ overslacked Ja, aber so einfach ist das nicht. Im Idealfall würden Sie nur im Hintergrundpuffer zeichnen, wenn Sie keine Terminaldienste verwenden. Wenn Sie TS verwenden, sollten Sie direkt in den Kontext zeichnen. Um dies zu vereinfachen, hat Microsoft einige Erweiterungen zu GDI + hinzugefügt, um eine OS/Framework-basierte doppelte Pufferung durchzuführen. –