Autor Beitrag
suga2001
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 38



BeitragVerfasst: Di 06.01.09 14:30 
Hallo ^^
Ich soll einen Ball von einem shape abprallen lassen. Die Seiten und Eckpunkte habe ich defniniert, aber der ball "fliegt" bis zur Hälfte einfach durch. Woran liegt das?
alles habe ich in einen Timer gepackt :

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
procedure TForm1.Timer1Timer(Sender: TObject);
var Mittelpunkt:TPoint;
Punkte:integer;
begin
Punkte:=0;
//Image(Ball) um Schrittweite bewegen
Image1.Left:=Image1.Left +vx;
Image1.Top:=Image1.Top +vy;
if (Image1.Left <= Panel1.Left) OR (Image1.Left >= Panel1.Width - Image1.Width -1)
then vx:=vx*-1// links und rechts
Mittelpunkt:=Image1.BoundsRect.BottomRight;
Mittelpunkt.x:=Mittelpunkt.X-Image1.Width DIV 2;

if PtInRect(Shape1.BoundsRect,Mittelpunkt) THEN vy:=vy*-1;
Mittelpunkt:=Image1.BoundsRect.BottomRight;
Mittelpunkt:=Image1.BoundsRect.TopLeft;
Mittelpunkt.x:=Mittelpunkt.X-Image1.Width DIV 2;

if PtInRect(Shape2.BoundsRect,Mittelpunkt) THEN vy:=vy*-1;
Mittelpunkt:=Image1.BoundsRect.BottomRight;
Mittelpunkt:=Image1.BoundsRect.TopLeft;

Mittelpunkt.x:=Mittelpunkt.X-Image1.Width DIV 2;


if (Image1.Top <= Panel1.Top) OR (Image1.Top >= Panel1.Height -Image1.Height -1)
then vy:= vy*-1//oben und unten

if (image1.Top >=Panel1.Height - Image1.Height-1)then inc(Punkte);
Label2.Caption:=inttostr(Punkte);


end;


