我在一个移植自上使用了30张png图片来制作一个简单的动画,一个Timer每33毫秒制作一个事件来改变拥有png图像的TImage组件的可见性,我尝试了其他帖子中建议的所有方法来停止闪烁,但无法解决问题。
unit Animation;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, AdvShaper, pngimage, ExtCtrls, StdCtrls;
type
TAnimation_Form = class(TForm)
Image1: TImage;
Timer: TTimer;
Image2: TImage;
Image3: TImage;
Image4: TImage;
Image5: TImage;
Image6: TImage;
Image7: TImage;
Image8: TImage;
Image9: TImage;
Image10: TImage;
Image11: TImage;
Image12: TImage;
Image13: TImage;
Image14: TImage;
Image15: TImage;
Image16: TImage;
Image17: TImage;
Image18: TImage;
Image19: TImage;
Image20: TImage;
Image21: TImage;
Image22: TImage;
Image23: TImage;
Image24: TImage;
Image25: TImage;
Image26: TImage;
Image27: TImage;
Image28: TImage;
Image29: TImage;
Image30: TImage;
Exit: TButton;
procedure TimerTimer(Sender: TObject);
procedure ExitClick(Sender: TObject);
private
{ Private declarations }
Image_Counter:Integer;
procedure ChooseImage(I:Integer);
procedure Init();
public
{ Public declarations }
end;
procedure Run_Animation_Form();
procedure Finish_Animation_Form();
implementation
var
Animation_Form: TAnimation_Form;
{$R *.dfm}
procedure Finish_Animation_Form();
Begin
Animation_Form.Close;
End;
procedure Run_Animation_Form();
Begin
Animation_Form := TAnimation_Form.Create(nil);
Try
Animation_Form.Init();
Animation_Form.ShowModal();
Finally
Animation_Form.Free;
End;
End;
{ TAnimation_Form }
procedure TAnimation_Form.ChooseImage(I: Integer);
begin
TwinControl(FindComponent(Format('Image%d',[I]))).Visible := False;
TwinControl(FindComponent(Format('Image%d',[I+1]))).Visible := True;
end;
procedure TAnimation_Form.ExitClick(Sender: TObject);
begin
Close;
end;
procedure TAnimation_Form.Init;
begin
TransparentColor := True;
TransparentColorValue := Color;
Image1.Visible := True;
Image_Counter:=1;
ControlStyle:=ControlStyle - [csOpaque];
BorderWidth := 10;
Anchors := [akLeft, akTop, akBottom, akRight];
end;
procedure TAnimation_Form.TimerTimer(Sender: TObject);
begin
if Image_Counter >= 30 then
Begin
Image30.Visible := False;
Image1.Visible := True;
Image_Counter:=1;
End
else
Begin
ChooseImage(Image_Counter);
Inc(Image_Counter);
End;
end;
end.
谢谢你的帮助,很抱歉我的英语不好
与其使用多个重叠的TImage
对象并交换它们的Visible
属性,我建议您创建一个由30个TPNGImage
对象组成的数组,然后:
-
使用始终可见的单个
TImage
,并在TTimer
过期时将所需的PNG分配给其TImage.Picture
属性:unit Animation; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, AdvShaper, pngimage, ExtCtrls, StdCtrls; type TAnimation_Form = class(TForm) Image1: TImage; Timer: TTimer; Exit: TButton; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure TimerTimer(Sender: TObject); procedure ExitClick(Sender: TObject); private { Private declarations } Image_Counter: Integer; Images: array[0..29] of TPNGImage; public { Public declarations } end; procedure Run_Animation_Form(); procedure Finish_Animation_Form(); implementation var Animation_Form: TAnimation_Form = nil; {$R *.dfm} procedure Finish_Animation_Form(); Begin if Animation_Form <> nil then Animation_Form.Close; End; procedure Run_Animation_Form(); Begin Animation_Form := TAnimation_Form.Create(nil); Try Animation_Form.ShowModal(); Finally FreeAndNil(Animation_Form); End; End; { TAnimation_Form } procedure TAnimation_Form.FormCreate(Sender: TObject); var I: Integer; begin for I := Low(Images) to High(Images) do begin Images[I] := TPNGImage.Create; // load PNG image into Images[I] as needed... end; // FYI, these properties can be set at design time... TransparentColor := True; TransparentColorValue := Color; Image1.Visible := True; BorderWidth := 10; Anchors := [akLeft, akTop, akBottom, akRight]; Image_Counter := 0; Image1.Picture := Images[0]; ControlStyle := ControlStyle - [csOpaque]; end; procedure TAnimation_Form.FormDestroy(Sender: TObject); var I: Integer; begin for I := Low(Images) to High(Images) do Images[I].Free; end; procedure TAnimation_Form.ExitClick(Sender: TObject); begin Close; end; procedure TAnimation_Form.TimerTimer(Sender: TObject); begin Inc(Image_Counter); if Image_Counter > High(Images) then Image_Counter := 0; Image1.Picture := Images[Image_Counter]; end; end.
-
使用单个
TPaintBox
并为其分配一个OnPaint
事件处理程序,将当前PNG绘制到TPaintBox.Canvas
上,然后让TTimer
简单地更新当前PNG并调用TPaintBox.Invalidate()
来触发重新绘制:unit Animation; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, AdvShaper, pngimage, ExtCtrls, StdCtrls; type TAnimation_Form = class(TForm) PaintBox1: TPaintBox; Timer: TTimer; Exit: TButton; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure TimerTimer(Sender: TObject); procedure ExitClick(Sender: TObject); procedure PaintBox1Paint(Sender: TObject); private { Private declarations } Image_Counter: Integer; Images: array[0..29] of TPNGImage; public { Public declarations } end; procedure Run_Animation_Form(); procedure Finish_Animation_Form(); implementation var Animation_Form: TAnimation_Form = nil; {$R *.dfm} procedure Finish_Animation_Form(); Begin if Animation_Form <> nil then Animation_Form.Close; End; procedure Run_Animation_Form(); Begin Animation_Form := TAnimation_Form.Create(nil); Try Animation_Form.ShowModal(); Finally FreeAndNil(Animation_Form); End; End; { TAnimation_Form } procedure TAnimation_Form.FormCreate(Sender: TObject); var I: Integer; begin for I := Low(Images) to High(Images) do begin Images[I] := TPNGImage.Create; // load PNG image into Images[I] as needed... end; // FYI, these properties can be set at design time... TransparentColor := True; TransparentColorValue := Color; Image1.Visible := True; BorderWidth := 10; Anchors := [akLeft, akTop, akBottom, akRight]; Image_Counter := 0; ControlStyle := ControlStyle - [csOpaque]; end; procedure TAnimation_Form.FormDestroy(Sender: TObject); var I: Integer; begin for I := Low(Images) to High(Images) do Images[I].Free; end; procedure TAnimation_Form.ExitClick(Sender: TObject); begin Close; end; procedure TAnimation_Form.TimerTimer(Sender: TObject); begin Inc(Image_Counter); if Image_Counter > High(Images) then Image_Counter := 0; PaintBox1.Invalidate; end; procedure TAnimation_Form.PaintBox1Paint(Sender: TObject); begin PaintBox1.Canvas.Draw(0, 0, Images[Image_Counter]); // or: // PaintBox1.Canvas.StretchDraw(Rect(0, 0, PaintBox1.Width, PaintBox1.Height), Images[Image_Counter]); end; end.