Основным способом передвижения изображения по фоновому изображению заключается в следующем. Сначала создается одноцветный точечный рисунок того же размера, что и движущееся изображение с черным силуэтом, например, самолет на белом фоне. Это будет маска. Вы также должны создать Bitmap такого же размера, чтобы хранить ту часть фона, которую будем перезаписывать. Процесс передвижения выглядит следующим образом:
- Восстанавливаем участок фона, где будет движущееся изображение из Bitmap для хранения.
- Копируем прямоугольник фона для хранения из нового места.
- Копируем изображение на фон, используя SRCINVERT.
- Копируем маску на фон, используя SRCAND.
- Копируем изображение на фон еще раз, используя SRCINVERT.
Эти операции могут быть обработаны при помощи CopyRect, но будет невероятное мерцание экрана. Поэтому мы будем использовать функцию Windows API BitBlt.
Вот пример использования этого:
unit Anim1;
interface
uses
SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
Forms, Dialogs;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure FormDestroy(Sender: TObject);
protected
FStorage: TBitMap;
FMask: TBitMap;
FImage: TBitMap;
FOldRect: TRect;
FNewRect: TRect;
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin
FMask := TBitMap.Create;
FMask.LoadFromFile(ExtractFilePath(Application.ExeName) + 'MYMASK.BMP');
FImage := TBitMap.Create;
FImage.LoadFromFile(ExtractFilePath(Application.ExeName) + 'MYBMP.BMP');
FStorage := TBitMap.Create;
FStorage.Width := FImage.Width;
FStorage.Height := FImage.Height;
Screen.Cursor := crNone;
end;
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
const
FirstTime: boolean = True;
begin
{ 1) Восстанавливаем Form1: копируем сохраненное изображение
на Form1 в его старую позицию }
if FirstTime then FirstTime := False
else BitBlt(Form1.Canvas.Handle, FOldRect.Left, FOldRect.Top, FImage.Width,
FImage.Height,
FStorage.Canvas.Handle, 0, 0,
SRCCOPY);
{ Сохраняем старую позицию }
FNewRect := Rect(X, Y, X + FImage.Width, Y + FImage.Height);
FOldRect := FNewRect;
{ 2) Сохраняем копию Form1: копируем прямоугольник из в Bitmap
для хранения из Form1 в новой позиции. }
BitBlt(FStorage.Canvas.Handle, 0, 0, FImage.Width, FImage.Height,
Form1.Canvas.Handle, FNewRect.Left, FNewRect.Top,
SRCCOPY);
{ 3) Копируме изображение на Form1, используя SRCINVERT }
BitBlt(Form1.Canvas.Handle, FNewRect.Left, FNewRect.Top,
FImage.Width, FImage.Height,
FImage.Canvas.Handle, 0, 0,
SRCINVERT);
{ 4) Копируем маску на Form1, используя SRCAND }
BitBlt(Form1.Canvas.Handle, FNewRect.Left, FNewRect.Top,
FImage.Width, FImage.Height,
FMask.Canvas.Handle, 0, 0,
SRCAND);
{ 5) Копируем изображение на Form1, также используем SRCINVERT }
BitBlt(Form1.Canvas.Handle, FNewRect.Left, FNewRect.Top,
FImage.Width, FImage.Height,
FImage.Canvas.Handle, 0, 0,
SRCINVERT);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
FMask.Free;
FImage.Free;
FStorage.Free;
end;
end.
В этом проекте спрайт Bitmap 32 х 32 точки, определенные в MyMask.bmp и MyBmp.bmp , который будет заменять курсор мыши. Мы могли бы заменить курсор мыши из ресурсов, но замена курсора мыши спрайтом позволяет продемонстрировать анимацию с минимальной логикой для управления им.
|