Використання бітових образів

У попередньому прикладі зображення формувалося з графічних примітивів. Тепер розглянемо, як можна реалізувати переміщення одного складного зображення на тлі іншого, наприклад переміщення літака на тлі міського пейзажу.

Ефект переміщення картинки може бути створений шляхом періодичної перемальовування картинки з деяким зміщенням щодо її попереднього стану. При цьому передбачається, що перед висновком картинки в новій точці спочатку видаляється попереднє зображення. видалення картинки може бути виконано шляхом перемальовування всієї фонової картинки або тільки тієї її частини, яка перекрита бітовим чином, що рухається.

У даній програмі використовується другий підхід. Картинка виводиться застосуванням методу Draw до властивості canvas компонента Image, a стирається шляхом копіювання (метод copyRect) потрібної частини фону з буфера на поверхню компонента Image.

Форма програми приведена на рис. 10.18, а текст – в лістингу 10.10.

Компонент image використовується для виведення фону, а компонент Timer – для організації затримки між циклами видалення і виведення на новому місці зображення літака.

Лістинг 10.10. Летить літак

unit anim_;
interface
uses
Windows, Messages, SysUtils,

Classes, Graphics, Controls,

Forms, Dialogs, ExtCtrls, StdCtrls, Buttons;
type
TForm1 = class (TForm)
Timer1: TTimer;
Image1: Tlmage;
procedure FormActivate (Sender: TObject);
procedure Timer1Timer (Sender: TObject);
procedure FormClose (Sender: TObject;

var Action: TCloseAction); private
{ Private declarations} public
{ Public declarations} end;
var
Form1: TForm1;
implementation
{$ R * .DFM}
var
Back, bitmap, Buf: TBitMap; // фон, картинка, буфер

BackRct : TRect; // область фону, яка повинна бути
// відновлена з буфера

BufRet: Trect; // область буфера, яка використовується для
// відновлення фону
х, у: integer; // поточний стан картинки

W, H: integer; // розміри картинки
procedure TForm1.FormActivate (Sender: TObject);

begin
// створити три об'єкти - бітових образу

Back : = TBitmap.Create; // фон

bitmap : = TBitmap.Create; // картинка

Buf : = TBitmap.Create; // буфер
// завантажити і вивести фон

Back.LoadFromFile ( 'factory.bmp');

Form1.Image1.canvas.Draw (0,0, Back);
// завантажити картинку, яка буде рухатися
bitmap.LoadFromFile ( 'aplane.bmp');
// визначимо  "прозорий "колір
bitmap.Transparent : = True;
bitmap.TransParentColor : = Bitmap.canvas.pixels [1,1];
// створити буфер для збереження копії області фону,
// на яку накладається картинка
W: = bitmap.Width;
Н: = bitmap.Height;
Buf.Width: = W;
Buf.Height: = H;
Buf.Palette: = Back.Palette;

// Щоб забезпечити відповідність палітр //
Buf.Canvas.CopyMode: = cmSrcCopy;
// визначимо область буфера, яка

// буде використовуватися
// для відновлення фону

BufRct: = Bounds (0,0, W, H);
// початкове положення картинки

х : = -W; у: = 20;
// визначимо зберігається область фону

BackRct: = Bounds (x, y, W, H); // і збережемо її
Buf.Canvas.CopyRect (BufRet, Back.Canvas, BackRct);

end;
// обробка сигналу таймера
procedure TForm1.Timer1Timer (Sender: TObject);
begin
// відновленням фону (з буфера) видалимо малюнок
Forml.image1.canvas.Draw (x, у, Buf);
x: = x + 2;
if x > fоrm1.Image1.Width then x: = - W;
// визначимо зберігається область фону
BackRct: = Bounds (x, у, W, H);
// збережемо її копію
Buf.Canvas.CopyRect (BufRct, Back.Canvas, BackRct);
// виведемо малюнок
Forml.image1.canvas.Draw (x, y, bitmap);

end;
// завершення роботи програми
procedure TForm1.FormClose (Sender: TObject; var Action: TCloseAction);
begin
// звільнимо пам'ять, виділену
// для зберігання бітових образів
Back.Free;
bitmap.Free;
Buf.Free;

end;

end.

Рис. 10.18. Форма програми Літак

Для зберігання бітових образів (картинок) фону і літака, а також копії області фону, що перекривається зображенням літака, використовуються об’єкти типу TBitMap, які створюються динамічно процедурою FormActivate. Ця ж процедура завантажує з файлів картинки фону (factory.bmp) і літака (aplane.bmp), а також зберігає область фону, на яку вперше буде накладатися картинка.

Збереження копії фону виконується за допомогою методу CopyRect, який дозволяє виконати копіювання прямокутного фрагмента одного бітового образу в інший. Об’єкт, до якого застосовується метод CopyRect, є приймачем копії бітового образу. В якості параметрів методу передаються координати і розмір області, куди повинно бути виконано копіювання, поверхня, звідки має бути виконано копіювання, а також становище і розмір копируемой області.

Інформація про стан і розмірі копируемой в буфер області фону, на яку буде накладено зображення літака і яка згодом повинна бути відновлена з буфера, знаходиться в структурі BackRct типу TRect. Для заповнення цієї структури використовується функція Bounds.

Слід звернути увагу на те, що початкове значення змінної х, яка визначає положення лівої верхньої точки бітового образу рухомої картинки, – негативне число, рівне ширині бітового образу картинки. Тому на початку роботи програми зображення літака не з’являється, картинка промальовується за кордоном видимої області. З кожним подією OnTimer значення координати х збільшується, і на екрані з’являється та частина бітового образу, координати якої більше нуля. Та ким чином, у спостерігача створюється враження, що літак вилітає з-за лівої кордону вікна.