Laden...

GDI+: Flackern trotz Double Buffering?

Erstellt von trigger3 vor 14 Jahren Letzter Beitrag vor 14 Jahren 4.121 Views
t
trigger3 Themenstarter:in
59 Beiträge seit 2008
vor 14 Jahren
GDI+: Flackern trotz Double Buffering?

hi,

ich programmiere mir gerade ein kleines Jump and Run. Zwar wusste ich das GDI gern die Form zum flackern bringt doch man kann es ja anscheinen umgehen in dem man die Bilder in eine Bitmap zeichnet und dann die Bitmap auf die Form zeichnet.

Hier mein bisheriger Code:

   
public Bitmap CurrScreen;
public Graphics Grafik;
   
//onload
{
this.CurrScreen = new Bitmap(BackGround.IMG, FormToDrawOn.ClientRectangle.Width, FormToDrawOn.ClientRectangle.Height);

this.Grafik = Graphics.FromImage(CurrScreen);
}

//die 2 fach überladene aDraw Funktion wird aufgerufen wenn sich ein Bild ändert, der komplette Code ist allerdings zu lange und falls doch Fragen da sind kann ich sie entweder beantworten oder den Source einstellen

        public void aDraw(Image bild, int x, int y, float Width, float Height)
        {
            Grafik.DrawImage(bild, x, y, Width, Height);
        }


        public void aDraw(Color Color, Rectangle Rectangle)
        {

            Grafik.FillRectangle(new SolidBrush(Color), Rectangle);
        }

 void GameTimer_Tick(object sender, EventArgs e)
        {
            Graphics g = this.Form.CreateGraphics();
            g.DrawImage(CurrScreen, 0, 0);
            g.Dispose();
        }

        void Form_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.DrawImage(CurrScreen, 0, 0);
        }

Mein eher gemütliches Jump and Run bewegt sich bei 20 Bildern pro Sekunde.

Fehlerbeschreibung:
Man sieht jede Bewegung die man bisher mit der Figut getätigt hat. Der Hintergrund bleibt solide wobei die Figur flackert (Bild da-Bild weg - Bild da- Bild weg)

Da ganze ist bei mir in einer externen Klasse untergebracht. Das //onload ist also nicht das laden einer Form sondern das instanziieren eines neuen Spieles welches bei mir nach dem abschluss des ersten Ladens erstellt wird.

Mit freundlichen Grüßen,
trigger3

946 Beiträge seit 2008
vor 14 Jahren

Das DoubleBuffering hebt das Flackern nicht immer auf.

Ich würde eher eine PictureBox verwenden und ihr immer ein anderes Bild zuweisen

Dazu siehe
[Artikel] Flackernde Controls und flackerndes Zeichnen vermeiden
[Tutorial] Zeichnen in Windows-Programmen (Paint/OnPaint, PictureBox)

Ansonsten kannst du auch eine ganz andere Technologie nehmen.
WPF ist dafür super geeignet, aber leider auch etwas schwer.
Oder XNA.

1.346 Beiträge seit 2008
vor 14 Jahren

Außerdem sollte man CreateGraphics nicht benutzen, sondern die Draw Methode überschreiben.

Du kanst Invalide Aufrufen, damit es sich neuzeichnet.

Gruß pdelvo

t
trigger3 Themenstarter:in
59 Beiträge seit 2008
vor 14 Jahren

Form.Invalidate();

führt doch aber 100%tig zu einem flackern oder?

Ich werd dann wohl meine paar 100 Zeilen wohl doch umkrempeln müssen, danke an euch zwei.

1.346 Beiträge seit 2008
vor 14 Jahren

Er löscht die Zeichenoberfläche nicht. Deswegen flackerts nicht.
Er ruft nicht e.Graphic.Clear(/Color/) auf.

Gruß pdelvo

t
trigger3 Themenstarter:in
59 Beiträge seit 2008
vor 14 Jahren

Ich habe es jetzt wie folgt gelöst, dabei konnte ich bei meinen Grundfunktionen bleiben und hab die Form als Zeichenplattform mit einer Imagebox vertauscht.


void GameTimer_Tick(object sender, EventArgs e)
        {
                Hero.Move(CheckMoveDirec());
                PicBox.Image = CurrScreen;
                PicBox.Invalidate();
        }

        void PicBox_Paint(object sender, PaintEventArgs e)
        {
            
            Grafik.Clear(Color.Black);
        }



das ist komplett Flicker frei

42 Beiträge seit 2006
vor 14 Jahren

Noch ein Tipp:

Einen der überladenen Konstruktoren bei Invalidate() benutzen, wenn möglich, damit nicht die gesamte Zeichenfläche jedes Mal neugezeichnet wird:

PicBox.Invalidate(Rectangle);

~ There's no knowledge that is not power~