怎样实现快速动画,并且图象不闪烁(50分)

  • 主题发起人 主题发起人 孟庭苇
  • 开始时间 开始时间

孟庭苇

Unregistered / Unconfirmed
GUEST, unregistred user!
怎样在有图象背景的情况下实现快速动画,并且图象不闪烁?
 
哇! 孟庭苇!!!

我做这种东西,一般是连续地把上一副图片和下一副图片合成一副draw出来.
 
把动画作小一点,就不会闪了吧
 
一个很有趣的现象: 继承自TWinControl类的(有windows handle的)不会闪
烁, 继承自TGraphicControl类的控件几乎都会闪烁, 特别是transparent的
(如果csOpaque in Controlstyle的话闪得好点).
如果活用Wincontrol和window Region的话, 一样可以做出透明的动画, 而
且比用bitmap画的流畅.(象word的小助手那种)
 
把image放在一个Panel上,移动Panel而不是移动image就好了
 
继承自TWinControl的控件好像都可以自动出发OnPaint事件。
 
>一个很有趣的现象: 继承自TWinControl类的(有windows handle的)不会闪
>烁, 继承自TGraphicControl类的控件几乎都会闪烁, 特别是transparent的
>(如果csOpaque in Controlstyle的话闪得好点).

因为TGraphicControl使用Parent的DC绘图的,每次重绘前要画背景,
TWinControl由windows管理绘图,确实会快些.

>如果活用Wincontrol和window Region的话, 一样可以做出透明的动画, 而
>且比用bitmap画的流畅.(象word的小助手那种)

呵呵,这样的动画我也作过...



 
用两个图片,一个可见一个不可见,然后交替显示。好多的文字动画
是这个原理的。
 
不闪好解决,用双缓冲,和kongg说的相似,若还想不跳
你的精灵需要有自己的掩膜作称底然后用与/或的方法放到环境中


 
呵呵,
其实在老问题中eYes等大富翁已经指出了较好的解决办法,
就是不重画背景。
这有个俄国佬写的小例子,大家可以借鉴一下:
unit FFPBox;
{=======================================================}
interface
{=======================================================}
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls;

type
TFFPaintEvent = procedure (Sender: TObject; Canvas: TCanvas) of Object;

TFlickerFreePaintBox = class(TCustomControl)
private
{ Private declarations }
FOnFFPaint:TFFPaintEvent;
protected
{ Protected declarations }
procedure Paint; override;
procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
published
{ Published declarations }
property OnPaint:TFFPaintEvent read FOnFFPaint write FOnFFPaint;
property Align;
property Color;
property DragCursor;
property DragMode;
property Enabled;
property Font;
property ParentColor;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property ShowHint;
property Visible;
property OnClick;
property OnDblClick;
property OnDragDrop;
property OnDragOver;
property OnEndDrag;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property OnStartDrag;
end;

procedure Register;
{=======================================================}
implementation
{=======================================================}
constructor TFlickerFreePaintBox.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
TabStop := False;
end;
{-------------------------------------------------------}
procedure TFlickerFreePaintBox.Paint;
var bmp: TBitmap;
begin
if csDesigning in ComponentState then
with Canvas do
begin
Pen.Style := psDash;
Brush.Style := bsSolid;
Canvas.Brush.Color := Color;
Rectangle(0, 0, Width, Height);
exit;
end;

bmp := TBitmap.Create;
try
bmp.Canvas.Brush.Color := Color;
bmp.Width := Width;
bmp.Height := Height;
bmp.Canvas.Font := Font;
if Assigned(FOnFFPaint) then begin
FOnFFPaint(Self, bmp.Canvas);
Canvas.Draw(0,0, bmp);
end;
finally
bmp.Free;
end;
end;
{-------------------------------------------------------}
{------------------------关键之处-----------------------}
procedure TFlickerFreePaintBox.WMEraseBkgnd(var Message: TWMEraseBkgnd);
begin
Message.Result := 1;
end;
{=======================================================}
procedure Register;
begin
RegisterComponents('System', [TFlickerFreePaintBox]);
end;

end.
 
先用Tbitmap.loadfromfile装载图片,然后copyrect到一个Tform上,即不闪烁。
 
作动画当然用DirectX的DirectDraw最方便,请看看三维游戏就知道效果了。
 
使用directdraw能实现高性能的动画。
 
>>把image放在一个Panel上,移动Panel而不是移动image就好了
知道它为什么这样吗?我也是奇怪的很。但如果双层Panel又会闪了。
 
利用directdraw的双缓冲技术应该可以吧?!
 
利用directdraw的双缓冲技术应该可以吧?!
可 directdraw 可能还要学一阵
用 bitblt(’接受拷贝的图片‘,x,y,width,height,‘被拷贝的图片‘,x,
y,srccopy);
把一个图片从一个位置靠到另一个位置。
 
利用线程,在后台先画一个好一副图,然后bitblt上去,本人正在做此类程序。
 

Similar threads

回复
0
查看
690
不得闲
回复
0
查看
978
不得闲
回复
0
查看
863
不得闲
D
回复
0
查看
2K
DelphiTeacher的专栏
D
后退
顶部