Programación General > Delphi
Mover De Un Bmp Horizontalmente Sin Parpadeos
(1/1)
Deiv:
Deseo hacer mover una imagen de izquierda a derecha o viceversa, inicialmente intenté con un TImage, luego con un TBitMap como muestro abajo al evento de un Button OnMouseMove, el primero me parpadea la imagen, el segundo no borra el BitMap.
--- Código: Text --- type TForm1 = class(TForm) Button1: TButton; Image1: TImage; Timer1: TTimer; procedure Button1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); procedure Timer1Timer(Sender: TObject); procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Button1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin Timer1.Enabled:=true; end; procedure TForm1.Timer1Timer(Sender: TObject); begin Image1.Left:=Image1.Left + 4; if Image1.Left+Image1.width >= Form1.width then Timer1.Enabled:=false; end; procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin Timer1.Enabled:=false; end; end.
LUEGO ME RECOMENDARON UTILIZAR UN TBitMap, PARA EVITAR EL PARPADEO Y ASÍ LO HICE, PERO AQUÍ TENGO EL PROBLEMA DE QUE CONSTANTEMENTE ME REDIBUJA, NO PUEDO HACER QUE UN RATO DIBUJE y luego se Borre (MOVERSE)
--- Código: Text --- var Form1: TForm1; i:integer=0;implementation {$R *.dfm} procedure TForm1.Button1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);begin G:= TBitMap.Create; G.LoadFromFile('E:\molecule14.bmp'); Timer1.Enabled:=true;end; procedure TForm1.Timer1Timer(Sender: TObject);begin Canvas.Draw(10+i,10,G); i:=i+2;end; procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);begin Timer1.Enabled:=false; i:=0;end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);begin G.Free;end; end.
¿Como lo soluciono?
Saludos
bartolomeo:
Y ahas mirado la forma de hacer los intervalos de tiempo aun mas pequeños ? :blink:
Amilius:
--- Código: Text --- procedure TForm1.Button1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);begin G:= TBitMap.Create; G.LoadFromFile('E:\molecule14.bmp'); Timer1.Enabled:=true;end;
No pues asi no :blink: :blink: :blink: :blink: :blink:
Crea el bitmap al crear tu form, destruyelo al destruir el form.
Para mejor control utiliza un Tpaintbox para definir el area grafica dinamica de tu form. Luego en su evento on paint pintas el tbitmap, solo la parte que necesita ser pintada, informacion que te da el clip (OJO que no modificas tu Tbitmap al responder a este evento). Mejor si haces eso con un bitblt() directamente y no con el lento draw. En el evento ontimer preparas la imagen en tu Tbitmap e inmediatamente invalidas el control Tpaintbox o lo refrescas para que llame a su paint y este a la vez al evento on paint.
Deiv:
Mi poca experiencia en gráficos no me permite entender tu explicación Amilius, he implementado el PaintBox para definir el área de movimiento de mi BMP, pero no entiendo como hacerlo mover (como invalidar el TPaintBox, como dices), en el siguiente código me sigue redibujando una y otra vez sobrepintándose:
--- Código: Text --- type TForm1 = class(TForm) PaintBox1: TPaintBox; BitBtn1: TBitBtn; Timer1: TTimer; procedure BitBtn1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); procedure FormCreate(Sender: TObject); procedure Timer1Timer(Sender: TObject); procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); procedure FormDestroy(Sender: TObject); var Form1: TForm1; G:TBitMap; i:integer=0; implementation {$R *.dfm} procedure TForm1.BitBtn1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);begin Timer1.Enabled:=true;end; procedure TForm1.FormCreate(Sender: TObject);begin G:= TBitMap.Create; G.LoadFromFile('E:\molecule14.bmp');end; procedure TForm1.Timer1Timer(Sender: TObject);begin PaintBox1.Canvas.Draw(10+i,10,G); i:=i+2;end; procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);begin Timer1.Enabled:=false; i:=0;end; procedure TForm1.FormDestroy(Sender: TObject);begin G.Free;end; end. Agradeceré una vez mas su orientación.
Saludos
Amilius:
Aqui:
PaintBox1.Canvas.Draw(10+i,10,G);
Estas pintando directamente sobre el paintbox. Es mejor pintar primero sobre OTRO bitmap, como "SuperficieDeRender" que hace de buffer y luego pasar el resultado final al paintbox cuando sea necesario, algo como:
PaintBox1.Canvas.Draw(0,0,SuperficieDeRender);
Esto ultimo en el evento onpaint del PaintBox.
De esta forma evitas parpadeo al evitar trabajar sobre la memoria de video que tenga asignado el paintbox.
Para invalidar y forzar que sea pintado usas .invalidate(); o bien puedes llamar a .repaint().
Navegación
Ir a la versión completa