i used 30 png pictures on a transplanted from to make a simple animation, a Timer make an event every 33 Millisecond to change the visibility of the TImage Components which have the png images, i tried all the method suggested in other posts to stop flickering but could not solve the problem.
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.
Thanks for your help and sorry for my bad English
Rather than using multiple overlapping TImage
objects and swapping their Visible
property, I would suggest you create an array of 30 TPNGImage
objects and then either:
use a single TImage
that is always visible and assign the desired PNG to its TImage.Picture
property whenever the TTimer
elapses:
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.
use a single TPaintBox
and assign an OnPaint
event handler to it that draws the current PNG onto the TPaintBox.Canvas
, and then have the TTimer
simply update the current PNG and call TPaintBox.Invalidate()
to trigger a repaint:
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.