Podwójne buforowanie
const Szerokosc = 20; Wysokosc = 20; var Pozycja: Integer; procedure TForm1.Timer1Timer(Sender: TObject); begin Canvas.Pen.Color := clWhite; Canvas.Brush.Color := clWhite; Canvas.Rectangle(Pozycja, 100, Pozycja + Szerokosc, 100 + Wysokosc); Pozycja := Pozycja + 1; end;
W rezultacie program będzie rysował grubą linię po środku ekranu
Dobrym sposobem będzie rysowanie linii w kolorze tla za kwadratem.
Canvas.MoveTo(Pozycja - 1, 100); Canvas.LineTo(Pozycja - 1 , 100 + Wysokosc);
Ale co zrobić, gdy animacja będzie zawierała wiele rożnych figur, a tło nie będzie w postaci jednolitego koloru tylko bitmapy?
Własnie w takich momentach warto wykorzystać "Double Buffering"
Wystarczy zadeklarować dodatkową zmienną TCanvas
var Buf: TCanvas;
i tło jako bitmapę:
Bitmap: TBitmap;
Inicjalizujemy Bufor:
Buf := TBitmap.Create(Self); Buf.Width := Form1.Canvas.Width; Buf.Height := Form1.Canvas.Height;
a nastepnie wczytujemy tlo:
Bitmap := TBitmap.Create; Bitmap.LoadFromFile('obrazek.bmp');
wtedy procedura wygląda tak:
procedure TForm1.Timer1Timer(Sender: TObject); var l: Integer; begin Buf.Draw(0, 0, Bitmap); {rysujemy tlo} Buf.Pen.Color := clWhite; Buf.Brush.Color := clWhite; Buf.Rectangle(Pozycja, 100, Pozycja + Szerokosc, 100 + Wysokosc); Pozycja := Pozycja + 1; {kopiujemy Buf na ekran} Form1.Canvas.CopyRect(Form1.Canvas.ClipRect, Buf, Buf.ClipRect); end;
W efekcie prostokąt porusza się bez migotania i na tle które wczytaliśmy.
Zasada jest prosta. Pierw rysujemy całą animację w pamięci (zmienna Buf), a następnie kopiujemy ją na ekran (procedure CopyRect) , co daje efekt płynności i wrażenia, że całość rysuje się naraz.
5 komentarzy
bez jaj.... ale ten artykuł jest strasznie pokręcony ... i wyskakują błędy. Może jestem początkujący ale na necie znalazłem banalne rozwiązanie ... i piszę je dla tych co się załamali usiłując przepisać ten kod:
Problem: mruganie obrazka podczas przesuwania po formie
Rozwiązanie: Forma > OnCreate > wklepać ..... DoubleBuffered := True
Nie ma prawa migać ... Pozdrawiam
Juz mam ok.
//****************************************************
// Tworzymy bufor dla obrazka
//****************************************************
backgroundImage := TImage.Create( Self );
backgroundCanvas := TCanvas.Create;
//zaladuj obrazek
backgroundImage.Picture.LoadFromFile('obrazek.bmp');
Warto spojrzeć, jak to jest zrobione w demie Delphi - Demos\EarthPng\
Tu mi sie wywala, ze argumenty złe:
Buf := TBitmap.Create(Self); <------- [Error] ClockZ.pas(185): Too many actual parameters
Co mam zrobić?
A nie lepiej tak:
DoubleBuffered := True;