Воспользуемся способом №2, известным как "буферизация фона". Его идея даже проще – нужно перед отрисовкой каждого кадра запоминать фон под движущимся элементом картинки в отдельной переменной, а затем восстанавливать его. Наша летающая тарелка вписывается в прямоугольник с координатами (x,y) – (x+20,y+10). Чтобы запомнить такой фрагмент изображения, понадобится глобальная переменная типа TBitMap. Ее надо проинициализировать в начале работы программы (событие формы OnCreate) и удалить из памяти перед завершением работы (событие формы OnDestroy). Также введем константы UFOWidth и UFOHeight для хранения габаритных размеров перемещаемого фрагмента изображения и немного украсим нашу тарелку.
var Form1:TForm1;
mm:TBitMap;
const UFOWidth=20;
UFOHeight=10;
PROCEDURE Ufo(x,y:INTEGER);
begin
WITH Form1.Image1.Canvas DO
BEGIN
Pen.Color:=clBlue;
Brush.Color:=clWhite;
Pen.Width:=1;
Ellipse(x,y,x+UFOWidth,y+UFOHeight);
Pen.Color:=clRed;
MoveTo(x,y+UFOHeight DIV 2);
LineTo(x+UFOWidth,y+UFOHeight DIV 2)
END
END;
procedure TForm1.FormCreate(Sender: TObject);
begin
mm:=TBitMap.Create;
// задаем размеры буфера, равные размерам НЛО
mm.Width:=UFOWidth;
mm.Height:=UFOHeight
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
mm.Free
end;
Собственно отрисовка с буферизацией фона выполняется следующим образом:
procedure TForm1.Button1Click(Sender: TObject);
var i:word;
begin
DoubleBuffered:=true;
with Image1.Canvas do
begin
Brush.Color:=clBlack;
FillRect(Image1.ClientRect);
// вывод звездного неба
for i:=1 to 1500 do
Pixels[Random(Image1.Width),Random(Image1.Height)]:=
clWhite;
FOR i:=0 TO Image1.Width DO
BEGIN
// Запоминаем фрагмент в буфере
mm.Canvas.CopyRect(Rect(0,0,mm.Width,mm.Height),
Image1.Canvas,Rect(i,i DIV 2,i+UFOWidth,I DIV 2
+ UFOHEight));
// Рисуем НЛО
Ufo(i, i DIV 2);
// Ждем
Application.ProcessMessages;
Sleep(30);
// Восстанавливаем фон
Image1.Canvas.Draw(i,i DIV 2,mm);
END
END
end;
Метод C1.CopyRect(R1,C2,R2) копирует изображение, содержащееся в прямоугольнике R2 на холсте С2, в прямоугольник R1 на холсте С1. Разумеется, прямоугольники должны быть одинакового размера, хотя и могут находиться в разных частях холстов.
Метод C1.Draw(x,y,m) выводит изображение, хранящееся в переменной m типа TBitMap, на холст C1 в точке x,y.
В результате мы получили настоящую цветную анимацию в лучших диснеевских традициях, что и требовалось.