2010-03-02 3 views
15

Je dessine constamment des cadres, et j'ai besoin de la forme pour ne pas scintiller. Comment puis-je accomplir cela?Comment réparer Flicker dans un formulaire WinForms?

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; 
     } 
    } 
} 

Il y a le code actuel. Suggestions?

+0

C# ne pas les formes. –

Répondre

12

Collez ce code dans votre constructeur Form1:

this.DoubleBuffered = true; 
+0

Cela semble fonctionner correctement ... Mais en laissant le jury jusqu'à ce que je peux le tester avec plus de graphiques simultanés. – Bloodyaugust

12
  1. Est-ce votre rendu dans le gestionnaire d'événements Paint
  2. Désactiver l'effacement automatique de l'arrière-plan.
  3. Activez la double mise en mémoire tampon via les styles ou manuellement.
  4. Lorsque vous voulez repeindre, appelez Invalidate

Si vous essayez de tirer d'une animation fluide, alors que je pourrais sauter recommande bateau à WPF, OpenGL ou XNA. Le GDI + n'a pas été conçu pour l'animation (la boucle de messages de Windows n'est pas un système en temps réel, donc vous aurez toujours de la gigue).

+2

Utilisez également une minuterie au lieu de Thread.Sleep. – SLaks

+0

# 1 ... Je pense que vous vouliez dire faire votre rendu à un tampon hors écran si nécessaire, et simplement BitBlt à votre formulaire dans le gestionnaire d'événements Paint. – overslacked

+0

@overslacked Oui, mais ce n'est pas si simple. Idéalement, vous ne dessinez dans le tampon arrière que si vous n'utilisez pas les services Terminal Server. Lorsque vous utilisez TS, vous devez dessiner directement dans le contexte. Pour simplifier cela, Microsoft a ajouté quelques extensions à GDI + pour effectuer une double mise en mémoire tampon basée sur OS/Framework. –

Questions connexes