webForumDet fria alternativet

Flimmer i animation

.NET

6 svar · 397 visningar · startad av haagel

Medlem sedan feb. 2006134 inlägg
Frågan#1

Jag har gjort en animation som flimrar väldigt mycket. Om jag förstår det rätt så ska man använda sig av en minnesbuffert för att komma runt detta problem. Man ska rita till bufferten och sedan visa det på skärmen först när allt ritats klart.

Men hur gör man detta? Jag ritar mina objekt (rektanglar och cirklar) i en Panel.

Medlem sedan aug. 2001145 inlägg
#2

Hmm, va ett bra tag sedan men nått i stil med

sdc = GetDC(hwnd); // screendc, den du renderar till nu när de flimmrar

skapar buffer i initieringen.

bm =CreateCompatibleBitmap(sdc,
GetDeviceCaps(sdc, HORZRES),
GetDeviceCaps(sdc, VERTRES));

mdc = CreateCompatibleDC(NULL);

// Rendera allt till mdc

// Kopiera bufferten till screendc
SelectObject(mdc, bm)
BitBlt(sdc, 0,0, width,height, mdc, 0,0, SRCCOPY);

Nått liknande iaf, kolla upp funktionerna på msdn.

Inte så mycket direkt hjälp men en spark i rätt riktning iaf :)

Medlem sedan feb. 2006134 inlägg
#3

Tack Dies_irae, jag förstår ungefär hur det är tänkt att fungera. Men när jag letar i MSDN hittar jag mer om klasserna "BufferedGraphics", "BufferedGraphicsContext" mfl.

Jag glömde förresten nämna att jag jobbar i C# (i Visual Studio 2005).

Har hittat lite exempelkod i MSDN men jag vet inte riktigt vart jag ska skriva koden.

Jag har ett formulär (Form1) i vilket jag lagt en "Panel". För denna panel har jag sedan en Paint-metod (händelsehanterare) som ritar ut diverse objekt (rektanglar och cirklar) med en instans av Graphics-klassen.

I Form1:

private void gamePanel_Paint(object sender, PaintEventArgs e)
{
    Graphics g = e.Graphics;

    leftPaddle.Draw(g);
    rightPaddle.Draw(g);
    ball.Draw(g);
}

Draw-metoden för leftPaddle och RightPaddle ser ut som följer:

public void Draw(Graphics g)
{
    g.FillRectangle(Brushes.White, this.xPosition, this.yPosition, this.width, this.height);
}

Och för ball:

public void Draw(Graphics g)
{
    g.FillEllipse(Brushes.White, this.xPosition, this.yPosition, this.width, this.height);
}

Detta fungerar alltså, men det flimrar rejält. Var skriver jag koden som ritar till en buffert?

Medlem sedan feb. 20002 300 inlägg
#4

haagel skrev:

Detta fungerar alltså, men det flimrar rejält. Var skriver jag koden som ritar till en buffert?

Om du har en överlagrad panel som du ritar på så kan du lägga detta i konstruktorn för panelen:

this.SetStyle(ControlStyles.DoubleBuffer | 
      ControlStyles.UserPaint | 
      ControlStyles.AllPaintingInWmPaint,
      true);

Annars får du använda double buffering: http://msdn2.microsoft.com/en-us/library/6e2a1b49.aspx

Enkelt förklarat så ritar du allting du ska rita ut på en temporär bitmap. Inte förräns du ritat klart allting så ritar du bitmapen till skärmen.

Medlem sedan feb. 2006134 inlägg
#5

Tack Phorper, men jag får ändå inte till det...

Jag skrev om min Paint-metod till följande:

private void gamePanel_Paint(object sender, PaintEventArgs e)
{      
    Graphics g = e.Graphics;

    Bitmap bufferBitmap = new Bitmap(gamePanel.Width, gamePanel.Height);
    Graphics bufferGraphics = Graphics.FromImage(bufferBitmap);

    leftPaddle.Draw(bufferGraphics);
    rightPaddle.Draw(bufferGraphics);
    ball.Draw(bufferGraphics);

    g.DrawImage(bufferBitmap, 0, 0);

    g.Dispose();
    bufferGraphics.Dispose();
}

Det fungerar på så vis att grafiken ritas ut som den ska, men nu flimrar det ännu värre :( Vad gör jag för fel?

Medlem sedan dec. 2005664 inlägg
#6

Har du tittat på metoden SetStyle som finns på ditt formulär?

Medlem sedan feb. 2006134 inlägg
#7

Ja, jag testade att skriva in följande i kontruktorn till mitt formulär:

SetStyle(ControlStyles.OptimizedDoubleBuffer, true);

Tyvärr blev det ingen skillnad... :(

Hur är det när man skriver in detta? Gäller det då för fomuläret och alla dess kontroller. Jag ritar ju som jag nämde inte direkt i formuläret utan i en "Panel" som ligger i formuläret.

Hur som helst, är tacksam för alla idéer och tar gärna emot fler! :)

273 ms totalt · 4 externa anrop · v20260731065814-full.a51de22e
142 ms — deklarationer (db)
0 ms — hämta statistik (cache)
127 ms — hämta tråd, inlägg och bilagor (db)
132 ms — ändringar (db)