Haben Sie Ihr Bild über Windows Desktop platziert - oder über Sie TForm1
? Ich schätze das letztere. Sie müssten sich also um die WINDOW-Größe kümmern, nicht um die DESKTOP-Größe.
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;
PS. In einem unwahrscheinlichen Fall brauchen Sie wirklich die Windows-Desktop-Koordinaten und nicht Ihre Formular-Koordinaten Sie sie bei
http://docwiki.embarcadero.com/Libraries/XE7/en/Vcl.Forms.TScreen.DesktopRect
Aber nutzen diese Informationen bekommen würden Sie ein anderes Problem zu lösen haben - wie Sie Ihre Image1
über platzieren Desktop und nicht über das Formular, das für Sie viel komplexer ist. Also ich glaube nicht, dass du Desktop wirklich meintest ....
UPD. Der obige Code ist sehr einfach und leicht zu verstehen, aber es macht nur wenige implizite Annahmen, um korrekt zu funktionieren. Diese Annahmen sind:
Die Größe des Fensters (Formulars) wird einmal für alle festgelegt, es würde nie in der Größe geändert werden.
Die Imagebox-Größe ist für alle einmal festgelegt, es würde nie in der Größe geändert werden.
Das Fenster ist größer als eine Bildbox in beiden Dimensionen.
Nur unser Verfahren kann die Imagebox verschieben, es gibt nichts anderes, was sie bewegen könnte.
Angesichts dieser Annahmen (natürlich für Computer mit fester Bildschirmgröße vor vielen Jahren) gibt es keine Notwendigkeit zu analysieren, ob das bewegte Objekt auch links oder rechts, zu hoch oder zu niedrig ist. Es spielt nur eine Rolle, ob die neue Koordinate korrekt ist oder nicht - wenn sie nicht mehr korrekt ist, dann reicht das "Hüpfen" - das Umkehren der Richtung, ohne zu schauen, welcher es war -. Wenn der Benutzer beispielsweise plötzlich die Größe des Fensters ändern und es so klein machen kann, dass die Bildbox aus dem Fenster herausfallen würde, würde diese Methode unendlich viele Richtungen ändern, da die Koordinaten bei diesen sehr kleinen Änderungen immer falsch wären. Bewegung erlaubt zu haben.
, um mögliche plötzliche und große Veränderungen in der Geometrie Zur Anpassung gibt es eine Reihe von Ansätzen sein kann, aber das einfachste man würde zwei Änderungen vor: Unterscheidung zwischen zwei Fällen von falschen Koordinaten (zu wenig oder zu groß wäre jetzt verschiedene Fälle) und sofortige Sprünge des Bildes in die zulässige Box, wenn sie benötigt werden, selbst wenn der Sprung groß und nicht glatt wäre.
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. Mehrere Steuerelemente bewegen sich.
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;
.... und so weiter. Beenden Sie die Konvertierung von eins zu viele als Ihre Hauptaufgabe.
Verwenden Sie keine Werte für X und Y, die bei einer Addition nach Oben oder Links das Bild zu weit verschieben würden. –
@KenWhite das ist genau sein Problem, er möchte erkennen, wenn er nach draußen geht ... entweder das Fenster oder der Desktop –
@ Arioch'The: Ja, und ich sagte ihm, wie man es tut - nach der Generierung X-und Y-Werte Vergewissern Sie sich vor dem Hinzufügen von "Oben" oder "Links", dass das Bild nicht nach außen zeigt. –