Delphi - 图像在桌面坐标内随机移动

时间:2016-04-01 13:00:59

标签: delphi delphi-7

我想创建一个小应用程序,它应该将图像平滑地移动到桌面坐标中。 我想知道如何限制图像保留在桌面内? 我试着像这样移动图像:

procedure TForm1.Timer1Timer(Sender: TObject);
Var
  X, Y :Integer;
begin
  X:= random(2+1);
   Y:= random(2+1);
    Image1.Left:= Image1.Left + X;
     Image1.Top:= Image1.Top + Y;
      Image1.Refresh;
end; 

感谢任何帮助。

感谢。

1 个答案:

答案 0 :(得分:0)

您的图像是放在Windows桌面上还是放在type TForm1=class(TForm) .... private ImageMovesLeft, ImageMovesUp: Boolean; end; ..... procedure TForm1.Timer1Timer(Sender: TObject); Var dX, dY, NewLeft, NewTop :Integer; FormSize: TRect; begin dX := random(2+1); // did you really mean "random(3)" or "1+random(2)" ??? dY := random(2+1); FormSize := Self.ClientRect; FormSize.Bottom := FormSize.Bottom - Image1.Height - 1; FormSize.Right := FormSize.Right - Image1.Width - 1; // now we have the "box" in which the Image's topleft corner must be If ImageMovesLeft then dX := -dX; If ImageMovesUp then dY := -dY; NewLeft := Image1.Left + dX; NewTop := Image1.Top + dY; if ( NewTop >= FormSize.Top ) and ( NewTop <= FormSize.Bottom ) then begin Image1.Top := NewTop; // we fit into the allowed box end else begin ImageMovesUp := not ImageMovesUp; // we did not fit and have to bounce back end; if ( NewLeft >= FormSize.Left ) and ( NewLeft <= FormSize.Right ) then begin Image1.Left := NewLeft; // we fit into the allowed box end else begin ImageMovesLeft := not ImageMovesLeft; // we did not fit and have to bounce back end; end; 之上?我猜后者。所以你必须关心WINDOW大小,而不是DESKTOP大小。

Image1

PS。在不太可能的情况下,您确实需要Windows DESKTOP坐标而不是表格坐标,您可以在

处获取它们

http://docwiki.embarcadero.com/Libraries/XE7/en/Vcl.Forms.TScreen.DesktopRect

但要使用这些信息,您必须解决另一个问题 - 如何将procedure TForm1.Timer1Timer(Sender: TObject); var dX, dY, NewLeft, NewTop :Integer; FormSize: TRect; begin dX := random(2+1); // did you really mean "random(3)" or "1+random(2)" ??? dY := random(2+1); FormSize := Self.ClientRect; FormSize.Bottom := FormSize.Bottom - Image1.Height - 1; FormSize.Right := FormSize.Right - Image1.Width - 1; // now we have the "box" in which the Image's topleft corner must be If ImageMovesLeft then dX := -dX; If ImageMovesUp then dY := -dY; NewLeft := Image1.Left + dX; NewTop := Image1.Top + dY; if NewLeft > FormSize.Right then begin ImageMovesLeft := True; NewLeft := FormSize.Right; end; if NewLeft < FormSize.Left then begin ImageMovesLeft := False; NewLeft := FormSize.Left; end; if NewTop > FormSize.Bottom then begin ImageMovesUp := True; NewTop := FormSize.Bottom; end; if NewTop < FormSize.Top then begin ImageMovesUp := False; NewTop := FormSize.Top; end; Image1.Top := NewTop; Image1.Left := NewLeft; end; 放在桌面而不是桌面上,这对您来说要复杂得多。所以我认为你并不真正想要桌面......

UPD。上面的代码如果非常简单易懂,但很少有隐含的假设可以正常工作。这些假设是:

  • 窗口(窗体)大小固定一次,永远不会调整大小。
  • 图像框大小固定一次,永远不会调整大小。
  • 窗口大于两个维度的图像框。
  • 只有我们的程序可以移动图像框,没有其他任何东西可以移动它。

鉴于这些假设(很多年前固定屏幕尺寸计算机很自然),没有必要分析移动物体是否过于偏右,太高或太低。只有当新坐标不正确时才重要 - 如果它不再正确,那么“弹跳” - 反转方向而不查看它是哪一个 - 就足够了。但是,例如,如果用户突然调整窗口的大小并使其变得如此之小以至于图像框落在它之外 - 那么这种方法会无限地切换方向,因为坐标总是不正确的,因为那些非常小的变化“平滑”运动允许。

为了适应几何中可能的突然和大的变化,可以有许多方法,但最简单的方法是做出两个改变:区分两个错误坐标的情况(太少或太大现在会有所不同案例)并在需要时将图像即时跳转到允许的框中,即使跳跃很大且不平滑。

type TControlledObject = record
       obj: TControl;
       MovesLeft, MovesUp: Boolean;
end;

type TForm1=class(TForm)
....
private
   images: array of TControlledObject;
end;

procedure TForm1.FormShow(....);
begin
  SetLength(images, 3);

  with images[0] do begin
     obj := Self.Image1;
     MovesLeft := random >= 0.5;
     MovesUp   := random >= 0.5;
  end;
  with images[1] do begin
     obj := Self.Image2;
     MovesLeft := random >= 0.5;
     MovesUp   := random >= 0.5;
  end;
  with images[2] do begin
     obj := Self.Image3;
     MovesLeft := random >= 0.5;
     MovesUp   := random >= 0.5;
  end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
  i: Integer
begin
  for i := 0 to Length(images)-1 do 
    MoveImage(images[i]);
end;

procedure TForm1.MoveImage(var ImgRec: TControlledObject);
var .....
begin 
  dX := random(2+1); // did you really mean "random(3)" or "1+random(2)" ???
  dY := random(2+1);

  FormSize := Self.ClientRect;
  FormSize.Bottom := FormSize.Bottom - ImgRec.obj.Height - 1;
  FormSize.Right  := FormSize.Right  - ImgRec.obj.Width - 1;

  // now we have the "box" in which the Image's topleft corner must be

  If ImgRec.MovesLeft then dX := -dX;
  If ImgRec.MovesUp   then dY := -dY;

UPD。几个控件移动。

for(Coord c:coords)
   canvas.drawLine(c.getX(), c.getY(), c.getX()+x.getWidth(), y.getY()+y.getHeight(), paint);  

....等等。完成从一个到多个的转换作为您的家庭任务。