Sieht jemand, wo mein Fehler ist oder was ich vergessen habe?`
Danke schon mal im Voraus ^^
Marc.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1876
Erhaltene Danke: 129

Win 8.1, Xubuntu 15.10

BeitragVerfasst: Di 06.01.09 14:48 
Du musst den Radius bzw. die Seitenlängen in deiner Berechnung berücksichtigen. ;)
So in etwa sollte es gehen - hab es jetzt nicht getestet. Muss jetzt auch schnell weg.
user profile iconsuga2001 hat folgendes geschrieben Zum zitierten Posting springen:
if ((Image1.Left + Radius) => Panel1.Left) and (Image1.Left <= Panel1.Left + Panel1.Width)


Grüße,
Marc

PS: Deine Formatierung ist ein Graus.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Di 06.01.09 15:48 
user profile iconsuga2001 hat folgendes geschrieben Zum zitierten Posting springen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
if PtInRect(Shape1.BoundsRect,Mittelpunkt) THEN vy:=vy*-1;
Mittelpunkt:=Image1.BoundsRect.BottomRight;
Mittelpunkt:=Image1.BoundsRect.TopLeft;
Mittelpunkt.x:=Mittelpunkt.X-Image1.Width DIV 2;

if PtInRect(Shape2.BoundsRect,Mittelpunkt) THEN vy:=vy*-1;
Mittelpunkt:=Image1.BoundsRect.BottomRight;
Mittelpunkt:=Image1.BoundsRect.TopLeft;

Mittelpunkt.x:=Mittelpunkt.X-Image1.Width DIV 2;
Kann es sein, dass du denkst, dass zu dem if alles danach gehört? Das stimmt nicht. Die korrekte Einrückung:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
if PtInRect(Shape1.BoundsRect,Mittelpunkt) then
  vy := vy * -1;

Mittelpunkt := Image1.BoundsRect.BottomRight;
Mittelpunkt := Image1.BoundsRect.TopLeft;
Mittelpunkt.x := Mittelpunkt.X - Image1.Width div 2;

if PtInRect(Shape2.BoundsRect,Mittelpunkt) then
  vy := vy * -1;

Mittelpunkt : =Image1.BoundsRect.BottomRight;
Mittelpunkt := Image1.BoundsRect.TopLeft;
Mittelpunkt.x := Mittelpunkt.X - Image1.Width div 2;
Die if-Abfragen habe ich einzeln geschrieben um zu zeigen, dass die mir den folgenen Zeilen jeweils nix zu tun haben. Du weist also Mittelpunkt und vy immer wieder neu zu. Auch in diesen Zeilen bereits:
ausblenden Delphi-Quelltext
1:
2:
Mittelpunkt := Image1.BoundsRect.BottomRight;
Mittelpunkt := Image1.BoundsRect.TopLeft;
In der zweiten Zeile überschreibst du den Wert der ersten.

Wenn du mehrere Befehle in if schreiben willst, dann musst du begin..end benutzen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
if PtInRect(Shape1.BoundsRect,Mittelpunkt) then
begin
  vy := vy * -1;
  Mittelpunkt := Image1.BoundsRect.BottomRight;
  Mittelpunkt := Image1.BoundsRect.TopLeft;
  Mittelpunkt.x := Mittelpunkt.X - Image1.Width div 2;
end;
Da hier aber die Befehle ohnehin wiederholt werden, lässt sich dein aktueller Quelltext auch stark kürzen, die auskommentierten Zeilen haben keine Wirkung, was dir eigentlich auch der Compiler sagen sollte...
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
procedure TForm1.Timer1Timer(Sender: TObject);
var
  Mittelpunkt: TPoint;
  Punkte: Integer;
begin
  Punkte := 0;
  // Image(Ball) um Schrittweite bewegen
  Image1.Left := Image1.Left + vx;
  Image1.Top := Image1.Top + vy;
  if (Image1.Left <= Panel1.Left) or (Image1.Left >= Panel1.Width - Image1.Width -1then
    vx := vx * -1// links und rechts
  //Mittelpunkt := Image1.BoundsRect.BottomRight;
  //Mittelpunkt.x := Mittelpunkt.X - Image1.Width div 2;

  if PtInRect(Shape1.BoundsRect,Mittelpunkt) then
    vy := vy * -1;
  //Mittelpunkt := Image1.BoundsRect.BottomRight;
  //Mittelpunkt := Image1.BoundsRect.TopLeft;
  //Mittelpunkt.x := Mittelpunkt.X - Image1.Width div 2;

  if PtInRect(Shape2.BoundsRect,Mittelpunkt) then
    vy := vy * -1;
  //Mittelpunkt := Image1.BoundsRect.BottomRight;
  Mittelpunkt := Image1.BoundsRect.TopLeft; // <-- HIER weist du Mittelpunkt zuletzt zu, dies ist der benutzte Wert!
  Mittelpunkt.x := Mittelpunkt.X - Image1.Width div 2;

  if (Image1.Top <= Panel1.Top) or (Image1.Top >= Panel1.Height -Image1.Height -1then
    vy := vy * -1//oben und unten

  if (image1.Top >= Panel1.Height - Image1.Height-1then
    Inc(Punkte);
  Label2.Caption := IntToStr(Punkte);
end;
suga2001 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 38



BeitragVerfasst: Mo 12.01.09 20:46 
Danke für die schnelle und informative Antwort.
Ich habe den Quelltext nun übernommen und ausprobiert. Leider hat das nun den Effekt, dass mein image1 einfach durch meine shapes durchfliegt, als wenn sie gar nicht da wären.
Vorher ist image1 noch am oberen rand des shapes abgeprallt, was nun nicht mehr so ist. ich bin echt ratlos...
Marc.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1876
Erhaltene Danke: 129

Win 8.1, Xubuntu 15.10

BeitragVerfasst: Mo 12.01.09 21:43 
user profile iconsuga2001 hat folgendes geschrieben Zum zitierten Posting springen:
Danke für die schnelle und informative Antwort.

Habe ich dir nicht auch geantwortet? :roll:
Nochmal: Du musst zur Position die Breite dazurechnen!
ausblenden Delphi-Quelltext
1:
2:
 if ((Image1.Left + Image1.Width) >= Panel1.Left) and (Image1.Left <= Panel1.Left + Panel1.Width)  then
  vx:=vx*-1;

Funktioniert bei mir tadellos...

Warum die Breite wichtig ist:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
    A-------B
   // A gibt die linke Kante deines Images an und befindet sich an der Stelle "Left". 
   // Das Image besteht jedoch nicht nur aus einer Kante, sondern bildet ein ganzes Rechteck,
   // dargestellt durch die Striche. Mit A+Width kommst du zur rechten Kante, die du bei der Kollision von Links mit dem Panel prüfst.
   // und vice versa...


Grüße,
Marc.


Zuletzt bearbeitet von Marc. am Mo 12.01.09 21:51, insgesamt 2-mal bearbeitet
suga2001 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 38



BeitragVerfasst: Mo 12.01.09 21:46 
doch, hast du ^^ . das war ernst gemeint :roll: . ich fand alles informativ :idea: , aber nun ist mir aufgefallen,dass ich mir die ganze Zeit falsch ausgedrückt habe. von meinen panelseiten prallt der ball wunderbar ab. :wink:

wenn der aber auf mein shap1 trifft, bleibt er hängen oder stottert, fliegt sogar manchmal einfach ein stücks ins shape, wobei ich auch da die grenzen definiert habe.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Di 13.01.09 13:31 
Ich hab jetzt nochmal geschaut. Die auskommentierten Zeilen haben doch teilweise eine Wirkung, weil du prüfst, ob der Punkt in dem Rechteck liegt und da verschiedene Punkte des Rechtecks angibst. :oops:
Aber was das bewirken soll ist mir nicht so klar.

Wie wäre es, wenn du eine Funktion schreibst, die dir zurückgibt, ob es eine Kollision gibt, wenn du zwei Rechtecke der Komponenten und die aktuelle Bewegung übergibst. Dann prüfst du eine Kollision bei der aktuellen Bewegung in x-Richtung und y-Richtung und kehrst ggf. die entsprechende Bewegung um.