2010-03-02 17 views
15

Estoy dibujando cuadros constantemente, y necesito el formulario para no parpadear. ¿Cómo logro esto?¿Cómo reparar el parpadeo en un formulario de 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; 
     } 
    } 
} 

Ahí está el código actual. Sugerencias?

+0

C# no tiene formas. –

Respuesta

12

Pega esto en el constructor de Form1:

this.DoubleBuffered = true; 
+0

Esto parece funcionar bien ... Pero tendré que esperar al jurado hasta que pueda probarlo con más y gráficos simultáneos. – Bloodyaugust

12
  1. Haga su representación en el controlador de eventos Paint
  2. borrado automático de desactivación del fondo.
  3. Habilite el doble almacenamiento en búfer mediante los estilos o manualmente.
  4. Cuando desee volver a pintar, llame Invalidate

Si usted está tratando de tirar de animación suave, entonces te recomiendo abandonar el barco a WPF, OpenGL, o XNA. GDI + no fue diseñado para la animación (el bucle de mensajes de Windows no es un sistema en tiempo real, por lo que siempre tendrá nerviosismo).

+2

Además, use un temporizador en lugar de 'Thread.Sleep'. – SLaks

+0

# 1 ... Creo que quiso decir hacer su renderizado en un búfer fuera de la pantalla cuando sea necesario, y simplemente BitBlt a su formulario en el controlador de eventos de Paint. – overslacked

+0

@overslacked Sí, pero en realidad no es así de simple. Idealmente, solo dibujaría en el búfer posterior cuando no use Servicios de Terminal Server. Al usar TS, debe dibujar directamente en el contexto. Para simplificar esto, Microsoft agregó algunas extensiones a GDI + para hacer un búfer doble basado en OS/Framework. –

Cuestiones relacionadas