Движение спрайта по фоновому изображению
Вы также должны создать 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
, который будет заменять курсор мыши. Мы могли бы заменить курсор мыши из ресурсов, но замена курсора мыши спрайтом позволяет продемонстрировать анимацию с минимальной логикой для управления им.
Комментарии