Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Timer.Interval<1 (https://www.delphipraxis.net/71096-timer-interval-1-a.html)

Martin.Ghosts 8. Jun 2006 22:53

Re: Timer.Interval<1
 
Zitat:

Teste doch einfach vorm Verschieben, ob's drüber hinaus geht und verschiebe nach der Abfrage.
(zu Matze) Klar, das könnte man machen. Jedoch wird dann die Wand sehr warscheinlich nicht berührt.

(zu SirThornberry) Hier mal mein Quelltext:
Delphi-Quellcode:
var
  Form1: TForm1;
  x, y: Integer;

implementation

{$R *.dfm}

procedure TForm1.Move;
begin
  Form1.Shape1.Left:= Form1.Shape1.Left + (x);
  Form1.Shape1.Top:= Form1.Shape1.Top + (y);
  if (Form1.Shape1.Left <= 0) then
    x:= (-1) * x;
  if (Form1.Shape1.Top <= 0) then
    y:= (-1) * y;
  if ((Form1.Shape1.Left + Form1.Shape1.Width) >= Form1.Width) then
    x:= (-1) * x;
  if ((Form1.Shape1.Top + Form1.Shape1.Height) >= Form1.Height) then
    y:= (-1) * y;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  x:= -1;
  y:= -1;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Form1.Move;
end;

end.
Wenn ich dich richtig versehe meinst du es so:
Delphi-Quellcode:
var
  Form1: TForm1;
  x, y, count: Integer;

implementation

{$R *.dfm}

procedure TForm1.Move;
begin
  Form1.Shape1.Left:= Form1.Shape1.Left + (x);
  Form1.Shape1.Top:= Form1.Shape1.Top + (y);
  if (Form1.Shape1.Left <= 0) then
    x:= (-1) * x;
  if (Form1.Shape1.Top <= 0) then
    y:= (-1) * y;
  if ((Form1.Shape1.Left + Form1.Shape1.Width) >= Form1.Width) then
    x:= (-1) * x;
  if ((Form1.Shape1.Top + Form1.Shape1.Height) >= Form1.Height) then
    y:= (-1) * y;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  x:= -1;
  y:= -1;
  count:= 0;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  if (count = 25) then
    begin
      count:= 0;
      Form1.Move;
    end
  else
    count:= count + 1;
end;

end.
Dadurch bewegt sich der Ball jedoch nochmal deutlich langsamer.

SirThornberry 8. Jun 2006 22:57

Re: Timer.Interval<1
 
hat es etwas falsch verstanden. Anstelle jedes mal vom Shape die Koordinaten zu ändern (wodurch ja das form und das darauf neu gezeichnet wird) sollst du die Koordinaten in einer extra Variablen ändern und dann nur maximal 25 mal pro sekunden diese koordinanten für das Shape übernehmen.

Martin.Ghosts 8. Jun 2006 23:17

Re: Timer.Interval<1
 
Hab mal gerade versucht das zu realisieren, jedoch ohne Erfolg. Erlich gesagt, habe ich keine Ahnung, wie ich das umsetzen könnte.

SirThornberry 8. Jun 2006 23:56

Re: Timer.Interval<1
 
nimm einfach anstelle von shape1 ein rect. und wenn du die move-procedure eine bestimmte anzahl mal aufgerufen hast überträgst du die daten auf dein shape

Cöster 9. Jun 2006 15:35

Re: Timer.Interval<1
 
Ich würd das Interval vom Timer auf 20 setzen (also 50 Bilder pro Sekunde, mehr kann das menschliche Auge nicht wahrnehmen). Die Timer-Procedure änderst du dann in
Delphi-Quellcode:
var i: integer;
begin
 For i:=1 to 20 do Form1.Move;
end;

alzaimar 9. Jun 2006 15:48

Re: Timer.Interval<1
 
Timer auf 20ms einstellen und einfach rechnen, wie weit sich der Ball seit der letzten Bewegung fortbewegt hätte. Dazu muss nur der Bewegungsvektor (dx,dy) bekannt sein. Dx gibt dabei die Anzahl der Pixel an, die sich das Objekt in einer bestimmten Zeit in X-Richtung verschiebt, und Dy eben in Y-Richtung. Als "bestimmte Zeit" kann man ja z.B. 50ms nehmen.

Delphi-Quellcode:
Procedure TMyForm.MyTimer (Sender : Tobject);
Begin
  dt := (GetTickCount - LastTickCount);
  MoveInX := Muldiv (dx,dt,50);
  MoveInY := MulDiv (dy,dt,50);
// Das Objekt bewegt sich also von seiner augenblicklichen Position aus um MoveInX Pixel
// nach rechts und MoveInY Pixel nach oben.
// Es ist nun ein leichtes, etwaige Kollisionen mit irgendwelchen Wänden zu berechnen
// (einfache Schnittpunktberechnung zweier Geraden).
// Zum Schluss merken wir uns die Zeit, nachdem das Objekt gezeichnet wurde.
  LastTickCount := GetTickCount;
End;
Das Timer-Interval ist hier egal, denn das Objekt wird sich immer mit korrekter Geschwindigkeit bewegen. Eine Auflösung von ca. 20-40 ms sollte wohl reichen.

himitsu 9. Jun 2006 17:17

Re: Timer.Interval<1
 
Zitat:

Zitat von Martin.Ghosts
(zu Matze) Klar, das könnte man machen. Jedoch wird dann die Wand sehr warscheinlich nicht berührt.

Dann prüfe halt nachher und verschieb es wieder ein Stück zurück, wenn es drüberraus ging.

x := (-1) * x;? ... wie wär es mit x := -x; :gruebel:

Außerdem brauchst du in einer Klassenprozedur (z.B. TForm1) nicht nochmal die Klassenvariable (z.B. Form1) angeben.

Delphi-Quellcode:
procedure TForm1.Move;
begin
  Form1.Shape1.Left := Form1.Shape1.Left + x;
  Form1.Shape1.Top := Form1.Shape1.Top + y;
  if Form1.Shape1.Left <= 0 then begin
    if Form1.Shape1.Left < 0 then Form1.Shape1.Left := 0;
    x:= -x;
  end else if Form1.Shape1.Left + Form1.Shape1.Width >= Form1.Width then begin
    if Form1.Shape1.Left > Form1.Width - Form1.Shape1.Width then Form1.Shape1.Left := Form1.Width - Form1.Shape1.Width;
    x:= -x;
  end;
  if Form1.Shape1.Top <= 0 then begin
    if Form1.Shape1.Top < 0 then Form1.Shape1.Top := 0;
    y:= -y;
  end else if Form1.Shape1.Top + Form1.Shape1.Height >= Form1.Height then begin
    if Form1.Shape1.Top > Form1.Height - Form1.Shape1.Height then Form1.Shape1.Top := Form1.Height - Form1.Shape1.Height;
    y:= -y;
  end;
end;
so isses doch bestimmt auch übersichtlicher?
Delphi-Quellcode:
procedure TForm1.Move;
begin
  Shape1.Left := Shape1.Left + x;
  Shape1.Top := Shape1.Top + y;
  if Shape1.Left <= 0 then begin
    if Shape1.Left < 0 then Shape1.Left := 0;
    x:= -x;
  end else if Shape1.Left + Shape1.Width >= Width then begin
    if Shape1.Left > Width - Shape1.Width then Shape1.Left := Width - Shape1.Width;
    x:= -x;
  end;
  if Shape1.Top <= 0 then begin
    if Shape1.Top < 0 then Shape1.Top := 0;
    y:= -y;
  end else if Shape1.Top + Shape1.Height >= Height then begin
    if Shape1.Top < Height - Shape1.Height then Shape1.Top := Height - Shape1.Height;
    y:= -y;
  end;
end;
Und wenn du jetzt noch erstmal über temporäre Variablen gehst, dann wird das Shap auch nich (falls es über'n Rand hinausging) zweimal verschoben, außerdem sind Variablen schneller, als die Setter-/Getterprozeduren (der Shape).
Delphi-Quellcode:
procedure TForm1.Move;
var x2, y2: integer;
begin
  x2 := Shape1.Left + x;
  y2 := Shape1.Top + y;
  if x2 <= 0 then begin
    if x2 < 0 then x2 := 0;
    x:= -x;
  end else if x2 + Shape1.Width >= Width then begin
    if x2 > Width - Shape1.Width then x2 := Width - Shape1.Width;
    x:= -x;
  end;
  if y2 <= 0 then begin
    if y2 < 0 then y2 := 0;
    y:= -y;
  end else if y2 + Shape1.Height >= Height then begin
    if y2 < Height - Shape1.Height then y2 := Height - Shape1.Height;
    y:= -y;
  end;
  Shape1.Left := x2;
  Shape1.Top := y2;
end;
So ging es auch noch:
Delphi-Quellcode:
procedure TForm1.Move;
var x2, y2: integer;
begin
  x2 := Shape1.Left + x;
  y2 := Shape1.Top + y;
  if x2 <= 0 then begin
    x2 := 0;
    x:= -x;
  end else if x2 + Shape1.Width >= Width then begin
    x2 := Width - Shape1.Width;
    x:= -x;
  end;
  if y2 <= 0 then begin
    y2 := 0;
    y:= -y;
  end else if y2 + Shape1.Height >= Height then begin
    y2 := Height - Shape1.Height;
    y:= -y;
  end;
  Shape1.Left := x2;
  Shape1.Top := y2;
end;
jetzt könnte man noch Fomr1.Width und Form1.Height durch Variablen ersetzen (welche in TForm1.OnCreate und eventuell noch TForm1.OnResize gesetzt werden).
Und aus Shape1.Width und Shape1.Height lassen sich schöne Konstanten machen. (schneller gehts dann wohl nicht mehr mit der Speicherverwaltung ... in VCL)


[add]
natürlich wäre es mit der von alzaimar vorgeschlagen Schnittpunktberechnung besser, weil dann ja beide Richtungen angepasst werden, aber o gehts auch (halbwegs) ... 's wird ja jeweils nur eine der Richtungen zurückgesetzt.

Und das LastTickCount := GetTickCount; würde ich auch gleich mal am Anfang mit machen, damit es zu keiner Zeitverschiebung kommt, da das Zeichen/verschieben auch etwas Zeit benötigt.
Delphi-Quellcode:
procedure TForm1.Move;
var x2, y2, t: integer;
  dt: Cardinal;
begin
  dt := GetTickCount - LastTickCount;
  LastTickCount := GetTickCount;
  x2 := Shape1.Left + MulDiv(x, dt, 50);
  y2 := Shape1.Top + MulDiv(y, dt, 50);
  if x2 <= 0 then begin
    x2 := 0;
    x:= -x;
  end else begin
    t := Width - Shape1.Width;
    if x2 >= t then begin
      x2 := t;
      x:= -x;
    end;
  end;
  if y2 <= 0 then begin
    y2 := 0;
    y:= -y;
  end else begin
    t := Height - Shape1.Height;
    if y2 >= t then begin
      y2 := t;
      y:= -y;
    end;
  end;
  Shape1.Left := x2;
  Shape1.Top := y2;
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:37 Uhr.
Seite 2 von 2     12   

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz