CoyRect还是对象素的整块复制,而BitBlt一次只复制一个象素!这样吧,给你一
段代码,是关于如何生成动画,请仔细研究!
unit MainFrm;
interface
uses
SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
Forms, Dialogs, Menus, Stdctrls;
{$R SPRITES.RES } // Link in the bitmaps
type
TSprite = class
private
FWidth: integer;
FHeight: integer;
FLeft: integer;
FTop: integer;
FAndImage, FOrImage: TBitMap;
public
property Top: Integer read FTop write FTop;
property Left: Integer read FLeft write FLeft;
property Width: Integer read FWidth write FWidth;
property Height: Integer read FHeight write FHeight;
constructor Create;
destructor Destroy; override;
end;
TMainForm = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormPaint(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
BackGnd1, BackGnd2: TBitMap;
Sprite: TSprite;
GoLeft,GoRight,GoUp,GoDown: boolean;
procedure MyIdleEvent(Sender: TObject; var Done: Boolean);
procedure DrawSprite;
end;
const
BackGround = 'BACK2.BMP';
var
MainForm: TMainForm;
implementation
{$R *.DFM}
constructor TSprite.Create;
begin
inherited Create;
{ Create the bitmaps to hold the sprite images that will
be used for performing the AND/OR operation to create animation }
FAndImage := TBitMap.Create;
FAndImage.LoadFromResourceName(hInstance, 'AND');
FOrImage := TBitMap.Create;
FOrImage.LoadFromResourceName(hInstance, 'OR');
Left := 0;
Top := 0;
Height := FAndImage.Height;
Width := FAndImage.Width;
end;
destructor TSprite.Destroy;
begin
FAndImage.Free;
FOrImage.Free;
end;
procedure TMainForm.FormCreate(Sender: TObject);
begin
// Create the original background image
BackGnd1 := TBitMap.Create;
with BackGnd1 do
begin
LoadFromResourceName(hInstance, 'BACK');
Parent := nil;
SetBounds(0, 0, Width, Height);
end;
// Create a copy of the background image
BackGnd2 := TBitMap.Create;
BackGnd2.Assign(BackGnd1);
// Create a sprite image
Sprite := TSprite.Create;
// Initialize the direction variables
GoRight := true;
GoDown := true;
GoLeft := false;
GoUp := false;
{ Set the application's OnIdle event to MyIdleEvent which will start
the sprite moving }
Application.OnIdle := MyIdleEvent;
// Adjust the form's client width/height
ClientWidth := BackGnd1.Width;
ClientHeight := BackGnd1.Height;
end;
procedure TMainForm.FormDestroy(Sender: TObject);
begin
// Free all objects created in the form's create constructor
BackGnd1.Free;
BackGnd2.Free;
Sprite.Free;
end;
procedure TMainForm.MyIdleEvent(Sender: TObject; var Done: Boolean);
begin
DrawSprite;
{ Allow OnIdle to be called even when no messages are in the
application's message queue}
Done := False;
end;
procedure TMainForm.DrawSprite;
var
OldBounds: TRect;
begin
// Save the sprite's bounds in OldBounds
with OldBounds do
begin
Left := Sprite.Left;
Top := Sprite.Top;
Right := Sprite.Width;
Bottom := Sprite.Height;
end;
{ Now change the sprites bounds so that it moves in one direction
or changes direction when it comes in contact with the form's
boundries }
with Sprite do
begin
if GoLeft then
if Left > 0 then
Left := Left - 1
else begin
GoLeft := false;
GoRight := true;
end;
if GoDown then
if (Top + Height) < self.ClientHeight then
Top := Top + 1
else begin
GoDown := false;
GoUp := true;
end;
if GoUp then
if Top > 0 then
Top := Top - 1
else begin
GoUp := false;
GoDown := true;
end;
if GoRight then
if (Left + Width) < self.ClientWidth then
Left := Left + 1
else begin
GoRight := false;
GoLeft := true;
end;
end;
{ Erase the original drawing of the sprite on BackGnd2 by copying
a rectangle from BackGnd1 }
with OldBounds do
BitBlt(BackGnd2.Canvas.Handle, Left, Top, Right, Bottom,
BackGnd1.Canvas.Handle, Left, Top, SrcCopy);
{ Now draw the sprite onto the off-screen bitmap. By performing the
drawing in an off-screen bitmap, the flicker is eliminated. }
with Sprite do
begin
{ Now create a black hole where the sprite first existed by And-ing
the FAndImage onto BackGnd2 }
BitBlt(BackGnd2.Canvas.Handle, Left, Top, Width, Height,
FAndImage.Canvas.Handle, 0, 0, SrcAnd);
// Now fill in the black hole with the sprites original colors
BitBlt(BackGnd2.Canvas.Handle, Left, Top, Width, Height,
FOrImage.Canvas.Handle, 0, 0, SrcPaint);
end;
{ Copy the sprite at it's new location to the form's Canvas. A
rectangle slightly larger than the sprite is needed
to effectively erase the sprite by over-writing it, and draw the
new sprite at the new location with a single BitBlt call }
with OldBounds do
BitBlt(Canvas.Handle, Left - 2, Top - 2, Right + 2, Bottom + 2,
BackGnd2.Canvas.Handle, Left - 2, Top - 2, SrcCopy);
end;
procedure TMainForm.FormPaint(Sender: TObject);
begin
// Draw the background image whenever the form gets painted
BitBlt(Canvas.Handle, 0, 0, ClientWidth, ClientHeight,
BackGnd1.Canvas.Handle, 0, 0, SrcCopy);
end;
end.