【问题标题】:How to stop flickering in layered image animation如何停止分层图像动画中的闪烁
【发布时间】:2013-12-10 18:19:59
【问题描述】:

我在一个移植的 from 上使用了 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.

感谢您的帮助,对不起我的英语不好

【问题讨论】:

  • 这是一种非常糟糕的动画制作方式。
  • 我是编程新手,任何关于在 delphi 中制作动画的建议将不胜感激
  • Exit: TButton;: 永远不要给一个组件(或一个例程)一个已经在别处声明过的名字。您应该尽量避免对语法进行限定,并尽量减少对您自己、您的团队成员和您的代码用户的混淆。
  • 该按钮的好听的名称:Exit_Button OnClick-Method 将在 Exit_ButtonClick 中重命名。在那里你应该调用一个表单方法DoExit 并将所有代码退出那里。

标签: delphi vcl


【解决方案1】:

建议您创建一个包含 30 个 TPNGImage 对象的数组,然后:

  1. 使用始终可见的单个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.
    
  2. 使用单个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.
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-17
    • 1970-01-01
    • 1970-01-01
    • 2015-04-21
    • 2017-03-09
    • 2014-07-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多