用双缓冲实现图形的移动

来源:互联网 发布:上海软件培训 编辑:程序博客网 时间:2024/06/05 17:04

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    Image1: TImage;
    Timer1: TTimer;
    Button2: TButton;
    Button3: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    procedure RefreshActivePoint;
    procedure MoveImage;
    { Private declarations }
  public
    { Public declarations }
    FBitMap:TBitMap; //保存图形
    FBitMapBuff:TBitMap; //缓冲区
    FActivePoint:TPoint; //当前移动到的位置
    FMoveXSpace:Integer; //X方向要移动的距离
    FMoveYSpace:Integer; //Y方向要移动的距离
    FStop:Boolean;
  end;


var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  FBitMapBuff:=TBitmap.Create;
  FBitMap:=TBitmap.Create;
  //缓冲区图大小和Image1大小相同
  FBitMapBuff.Width:=Image1.Width;
  FBitMapBuff.Height:=Image1.Height;
  FBitMap.LoadFromFile('D:/Winnt/Greenstone.bmp');
  FActivePoint:=Point(0,0);
  FMoveXSpace:=10;
  FMoveYSpace:=10;
end;

function  GetRandomSpace:Integer;
begin
//返回一个随机的移动距离
  Randomize;
  Result:=Random(30);
end;

procedure TForm1.RefreshActivePoint;
begin
   //检查移动边界,确定下一个要移动到的位置
  if (FActivePoint.X+FBitMap.Width>=Image1.Width) then
    FMoveXSpace:=0-GetRandomSpace
  else if FActivePoint.X<=0 then
    FMoveXSpace:=GetRandomSpace;

  if FActivePoint.Y+FBitMap.Height>=Image1.Height then
    FMoveYSpace:=0-GetRandomSpace
  else if FActivePoint.Y<=0 then
    FMoveYSpace:=GetRandomSpace;
  FActivePoint:=Point(FActivePoint.X+FMoveXSpace,FActivePoint.Y+FMoveYSpace);

  if FActivePoint.X+FBitMap.Width>Image1.Width then
    FActivePoint.X:=FActivePoint.X-(FActivePoint.X+FBitMap.Width-Image1.Width)
  else if FActivePoint.X<0 then
    FActivePoint.X:=0;

  if FActivePoint.Y+FBitMap.Height>Image1.Height then
    FActivePoint.Y:=FActivePoint.Y-(FActivePoint.Y+FBitMap.Height-Image1.Height)
  else if FActivePoint.Y<0 then
    FActivePoint.Y:=0;
end;

procedure  TForm1.MoveImage;
begin
  //先绘制缓冲区中的图形
  With FBitMapBuff do
  begin
    FreeImage;
    CleanupInstance;
    Canvas.FillRect(Rect(0,0,FBitMapBuff.Width,FBitMapBuff.Height));
    Canvas.Draw(FActivePoint.X,FActivePoint.Y,FBitMap);
  end;
  //然后直接给Image 绘制
  Image1.Canvas.Draw(0,0,FBitMapBuff);
  RefreshActivePoint;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
//循环移动
  FStop:=Not FStop;
  while FStop do
  begin
    MoveImage;
    Application.ProcessMessages;
  end;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
//定时器移动
  Timer1.Enabled:=Not Timer1.Enabled;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  MoveImage;
end;

end. 

原创粉丝点击