2016-04-01 6 views
-1

Ich möchte eine kleine Anwendung erstellt, die Bilder reibungslos in die Desktop-Koordinaten verschieben sollte. Ich frage mich, wie kann ich begrenzen, dass das Bild auf dem Desktop bleibt? Ich habe versucht so, um das Bild zu verschieben:Delphi - Bild bewegt sich zufällig innerhalb der Desktop-Koordinaten

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; 

Jede Hilfe sehr geschätzt wird.

Danke.

+1

Verwenden Sie keine Werte für X und Y, die bei einer Addition nach Oben oder Links das Bild zu weit verschieben würden. –

+0

@KenWhite das ist genau sein Problem, er möchte erkennen, wenn er nach draußen geht ... entweder das Fenster oder der Desktop –

+0

@ 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. –

Antwort

0

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.

    +0

    Das Poster sagt * über den Desktop *, also sind anscheinend nicht die Fenstermaße ein Problem. –

    +0

    @Ken, ja, ich habe das angesprochen. Aber ehrlich gesagt, Ken, denkst du, dass eine Person fragt, wie man das Bild innerhalb vorgegebener Grenzen bewegt - bereits gelöst, wie man eine No-Caption ohne Grenzen macht - alle anderen Formen, um diesen Magier zu hosten und über den Desktop zu schweben? Machst du? Wenn ja, dann gibt es einen Link zu Desktops "TRect" und er kann stattdessen "TForm1.ClientRect" verwenden - vorausgesetzt, das war sein EINZIGES Problem in diesem Bestreben. –

    +0

    @KenWhite eigentlich hat er nicht gesagt, dass er das Bild "über den Desktop" verschieben wollte, sagte er "in die Desktop-Koordinaten" Was immer das bedeuten könnte. Ich denke, er hat nur mit Englisch zu kämpfen, so dass dieser Teil ignoriert werden könnte. –