Двойная буферизация или Анимация без мерцания
10.12.2007 от Иван ШиркоСтраница: 1 2
Давайте рассмотрим реализацию этого алгоритма на Delphi. В данном примере по сложному фону будет летать по круговой траектории самолётик (рис.1).

Вначале нужно объявить несколько констант и переменных:
const
//координаты центра окружности
xc = 200;
yc = 200;
//приращение угла
dl = 0.05;
//радиус окружности
R=100;
var
//для хранения изображений
sam, buf: TBitmap;
BufRct: TRect;
l: real;
x, y:integer;
w, h:integer;
Действия при запуске программы:
//создаём объекты для хранения изображений
Buf:=TBitmap.Create;
Sam:=TBitmap.Create;
//делаем фон самолётика прозрачным
Sam.Transparent:=true;
//загружаем изображение самолётика
Sam.LoadFromFile('sam.bmp');
//устанавливаем размеры буфера такими же, как у самолётика
w := Sam.Width;
h := Sam.Height;
Buf.Width:=w;
Buf.Height:=h;
//начальный угол
l := 0;
//начальные координаты
x := round(xc+R*cos(l));
y := round(yc+R*sin(l));
//сохраняем участок фона
BufRct := Bounds(x,y,w,h);
Buf.Canvas.CopyRect(Buf.Canvas.ClipRect,Image1.Canvas,BufRct);
//рисуем самолётик
Image1.Canvas.Draw(x,y,sam);
//запускаем таймер
Timer1.Enabled := true;
Теперь через небольшой промежуток времени выполняем процедуру:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
//восстанавливаем участок фона
Image1.Canvas.Draw(x,y,buf);
//увеличиваем угол
l := l + dl;
//если самолёт сделал круг, то отнимаем от угла 2 пи
if (l>2*pi) then
l := l - 2*pi;
//высчитываем координаты по новому углу
x := round(xc+R*cos(l));
y := round(yc+R*sin(l));
//сохраняем участок фона в буфер
BufRct := Bounds(x,y,w,h);
Buf.Canvas.CopyRect(Buf.Canvas.ClipRect,Image1.Canvas,BufRct);
//рисуем самолётик
Image1.Canvas.Draw(x,y,sam);
end;
Разумеется, этот алгоритм можно перенести и на случай движения изображения по движущемуся фону, достаточно лишь математически учесть изменение положения фона. Метод двойной буферизации применяют также и для неподвижных объектов, например, для отображения какой-нибудь анимации (флаг развевается на ветру), т.е. после каждого кадра анимации мы восстанавливаем фон, чтобы исключить наложение кадров друг на друга.
Как видим, метод двойной буферизации достаточно легко реализовать, но несмотря на это он показывает очень хорошие результаты. И правильное использование описанного алгоритма делает программу с простой анимацией более эффектной и профессиональной без особых усилий программиста.
Иван Ширко
ishyrko@gmail.com
Страница: 1 2
Рубрики: Delphi |